-
Bug
-
Resolution: Unresolved
-
Major
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
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:
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); } }