Duplicate :
|
|
Duplicate :
|
|
Relates :
|
|
Relates :
|
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.
|