dev@glassfish.java.net

Re: Glassfish v2 (build38) - ClassNotFoundException for webapps loading classes from agents via "-javaagent:" jvm-option (System CL)

From: Max Poon <maxpoon_at_dev.java.net>
Date: Wed, 14 Mar 2007 14:50:45 +0800

Hi Sivakumar

Thanks! Some comments on your suggestions :

1) Putting required logger classes/jar in web app - This seems not
helping as the problem is on accessing classes loaded by the children
class loaders (CL) from the System CL (via "-javaagent:" jvm option),
not from the Web CL or App CL. Kindly advise if I understand correctly.

2) I just notice : it seems that Application Class Loader (CL) is
involved in the exception causing execution stack:

    Could not load Logmanager
    "com.sun.enterprise.server.logging.ServerLogManager"
    java.lang.ClassNotFoundException:
    com.sun.enterprise.server.logging.ServerLogManager
        ...
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        ...
        at org.aspectj.weaver.loadtime.Agent.<clinit>(Agent.java:33)*

  Questions:

  (a) as the "-javaagent:<aspectjweaver.jar>" jvm option requires
loading by System CL, why is AppCL involved?

  (b) if AppCL is used, then GlassFish should be able to load
com.sun.enterprise.server.logging.ServerLogManager (in appserv-rt.jar)
via delegating up to the Shared Chain CL per GlassFish default
behavior. Then, why was the above exception thrown?

Thanks again!
Max


