Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 321390

Summary: Reliable way to detect HotSpot Java 7 VM
Product: [Eclipse Project] Equinox Reporter: John Arthorne <john.arthorne>
Component: LauncherAssignee: Project Inbox <equinox.launcher-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: enhancement    
Priority: P3 CC: aniefer, kelly.ohair, mike.milinkovich, Mike_Wilson, mistria, remy.suen, tjwatson
Version: 3.6   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description John Arthorne CLA 2010-07-30 13:32:16 EDT
Currently we check for a company name ("Sun" in 3.6.0 or earlier, and either "Oracle" or "Sun" in releases since 3.6.1) to determine if the JVM is the HotSpot VM. This is done so that we can determine if the XXMaxPermSize argument is needed. We should investigate if there is a less brittle way to perform this check for Java 7 JVMs and beyond.

Andrew, can you first summarize the details of how we perform this check today?
Comment 1 Andrew Niefer CLA 2010-07-30 14:01:34 EDT
There are two cases here depending on how we are starting java
1) execing java(w).exe
2) using JNI invocation API on jvm.dll (libjvm.so)

On Windows, both (1) and (2) we use GetFileVersionInfo (http://msdn.microsoft.com/en-us/library/ms647003%28VS.85%29.aspx) on the executable or dll to check for a CompanyName of "Sun Microsystems" or now also "Oracle".

On *nix, in case (1) we exec "java -version" and look for the string "Java HotSpot(TM)" or "OpenJDK" in the result.  In case (2) if we don't know the location of the java.exe we default to not sun and do not apply the XXMaxPermSize vm arg.

I would be good to have a method that worked on all platforms when looking at either the java executable or the shared library (jvm.dll/libjvm.so).

On Windows, one possibility would be if we could use LoadLibraryEx http://msdn.microsoft.com/en-us/library/ms684179%28VS.85%29.aspx to load the exe or dll with LOAD_LIBRARY_AS_DATAFILE.  Then we could load something from the string table (http://msdn.microsoft.com/en-us/library/ms647486%28v=VS.85%29.aspx)

On *nix, we might be left with just dlopen and dlsym to find a function or string.
Comment 3 Kelly O'Hair CLA 2010-09-29 14:14:17 EDT
If we could decide on something fairly quickly, there is a chance we could add a simple text file, like the Linux /etc/*release* files, or something to the root of the jdk7 installation tree. It would need to be a read-only file, and could take the shape of a properties file, e.g. "jdk.properties" or "jdk.release", and it could contain select java property values, something like:
  java.vendor = Oracle Corporation
  java.vendor.url = http://java.oracle.com/
  java.vm.vendor = Oracle Corporation
  java.vm.name = Java HotSpot(TM) Server VM
  java.version = 1.7.0-ea
  java.vm.version = 19.0-b06
  java.runtime.version = 1.7.0-ea-b111
  java.specification.version = 1.7
I hesitate to call it a properties file, but the properties file syntax seems to work. It also can only list one vm name (Server in this example), but often there are many vms in a jdk shipment, not sure how to deal with that.
Tools could check for this file existing, use it, or fallback to the old techniques. But if we had a file like this, it could be used on all platforms.

Please comment and let me know what you think, or if you have other ideas or improvements on this. For jdk7, timing is critical, and I would need to get approval from the jdk7 team on whatever is decided. Adding it to future updates of jdk5 and jdk6 might be a little more difficult, but potentially possible.

-kto
Comment 4 Andrew Niefer CLA 2010-09-29 14:44:38 EDT
I do like the text file idea, I remember originally on linux we considered looking for a LICENSE file.

In general, your comment reminds me very much of the Execution Environment Description files that we came up with in 3.3/3.4.  I don't know why I didn't think of this earlier.

http://wiki.eclipse.org/Execution_Environment_Descriptions

Basically this file is a newline separated list of vm arguments needed to start the vm in a particular configuration.  The launcher itself is reading a handful of these properties and they are all passed on to the vm.

One option would be to ship one of these files with each vm in the jdk.  The files could be siblings to the vm library and have the same name and different extension.  As well as a default file in the jre/bin for when we launch with the java.exe.

I don't know what happens in the vm if these java.* properties are defined on the command line and conflict with what the vm would have set.
Comment 5 John Arthorne CLA 2010-09-29 15:04:01 EDT
The simple text file in a well-known location sounds like a good plan. That would give us a consistent story on all platforms and greatly simplify our VM detection (although for compatibility with older VM's we'll likely need to fallback to the current detection if the file is missing).

Andrew, I guess the property we would sniff for is the VM name here. It was the VM vendor change that broke us originally, so hopefully the "HotSpot" name in the java.vm.name property is the most stable thing to look for. That would also allow us to distinguish JRockit from HotSpot if necessary (whose vendor names I assume will be identical now).
Comment 6 Kelly O'Hair CLA 2010-09-29 16:17:27 EDT
(In reply to comment #4)
[snip]
> 
> I don't know what happens in the vm if these java.* properties are defined on
> the command line and conflict with what the vm would have set.

My expectation would be that this file, and the property values in it, would be strictly read-only and also NOT be used to set the system properties as the vm starts up. As the install image is created I would just run a small java app to dump these out, so they would be like a sample of the default system property values for the jdk in the install image.

Anyone changing the system properties is in unknown territory, and I'm not even sure some of these can be changed at runtime.

-kto
Comment 7 Kelly O'Hair CLA 2010-09-29 16:26:04 EDT
(In reply to comment #5)
> The simple text file in a well-known location sounds like a good plan. That
> would give us a consistent story on all platforms and greatly simplify our VM
> detection (although for compatibility with older VM's we'll likely need to
> fallback to the current detection if the file is missing).
> 
> Andrew, I guess the property we would sniff for is the VM name here. It was the
> VM vendor change that broke us originally, so hopefully the "HotSpot" name in
> the java.vm.name property is the most stable thing to look for. That would also
> allow us to distinguish JRockit from HotSpot if necessary (whose vendor names I
> assume will be identical now).

It was my impression that multiple VMs could be, and are, delivered in a single jdk, and what VM you get (e.g. server or client) sometimes depends on factors not obvious, unless you explicitly ask for one, e.g. -client or -server. If for example, we also delivered a Jrocket VM, that could be confusing for you I suspect. :^(

-kto
Comment 8 Kelly O'Hair CLA 2010-11-29 19:09:15 EST
In jdk7, this change is being tracked as 6989472.

I'd like to get reviewer comments on this proposed change:

 6989472: Provide simple jdk identification information in the install image
 http://cr.openjdk.java.net/~ohair/openjdk7/jdk_release/webrev/

The above change creates a small text file called "jdk.release" at the top of the install image with some basic values that could help direct any app using the jdk in constructing a command line or even being assured that this jdk install image will even work on your existing system.

The make variable COMPANY_NAME determines the vendor name during a build, so a Linux 64bit build from a make command line like:
  make COMPANY_NAME="Test Company Name"
should result in a jdk.release file that looks something like:

os.name = Linux
os.version = 2.6
os.arch = amd64
java.vendor = Test Company Name
java.version = 1.7.0-internal
java.vm.vendor = Test Company Name
java.vm.name = Hotspot(TM)
java.vm.version = 20.0-b02

A formal Oracle jdk7 EA build on Linux 64bit should look something like:

os.name = Linux
os.version = 2.6
os.arch = amd64
java.vendor = Oracle Corporation
java.version = 1.7.0-ea
java.vm.vendor = Oracle Corporation
java.vm.name = Hotspot(TM)
java.vm.version = 20.0-b02

Please let me know what you think.

-kto
Comment 9 Andrew Niefer CLA 2010-12-01 11:43:11 EST
(In reply to comment #8)
This comment looks fine to me, we would use the java.vm.name property to identify the vm here, this avoids issues when someone compiles their own jdk and the company name changes.  Also, the os.arch is useful to help the launcher identify if there is going to be a 32 vs 64 bit mismatch between the eclipse install and the jre.  (We may have a bug about this but I couldn't find it in a quick search).

I'm not allowed to look at the openjdk so can't comment on the actual patch.
One question is the name/location:  We have "jdk.release" at the root of the install, is that file still around if someone just has the jre and not a full jdk?
Comment 10 Kelly O'Hair CLA 2010-12-01 15:03:13 EST
I had not planned on doing this for a JRE, but could if that was an issue, creating a "jre.release" file, or maybe the filename should just be "release". I had assumed that most tools would need a javac, and that a the jdk images were of primary concern (no javac in a JRE).

Quite a bit of discussion on this on the openjdk alias, which is where the final decision will be. Kind of hard that these 2 open source projects cannot look at each others mailing lists or sources. :^( I thought all of IBM could work on OpenJDK now???

Right now, a Linux 64bit build should result in a jdk.release file that looks something like:

jdk.os.name = Linux
jdk.os.version = 2.6
jdk.os.arch = amd64
jdk.version = 1.7.0
jdk.vm.info.files = jre/lib/amd64/jvm.cfg

The jre/lib/amd64/jvm.cfg file contains information on the VMs used based on the options passed in, e.g. '-client', '-server', etc. If we had a formal "vm.release" file I could refer to that.

I know this is a bit far from the original proposal but the vendor and trademark names posed a bit of a problem, and the determination of the VM that was going to be used also was a little tricky.

It's not a done deal, so let me know what you think.

-kto
Comment 11 Andrew Niefer CLA 2010-12-01 16:00:34 EST
Eclipse works fine on a jre, we have our own compiler in org.eclipse.jdt.core so don't need the full jdk.

The jvm.cfg file also seems like useful information, we currently have problems around using the -server or -client arguments (bug 204009).

We had noticed that the jdk.release file as shown in comment #8 doesn't really allow for differences in separate jvms, I wasn't sure we needed this level of detail.  Is it conceivable that one jre would include (for example) both hotspot and jrockit with appropriate -client/-jrockit command line args? (And that they are different enough that we would need to distinguish them).


(bug 221969 - 32bit vs 64 bit mismatch)
Comment 12 Eclipse Webmaster CLA 2019-09-06 16:13:03 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 13 Mickael Istria CLA 2020-03-23 13:31:30 EDT
Java 7 isn't supported any more.