2

In WSL2, with ubuntu distro, I defined a new variable in /etc/profile (I also tried ~/.bashrc and /etc/environment)

export JDK_17_0=/home/scaventz/sdk/jdk-17

then source /etc/profile

then I try to get this variable by creating a Java Project in Windows with Intellij IDEA (The project itself is located in WSL2 of course):

public class Main {
    public static void main(String[] args) {
        String prop = "JDK_17_0";
        String jdk = System.getProperty(prop);
        if (jdk == null) {
            jdk = System.getenv(prop);
        }
        System.out.println(jdk);
    }
}

I get a null.

It seems a WSL2 related issue, is there any workaround?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
scaventz
  • 45
  • 4
  • What does it mean: The project itself is located in WSL2? – Alexandr Ivanov Aug 27 '21 at 03:21
  • Sorry for didn't describe it clearly, It means I created a java project in WSL2, and open it with IDEA in Windows. – scaventz Aug 27 '21 at 03:28
  • The problem with exporting an environment variables is that it only persists for your terminal sessions, I think the same goes for `source /etc/profile` . You said you added it to ~/.bashrc? Can you echo that variable from your WSL2 terminal? – Sam Orozco Aug 27 '21 at 03:59
  • do you start your application in WSL2 terminal? – Alexandr Ivanov Aug 27 '21 at 04:02
  • 1
    Env vars are private to each process. Changing an env var in one process does not modify it in a different process. I suspect you think env vars are global. That is incorrect. – Kurtis Rader Aug 27 '21 at 04:29
  • @SamOrozco Yes, it works fine with WSL2 terminal – scaventz Aug 27 '21 at 04:29
  • @AlexandrIvanov It works fine if I run `java Main` in WSL2 terminal, but it failed and printed `null` when i use IDEA or run a command like `wsl /home/scaventz/.sdkman/candidates/java/8.0.292.hs-adpt/bin/java -classpath /home/scaventz Main` in CMD – scaventz Aug 27 '21 at 04:40
  • 2
    @scaventz: Environment variables are inherited transitively by the **child** processes. You have to arrange that your Java program is run as a child process from the bash process which sets the variable. – user1934428 Aug 27 '21 at 08:33

1 Answers1

2

Yes, that's to be expected, and yes, there's a workaround. By default, exported WSL environment variables do not propagate back to the Windows environment. You can see the same behavior by (starting in WSL/Bash):

> export JDK_17_0=/home/scaventz/sdk/jdk-17
> powershell.exe
PS > $env:JDK_17_0

... which will not return anything.

But WSL does have an Interop feature for sharing environment variables between WSL and Windows processes.

Repeating our previous example:

> export JDK_17_0=/home/scaventz/sdk/jdk-17
> WSLENV=JDK_17_0 powershell.exe
PS > $env:JDK_17_0
/home/scaventz/sdk/jdk-17

Note that this doesn't directly modify the System environment variables in Windows; it just injects a new variable into the powershell.exe process. So you should be able to do the same thing by calling the Intellij IDEA Windows executable (you may need the full /mnt/c/... path to it, if it isn't in the Windows path) in the same manner. Because the Windows Java executable is being kicked off by Intellij, environment variables that are set for the Intellij processes should propagate to the Java process.

While I don't have that particular setup here at the moment, I was at least able to confirm it by launching VSCode from within that PowerShell session above. Inside VSCode, the environment variable was still available.

Also be aware, of course, of the differences in the path structure between WSL/Linux and Windows. Just because you can pass /home/scaventz/sdk/jdk-17 into Java running on Windows doesn't mean that it will understand it. Java on Windows understands Windows path structure. It won't have direct access to anything in /home/scaventz/sdk/jdk-17.

I realize that you aren't trying to access the filesystem in that example, but I assume that's a future step for you since you are passing a path. So you will probably want to use the translatable path option for WSLENV:

> export JDK_17_0=/home/scaventz/sdk/jdk-17
> WSLENV=JDK_17_0/p powershell.exe
PS > $env:JDK_17_0
\\wsl$\Ubuntu\home\scaventz\sdk\jdk-17 # Or \\wsl$\whatever_your_distribution_is_named\...

Side note:

It seems a WSL2 related issue

To be fair, not really. The way that you are describing things, you would see the same behavior if you did this from PowerShell. Try setting the same environment variable in PowerShell, then launch Intellij IDEA from the Windows Start Menu. It won't have access to that variable either.

Only when launching a new process from within a parent process do you have any hope of passing a variable to a that new process.

Unless you use PowerShell to modify the System variables like so. And note that you could do that through WSL's Interop with PowerShell as well, if needed.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70