Sivakumar Thyagarajan wrote:
> Hi Max
>
> > _Questions
> ..
> >
> > 1. how can we have the classes specified via *-javaagent:* able to
> > load those classes (e.g. in Shared Chain CL) available lower down
> > in the CL hierarchy (coz' it may not be feasible to put
> everything
> > in System CL) ?
>
> As you have mentioned already in your analysis, this is because
> aspectjweaver loaded by the system classloader cannot see classes
> loaded lower in the hierarchy such as the Logging Manager and AFAIK
> there is no easy fix for this.
>
> No easy fix because the static block at java.util.logging.LogManager
> tries to load using both the SystemClassLoader and the Thread context
> classloader (which at the time of initialization of the PreMain class
> is not set to a classloader that can load the specified
> loggingmanager) and both would not be able to load the loggingmanager.
>
> Unfortunately, while we did the earlier classloader changes in
> GlassFish v1, we tried to move our logging manager
> [com.sun.enterprise.server.logging.ServerLogManager] higher up in the
> hierarchy [to be placed with appserv-launch.jar] but it had
> dependencies on a whole lot of other appserv-rt.jar classes and hence
> couldn't get this out.
>
> Possible Workarounds:
> - I don't have the soruces for Aj/JDK14Trace. Is there a way to
> disable AspectJWeaver logging? ie an option to not have this done at all
>> at java.util.logging.Logger.getLogger(Logger.java:274)
>> at org.aspectj.weaver.tools.Jdk14Trace.<init>(Jdk14Trace.java:25)
>> at
>> org.aspectj.weaver.tools.Jdk14TraceFactory.getTrace(Jdk14TraceFactory.java:17)
>>
>> at org.aspectj.weaver.loadtime.Aj.<clinit>(Aj.java:32)
> If yes, we could use that as a temproary workaround
>
> - AspectJ weaving using WeavingURLClassLoader.
>
> - use a custom server log Manager. I know this is not supported but if
> the custom log manager is bundled with the aspectjweaver class or
> specified in the system classpath this would help aspectjweaver to
> continue to load.
>
> If none of these help, someone from the admin team could let us know
> if it would be possible to separate out our LoggingManager, so that
> this could be moved higher up in the classloader hierarchy.
>
> > 2. can we override *java.util.logging.manager* within
> > context/execution of our web apps (vs that set during glassfish
> > initialisation) so it points to something available with the web
> > apps (e.g. apache commons logging, log4J, etc) ?
>
> For log4j style configuration for a web app, does this help?
> https://glassfish.dev.java.net/servlets/ReadMsg?list=users&msgNo=590
>
> > Adding to domain.xml the jvm-option :
> >
> > * -Dcom.sun.aas.useNewClassLoader=false
> >
> > to try to disable the new Shared Chain Class Loader does not seem to
> help.
>
> This was more of a internal temporary flag we introduced during
> GlassFish v1 days. This may be broken. I shall check this. If this is
> fixed, this would be a workaround as well :)
>
> Thanks
> --Siva.
>
> Max Poon wrote:
>> Hi all
>>
>> I tried to deploy an web application onto the current latest
>> glassfish v2 build 38
>> <https://glassfish.dev.java.net/downloads/v2-b38.html> running on sun
>> jdk 1.6.0 <http://java.sun.com/javase/downloads/index.jsp>
>> (build105). I encountered a couple of problems and appreciate if you
>> can kindly help me resolve them.
>>
>> Though the web app was deployed and started successfully, it seems
>> not able to load the logger
>> *(com.sun.enterprise.server.logging.ServerLogManager*) specified by
>> *java.util.logging.manager*, throwing the following exception and
>> subsequent logging entries for glassfish become missing.
>>
>> _GlassFish start-up log extract
>> _
>> /mnt/JavaEE-SDK/jdk/jre/../bin/java
>> -client
>> -Xmx512m
>> -XX:NewRatio=2
>> *-javaagent:/mnt/glassfish-v2b38/domains/domain1/applications/j2ee-modules/glassbox/install/aspectjweaver.jar*
>>
>> -Dcom.sun.aas.defaultLogFile=/mnt/glassfish-v2b38/domains/domain1/logs/server.log
>>
>> -Djava.endorsed.dirs=/mnt/glassfish-v2b38/lib/endorsed
>> -Djava.security.policy=/mnt/glassfish-v2b38/domains/domain1/config/server.policy
>>
>> -Djava.security.auth.login.config=/mnt/glassfish-v2b38/domains/domain1/config/login.conf
>>
>> -Dsun.rmi.dgc.server.gcInterval=3600000
>> -Dsun.rmi.dgc.client.gcInterval=3600000
>> -Djavax.net.ssl.keyStore=/mnt/glassfish-v2b38/domains/domain1/config/keystore.jks
>>
>> -Djavax.net.ssl.trustStore=/mnt/glassfish-v2b38/domains/domain1/config/cacerts.jks
>>
>> -Djava.ext.dirs=/mnt/JavaEE-SDK/jdk/jre/../lib/ext:/mnt/JavaEE-SDK/jdk/jre/../jre/lib/ext:/mnt/glassfish-v2b38/domains/domain1/lib/ext:/mnt/glassfish-v2b38/javadb/lib
>>
>> -Djdbc.drivers=org.apache.derby.jdbc.ClientDriver
>> -Djavax.management.builder.initial=com.sun.enterprise.admin.server.core.jmx.AppServerMBeanServerBuilder
>>
>> -Dcom.sun.enterprise.config.config_environment_factory_class=com.sun.enterprise.config.serverbeans.AppserverConfigEnvironmentFactory
>>
>> -Dcom.sun.enterprise.taglibs=appserv-jstl.jar,jsf-impl.jar
>> -Dcom.sun.enterprise.taglisteners=jsf-impl.jar
>> *-Dglassbox.install.dir=/mnt/glassfish-v2b38/domains/domain1/applications/j2ee-modules/glassbox/install/glassbox/
>>
>> -Daj.weaving.verbose=false*
>> -Dcom.sun.aas.classloader.optionalOverrideableChain=webservices-rt.jar,webservices-tools.jar,commons-logging.jar,commons-launcher.jar
>>
>> -Dcom.sun.aas.classloader.appserverChainJars=admin-cli.jar,admin-cli-ee.jar,dbschema.jar,j2ee-svc.jar
>>
>> -Dcom.sun.aas.classloader.serverClassPath.ee=%HADB_HOME%/lib/hadbjdbc4.jar,/mnt/glassfish-v2b38/lib/SUNWjdmk/5.1/lib/jdmkrt.jar,%HADB_HOME%/lib/dbstate.jar,%HADB_HOME%/lib/hadbm.jar,%HADB_HOME%/lib/hadbmgt.jar,%MFWK_HOME%/lib/mfwk_instrum_tk.jar
>>
>> -Dcom.sun.aas.configName=server-config
>> -Ddomain.name=domain1
>> -Djmx.invoke.getters=true
>> -Dcom.sun.aas.classloader.optionalOverrideableChain.ee=
>> -Dcom.sun.updatecenter.home=/mnt/glassfish-v2b38/updatecenter
>> -Dcom.sun.aas.instanceRoot=/mnt/glassfish-v2b38/domains/domain1
>> -Dcom.sun.aas.domainName=domain1
>> -Dcom.sun.aas.classloader.sharedChainJars=javaee.jar,/mnt/JavaEE-SDK/jdk/jre/../lib/tools.jar,install/applications/jmsra/imqjmsra.jar,commons-launcher.jar,/mnt/glassfish-v2b38/imq/lib/jaxm-api.jar,/mnt/glassfish-v2b38/imq/lib/fscontext.jar,/mnt/glassfish-v2b38/imq/lib/imqbroker.jar,/mnt/glassfish-v2b38/imq/lib/imqjmx.jar,/mnt/glassfish-v2b38/imq/lib/imqxm.jar,/mnt/glassfish-v2b38/lib/ant/lib/ant.jar,webservices-rt.jar,webservices-tools.jar,mail.jar,jsf-api.jar,jsf-impl.jar,appserv-jstl.jar,appserv-env.jar,jmxremote_optional.jar,/mnt/glassfish-v2b38/lib/SUNWjdmk/5.1/lib/jdmkrt.jar,commons-logging.jar,activation.jar,appserv-rt.jar,appserv-admin.jar,appserv-cmp.jar,/mnt/glassfish-v2b38/updatecenter/lib/updatecenter.jar,/mnt/glassfish-v2b38/jbi/lib/jbi.jar
>>
>> -Dcom.sun.aas.classloader.sharedChainJars.ee=appserv-se.jar,appserv-ee.jar,%HADB_HOME%/lib/dbstate.jar,%HADB_HOME%/lib/hadbjdbc4.jar,jgroups-all.jar,%MFWK_HOME%/lib/mfwk_instrum_tk.jar
>>
>> *-Djava.util.logging.manager=com.sun.enterprise.server.logging.ServerLogManager
>>
>> *-Dcom.sun.enterprise.overrideablejavaxpackages=javax.help,javax.portlet
>> -Dcom.sun.aas.classloader.serverClassPath=/mnt/glassfish-v2b38/lib/install/applications/jmsra/imqjmsra.jar,/mnt/glassfish-v2b38/imq/lib/jaxm-api.jar,/mnt/glassfish-v2b38/imq/lib/fscontext.jar,/mnt/glassfish-v2b38/imq/lib/imqbroker.jar,/mnt/glassfish-v2b38/imq/lib/imqjmx.jar,/mnt/glassfish-v2b38/lib/ant/lib/ant.jar,/mnt/glassfish-v2b38/lib/SUNWjdmk/5.1/lib/jdmkrt.jar
>>
>> -Dcom.sun.aas.classloader.appserverChainJars.ee=
>> -Dcom.sun.aas.configRoot=/mnt/glassfish-v2b38/config
>> -Djava.library.path=/mnt/glassfish-v2b38/lib:/mnt/glassfish-v2b38/lib:/mnt/glassfish-v2b38/lib
>>
>> -Dcom.sun.aas.instanceName=server
>> -Dcom.sun.aas.processLauncher=SE
>> -Dcom.sun.aas.installRoot=/mnt/glassfish-v2b38
>> -Dcom.sun.aas.ClassPathPrefix=
>> -Dcom.sun.aas.ClassPathSuffix=
>> -Dcom.sun.aas.ServerClassPath=
>> -Dcom.sun.aas.promptForIdentity=true
>> -cp
>> :/mnt/glassfish-v2b38/lib/appserv-launch.jar:/mnt/glassfish-v2b38/lib/ant/lib/ant-launcher.jar:/mnt/glassfish-v2b38/domains/domain1/applications/j2ee-modules/glassbox/install/glassboxMonitor.jar
>>
>> com.sun.enterprise.server.PELaunch
>> start
>> *Could not load Logmanager
>> "com.sun.enterprise.server.logging.ServerLogManager"
>> java.lang.ClassNotFoundException:
>> com.sun.enterprise.server.logging.ServerLogManager*
>> at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
>> at java.security.AccessController.doPrivileged(Native Method)
>> at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
>> at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
>> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
>> at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
>> at java.util.logging.LogManager$1.run(LogManager.java:166)
>> at java.security.AccessController.doPrivileged(Native Method)
>> at java.util.logging.LogManager.<clinit>(LogManager.java:156)
>> * at java.util.logging.Logger.getLogger(Logger.java:274)
>> at org.aspectj.weaver.tools.Jdk14Trace.<init>(Jdk14Trace.java:25)
>> at
>> org.aspectj.weaver.tools.Jdk14TraceFactory.getTrace(Jdk14TraceFactory.java:17)
>>
>> at org.aspectj.weaver.loadtime.Aj.<clinit>(Aj.java:32)
>> at
>> org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.<clinit>(ClassPreProcessorAgentAdapter.java:32)
>>
>> at org.aspectj.weaver.loadtime.Agent.<clinit>(Agent.java:33)*
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>
>> at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at
>> sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
>>
>> at
>> sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
>>
>> Mar 12, 2007 6:35:57 PM com.sun.enterprise.server.PEMain main
>> INFO: Starting Sun Java System Application Server 9.1 (build b38-rc) ...
>> Mar 12, 2007 6:36:06 PM com.sun.enterprise.server.ss.ASLazyKernel
>> startASSocketServices
>> INFO: CORE5098: AS Socket Service Initialization has been completed.
>> Mar 12, 2007 6:36:07 PM com.sun.enterprise.server.ApplicationServer
>> printStartupInfo
>> INFO: CORE5076: Using [Java HotSpot(TM) Client VM, Version 1.6.0]
>> from [Sun Microsystems Inc.]
>>
>> It seems that
>>
>> * *org.aspectj.weaver.tools.Jdk14Trace* (from *aspectjweaver.jar*
>> specified in *-javaagent:* jvm option)
>>
>> tried to load
>>
>> * *com.sun.enterprise.server.logging.ServerLogManager *in
>> *appserv-rt.jar* loaded via Shared Chain Class Loader (specified
>> by *-Djava.util.logging.manager* loadable via
>> -Dcom.sun.aas.classloader.sharedChainJars)
>>
>> The exception observed (enclosed) can be explained if classes
>> specified in -javaagent: are loaded by System CL (which is parent of
>> Shared Chain CL so cannot load those classes in its children)
>> according to the GlassFish class loading hierarchy
>> <https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beade.html#beadh>.
>>
>> _Questions
>> _
>> In this case,
>>
>> 1. how can we have the classes specified via *-javaagent:* able to
>> load those classes (e.g. in Shared Chain CL) available lower down
>> in the CL hierarchy (coz' it may not be feasible to put everything
>> in System CL) ?
>> 2. can we override *java.util.logging.manager* within
>> context/execution of our web apps (vs that set during glassfish
>> initialisation) so it points to something available with the web
>> apps (e.g. apache commons logging, log4J, etc) ?
>>
>> Adding to domain.xml the jvm-option :
>>
>> * -Dcom.sun.aas.useNewClassLoader=false
>>
>> to try to disable the new Shared Chain Class Loader does not seem to
>> help.
>>
>> Btw, this seems like a generic problem of deploying AspectJ
>> Load-Time-Weaving (LTW) web application on GlassFish due to the
>> requirement of AspectJ LTWeaver to be loaded via "-javaagent:" jvm
>> option (hence via System Class Loader) in GlassFish. (Ref. AspectJ
>> Load-Time Weaving Configuration
>> <http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html>).
>>
>>
>> Appreciate any input / ideas....
>>
>> Thanks!
>> Max