JDK-8057122 : os.name returns Windows 8 on Windows 8.1 when using jvm.dll
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7u67
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_8
  • CPU: x86
  • Submitted: 2014-09-02
  • Updated: 2017-07-21
  • Resolved: 2017-07-21
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) Client VM (build 24.65-b04, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [version 6.3.9600]
Windows 8.1 32 bits

A DESCRIPTION OF THE PROBLEM :
System.getProperty("os.name") will report "Windows 8" when run using a launcher that load jvm.dll to start a JVM whereas running the same code using java.exe will report "Windows 8.1".

Only one JVM is installed and it's the latest version of Java 7 (update 67).
This version includes the fix for bug JDK-8022452 ("Hotspot needs to know about Windows 8.1 and Windows Server 2012 R2").

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Run the attached Java code using java.exe: output will be Windows 8.1
- Build the launcher exe file (done with Visual Studio 2013 Express) and run the same class: output will be Windows 8. To run this test you need in a terminal to type: TestJvm.exe ShowOsName C:\path\to\class\file\folder

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When running the class using the custom launcher that use jvm.dll I expected the output of os.name to be the same as when running with java.exe: Windows 8.1
ACTUAL -
os.name: Windows 8

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Java source code for test class:
class ShowOsName {
    public static void main(String[] args) {
		System.out.println("os.name: " + System.getProperty("os.name"));
    }
}

Source code of the launcher that use jvm.dll (can be build with a basic Visual Studio Express project that include jni.h):
// Code of this application is based on example available here: http://www.codeproject.com/Articles/17352/JVM-Launcher

#include "stdafx.h"
#include <stdio.h>
#include <jni.h>
#include <string>
#include <windows.h>

using namespace std;

/** Pointer to the virtual machine */
JavaVM     *g_psJvm;

/** Command line arguments */
char       **g_pcMain_argv = NULL;

/** Number of command line arguments */
int        g_iMain_argc = 0;

/** Main class */
char       *g_pcMainClass;

/** Handle to the jvm.dll */
HINSTANCE  g_sHandle;

/** JNI Exception handling */
jthrowable g_sException;

/** JVM classpath */
char       *g_pcClasspath;

typedef jint(JNICALL CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);

JNIEnv* CreateVm()
{
	// JNI environment
	JNIEnv           *psJNIEnv;

	// Java VM init arguments
	JavaVMInitArgs   sJavaVMInitArgs;

	// Return value
	int iRetval = 0;

	// Pointer to function to create Java VM
	CreateJavaVM_t   *pfnCreateJavaVM;

	// JVM options (we only specify one option: classpath)
	JavaVMOption     psJavaVMOption[1];

	// Load the Java VM DLL
	if ((g_sHandle = LoadLibrary(TEXT("C:\\Program Files\\Java\\jre7\\bin\\client\\jvm.dll"))) == NULL){
		printf("Unable to load C:\\Program Files\\Java\\jre7\\bin\\client\\jvm.dll\n");
		return NULL;
	}

	// Get pointer to create Java VM function in library
	pfnCreateJavaVM = (CreateJavaVM_t *)GetProcAddress(g_sHandle, "JNI_CreateJavaVM");
	if (pfnCreateJavaVM == NULL)
	{
		printf("Unable to find JNI_CreateJavaVM\n");
		return NULL;
	}

	// Set the JVM classpath
	psJavaVMOption[0].optionString = g_pcClasspath;

	// We have only one option
	sJavaVMInitArgs.nOptions = 1;

	// JNI Version
	sJavaVMInitArgs.version = JNI_VERSION_1_6;

	// Add the Java VM options
	sJavaVMInitArgs.options = psJavaVMOption;

	// Call function to create JVM
	iRetval = pfnCreateJavaVM(&g_psJvm, (void **)&psJNIEnv, &sJavaVMInitArgs);
	if (iRetval != 0)
	{
		printf("Cannot Create JVM\n");
		return NULL;
	}

	return psJNIEnv;
}


void InvokeClass(JNIEnv* psJNIEnv)
{
	// Class to call
	jclass          jcJclass;

	// Main method
	jmethodID       jmMainMethod;

	// Args (not use)
	jobjectArray    joApplicationArgs = NULL;

	//Check for JVM
	if (psJNIEnv == NULL)
		return;

	// Find the class
	jcJclass = psJNIEnv->FindClass(g_pcMainClass);

	// Exception handling(If the class not found)
	g_sException = (psJNIEnv)->ExceptionOccurred();
	if (g_sException != NULL)
	{
		psJNIEnv->ExceptionDescribe();
		return;
	}

	if (jcJclass == NULL)
	{
		printf("Error: cannot find class.\nClass: %s\n", g_pcMainClass);
		return;
	}

	// Find the main method.
	jmMainMethod = psJNIEnv->GetStaticMethodID(jcJclass, "main", "([Ljava/lang/String;)V");

	// Exception handling(If the class not found)
	g_sException = (psJNIEnv)->ExceptionOccurred();
	if (g_sException != NULL)
	{
		psJNIEnv->ExceptionDescribe();
		return;
	}

	if (jmMainMethod == NULL)
	{
		printf("Error: cannot find main method.\n ");
		return;
	}

	// Call the main method.
	psJNIEnv->CallStaticVoidMethod(jcJclass, jmMainMethod, joApplicationArgs);

	// Destroy the JVM
	// This may not work in all jvm version !.
	g_psJvm->DestroyJavaVM();

}

/**
* Main
*/
int main(int argc, char **argv) {

	g_iMain_argc = argc;
	g_pcMain_argv = argv;

	// Extract main class name
	g_pcMainClass = _strdup(g_pcMain_argv[1]);

	g_pcClasspath = (char *)malloc(strlen(g_pcMain_argv[2]) + 100);
	sprintf(g_pcClasspath, "-Djava.class.path=%s", g_pcMain_argv[2]);

	// Create JVM
	JNIEnv* psJNIEnv = CreateVm();

	// Invoke the class
	InvokeClass(psJNIEnv);

	FreeLibrary(g_sHandle);

	system("pause");

	return 1;
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I found out about this issue running Eclipse that use by default jvm.dll.
Specifying -vm argument in eclipse.ini configuration file and provide full path to javaw.exe allow to bypass this bug.


Comments
The submitter merely proved the source of the bug. That's not a reason to close it as not an issue. Perhaps this has already been addressed in JDK 8 updates but in that case it should be shown to be so and closed as a duplicate instead.
21-04-2015

Another updated from the submitter: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028642.html -------------------------------------------- As suggest by Alan Bateman I did a test with a manifest include in the launcher and it works! Adding manifest like the one provided here: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074%28v=vs.85%29.aspx fix the issue and os.name is correctly reported as Windows 8.1 (didn't tested yet with Windows server). -------------------------------------------- Closing the bug as not an issue
23-09-2014

Update from the submitter: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028637.html -------------------------------------------- Few days ago I report an issue about os.name value when using jvm.dll on Windows 8.1 ( JDK-8057122). Today I reproduce the same issue on Windows Server 2012 r2. Running the Java class using java.exe will report correct (meaning including r2) os.name version, using the dll, "r2" will not be part of os.name. Source code of a custom launcher that load the dll is already available on the bug report but here is a download link to the full Visual Studio 2013 project: https://www.dropbox.com/s/2fbtili51b7r66a/TestJvm.zip?dl=0 I can do any kind of additional tests if needed, I just have a lack of knowledges about Windows applications building process.
11-09-2014

Bernd Eckenfels points out another example where this is an issue: https://issues.apache.org/jira/browse/DAEMON-322
10-09-2014

It would be good to check the custom launcher too to see if it has a manifest, I think Windows 8.1 reports the system as Windows 8 when you don't have a manifest that targets 8.1. Another thing that we need to do is to replace the usages of GetVersionEx in the JDK and use the Version Helper API instead.
10-09-2014

According to http://www.oracle.com/technetwork/java/javase/config-417990.html Windows 8.x should be supported. The fixes for https://bugs.openjdk.java.net/browse/JDK-8022452 https://bugs.openjdk.java.net/browse/JDK-8020191 were backported to 7u55, 7u60, 7u65. Need to verify if the fixes might have failed.
03-09-2014