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

Thread losing ContextClassLoader through Invocation API

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 1.2.2, 1.3.1
    • hotspot
    • x86, sparc
    • solaris_2.6, windows_nt



      Name: krC82822 Date: 08/07/2001


      7 Aug 2001, kevin.ryan@eng -- reproducible with 1.3.1 and 1.4 beta (build 65)
      on Solaris 2.8 (please also see Comments section)
      ----------------
      java version "1.3.1"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
      Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

      When invoking methods through the invocation API, trying to obtain the context
      ClassLoader for a Thread will return null
      unless the Thread is the main Thread which was used to create the JVM.

      In a simple example, I have Thread 1 which creates a JVM and invokes a method on
      a class. I then launch a second Thread
      which invokes the same method on the class. In Thread 1 is the context
      classloader ok (it is the application classloader).
      In Thread 2 though, the Thread.getContextClassLoader() returns null.


      ********* Java Code *********
      public final class JVMInvoker
      {
            public static void invoke() {
                    Thread me = Thread.currentThread();
                    
                    System.out.println(
                            "JAVA: Calling Thread : " + me
                    );
                    System.out.println(
                            "JAVA: ContextClassLoader: " + me.getContextClassLoader()
                    );
            }
      }


      ********* Invocation Code *********
      #include <pthread.h>

      #include <jni.h>
      #include <malloc.h>
      #include <stdlib.h>


      //------------------------------------------------------
      // Globals

      static JavaVM* m_JVM;
      static jmethodID m_JavaInvokerMID;
      static jclass m_JavaInvokerClazz;



      //------------------------------------------------------
      // Function Decls

      extern "C" {
      void createJavaVM();
      void invokeMethod();
      void* launchThread(void*);
      }


      //------------------------------------------------------
      // Main

      static JavaVM* jvm = NULL;

      int main(int, char**)
      {
      fprintf(stdout, "\n");

      // creates the VM and calls invokeMethod
      createJavaVM();

      fprintf(stdout, "\n");

      pthread_t tid;
      pthread_create(&tid, NULL, launchThread, NULL);

      fprintf(stdout, "\n");
      }


      //------------------------------------------------------
      // createJavaVM

      void createJavaVM()
      {
      JNIEnv* env = NULL;

      JavaVMInitArgs vm_args;
      JavaVMOption* options = (JavaVMOption*)malloc(sizeof(JavaVMOption));

      options[0].optionString = (char*)"-Djava.class.path=.";
      options[0].extraInfo = (void*)0;

      vm_args.version = JNI_VERSION_1_2;
      vm_args.options = options;
      vm_args.nOptions = 1;
      vm_args.ignoreUnrecognized = JNI_FALSE;

      jint result = JNI_CreateJavaVM(&m_JVM, (void**)&env, &vm_args);
      if ( result != JNI_OK ) {
      fprintf(stderr, "\nCould not create JAVA VM\n");
      exit(1);
      }

      const char* name = "JVMInvoker";
      jclass clazz = env->FindClass(name);
      if ( clazz == NULL ) {
      fprintf(stderr, "\nCould not load 'JVMInvoker'\n");
      exit(1);
      }

      m_JavaInvokerMID = env->GetStaticMethodID(clazz, "invoke", "()V");
      if ( m_JavaInvokerMID == 0 ) {
      fprintf(stderr, "\nCould not find method invoke()\n");
      exit(1);
      }

      m_JavaInvokerClazz = (jclass)env->NewGlobalRef(clazz);


      // now invoke method in same thread
      fprintf(
      stdout, "CPP : Thread (%d): Invoking JVMInvoker .... OK\n",
      pthread_self()
      );
      invokeMethod();
      }

      //------------------------------------------------------
      // invokeMethod

      void invokeMethod()
      {
      JNIEnv* env = NULL;

      jint result = m_JVM->AttachCurrentThread((void**)&env, 0);
      if ( result != JNI_OK ) {
      fprintf(
      stderr,
      "\nCould not attach current thread to JVM: Thread = %d",
      pthread_self()
      );
      exit(1);
      }

      fprintf(stdout, "CPP : Calling Thread = %d\n", pthread_self());
      env->CallStaticVoidMethod(
      m_JavaInvokerClazz,
      m_JavaInvokerMID
      );
      }

      //------------------------------------------------------
      // launchThread

      void* launchThread(void*)
      {
      fprintf(
      stdout, "CPP : Thread (%d): Invoking JVMInvoker .... NOK\n",
      pthread_self()
      );
      invokeMethod();

      return (void*)0;
      }


      ********* Makefile *********
      #-----------------------------------------------------------------
      # Vars

      CC = /opt/workshop6u1/bin/CC

      JAVA_HOME=/opt/java/jdk/1.3.1
      #JAVA_HOME=/opt/java/jdk/1.2.2_05a

      FLAGS = -DDEBUG -g +w2 -KPIC -mt
      INCLS = -I. -I$(JAVA_HOME)/include/solaris -I$(JAVA_HOME)/include
      LIBS = -L$(JAVA_HOME)/jre/lib/sparc -ljvm

      CPP_SOURCES = JVMInvoker.cpp

      JAVA_SOURCES = JVMInvoker.java

      EXENAME = jvminoker


      #-----------------------------------------------------------------
      # Rules

      all: java_compile exe

      java_compile:
      $(JAVA_HOME)/bin/javac -g -d . $(JAVA_SOURCES)


      exe:
      $(CC) -o $(EXENAME) $(FLAGS) $(INCLS) $(CPP_SOURCES) $(LIBS)

      run:
      CLASSPATH=. LD_LIBRARY_PATH=$(JAVA_HOME)/jre/lib/sparc $(EXENAME)


      clean:
      \rm -fr *.o *~ $(EXENAME) *.class
      (Review ID: 128509)
      ======================================================================

            collins Gary Collins (Inactive)
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: