Honor the JAVA_HOME environment variable
Is your feature request related to a problem? Please describe. Visualvm does not honor the JAVA_HOME variable. Having to start it with "bin/visualvm --jdkhome $JAVA_HOME" is an unneccessary annoyance.
Describe the solution you'd like If JAVA_HOME is set, then visualVM should use it as the default value for the jdkhome. If it is not set, visualvm should behave as it does today.
Describe alternatives you've considered None
Additional context JAVA_HOME is used by most Java startup scritps to locate the JRE to be used. Developers expect JAVA_HOME to be honored, and is usually set correctly on developer machines by jenv, sdkman, etc.
we can add configure visualvm_jdkhome in visualvm/etc/visualvm.conf file, then visualvm need no addinational arguments to run
Yes, but setting that is still a separate setup step, so it doesn' really solve the issue.
This has already been fixed for Windows in #112
So the logic / JVM precendence could be copied from there to make sure that it behaves consistently between Unix and Windows.
PR #643 Added JAVA_HOME to visulavm luncher & conf
@stoty Can you, please, describe in which situation you rely on JAVA_HOME? The current state is there for a long time, so it would be useful to know your use case. Note that NetBeans Platform code is primarily responsible for finding the JDK, so the problem should be ideally fixed there.
I am using the standalone visualvm distribution.
The JVM is chosen by the startup bash script on Unix, which chooses the JVM for running visualvm. I'm not sure what you mean by the NetBeans platform code. Possibly visualvm is started differently when it is started as a NetBeans module (as opposed to the standalone visualvm startup script) , but then this patch does not apply in that case.
I am working on multiple versions of multiple projects, which require different java versions, and use jenv to switch between them. All of my other tools (well, except for Eclipse) honor the JAVA_HOME environment variable.
Also, this patch only aligns the unix startup script behaviour with the existing Windows behaviour, which already honor JAVA_HOME (see my comment above with the commit )
I'm not sure what you mean by the NetBeans platform code.
If you do not specify JDK explicitly, it is chosen by NetBeans platform code, not by VisualVM launcher script.
I am working on multiple versions of multiple projects, which require different java versions
I see, but you are not required to run VisualVM on the same JDK as your project. VisualVM can simultaneously monitor Java processes running on different JDKs (JDK 6 up to JDK 24), so the JDK on which VisualVM is running has no connection to the JDK of your monitored processes.
patch only aligns the unix startup script behaviour with the existing Windows
Windows is a different story. The GH-112 fix in Windows is basically a workaround for VisualVM not starting at all in some situations (see discussion at GH-112). Again, on Windows, the JDK should be chosen by the NetBeans Platform code. Currently there are some historical changes in VisualVM Windows launcher regarding JDK selection, but they are unrelated to JDK_HOME. So unless this is a critical problem, I do not want to apply a similar workaround to the Unix launcher in VisualVM.
It looks like NetBeans Platform updated the Windows code to consider JAVA_HOME (See NB-8408) so GH-112 could be removed once we update VisualVM to use NetBeans Platform 26.
If you do not specify JDK explicitly, it is chosen by NetBeans platform code, not by VisualVM launcher script.
That does not match my experience. If you do not add the cli option or set it in the command line, then VisualVM will not find any JVM, and will not start.
also, there is heuristics in the VisualVM laucher script to find the JVM.
visualvm script call to nbexec script which exepect --jdkhome argument
./nbexec --help
Usage: ./nbexec {options} arguments
General options:
--help show this help
--jdkhome <path> path to Java(TM) 2 SDK, Standard Edition
-J<jvm_option> pass <jvm_option> to JVM
--cp:p <classpath> prepend <classpath> to classpath
--cp:a <classpath> append <classpath> to classpath
The operation couldn’t be completed. Unable to locate a Java Runtime.
Please visit http://www.java.com for information on installing Java.
Cannot find java. Please use the --jdkhome switch.
From visualvm script we are composeing the arguments & delegate to nbexec
/bin/bash /Users/Documents/oracle.visualvm/visualvm/dist/visualvm/platform/lib/nbexec
--userdir '/Users/Library/Application Support/VisualVM/dev'
--cachedir /Users/Library/Caches/VisualVM/dev
--jdkhome /Library/Java/JavaVirtualMachines/JDK17GVM
-J-Xdock:name=VisualVM
-J-Xdock:icon=/Users/Documents/oracle.visualvm/visualvm/dist/visualvm/etc/visualvm.icns
--branding visualvm
--clusters /Users/Documents/oracle.visualvm/visualvm/dist/visualvm/visualvm:
-J-Xms24m
-J-Xmx768m
-J-Dnetbeans.accept_license_class=org.graalvm.visualvm.modules.startup.AcceptLicense
-J-Dnetbeans.importclass=org.graalvm.visualvm.modules.startup.ImportSettings
-J-Dsun.jvmstat.perdata.syncWaitMs=10000
-J-Dsun.java2d.noddraw=true
-J-Dsun.java2d.d3d=false
-J-DTopSecurityManager.disable=true
-J-Dorg.netbeans.core.TimeableEventQueue.quantum=360000
-J-Dpolyglot.js.nashorn-compat=true
-J-Dsun.misc.URLClassPath.disableJarChecking=true
-J-Djdk.attach.allowAttachSelf=true
-J-Dorg.openide.util.ImageUtilities.level=950
-J--add-exports=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED
-J--add-exports=java.desktop/sun.awt=ALL-UNNAMED
-J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor.event=ALL-UNNAMED
-J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
-J--add-exports=java.desktop/sun.swing=ALL-UNNAMED
-J--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED
-J--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED
-J--add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED
-J--add-opens=java.base/java.net=ALL-UNNAMED
-J--add-opens=java.base/java.lang.ref=ALL-UNNAMED
-J--add-opens=java.base/java.lang=ALL-UNNAMED
-J--add-opens=java.desktop/javax.swing=ALL-UNNAMED
-J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED
-J-XX:+IgnoreUnrecognizedVMOptions
-J-Dnetbeans.logger.console=true
-J-Dnetbeans.exception.report.min.level=900
-J-ea
If you do not specify JDK explicitly, it is chosen by NetBeans platform code, not by VisualVM launcher script.
That does not match my experience. If you do not add the cli option or set it in the command line, then VisualVM will not find any JVM, and will not start.
It works fine. In general, you are not required to specify the JDK. Of course there could be system configuration, when JDK is not found. That is why I asked for your use-case.
visualvm script call to
nbexecscript which exepect --jdkhomeargument
VisualVM launcher does not require JDK. If you do not specify it, the nbexec invocation looks like this:
+ exec /bin/bash /home/thurka/Projects/visualvm_219/platform/lib/nbexec
--userdir /home/thurka/.visualvm/2.1.9
--cachedir /home/thurka/.cache/visualvm/2.1.9
--jdkhome
--branding visualvm
--clusters /home/vscode/Projects/visualvm_219/visualvm:
-J-Xms24m
-J-Xmx768m
-J-Dnetbeans.accept_license_class=org.graalvm.visualvm.modules.startup.AcceptLicense
-J-Dnetbeans.importclass=org.graalvm.visualvm.modules.startup.ImportSettings
-J-Dsun.jvmstat.perdata.syncWaitMs=10000
-J-Dsun.java2d.noddraw=true
-J-Dsun.java2d.d3d=false
-J-Dorg.netbeans.core.TimeableEventQueue.quantum=360000
-J-Dpolyglot.js.nashorn-compat=true
-J-Dsun.misc.URLClassPath.disableJarChecking=true
-J-Djdk.attach.allowAttachSelf=true
-J-Dorg.openide.util.ImageUtilities.level=950
-J--add-exports=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED
-J--add-exports=java.desktop/sun.awt=ALL-UNNAMED
-J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor.event=ALL-UNNAMED
-J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
-J--add-exports=java.desktop/sun.swing=ALL-UNNAMED
-J--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED
-J--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED
-J--add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED
-J--add-opens=java.base/java.net=ALL-UNNAMED
-J--add-opens=java.base/java.lang.ref=ALL-UNNAMED
-J--add-opens=java.base/java.lang=ALL-UNNAMED
-J--add-opens=java.desktop/javax.swing=ALL-UNNAMED
-J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED
-J-XX:+IgnoreUnrecognizedVMOptions
stoty@stoty-Precision-5570:~/visualvm_22/bin $ ./visualvm
Cannot find java. Please use the --jdkhome switch.
stoty@stoty-Precision-5570:~/visualvm_22/bin $
There is no visualvm.exe for unix. Either the bash script finds a java and uses it to start visualvm/netbeans or it fails.
nbexec#L130-L179 script checking jdk location , but it is not considering JAVA_HOME env var to be used as jdkhome.
Thanks @dasarathirout .
You are right, it makes sense to fix this problem there, and remove the redundant JAVA_HOME code from 'visualvm" Seems like nbexec simply is just unaware of the existence of non Apple Unix OSs.
(and even the MacOS logic could use some improvments)
Actually, it is aware (there is a default case), but it ignores JAVA_HOME, and the symlink resolution code doesn't work with jenv style shims.
There is no visualvm.exe for unix.
Right, but I was never talking about visualvm.exe.
Either the bash script finds a java and uses it to start visualvm/netbeans or it fails.
Right, but there are two scripts. bin/visualvm startup script does not search for jdk. The second script platform/lib/nbexec is responsible for launching java binary and can find the JDK if you do not specify it. The fact that it fails for you does not mean that it fails for everyone.
Please see https://github.com/apache/netbeans/pull/8725 @thurka .
nbexec#L130-L179 script checking jdk location , but it is not considering JAVA_HOME env var to be used as jdkhome.
.. and this is the right place for the fix. I already mentioned it here: https://github.com/oracle/visualvm/issues/623#issuecomment-3158015110
The right place for any platform application to have alternative launcher behaviour to the default is first and foremost its own launch script!