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 bugJDK-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.
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
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.
- duplicates
-
JDK-8066656 System.getProperty( " os.name " ) returns " Windows NT (unknown) " on Windows 10
- Closed
-
JDK-8020191 System.getProperty( " os.name " ) returns " Windows NT (unknown) " on Windows 8.1
- Closed
- relates to
-
JDK-8020191 System.getProperty( " os.name " ) returns " Windows NT (unknown) " on Windows 8.1
- Closed
-
JDK-8022452 Hotspot needs to know about Windows 8.1 and Windows Server 2012 R2
- Closed