Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8057122

os.name returns Windows 8 on Windows 8.1 when using jvm.dll

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 7u67
    • core-libs
    • x86
    • windows_8

      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.

            igerasim Ivan Gerasimov
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: