How to programmatically get all installed Java JVMs (not the default) using Java?

Does anyone know how to programmatically get all installed JVMs (and not by default) using Java ?

For example, 2 JVMs are installed on the user machine:

JDK 5 JDK 6 

I need to know all the versions installed in order to switch the one that it uses (by default) and then program javac to compile some source code using a specific JDK version.

I searched for some information on the Internet, I found:

But I could not find what I was looking for.

+8
java jvm
source share
10 answers

I recently encountered a very similar situation. The following code does almost what you need. He is looking for java JRE and JDK, not just JDK, but they are quite easy to edit to suit your needs. Beware: windows only

 /** * Java Finder by petrucio@stackoverflow(828681) is licensed under a Creative Commons Attribution 3.0 Unported License. * Needs WinRegistry.java. Get it at: https://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java * * JavaFinder - Windows-specific classes to search for all installed versions of java on this system * Author: petrucio@stackoverflow (828681) *****************************************************************************/ import java.util.*; import java.io.*; /** * Helper class to fetch the stdout and stderr outputs from started Runtime execs * Modified from http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 *****************************************************************************/ class RuntimeStreamer extends Thread { InputStream is; String lines; RuntimeStreamer(InputStream is) { this.is = is; this.lines = ""; } public String contents() { return this.lines; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; while ( (line = br.readLine()) != null) { this.lines += line + "\n"; } } catch (IOException ioe) { ioe.printStackTrace(); } } /** * Execute a command and wait for it to finish * @return The resulting stdout and stderr outputs concatenated ****************************************************************************/ public static String execute(String[] cmdArray) { try { Runtime runtime = Runtime.getRuntime(); Process proc = runtime.exec(cmdArray); RuntimeStreamer outputStreamer = new RuntimeStreamer(proc.getInputStream()); RuntimeStreamer errorStreamer = new RuntimeStreamer(proc.getErrorStream()); outputStreamer.start(); errorStreamer.start(); proc.waitFor(); return outputStreamer.contents() + errorStreamer.contents(); } catch (Throwable t) { t.printStackTrace(); } return null; } public static String execute(String cmd) { String[] cmdArray = { cmd }; return RuntimeStreamer.execute(cmdArray); } } /** * Helper struct to hold information about one installed java version ****************************************************************************/ class JavaInfo { public String path; //! Full path to java.exe executable file public String version; //! Version string. "Unkown" if the java process returned non-standard version string public boolean is64bits; //! true for 64-bit javas, false for 32 /** * Calls 'javaPath -version' and parses the results * @param javaPath: path to a java.exe executable ****************************************************************************/ public JavaInfo(String javaPath) { String versionInfo = RuntimeStreamer.execute( new String[] { javaPath, "-version" } ); String[] tokens = versionInfo.split("\""); if (tokens.length < 2) this.version = "Unkown"; else this.version = tokens[1]; this.is64bits = versionInfo.toUpperCase().contains("64-BIT"); this.path = javaPath; } /** * @return Human-readable contents of this JavaInfo instance ****************************************************************************/ public String toString() { return this.path + ":\n Version: " + this.version + "\n Bitness: " + (this.is64bits ? "64-bits" : "32-bits"); } } /** * Windows-specific java versions finder *****************************************************************************/ public class JavaFinder { /** * @return: A list of javaExec paths found under this registry key (rooted at HKEY_LOCAL_MACHINE) * @param wow64 0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app) * or WinRegistry.KEY_WOW64_32KEY to force access to 32-bit registry view, * or WinRegistry.KEY_WOW64_64KEY to force access to 64-bit registry view * @param previous: Insert all entries from this list at the beggining of the results *************************************************************************/ private static List<String> searchRegistry(String key, int wow64, List<String> previous) { List<String> result = previous; try { List<String> entries = WinRegistry.readStringSubKeys(WinRegistry.HKEY_LOCAL_MACHINE, key, wow64); for (int i = 0; entries != null && i < entries.size(); i++) { String val = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, key + "\\" + entries.get(i), "JavaHome", wow64); if (!result.contains(val + "\\bin\\java.exe")) { result.add(val + "\\bin\\java.exe"); } } } catch (Throwable t) { t.printStackTrace(); } return result; } /** * @return: A list of JavaInfo with informations about all javas installed on this machine * Searches and returns results in this order: * HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment (32-bits view) * HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment (64-bits view) * HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit (32-bits view) * HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit (64-bits view) * WINDIR\system32 * WINDIR\SysWOW64 ****************************************************************************/ public static List<JavaInfo> findJavas() { List<String> javaExecs = new ArrayList<String>(); javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Runtime Environment", WinRegistry.KEY_WOW64_32KEY, javaExecs); javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Runtime Environment", WinRegistry.KEY_WOW64_64KEY, javaExecs); javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Development Kit", WinRegistry.KEY_WOW64_32KEY, javaExecs); javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Development Kit", WinRegistry.KEY_WOW64_64KEY, javaExecs); javaExecs.add(System.getenv("WINDIR") + "\\system32\\java.exe"); javaExecs.add(System.getenv("WINDIR") + "\\SysWOW64\\java.exe"); List<JavaInfo> result = new ArrayList<JavaInfo>(); for (String javaPath: javaExecs) { if (!(new File(javaPath).exists())) continue; result.add(new JavaInfo(javaPath)); } return result; } /** * @return: The path to a java.exe that has the same bitness as the OS * (or null if no matching java is found) ****************************************************************************/ public static String getOSBitnessJava() { String arch = System.getenv("PROCESSOR_ARCHITECTURE"); String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432"); boolean isOS64 = arch.endsWith("64") || (wow64Arch != null && wow64Arch.endsWith("64")); List<JavaInfo> javas = JavaFinder.findJavas(); for (int i = 0; i < javas.size(); i++) { if (javas.get(i).is64bits == isOS64) return javas.get(i).path; } return null; } /** * Standalone testing - lists all Javas in the system ****************************************************************************/ public static void main(String [] args) { List<JavaInfo> javas = JavaFinder.findJavas(); for (int i = 0; i < javas.size(); i++) { System.out.println("\n" + javas.get(i)); } } } 

You will also need an updated version of WinRegistry.java to read the values ​​from the 32-bit and 64-bit Windows registry keys: https://stackoverflow.com/a/464829/

I'm usually not a Java programmer, so my code probably doesn't match the java conventions. Sue to me.

Here is an example of starting from a 64-bit Win 7 machine:

 >java JavaFinder C:\Program Files (x86)\Java\jre6\bin\java.exe: Version: 1.6.0_31 Bitness: 32-bits C:\Program Files\Java\jre6\bin\java.exe: Version: 1.6.0_31 Bitness: 64-bits D:\Dev\Java\jdk1.6.0_31\bin\java.exe: Version: 1.6.0_31 Bitness: 64-bits C:\Windows\system32\java.exe: Version: 1.6.0_31 Bitness: 64-bits C:\Windows\SysWOW64\java.exe: Version: 1.6.0_31 Bitness: 32-bits 
+11
source share

I quickly checked the Windows registry, and this key seems to provide a different version of Java installed on the system

HKEY_LOCAL_MACHINE \ SOFTWARE \ JavaSoft \ Java Runtime Environment

A further Google search confirmed that this is the correct location. Read these articles for details ...

Quickly get affordable Java JVMs on a workstation (Windows)

Java 2 Runtime Environment for Microsoft Windows

+3
source share

In principle, it is not possible to list all JVMs, not even from Java code. Consider various platforms, a different JDK provider, the JDK bundle in other database products to simulate a flight simulator and video rendering. Most JDKs are a simple reference to another, for example. v.1.2 indicated the installed v.6. The most common way to get the version is: java -version But we have a few points:

  • For Windows, check the registry HKEY_LOCAL_MACHINE \ Software \ JavaSoft \. Also consider the Wow6432Node mode for a 64-bit OS. Check out products from major Java software vendors.
  • Mac OS X / System / Library / Frameworks / JavaVM.framework / Versions + Open JDK
  • Linux and some other Unix - which java, / etc / alternatives / java rpm -qa | grep java etc.
+2
source share

On Windows platforms, you can disable the request for the installed JRE:

 java -version:1.6 -version 

This command will return with the "java version" 1.6.0_xx "if you installed it. If you did not install it, it will say:" The JRE 1.6 meeting specification could not be found "

This does not work on Linux, possibly because Linux does not have a standard way to install Java.

+2
source share

installed rather vaguely - even if the JRE and JDK come with the installer, in fact we just need to copy the JRE or JDK files to the machine and use them immediately.

In general, you need to find all the java or java.exe executables on your local computer and call java -version to see 1 if this executable named java / java.exe really (part) of the JRE.


Just saw that you asked for the JVM and want to call the compiler. If you are looking for JDK, use the method described above, but find all javac / javac.exe . They also have the -version .


1 there is no risk - there is no pleasure that comes with this method - please read Sean's remark carefully! If you cannot trust the machine (or its users), then you can test if the executable is script / batch or binary, even if the binary can also erase your disk, even the original javac executable can be replaced with some kind of evil code ...

+1
source share

At the Windows command prompt, you can run the following 2 commands (or run together as a batch file). It will look in Windows Add / Remove programs (registry entries) and report which versions of JAVA are found with the installation / removal of links, as well as the path to the folder and some other things.

 wmic product where "name LIKE '%%java%%'" get * /format:textvaluelist > temp_javavers.txt notepad.exe temp_javavers.txt 
+1
source share

I'm not sure if this question answers your question, but you can control which of the major versions of the JRE runs the applet or WebStart application using the Family Versioning function. This allows you to specify the major version of Java in which the applet runs. You should be able to get the javac location from there.

http://www.oracle.com/technetwork/java/javase/family-clsid-140615.html

0
source share

.. compile the source code using a specific version of the JDK.

Use the JavaCompiler (in the last JDK that the user can put their hands on) with the appropriate options for -source , -bootclasspath & -bootclasspath . The last two are part of the javac cross-compilation options .

As for the JDK search, put a JFileChooser with the path of the current JRE as the default directory. If the user cannot go from there to the JDK, it is doubtful that he should write code.

0
source share

To find Java versions, a better approach than finding javac.exe is to check the registry. Java creates the registry key HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment with the CurrentVersion string set to the version number, for example, 1.5 or 1.6.

You can use this information to search for JVM:

  • HKEY_LOCAL_MACHINE \ Software \ JavaSoft \ Java Runtime Environment \ 1.5 \ JavaHome = C: \ Program Files \ Java \ j2re1.5
  • HKEY_LOCAL_MACHINE \ Software \ JavaSoft \ Java Runtime Environment \ 1.5 \ RuntimeLib = C: \ Program Files \ Java \ j2re1.4.2 \ bin \ client \ jvm.dll

You can see more here: http://java.sun.com/j2se/1.4.2/runtime_win32.html

I am not familiar with registry access with Java, but you can always run the regedit command-line interface and analyze the results, which I did.

0
source share

As already mentioned, HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment should display a list of available JVMs, BUT I just found out that although this registry currently only contains the 64-bit version of JVM 1.6.0_31 on my machine, I also have There is a 32-bit Java version installed in C:\Windows\SysWOW64 .

Thus, the information provided in the registry does not display the full image, and if you want to run the 32-bit JVM on 64-bit Windows, try also C:\Windows\SysWOW64 .

0
source share

All Articles