10 Replies Latest reply on Oct 22, 2012 5:26 AM by alesj

    How to re-compile a class loader

    lavot

      Hi,

       

      I'm completely new here. I've been requested to help to improve perf on a project that runs under jboss 5.1.0.

      We've done a jstack and most of the threads that run our code are blocked in the class loader in loadClass(). I've downloaded 2.09.GA jar of the class loader which seemed to improve a little the perf but now most of the threads are blocked in doLoad().

      I've activated the traces for BaseClassLoader to try to understand which classes are loaded as after a few minutes of execution, I would have expected that all the classes would have been already loaded.

      And that seems to be true as far as I saw:

      2012-07-03 14:21:46,429 [WorkManager(2)-3] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@c9447{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sms-ejb.jar/} loadClass ...capabilities.common.adapter.CapOutgoingAdapterApi resolve=false

       

      2012-07-03 14:21:46,431 [WorkManager(2)-3] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@c9447{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sms-ejb.jar/} already loaded class interface ...capabilities.common.adapter.CapOutgoingAdapterApi{cl=BaseClassLoader@c9447{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sms-ejb.jar/} codeSource=(jar:file:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sms-ejb.jar!/ <no signer certificates>)}

       

      Therefore, I don't understand why my class loader goes to doLoad() and then there gets blocked on the synchronize.

       

      So, after that long introduction, here is my point. I'd like to understand better what is done in the class loader. So, I've decided to recompile a class loader with more traces but I failed. Could someone help me ?

       

      I checked out the code:

      c:\Program Files (x86)\Apache-Subversion-1.7.5\bin\svn.exe" co http://anonsvn.jboss.org/repos/jbossas/projects/jboss-cl/tags/2.0.9.GA 2.0.9.GA

       

      And tried to compile:

      mvn clean install

      And got what I didn't understand:

      [INFO] Scanning for projects...

      [INFO] Reactor build order:

      [INFO]   JBoss ClassLoader Parent POM

      [INFO]   JBoss ClassLoader

      [INFO]   JBoss ClassLoading

      [INFO]   JBoss ClassLoading VFS

      [INFO]   JBoss ClassLoader Distribution Build

      [INFO] ------------------------------------------------------------------------

      [INFO] Building JBoss ClassLoader Parent POM

      [INFO]    task-segment: [clean, install]

      [INFO] ------------------------------------------------------------------------

      [INFO] [clean:clean {execution: default-clean}]

      [INFO] [enforcer:enforce {execution: enforce-plugin-versions}]

      [INFO] [enforcer:enforce {execution: enforce-java-version}]

      [INFO] [enforcer:enforce {execution: enforce-maven-version}]

      [INFO] [site:attach-descriptor {execution: default-attach-descriptor}]

      [INFO] [source:jar-no-fork {execution: attach-sources}]

      [INFO] [install:install {execution: default-install}]

      [INFO] Installing C:\Users\Lionel\Documents\Dev\JBOSS_CL\2.

      0.9.GA\pom.xml to C:\Users\Lionel\Documents\M2_REPO\reposit

      ory\org\jboss\cl\jboss-cl\2.0.9.GA\jboss-cl-2.0.9.GA.pom

      [INFO] ------------------------------------------------------------------------

      [INFO] Building JBoss ClassLoader

      [INFO]    task-segment: [clean, install]

      [INFO] ------------------------------------------------------------------------

      [INFO] [clean:clean {execution: default-clean}]

      [INFO] Deleting file set: C:\Users\Lionel\Documents\Dev\JBO

      SS_CL\2.0.9.GA\classloader\target (included: [**], excluded: [])

      [INFO] [enforcer:enforce {execution: enforce-plugin-versions}]

      [INFO] [enforcer:enforce {execution: enforce-java-version}]

      [INFO] [enforcer:enforce {execution: enforce-maven-version}]

      [INFO] [resources:resources {execution: default-resources}]

      [INFO] Using 'UTF-8' encoding to copy filtered resources.

      [INFO] skip non existing resourceDirectory C:\Users\Lionel\Documents\

      Dev\JBOSS_CL\2.0.9.GA\classloader\src\main\resources

      [INFO] [compiler:compile {execution: default-compile}]

      [INFO] Compiling 52 source files to C:\Users\Lionel\Documents\

      Dev\JBOSS_CL\2.0.9.GA\classloader\target\classes

      [INFO] ------------------------------------------------------------------------

      [ERROR] BUILD FAILURE

      [INFO] ------------------------------------------------------------------------

      [INFO] Compilation failure

       

      could not parse error message: warning: [options] bootstrap class path not set i

      n conjunction with -source 1.5

      C:\Users\Lionel\Documents\Dev\JBOSS_CL\2.0.9.GA\classloader

      \src\main\java\org\jboss\classloader\spi\base\BaseClassLoader.java:115: warning:

      [deprecation] isDebugEnabled() in Logger has been deprecated

            if (log.isDebugEnabled())

                   ^

       

      C:\Users\Lionel\DocumentsDev\JBOSS_CL\2.0.9.GA\classloader

      \src\main\java\org\jboss\classloader\test\support\IsolatedClassLoaderTest.java:[

      61,22] error: name clash: suite(Class<?>) in IsolatedClassLoaderTest and suite(C

      lass) in AbstractTestCaseWithSetup have the same erasure, yet neither hides the

      other

       

       

      [INFO] ------------------------------------------------------------------------

      [INFO] For more information, run Maven with the -e switch

      [INFO] ------------------------------------------------------------------------

      [INFO] Total time: 5 seconds

      [INFO] Finished at: Wed Jul 04 21:02:32 CEST 2012

      [INFO] Final Memory: 32M/342M

      [INFO] ------------------------------------------------------------------------

       

       

      Thanks for help.

      Lionel

        • 1. Re: How to re-compile a class loader
          alesj

          Re-compile a class with more trace?

          You just need to turn on proper logging.

          • 2. Re: How to re-compile a class loader
            lavot

            Hi Ales,

             

            Thanks for getting involved in my problem.

             

            I want to change the code to introduce new traces as I want to understand how things work.

             

            Once the traffic is established which means that all the code has been executed once so all the classes are supposed to be loaded there are still some threads that go to block on the synchronize in doLoad(). I would have expected that they exit from loadClass() after the isLoaded() check.

             

            So I want to introduce some little changes in doLoad() to trace which class is preparing to load (at the beginning of doLoad()) and which one actually loaded (at the end). Something like that:

               protected Class<?> doLoadClass(String name, boolean resolve, boolean trace) throws ClassNotFoundException

               {

                  Class<?> result;

                 

                  // LIONEL

                  if (trace)

                    log.trace(this + " doLoadClass prepared for " + name );

                 

                  synchronized (this)

                  {

                     // JBCL-114: did we lose the race to the synchronized?

                     result = isLoadedClass(name, trace);

                    

                     // Not already loaded use the domain

                     if (result == null)

                        result = loadClassFromDomain(name, trace);

             

                     // Still not found

                     if (result == null)

                        return null;

             

                    // LIONEL

                    if (trace)

                        log.trace(this + " doLoadClass actually loaded " + name );

                       

                     // Link the class if requested

                     if (resolve)

                     {

                        if (trace)

                           log.trace(this + " resolveClass " + ClassLoaderUtils.classToString(result));

                        resolveClass(result);

                     }

             

                     return result;

                  }

               }

             

            From my traces, all the classes seem to be already loaded but why isn't this determined at the first isLoaded() check in loadClass() (which is not synchronized).

             

            So thanks to help to recompile it.

            Lionel

            • 3. Re: How to re-compile a class loader
              alesj

              Well, you can easily add the new trace logs, and just re-build the project -- "mvn clean install" should work.

              isLoaded only returns classes loaded from this exact classloader, where the classes might come from the whole domain.

              • 4. Re: How to re-compile a class loader
                lavot

                Well, mvn clean install didn't work.

                It failed while compiling tests. I removed all test sub-dir from the classloader directory tree and then the compilation was ok as I got the classloader jar.

                So seems to have a problem with the tests.

                 

                I'll try to get some traces and get back here if I have some questions (for sure I will :-) ).

                 

                Thanks

                • 5. Re: How to re-compile a class loader
                  lavot

                  Well, I'm back again. Here are the traces in which I've isolated one thread:

                   

                  Line 48: 2012-07-05 09:57:52,995 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} loadClass int resolve=false
                  Line 52: 2012-07-05 09:57:52,996 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} doLoadClass prepared for int
                  Line 67: 2012-07-05 09:57:52,998 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} aquireLockFairly Thread[WorkManager(2)-67,5,JBoss Pooled Threads]
                  Line 67: 2012-07-05 09:57:52,998 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} aquireLockFairly Thread[WorkManager(2)-67,5,JBoss Pooled Threads]
                  Line 72: 2012-07-05 09:57:53,000 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} aquiredLock Thread[WorkManager(2)-67,5,JBoss Pooled Threads] holding=1
                  Line 72: 2012-07-05 09:57:53,000 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} aquiredLock Thread[WorkManager(2)-67,5,JBoss Pooled Threads] holding=1
                  Line 80: 2012-07-05 09:57:53,001 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} load from domain int domain=ClassLoaderDomain@21447f{DefaultDomain}
                  Line 90: 2012-07-05 09:57:53,002 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} get resource locally int.class
                  Line 94: 2012-07-05 09:57:53,004 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} resource is blacklisted int.class
                  Line 97: 2012-07-05 09:57:53,005 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} unlock Thread[WorkManager(2)-67,5,JBoss Pooled Threads] holding=1
                  Line 97: 2012-07-05 09:57:53,005 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} unlock Thread[WorkManager(2)-67,5,JBoss Pooled Threads] holding=1
                  Line 105: 2012-07-05 09:57:53,005 [WorkManager(2)-67] TRACE org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1acc234{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-Delivery-db-ejb.jar/} class not found int

                   

                  So, from the traces, all the doLoadClass() I have are to load "int". Does someone have an idea why int class would be loaded. I thought that int wasn't a class ?

                   

                  Any suggestion ?

                   

                  Regards

                  Lionel

                  • 6. Re: How to re-compile a class loader
                    alesj

                    Looks like something specifically forced the load of int.class.

                    It is a class, see TYPE in Integer. ;-)

                    • 7. Re: How to re-compile a class loader
                      lavot

                      I thought that Integer was a class but not int...

                       

                      All the stacks that load int look similar and I don't know how to understand that:

                       

                      2012-07-05 14:20:20,587 [WorkManager(2)-64] WARN  org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@1f4899c{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sri-ejb.jar/} doLoadClass int hack int Throw java.lang.ClassNotFoundException: int from BaseClassLoader@1f4899c{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sri-ejb.jar/}------

                      java.lang.ClassNotFoundException: int from BaseClassLoader@1f4899c{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-cap-sri-ejb.jar/}

                                      at org.jboss.classloader.spi.base.BaseClassLoader.doLoadClass(BaseClassLoader.java:517)

                                      at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:449)

                                      at java.lang.ClassLoader.loadClass(ClassLoader.java:296)

                                      at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

                                      at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:307)

                                      at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:239)

                                      at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:220)

                                      at org.jboss.ejb3.service.ServiceContainer.invoke(ServiceContainer.java:608)

                                      at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)

                                      at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)

                                      at $Proxy459.getSessionContextManager(Unknown Source)

                                      at ....adapter.jms.impl.ejb.BaseAdapterOutgoingConnector.process(BaseAdapterOutgoingConnector.java:98)

                       

                      or

                      2012-07-05 14:20:20,594 [WorkManager(2)-81] WARN  org.jboss.classloader.spi.base.BaseClassLoader - BaseClassLoader@afceff{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-smsDelivery-db-ejb.jar/} doLoadClass int hack int Throw java.lang.ClassNotFoundException: int from BaseClassLoader@afceff{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-smsDelivery-db-ejb.jar/}------

                      java.lang.ClassNotFoundException: int from BaseClassLoader@afceff{vfszip:/opt/ESG/absapp/jboss-5.1.0.GA/server/prime/deploy/prime-smsDelivery-db-ejb.jar/}

                                      at org.jboss.classloader.spi.base.BaseClassLoader.doLoadClass(BaseClassLoader.java:517)

                                      at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:449)

                                      at java.lang.ClassLoader.loadClass(ClassLoader.java:296)

                                      at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

                                      at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:307)

                                      at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:239)

                                      at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:135)

                                      at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:216)

                                      at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)

                                      at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)

                                      at $Proxy607.getOutgoingRoutingRule(Unknown Source)

                                      at .....impl.logic.state.schema.InitState.processEvent(InitState.java:90)

                       

                      Some ideas?

                       

                      Thanks

                      • 8. Re: How to re-compile a class loader
                        alesj

                        Something is calling ClassLoader::loadClass("int").

                        • 9. Re: How to re-compile a class loader
                          lavot

                          Sure and from the stack something is "org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName"...

                          Even if I don't understand why "something" does that.

                          • 10. Re: How to re-compile a class loader
                            alesj

                            Sure and from the stack something is "org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName"...

                            Yeah, that's obvious. ;-)

                             

                            The question is my does it pass-in "int", instead of java.lang.Integer.

                            Or checks if the passed param is primitive type.

                             

                            I guess only debug could tell us this.