Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

maven.terminal.useJavaHome doesnt work if JAVA_HOME already set by shell startup scripts #495

Open
jahan01 opened this issue May 24, 2020 · 23 comments
Assignees

Comments

@jahan01
Copy link

jahan01 commented May 24, 2020

Describe the bug
"maven.terminal.useJavaHome": true, or maven.terminal.customEnv doesnt override JAVA_HOME on zsh. It works in bash shell (by changing"terminal.integrated.shell.osx": "/bin/bash").

Due to this I am not able to compile/package my project by clicking in mvn explorer as by default it uses my system jdk, not my project jdk as specified in java.home

To Reproduce
Steps to reproduce the behavior:

  1. Set below settings and make sure your default shell is zsh on mac.
"java.home": "/my/jdk/path",
"maven.terminal.useJavaHome": true,
"maven.terminal.customEnv": [
    {
        "environmentVariable": "JAVA_HOME",
        "value": "/my/jdk/path"
    },
    {
        "environmentVariable": "MY_MVN_ENV",
        "value": "my value"
    }
],
  1. Goto maven in explorer, and try to create a terminal by running mvn goal. For example run a custom goal of -version
  2. Check if Java version: in the console is same as java.home in your settings, not the JAVA_HOME set by your .zshrc or .zshenv
  3. However maven.terminal.customEnv is able to set variables other then JAVA_HOME. i.e, MY_MVN_ENV is set properly in the terminal

Expected behavior
System wide JAVA_HOME is overridden with java.home and able to compile using project specific JDK version.

Environments (please complete the following information as much as possible):

  • OS: Mac OS 10.15.4
  • VS Code version: 1.45.1
  • Extension version 0.21.4
@Eskibear
Copy link
Member

Here is a misunderstanding of setting maven.terminal.useJavaHome, it's indicating whether you are going to use value of setting java.home as your JAVA_HOME... You can set it to false, and have a try. Let me know if it works or not.

@Eskibear Eskibear self-assigned this May 25, 2020
@Eskibear Eskibear added the needs more info Further information is requested label May 25, 2020
@jahan01
Copy link
Author

jahan01 commented May 25, 2020

Okay, I am not clear how this works. I am listing the info from my system
.zshenv

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home

settings.json

"java.home": "/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home",
"maven.terminal.useJavaHome": true,

Run custom maven goal from explorer -version

Java version: 11.0.6.0.1,

Change this settings

"maven.terminal.useJavaHome": false,

I still get JDK 11 when I run -version

Java version: 11.0.6.0.1,

My intention is to use JDK 8, which is specific to this project and not global JDK 11.

@no-response no-response bot removed the needs more info Further information is requested label May 25, 2020
@Eskibear
Copy link
Member

Sorry about the misleading. If you want to use a specific JAVA_HOME, you can either:

  • set maven.terminal.useJavaHome to true, and set java.home in settings.json
    or
  • (recommended) simply use "maven.terminal.customEnv" as you mentioned.

I can reproduce your zsh issue, and it works well for bash as you mentioned. This extension tells vscode to append custom envs(e.g. JAVA_HOME) when opening a new integrated terminal. I just double checked it, the envs are correctly passed to vscode. and I guess that's probably related to how vscode loads the profiles, for zsh particularly.

Let me share my findings.

I have JDK 11/13/14 installed.

.bash_profile

# No JAVA_HOME specified

.zshenv

export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home

settings.json

"java.home": "/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home",
"maven.terminal.useJavaHome": true,

For Bash

Run mvn -version in a manually created terminal.

Java version: 14.0.1

Run custom maven goal from explorer -version

Java version: 11.0.7

For Zsh

Now I set "terminal.integrated.shell.osx": "/bin/zsh", it's buggy.
Run mvn -version in a manually created terminal.

Java version: 13.0.2

Run custom maven goal from explorer -version

Java version: 13.0.2

Now if I remove JAVA_HOME from .zshenv, it's working as expected
Run mvn -version in a manually created terminal.

Java version: 14.0.1

Run custom maven goal from explorer -version

Java version: 11.0.7

My guess is, for zsh, vscode first loads the custom envs passed by this extension, and later from .zshenv.

@Eskibear
Copy link
Member

@jahan01 try printing out the values in .zshenv like below, which somehow proves my hypothesis above.

echo before:$JAVA_HOME
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home
echo after:$JAVA_HOME

I'm not familiar with zshell, but I think there's no way to interfere zshell's behavior in this extension...

@jahan01
Copy link
Author

jahan01 commented May 25, 2020

@Eskibear : yes, you are right in saying that vscode sets the env variable at the terminal creation but it is overridden if the avariables are also set in shell start up scripts(.zshrc, .zshenv or .bash_profile etc.,)

I just observed behaviour is same both in zsh and bash. If you set JAVA_HOME in .bashrc, vscode is not able to override with maven.terminal.useJavaHome or maven.terminal.customEnv or even terminal.integrated.env.osx doesn't work in both the shells.

This also doesnt work (i.e., overridden by shell startup scripts)

 "terminal.integrated.env.osx": {
        "JAVA_HOME": "/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home",
   }

Earlier I had not set JAVA_HOME in .bash_profile so I assumed it was working fine in bash. Turns out this behaviour is same in both bash and zsh.

@Eskibear
Copy link
Member

OK, then I think it can be a regression introduced by #240 .

Previously it manually executed "export" statements for different kind of shells. So no matter what was written in the startup scripts, the command finally won...

Do you think we should revert the change and back to previous behavior? The side effect would be:

  • we have to detect shell types and assemble the "export" command for them by the extension itself.
  • you always have the "export" statement executed before your command.

also /cc @jdneo

@jahan01
Copy link
Author

jahan01 commented May 25, 2020

@Eskibear I am not an expert, but this is exactly what vscode-python extension do to activate virtual environment (though it doesnt do export, but I think approach is similar to what you describe). After terminal creation it assembles the command based on OS and virtual env and send them as a text to be executed.

Somehow, intellij idea and pycharm doesnt need to do these hacks, somehow the set correct variables without executing statements after terminal creation.

@jahan01 jahan01 changed the title maven.terminal.useJavaHome doesnt work on ZSH shells maven.terminal.useJavaHome doesnt work if JAVA_HOME already set by shell startup scripts May 25, 2020
@jahan01
Copy link
Author

jahan01 commented May 25, 2020

BTW, FYI I have opened a ticket in microsoft/vscode#98490 to get terminal.integrated.env.osx fixed.

@jahan01
Copy link
Author

jahan01 commented Jun 11, 2020

@Eskibear : I think VSCode has new API now for extensions to contribute to env variable in integrated terminals. See here and here

@thakkarparth007
Copy link

java.home has been deprecated recently. VSCode wants us to use 'java.jdt.ls.java.home' instead. As a result, I was not setting java.home in settings.json, and this extension kept giving JAVA_HOME not set correctly errors. So, I set java.home anyway and the extension stopped facing issues. This is a temporary workaround though, and ideally the extension should now read java.jdt.ls.java.home instead of java.home.

@Eskibear
Copy link
Member

@thakkarparth007 Thank you for reporting this. When did you see this error, and what's the full error message?

@thakkarparth007
Copy link

@Eskibear here's the error message I got when I saved a pom.xml file, or on clicking the "Dependencies" option in the maven toolbar.

Spawn {"command":"\"/home/parthdt2/apache-maven-3.8.4/bin/mvn\"","args":["-N","com.github.ferstl:depgraph-maven-plugin:3.3.1:graph","-DgraphFormat=text","-DshowDuplicates","-DshowConflicts","-DshowVersions","-DshowGroupIds","-DoutputDirectory=\"/home/parthdt2/.vscode-server/data/User/workspaceStorage/dea46b679bf34fed54910712a5990448/vscjava.vscode-maven\"","-DoutputFileName=\"044fa7c3c75de7b20913fb184edd5478.deps.txt\"","-f","\"/home/parthdt2/project/java_transformations/java_transformations/pom.xml\""]}
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.

This is when my settings.json file looked like this:

{
    //"java.home": "/home/parthdt2/.jabba/jdk/[email protected]",
    //"java.jdt.ls.java.home": "/home/parthdt2/.jabba/jdk/[email protected]",
    "terminal.integrated.env.linux": {
        "JAVA_HOME": "/home/parthdt2/.jabba/jdk/[email protected]"
    },
    "terminal.integrated.defaultProfile.linux": "zsh",
    "maven.executable.path": "/home/parthdt2/apache-maven-3.8.4/bin/mvn",
    "maven.terminal.useJavaHome": true // tried both commenting and uncommenting this.
}

I'm using Jabba for managing Java environments, and my ~/.zshrc loads the jdk automatically. Therefore, whenever a new terminal is opened, the JAVA_HOME variable is correctly set. However, vscode-maven seems to use spawn, and my VSCode doesn't load ~/.zshrc while starting, so the spawn function never gets to see the JAVA_HOME variable anywhere.

After seeing the explanation for maven.terminal.useJavaHome (Maven › Terminal: Use Java Home If this value is true, and if the setting java.home has a value, then the environment variable JAVA_HOME will be set to the value of java.home when a new terminal window is created.), I tried setting java.jdt.ls.java.home because that's the recommended way to set java.home, but that setting made no difference to vscode-maven. So I then set java.home explicitly ignoring VSCode's complains, and then vscode-maven was happy.

I've tried to give all details I could think of, let me know if you need more details!

@Eskibear
Copy link
Member

Thanks, it's very helpful for locating the problem.

The problem is, Maven requires you to set JAVA_HOME env (e.g. to run mvn commands), and you don't have the JAVA_HOME set in your zsh profile.

So I then set java.home explicitly ignoring VSCode's complains, and then vscode-maven was happy.

If java.home can work it around, then you may try maven.terminal.customEnv, see if it works.

@thakkarparth007
Copy link

you don't have the JAVA_HOME set in your zsh profile.

But I do have JAVA_HOME set in my zsh profile. I run jabba use [email protected] in the zshrc, and that automatically sets JAVA_HOME. I think the problem might be that the spawn call does not load the shell profile before executing the commands.

I'll try maven.terminal.customEnv and let you know.

@Eskibear
Copy link
Member

BTW, I just searched vscode's repo for zsh issues, check if microsoft/vscode#143061 helps?

@yorkish
Copy link

yorkish commented Nov 10, 2022

Trying to make it work on

RockyLinux 8.6
VsCode 1.73.1
Maven extension 0.39.2

I`ve added this piece of config everywhere (User / Workspace / Folder )

    "maven.terminal.customEnv": [
        {
            "environmentVariable": "FOO",
            "value": "bar"
        }
    ]

And opening a new integrated shell only to find that the FOO env variable isn't present.

tried that after banging my head over JAVA_HOME.

so the problem isn't linked to having JAVA_HOME set in .bashrc

@ivorobioff
Copy link

ivorobioff commented Feb 17, 2023

I wrote a simple maven plugin to test this problem out, and here's what I found. So, I use WSL2 with Ubuntu 22.04. JAVA_HOME is set to /home/linuxbrew/.linuxbrew/opt/openjdk@11. So, if I don't specify JAVA_HOME in maven.terminal.customEnv then within my plugin JAVA_HOME == null which makes sense. However, if I do specify JAVA_HOME but with different path not the one is set by default in the system then within my plugin I get the path assigned by default in the system not in the maven.terminal.customEnv configuration. It's definitely not working okay. You can see the screenshots demonstrating it.

Here I set JAVA_HOME to use a different sdk not the one specified in the system:

foo

Here, I don't specify JAVA_HOME at all:

bar

@Eskibear
Copy link
Member

Looks like JAVA_HOME is not loaded when vscode starts the terminal. Can you run echo $JAVA_HOME in the terminal where JAVA_HOME is null?

@Kambaa
Copy link

Kambaa commented Feb 23, 2023

Update: How about this approach?
https://www.baeldung.com/maven-different-jdk#setting-up-javahome-only-for-maven

https://stackoverflow.com/a/43524685/1020512

Hello, after this happenned to me, i read this page and done some googling. According to the links that i'll write below, we need JAVA_HOME env variable set to use maven commands successfully. So before anything, if we want to do some 'specific' JDK usage on maven, i think we need to set the JAVA_HOME explicitly, and then run the appropriate maven command.

https://www.baeldung.com/maven-java-home-jdk-jre
https://stackoverflow.com/questions/15279586/java-home-in-maven
https://subscription.packtpub.com/book/application-development/9781785286124/1/ch01lvl1sec13/changing-the-jdk-used-by-maven
(NOT So much for our case but good to know the options) https://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html
https://stackoverflow.com/questions/2503658/specify-jdk-for-maven-to-use
(check maven.terminal.useJavaHome did not work for me on /individual project folder and workspace level) https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-maven

@cypher256
Copy link

On macOS, the following solved the problem.
The following JAVA_HOME takes precedence over the OS JAVA_HOME environment variable.

"maven.terminal.customEnv": [
    {
        "environmentVariable": "JAVA_HOME",
        "value": "/xxx/java/21"
    },
    {
        "environmentVariable": "ZDOTDIR",
        "value": "~/.zsh_dummy"
    },
],

@Eskibear Eskibear assigned jdneo and testforstephen and unassigned Eskibear Dec 27, 2023
@cypher256
Copy link

@cypher256
Copy link

cypher256 commented Jan 19, 2024

Another ways to ignore the system's JAVA_HOME env var.

macOS

settings.json

"maven.terminal.customEnv": [
    {
        "environmentVariable": "JAVA_HOME",
        "value": "/xxx/java/21"
    },
    {
        "environmentVariable": "ZDOTDIR",
        "value": "/xxx/rcdir"
    }
],

/xxx/rcdir/.zshrc (See repository)

if [ -r ~/.zshrc ]; then
	JAVA_HOME_BACKUP=$JAVA_HOME
	source ~/.zshrc
	export JAVA_HOME=$JAVA_HOME_BACKUP
fi
export PATH="$JAVA_HOME/bin:$PATH"

Linux

settings.json

"maven.terminal.customEnv": [
    {
        "environmentVariable": "JAVA_HOME",
        "value": "/xxx/java/21" // For Maven
    }
],
"terminal.integrated.profiles.linux": {
    "bash": {
        "path": "bash",
        "env": {"JAVA_HOME": "/xxx/java/17"}, // Terminal Default
        "args": ["--rcfile", "/xxx/rcdir/.bashrc"]
    },
},

/xxx/rcdir/.bashrc (See repository)

if [ -r ~/.bashrc ]; then
    JAVA_HOME_BACKUP=$JAVA_HOME
    source ~/.bashrc
    export JAVA_HOME=$JAVA_HOME_BACKUP
fi
export PATH="$JAVA_HOME/bin:$PATH"

Windows

settings.json

"maven.terminal.customEnv": [
    {
        "environmentVariable": "JAVA_HOME",
        "value": "C:¥¥xxx¥¥java¥¥21"
    }
],

@Guan-Meng-Yuan
Copy link

hi,this is my .zshrc. It is working normally now.

if [ -z "$JAVA_HOME" ]; then
	JAVA_HOME=$(/usr/libexec/java_home)
	export JAVA_HOME
	echo "JAVA_HOME not set, defaulting to $JAVA_HOME"
else
	echo "JAVA_HOME is already set to $JAVA_HOME"
fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants