Commons Daemon
  1. Commons Daemon
  2. DAEMON-100

Thread.currentThread().getContextClassLoader() == null when the program is runned by Prunsrv

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.0.4
    • Component/s: Procrun
    • Labels:
      None
    • Environment:

      Description

      Thread.currentThread().getContextClassLoader() == null when the program is runned by Prunsrv, but when we run the same system using java.exe, Thread.currentThread().getContextClassLoader() is not null.

      1. __apxJavaWorkerThread.txt
        3 kB
        Antony Scerri
      2. DaemonLoader.patch
        0.7 kB
        Erik-Berndt Scheper

        Issue Links

          Activity

          Anton Vodonosov created issue -
          Anton Vodonosov made changes -
          Field Original Value New Value
          Environment Win XP, jre1.5.0_11, -Djava.security.policy=<path to the file with following content>: Win XP, jre1.5.0_11, -Djava.security.policy=<path to a file with following content>:

          grant {
              permission java.security.AllPermission "", "";
              permission com.sun.rmi.rmid.ExecPermission "<<ALL FILES>>";
              permission com.sun.rmi.rmid.ExecOptionPermission "*";
          };
          Mladen Turk made changes -
          Component/s Procrun [ 12313432 ]
          Hide
          Dominik Drzewiecki added a comment -

          I confirm.
          This one is particularly annoying when one is trying to launch Jboss AS as a service
          It is installed roughly by the following script:

          SET JBOSS_SERVICE_NATIVE=tomcat6
          SET JBOSS_HOME=c:\java\jboss-5.1.0.GA
          SET JBOSS_NATIVE=%JBOSS_HOME%\bin\native
          SET CONFIG=minimal
          SET SVC_NAME=jbossas
          SET SVC_DISP=JBoss Application Server 5.1
          SET SVC_DESC=JBoss Application Server 5.1.0 GA/Platform: Windows x86
          SET CP=%JBOSS_HOME%\bin\run.jar
          SET JVM=%JAVA_HOME%\jre\bin\server\jvm.dll
          SET JBOSS_OPTS=-c;%CONFIG%
          SET JVM_OPTS=-Xrs;-XX:MaxPermSize=256M;-Dsun.rmi.dgc.client.gcInterval=3600000;-Dsun.rmi.dgc.server.gcInterval=3600000;-Dorg.jboss.resolver.warning=true;-Djava.library.path=%JBOSS_NATIVE%;-Dprogram.name=run.bat
          SET JVM_MS=256
          SET JVM_MX=512

          %JBOSS_SERVICE_NATIVE% //IS//%SVC_NAME%%CONFIG% --DisplayName="%SVC_DISP% - %CONFIG%" --Description="%SVC_DESC% - %CONFIG%" --Install="%JBOSS_HOME%\bin%JBOSS_SERVICE_NATIVE%.exe" --Startup=manual --Classpath="%CP%" --StartClass=org.jboss.Main --StopClass=org.jboss.Shutdown --StartParams="%JBOSS_OPTS%" --StopParams="%JBOSS_OPTS%" --StartPath="%JBOSS_HOME%\bin" --StopPath="%JBOSS_HOME%\bin" --Jvm="%JVM%" --JvmOptions="%JVM_OPTS%" --JvmMs=%JVM_MS% --JvmMx=%JVM_Mx% --StartMode=jvm --StopMode=jvm --LogPath=%JBOSS_HOME%\server%CONFIG%\log --LogPrefix=jboss_service_ --LogLevel=DEBUG

          I had to change portions of org.jboss.Main in order to launch.

          ClassLoader parentCL = Thread.currentThread().getContextClassLoader();
          if ( parentCL == null )

          { parentCL = Main.class.getClassLoader(); }
          Show
          Dominik Drzewiecki added a comment - I confirm. This one is particularly annoying when one is trying to launch Jboss AS as a service It is installed roughly by the following script: SET JBOSS_SERVICE_NATIVE=tomcat6 SET JBOSS_HOME=c:\java\jboss-5.1.0.GA SET JBOSS_NATIVE=%JBOSS_HOME%\bin\native SET CONFIG=minimal SET SVC_NAME=jbossas SET SVC_DISP=JBoss Application Server 5.1 SET SVC_DESC=JBoss Application Server 5.1.0 GA/Platform: Windows x86 SET CP=%JBOSS_HOME%\bin\run.jar SET JVM=%JAVA_HOME%\jre\bin\server\jvm.dll SET JBOSS_OPTS=-c;%CONFIG% SET JVM_OPTS=-Xrs;-XX:MaxPermSize=256M;-Dsun.rmi.dgc.client.gcInterval=3600000;-Dsun.rmi.dgc.server.gcInterval=3600000;-Dorg.jboss.resolver.warning=true;-Djava.library.path=%JBOSS_NATIVE%;-Dprogram.name=run.bat SET JVM_MS=256 SET JVM_MX=512 %JBOSS_SERVICE_NATIVE% //IS//%SVC_NAME%%CONFIG% --DisplayName="%SVC_DISP% - %CONFIG%" --Description="%SVC_DESC% - %CONFIG%" --Install="%JBOSS_HOME%\bin%JBOSS_SERVICE_NATIVE%.exe" --Startup=manual --Classpath="%CP%" --StartClass=org.jboss.Main --StopClass=org.jboss.Shutdown --StartParams="%JBOSS_OPTS%" --StopParams="%JBOSS_OPTS%" --StartPath="%JBOSS_HOME%\bin" --StopPath="%JBOSS_HOME%\bin" --Jvm="%JVM%" --JvmOptions="%JVM_OPTS%" --JvmMs=%JVM_MS% --JvmMx=%JVM_Mx% --StartMode=jvm --StopMode=jvm --LogPath=%JBOSS_HOME%\server%CONFIG%\log --LogPrefix=jboss_service_ --LogLevel=DEBUG I had to change portions of org.jboss.Main in order to launch. ClassLoader parentCL = Thread.currentThread().getContextClassLoader(); if ( parentCL == null ) { parentCL = Main.class.getClassLoader(); }
          Hide
          Erik-Berndt Scheper added a comment -

          This can easily be fixed by adding the following code:

          ClassLoader defaultClassLoader = this.getClass().getClassLoader();
          Thread.currentThread().setContextClassLoader(defaultClassLoader );
          
          Show
          Erik-Berndt Scheper added a comment - This can easily be fixed by adding the following code: ClassLoader defaultClassLoader = this .getClass().getClassLoader(); Thread .currentThread().setContextClassLoader(defaultClassLoader );
          Hide
          Erik-Berndt Scheper added a comment - - edited

          Note that the DaemonLoader class (used by jsvc) also suffers from this issue, so ideally the code above should be added to the DaemonLoader. (and WinNT style should be started using the DaemonLoader).

          Show
          Erik-Berndt Scheper added a comment - - edited Note that the DaemonLoader class (used by jsvc) also suffers from this issue, so ideally the code above should be added to the DaemonLoader. (and WinNT style should be started using the DaemonLoader).
          Erik-Berndt Scheper made changes -
          Link This issue is related to DAEMON-157 [ DAEMON-157 ]
          Hide
          Erik-Berndt Scheper added a comment -

          Attached patch for DaemonLoader

          Show
          Erik-Berndt Scheper added a comment - Attached patch for DaemonLoader
          Erik-Berndt Scheper made changes -
          Attachment DaemonLoader.patch [ 12440325 ]
          Hide
          Mladen Turk added a comment -

          You patch will not solve this issue. Procrun doesn't use Daemon java code.
          The problem is that procrun unlike java.exe uses different thread for launching jvm.

          Show
          Mladen Turk added a comment - You patch will not solve this issue. Procrun doesn't use Daemon java code. The problem is that procrun unlike java.exe uses different thread for launching jvm.
          Hide
          Antony Scerri added a comment -

          Sorry to do this a little messily but i have a number of different contribution so a single patch isnt possible. I believe the solution to this problem which I encountered whilst handling an application hosting an RMI registry which was generating class not found exception when registering objects because of this lack of fully supporting class loader is the modification of the __apxJavaWorkerThread method in javajni.c. I have attached an updated version of this method with just the parts relating to this problem.

          Essentialy all it does is after the native thread is attached to the VM (which is different from the one which creates the main class. It checks to see if a thread context class loader can be found, this is incase the same thread that created the main class is now being used in which case it should already have one. I know this isnt the case at the moment but incase the design changes i thought it worth putting it inside a check. If not it then gets the class loader from the main class and assigns it to the current threads context class loader, therefore providing a fully functional class loader for the thread itself.

          There could be some more exception checking between all the calls added with appropriate failure paths, but this should be enough to demonstrate the core fix. I have succesffuly used this to get a java application loaded on windows through the prunsrv.exe that creates an RMI registry and registers objects appropriately.

          Show
          Antony Scerri added a comment - Sorry to do this a little messily but i have a number of different contribution so a single patch isnt possible. I believe the solution to this problem which I encountered whilst handling an application hosting an RMI registry which was generating class not found exception when registering objects because of this lack of fully supporting class loader is the modification of the __apxJavaWorkerThread method in javajni.c. I have attached an updated version of this method with just the parts relating to this problem. Essentialy all it does is after the native thread is attached to the VM (which is different from the one which creates the main class. It checks to see if a thread context class loader can be found, this is incase the same thread that created the main class is now being used in which case it should already have one. I know this isnt the case at the moment but incase the design changes i thought it worth putting it inside a check. If not it then gets the class loader from the main class and assigns it to the current threads context class loader, therefore providing a fully functional class loader for the thread itself. There could be some more exception checking between all the calls added with appropriate failure paths, but this should be enough to demonstrate the core fix. I have succesffuly used this to get a java application loaded on windows through the prunsrv.exe that creates an RMI registry and registers objects appropriately.
          Antony Scerri made changes -
          Attachment __apxJavaWorkerThread.txt [ 12448089 ]
          Hide
          Mladen Turk added a comment -

          Fixed in the SVN and will be part of 1.0.4
          There reason was because the jvm.dll requires to be loaded in the
          same thread as main class is started.
          Of course this is no where documented in the JNI specs
          (at least I wasn't able to find it)

          Show
          Mladen Turk added a comment - Fixed in the SVN and will be part of 1.0.4 There reason was because the jvm.dll requires to be loaded in the same thread as main class is started. Of course this is no where documented in the JNI specs (at least I wasn't able to find it)
          Mladen Turk made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Assignee Mladen Turk [ mturk@apache.org ]
          Fix Version/s 1.0.4 [ 12315226 ]
          Resolution Fixed [ 1 ]
          mturk committed 1000862 (1 file)
          Reviews: none

          Add DAEMON-100 to the list of fixed issues with 1.0.4

            People

            • Assignee:
              Mladen Turk
              Reporter:
              Anton Vodonosov
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development