Re: How to access webapp classes from a Context/Manager implementation (jar located in in $CATALINA_HOME/lib/)
Hi Konstantin, On Mon, 2010-01-11 at 05:19 +0300, Konstantin Kolinko wrote: 2010/1/11 Martin Grotzke martin.grot...@javakaffee.de: On Mon, 2010-01-11 at 02:54 +0300, Konstantin Kolinko wrote: 2010/1/10 Martin Grotzke martin.grot...@javakaffee.de: Hi, Jan 10, 2010 2:57:51 PM org.apache.catalina.connector.CoyoteAdapter service SEVERE: An exception or error occurred in the container during the request processing java.lang.NoClassDefFoundError: org/joda/time/format/ISODateTimeFormat at de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat.clinit(JodaDateTimeFormat.java:35) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) So, JodaDateTimeFormat was found and its clinit was called, but ISODateTimeFormat was not. JodaDateTimeFormat is the joda DateTime serializer shipped with the memcached-session-manager (msm), which should be used/activated if joda is available in the webapp classpath. ISODateTimeFormat is a class provided by joda. Where have you placed your joda jar? The joda jar is placed in WEB-INF/lib of the application. I don't want to have this in $CATALINA_HOME/lib as joda serialization shall only be supported if it's required by the webapp. The JodaDateTimeFormat comes with the msm jar located in tomcat's lib. That won't work. A class loaded from Common classloader cannot depend on classes that are in the Webapp classloader. Place them in the same place: either both in WEB-INF/lib, or both in $CATALINA_HOME/lib Thanx for this simple description, now I got it. A very simple test with my JodaDateTimeFormat placed in WEB-INF/lib is working - looks good! You may learn how java.lang.Class.forName() is called by the VM to load dependent classes, but there is a simple concern, that should be understandable: - when a web application is stopped (undeployed), all its assets have to be removed from memory. - webapp classloader belongs to the application, and takes some steps to destroy itself, when the application is stopped - classloader knows, what classes it has already loaded Simple, makes sense. When JodaDateTimeFormat class belongs to the Common classloader, it will be loaded in memory as long as Tomcat is running, and thus cannot depend on classes in the Webapp which are relatively short-lived. Implementation-wise that is class loader delegation model. The Webapp classloader is not a parent of the Common one. Reading docs again now with your explanation and the delegation model in mind I'd say that it's already in the docs :) Thanx for your help, cheers, Martin Also please read http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html I've already done that, but I didn't find the information to solve this issue. Also reading again didn't help ;-) Thanx cheers, Martin Best regards, Konstantin Kolinko - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org signature.asc Description: This is a digitally signed message part
How to access webapp classes from a Context/Manager implementation (jar located in in $CATALINA_HOME/lib/)
Hi, for some feature of the memcached-session-manager (memcached-based session failover, [1]) I want to access/reference webapplication classes (in WEB-INF/lib/) directly from my manager implementation (subclasses o.a.catalina.session.ManagerBase, registered via Context/Manager) when tomcat starts. Alternatively, I would like to do this during request time (in the context of a request). Unfortunately, this doesn't seem to work (the issue is describe later, below). The strange thing is that basically the memcached-session-manager (msm) already needs to have access to classes from the webapp, as it serialized/deserializes them (in the context of a request). In these cases I use the manager.getContainer().getLoader().getClassLoader(), which reports to be a WebappClassLoader. The exact issue that I have now is that I want to ship msm with custom serializers for certain types that are used when some class is avaible: e.g. if the application uses joda DateTime I want to activate a custom serializer for joda DateTime. The code that tries to load the serializer for joda DateTime looks like this: public class CustomFormatLoader { ... public static XMLFormat?[] loadFormats( final ClassLoader classLoader ) { final ListXMLFormat? result = new ArrayListXMLFormat?(); try { // see if we can load the JodaDateTimeFormat final XMLFormat? xmlFormat = (XMLFormat?) Class.forName( de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat, true, classLoader ).newInstance(); result.add( xmlFormat ); LOG.info( Loaded JodaDateTimeFormat. ); } catch ( final Exception e ) { LOG.info( JodaDateTimeFormat not loaded (joda seems to be not available). ); } return result.toArray( new XMLFormat?[result.size()] ); } } The JodaDateTimeFormat: public class JodaDateTimeFormat extends XMLFormatDateTime { private static final DateTimeFormatter FORMAT = ISODateTimeFormat.basicDateTime(); /** * @param cls */ protected JodaDateTimeFormat() { super( DateTime.class ); } ... } When I try to loadFormats in the context of a request, this exception is thrown: Jan 10, 2010 2:57:51 PM org.apache.catalina.connector.CoyoteAdapter service SEVERE: An exception or error occurred in the container during the request processing java.lang.NoClassDefFoundError: org/joda/time/format/ISODateTimeFormat at de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat.clinit(JodaDateTimeFormat.java:35) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at de.javakaffee.web.msm.serializer.javolution.CustomFormatLoader.loadFormats(CustomFormatLoader.java:46) at de.javakaffee.web.msm.serializer.javolution.ReflectionBinding.getFormat(ReflectionBinding.java:134) at javolution.xml.XMLFormat$OutputElement.add(XMLFormat.java:815) at javolution.xml.XMLObjectWriter.write(XMLObjectWriter.java:242) at de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoder.serialize(JavolutionTranscoder.java:108) at net.spy.memcached.transcoders.SerializingTranscoder.encode(SerializingTranscoder.java:135) at net.spy.memcached.MemcachedClient.asyncStore(MemcachedClient.java:274) at net.spy.memcached.MemcachedClient.set(MemcachedClient.java:631) at de.javakaffee.web.msm.MemcachedBackupSessionManager.storeSessionInMemcached(MemcachedBackupSessionManager.java:721) at de.javakaffee.web.msm.MemcachedBackupSessionManager.backupSession(MemcachedBackupSessionManager.java:495) at de.javakaffee.web.msm.SessionTrackerValve.backupSession(SessionTrackerValve.java:117) at de.javakaffee.web.msm.SessionTrackerValve.invoke(SessionTrackerValve.java:107) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at
Re: How to access webapp classes from a Context/Manager implementation (jar located in in $CATALINA_HOME/lib/)
On 10/01/2010 14:35, Martin Grotzke wrote: final XMLFormat? xmlFormat = (XMLFormat?) Class.forName( de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat, true, classLoader ).newInstance(); snip/ Can someone help with this? I suggest downloading a copy of the Tomcat source code and debugging your way through the call above. The first thing I'd check is whether classLoader is what you expect it to be and it if is, I'd then see what is going on in that call as it should find the class. Mark - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: How to access webapp classes from a Context/Manager implementation (jar located in in $CATALINA_HOME/lib/)
2010/1/10 Martin Grotzke martin.grot...@javakaffee.de: Hi, Jan 10, 2010 2:57:51 PM org.apache.catalina.connector.CoyoteAdapter service SEVERE: An exception or error occurred in the container during the request processing java.lang.NoClassDefFoundError: org/joda/time/format/ISODateTimeFormat at de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat.clinit(JodaDateTimeFormat.java:35) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) So, JodaDateTimeFormat was found and its clinit was called, but ISODateTimeFormat was not. Where have you placed your joda jar? Also please read http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html Best regards, Konstantin Kolinko - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: How to access webapp classes from a Context/Manager implementation (jar located in in $CATALINA_HOME/lib/)
On Mon, 2010-01-11 at 02:54 +0300, Konstantin Kolinko wrote: 2010/1/10 Martin Grotzke martin.grot...@javakaffee.de: Hi, Jan 10, 2010 2:57:51 PM org.apache.catalina.connector.CoyoteAdapter service SEVERE: An exception or error occurred in the container during the request processing java.lang.NoClassDefFoundError: org/joda/time/format/ISODateTimeFormat at de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat.clinit(JodaDateTimeFormat.java:35) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) So, JodaDateTimeFormat was found and its clinit was called, but ISODateTimeFormat was not. JodaDateTimeFormat is the joda DateTime serializer shipped with the memcached-session-manager (msm), which should be used/activated if joda is available in the webapp classpath. ISODateTimeFormat is a class provided by joda. Where have you placed your joda jar? The joda jar is placed in WEB-INF/lib of the application. I don't want to have this in $CATALINA_HOME/lib as joda serialization shall only be supported if it's required by the webapp. The JodaDateTimeFormat comes with the msm jar located in tomcat's lib. Also please read http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html I've already done that, but I didn't find the information to solve this issue. Also reading again didn't help ;-) Thanx cheers, Martin Best regards, Konstantin Kolinko - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org signature.asc Description: This is a digitally signed message part
Re: How to access webapp classes from a Context/Manager implementation (jar located in in $CATALINA_HOME/lib/)
2010/1/11 Martin Grotzke martin.grot...@javakaffee.de: On Mon, 2010-01-11 at 02:54 +0300, Konstantin Kolinko wrote: 2010/1/10 Martin Grotzke martin.grot...@javakaffee.de: Hi, Jan 10, 2010 2:57:51 PM org.apache.catalina.connector.CoyoteAdapter service SEVERE: An exception or error occurred in the container during the request processing java.lang.NoClassDefFoundError: org/joda/time/format/ISODateTimeFormat at de.javakaffee.web.msm.serializer.javolution.JodaDateTimeFormat.clinit(JodaDateTimeFormat.java:35) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) So, JodaDateTimeFormat was found and its clinit was called, but ISODateTimeFormat was not. JodaDateTimeFormat is the joda DateTime serializer shipped with the memcached-session-manager (msm), which should be used/activated if joda is available in the webapp classpath. ISODateTimeFormat is a class provided by joda. Where have you placed your joda jar? The joda jar is placed in WEB-INF/lib of the application. I don't want to have this in $CATALINA_HOME/lib as joda serialization shall only be supported if it's required by the webapp. The JodaDateTimeFormat comes with the msm jar located in tomcat's lib. That won't work. A class loaded from Common classloader cannot depend on classes that are in the Webapp classloader. Place them in the same place: either both in WEB-INF/lib, or both in $CATALINA_HOME/lib You may learn how java.lang.Class.forName() is called by the VM to load dependent classes, but there is a simple concern, that should be understandable: - when a web application is stopped (undeployed), all its assets have to be removed from memory. - webapp classloader belongs to the application, and takes some steps to destroy itself, when the application is stopped - classloader knows, what classes it has already loaded When JodaDateTimeFormat class belongs to the Common classloader, it will be loaded in memory as long as Tomcat is running, and thus cannot depend on classes in the Webapp which are relatively short-lived. Implementation-wise that is class loader delegation model. The Webapp classloader is not a parent of the Common one. Also please read http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html I've already done that, but I didn't find the information to solve this issue. Also reading again didn't help ;-) Thanx cheers, Martin Best regards, Konstantin Kolinko - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org