environment var not set on job process, and not propagated to forked sub-process

This issue is archived. You can view it, but you can't modify it. Learn more

XMLWordPrintable

      the EnvInject plugin does not really set the "environment variables" at the OS level, using native POSIX call "putenv()".
      It is only available in some jenkins sub-tasks when calling appropriate jenkins API to exec tasks... but not when calling plain old java code "System.exec()" within a Mojo.... so most Mojo don't work (my problem was when using maven-dotnet-plugin, that forks to execute "Msbuild.exe")

      When doing few search over google to set an environment variable in java, I found a piece of code that might be "portable enough", using JNA native calls to standards dlls (msvcrt on Windows / libc on Linux, which solve 100% of my needs)

      It simply exposes a method "putenv()" to be called as this:

      SetEnvUtil.putenv("testvar", "123", 1);

      So my request is to add such calls within the EnvInject plugin, but I don't know how to patch exactly the EnvInject jenkins plugin

      It depends on the JNA jar, for example using the maven dependency

          <dependency>
      	  <groupId>net.java.dev.jna</groupId>
      	  <artifactId>jna</artifactId>
      	  <version>3.4.0</version>
          </dependency>
      

      Here is the utility class

      SetEnvUtil.java
      import com.sun.jna.Library;
      import com.sun.jna.Native;
      
      public class SetEnvUtil {
      
          // Inside the Environment class...
          public interface WinLibC extends Library {
              public String getenv(String name);
              public int _putenv(String name);
          }
      
          public interface LinuxLibC extends Library {
              public String getenv(String name);
              public int setenv(String name, String value, int overwrite);
              public int unsetenv(String name);
          }
      
          private static Object libc;
          static {
              String osName = System.getProperty("os.name");
              if (osName.equals("Linux")) {
                  libc = Native.loadLibrary("c", LinuxLibC.class);
              } else {
                  libc = Native.loadLibrary("msvcrt", WinLibC.class);
              }
          }
      
          public static String getenv(String name) {
              if (libc instanceof LinuxLibC) {
                  return ((LinuxLibC) libc).getenv(name);
              } else {
                  return ((WinLibC) libc).getenv(name);
              }
          }
          
          public static int setenv(String name, String value, int overwrite) {
              if (libc instanceof LinuxLibC) {
                  return ((LinuxLibC) libc).setenv(name, value, overwrite);
              } else {
                  return ((WinLibC) libc)._putenv(name + "=" + value);
              }
          }
      
          public static int unsetenv(String name) {
              if (libc instanceof LinuxLibC) {
                  return ((LinuxLibC) libc).unsetenv(name);
              } else {
                  return ((WinLibC) libc)._putenv(name + "=");
              }
          }
      
      }
      

      I have done a simple Main for testing purpose, so you can convinced it works simply:

      SetEnvMain.java
      public class SetEnvMain {
      
          public static final String TEST_VAR_NAME  = "TEST_VAR";
      
          public static void main(String[] args) {
              dump("before setenv() ... ");
              
              // *** first setenv()  : add new env var 
              SetEnvUtil.setenv(TEST_VAR_NAME , "123", 1);
              
              dump("after setenv(\"" + TEST_VAR_NAME + ", \"123\") ... ");
      
              // *** second call setenv()  : override existing var 
              SetEnvUtil.setenv(TEST_VAR_NAME , "456", 1);
              
              dump("after setenv(\"" + TEST_VAR_NAME + ", \"456\") ... ");
          }
          
          public static void dump(String messagePrefix) {
              String var_native = SetEnvUtil.getenv(TEST_VAR_NAME);
              String var_cached = System.getenv(TEST_VAR_NAME); // FALSE... cached by java!
              System.out.println(messagePrefix + " " + TEST_VAR_NAME + ": " + var_native + ", (cached): " + var_cached);
          }
          
      }
      

            Assignee:
            Gregory Boissinot
            Reporter:
            Arnaud Nauwynck
            Archiver:
            Jenkins Service Account

              Created:
              Updated:
              Archived: