vscode-maven
vscode-maven copied to clipboard
maven.terminal.useJavaHome doesnt work if JAVA_HOME already set by shell startup scripts
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:
- 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"
}
],
- Goto maven in explorer, and try to create a terminal by running mvn goal. For example run a custom goal of
-version
- Check if
Java version:
in the console is same asjava.home
in your settings, not theJAVA_HOME
set by your.zshrc
or.zshenv
- However
maven.terminal.customEnv
is able to set variables other thenJAVA_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
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.
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.
Sorry about the misleading. If you want to use a specific JAVA_HOME, you can either:
- set
maven.terminal.useJavaHome
to true, and setjava.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
.
@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...
@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.
OK, then I think it can be a regression introduced by https://github.com/microsoft/vscode-maven/pull/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
@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.
BTW, FYI I have opened a ticket in microsoft/vscode#98490 to get terminal.integrated.env.osx
fixed.
@Eskibear : I think VSCode has new API now for extensions to contribute to env variable in integrated terminals. See here and here
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
.
@thakkarparth007 Thank you for reporting this. When did you see this error, and what's the full error message?
@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!
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.
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.
BTW, I just searched vscode's repo for zsh issues, check if https://github.com/microsoft/vscode/issues/143061 helps?
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
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:
Here, I don't specify JAVA_HOME
at all:
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?
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
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"
},
],
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"
}
],