Hey,
Problem:
ClassCastException
Casting an object from a JNDI lookup to a
javax.mail.Session
produces the
ClassCastException
.
Before you ask, I have used fully qualified class names.
object.getClass().getName()
returns
javax.mail.Session
Reason
The
ClassCastException
occurs because there are two different ClassLoaders.
javax.mail.Session.class.getClassLoader()
=
WebAppClassLoader
envCtx.lookup(Mailer.url).getClass().getClassLoader()
=
StandardClassLoader
Error-Producing Code
Session session;
try{
session = (Session) envCtx.lookup(Mailer.url);
}
catch(ClassCastException cce){
throw new ClassCastException("envCtx.lookup(Mailer.url).class = "
+envCtx.lookup(Mailer.url).getClass().getName());
}
Error
java.lang.ClassCastException: envCtx.lookup(Mailer.url).class = javax.mail.Session
at com.dhtmlkitchen.reg.mail.Mailer.sendMail(Mailer.java:110)
at com.dhtmlkitchen.reg.mail.Mailer.sendReminder(Mailer.java:72)
at com.dhtmlkitchen.reg.ChangeAccount.doPost(ChangeAccount.java:68)
debugClassLoader.jsp
<%@page import='com.dhtmlkitchen.reg.mail.Mailer,javax.naming.*,javax.mail.*'%>
<%!
public static String debugClassLoader()
throws NamingException {
Object obj = Mailer.envCtx.lookup( Mailer.url );
// Expect that to be a mail Session, check it out
StringBuffer sb = new StringBuffer();
sb.append("
");
sb.append(" obj.getClass() = ");
sb.append("
");
sb.append( obj.getClass() );
sb.append("
");
sb.append("
");
sb.append(" Session.class = ");
sb.append("
");
sb.append(Session.class);
sb.append("
");
sb.append("
");
sb.append(" obj.getClass().getClassLoader() = ");
sb.append("
");
sb.append(obj.getClass().getClassLoader());
sb.append("
");
sb.append("
");
sb.append(" Session.class.getClassLoader() = ");
sb.append("
");
sb.append(Session.class.getClassLoader());
sb.append("
");
sb.append("
");
sb.append("Session.class.getClassLoader() == obj.getClass().getClassLoader() = ");
sb.append("
");
sb.append(Session.class.getClassLoader() == obj.getClass().getClassLoader());
return sb.toString();
}
%>
<%=debugClassLoader()%>
The code above is simply a test page to examine the Objects and their classloaders.
The Result
ClassLoader.getSystemClassLoader()
sun.misc.Launcher$AppClassLoader@367a7f
jspPage.getClass().getClassLoader() =
org.apache.jasper.servlet.JasperLoader@7504c1
obj.getClass() =
class javax.mail.Session
Session.class =
class javax.mail.Session
obj.getClass().getClassLoader() =
StandardClassLoader
available:
Extension[javax.activation, implementationVendor=Sun Microsystems, Inc., implementationVendorId=com.sun, implementationVersion=1.0.2, specificationVendor=Sun Microsystems, Inc., specificationVersion=1.0]
Extension[org.apache.commons.beanutils, implementationVendor=Apache Software Foundation, implementationVersion=1.4-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.collections, implementationVendor=Apache Software Foundation, implementationVersion=1.1-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.dbcp, implementationVendor=Apache Software Foundation, implementationVersion=1.0, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.logging, implementationVendor=Apache Software Foundation, implementationVersion=1.0.1-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.pool, implementationVendor=Apache Software Foundation, implementationVersion=1.0.1, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.resources, implementationVendor=Apache Software Foundation, implementationVersion=0.1-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.services, implementationVendor=Apache Software Foundation, implementationVersion=1.0-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.jaxen, implementationVendor= bob mcwhirter & James Strachan., implementationVersion=1.0 FCS, specificationVendor=bob mcwhirter & James Strachan., specificationVersion=1.0 FCS]
Extension[javax.xml.parsers, implementationVendor=Sun Microsystems, Inc., implementationVendorId=com.sun , implementationVersion=1.2.0-FCS, specificationVendor=Sun Microsystems, Inc., specificationVersion=1.2]
Extension[org.saxpath, implementationVendor= werken digital., implementationVersion=1.0, specificationVendor=werken digital., specificationVersion=1.0 FCS]
Extension[Struts Framework, implementationVendor=Apache Software Foundation, implementationVendorId=org.apache, implementationVersion=1.0, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
delegate: true
repositories:
file:/development/tomcat/common/classes/
file:/development/tomcat/common/lib/activation.jar
file:/development/tomcat/common/lib/commons-beanutils.jar
file:/development/tomcat/common/lib/commons-collections.jar
file:/development/tomcat/common/lib/commons-dbcp.jar
file:/development/tomcat/common/lib/commons-fileupload.jar
file:/development/tomcat/common/lib/commons-logging.jar
file:/development/tomcat/common/lib/commons-pool.jar
file:/development/tomcat/common/lib/commons-resources.jar
file:/development/tomcat/common/lib/commons-services.jar
file:/development/tomcat/common/lib/commons-validator.jar
file:/development/tomcat/common/lib/dom.jar
file:/development/tomcat/common/lib/googleapi.jar
file:/development/tomcat/common/lib/jaxen-full.jar
file:/development/tomcat/common/lib/jaxp-api.jar
file:/development/tomcat/common/lib/jaxp.jar
file:/development/tomcat/common/lib/jdbc2_0-stdext.jar
file:/development/tomcat/common/lib/jstl.jar
file:/development/tomcat/common/lib/jta-spec1_0_1.jar
file:/development/tomcat/common/lib/mm.mysql-2.0.14-bin.jar
file:/development/tomcat/common/lib/naming-common.jar
file:/development/tomcat/common/lib/naming-resources.jar
file:/development/tomcat/common/lib/parser.jar
file:/development/tomcat/common/lib/sax.jar
file:/development/tomcat/common/lib/sax2r2.jar
file:/development/tomcat/common/lib/saxpath.jar
file:/development/tomcat/common/lib/servlet.jar
file:/development/tomcat/common/lib/standard.jar
file:/development/tomcat/common/lib/struts.jar
file:/development/tomcat/common/lib/taglibs-utility.jar
file:/development/tomcat/common/lib/tyrex-0.9.7.0.jar
file:/development/tomcat/common/lib/xalan.jar
file:/development/tomcat/common/lib/xerces.jar
file:/development/tomcat/common/lib/xercesImpl.jar
file:/development/tomcat/common/lib/xml-apis.jar
required:
----------> Parent Classloader:
sun.misc.Launcher$AppClassLoader@367a7f
Session.class.getClassLoader() =
WebappClassLoader
available:
Extension[com.sun.mail.smtp, implementationVendor=Sun Microsystems, Inc., implementationVendorId=com.sun, implementationVersion=1.2, specificationVendor=Sun Microsystems, Inc., specificationVersion=1.2]
delegate: false
repositories:
/WEB-INF/classes/
required:
----------> Parent Classloader:
StandardClassLoader
available:
delegate: true
repositories:
file:/development/tomcat/classes/
file:/development/tomcat/lib/jasper-compiler.jar
file:/development/tomcat/lib/jasper-runtime.jar
file:/development/tomcat/lib/naming-factory.jar
required:
----------> Parent Classloader:
StandardClassLoader
available:
Extension[javax.activation, implementationVendor=Sun Microsystems, Inc., implementationVendorId=com.sun, implementationVersion=1.0.2, specificationVendor=Sun Microsystems, Inc., specificationVersion=1.0]
Extension[org.apache.commons.beanutils, implementationVendor=Apache Software Foundation, implementationVersion=1.4-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.collections, implementationVendor=Apache Software Foundation, implementationVersion=1.1-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.dbcp, implementationVendor=Apache Software Foundation, implementationVersion=1.0, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.logging, implementationVendor=Apache Software Foundation, implementationVersion=1.0.1-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.pool, implementationVendor=Apache Software Foundation, implementationVersion=1.0.1, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.resources, implementationVendor=Apache Software Foundation, implementationVersion=0.1-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.apache.commons.services, implementationVendor=Apache Software Foundation, implementationVersion=1.0-dev, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
Extension[org.jaxen, implementationVendor= bob mcwhirter & James Strachan., implementationVersion=1.0 FCS, specificationVendor=bob mcwhirter & James Strachan., specificationVersion=1.0 FCS]
Extension[javax.xml.parsers, implementationVendor=Sun Microsystems, Inc., implementationVendorId=com.sun , implementationVersion=1.2.0-FCS, specificationVendor=Sun Microsystems, Inc., specificationVersion=1.2]
Extension[org.saxpath, implementationVendor= werken digital., implementationVersion=1.0, specificationVendor=werken digital., specificationVersion=1.0 FCS]
Extension[Struts Framework, implementationVendor=Apache Software Foundation, implementationVendorId=org.apache, implementationVersion=1.0, specificationVendor=Apache Software Foundation, specificationVersion=1.0]
delegate: true
repositories:
file:/development/tomcat/common/classes/
file:/development/tomcat/common/lib/activation.jar
file:/development/tomcat/common/lib/commons-beanutils.jar
file:/development/tomcat/common/lib/commons-collections.jar
file:/development/tomcat/common/lib/commons-dbcp.jar
file:/development/tomcat/common/lib/commons-fileupload.jar
file:/development/tomcat/common/lib/commons-logging.jar
file:/development/tomcat/common/lib/commons-pool.jar
file:/development/tomcat/common/lib/commons-resources.jar
file:/development/tomcat/common/lib/commons-services.jar
file:/development/tomcat/common/lib/commons-validator.jar
file:/development/tomcat/common/lib/dom.jar
file:/development/tomcat/common/lib/googleapi.jar
file:/development/tomcat/common/lib/jaxen-full.jar
file:/development/tomcat/common/lib/jaxp-api.jar
file:/development/tomcat/common/lib/jaxp.jar
file:/development/tomcat/common/lib/jdbc2_0-stdext.jar
file:/development/tomcat/common/lib/jstl.jar
file:/development/tomcat/common/lib/jta-spec1_0_1.jar
file:/development/tomcat/common/lib/mm.mysql-2.0.14-bin.jar
file:/development/tomcat/common/lib/naming-common.jar
file:/development/tomcat/common/lib/naming-resources.jar
file:/development/tomcat/common/lib/parser.jar
file:/development/tomcat/common/lib/sax.jar
file:/development/tomcat/common/lib/sax2r2.jar
file:/development/tomcat/common/lib/saxpath.jar
file:/development/tomcat/common/lib/servlet.jar
file:/development/tomcat/common/lib/standard.jar
file:/development/tomcat/common/lib/struts.jar
file:/development/tomcat/common/lib/taglibs-utility.jar
file:/development/tomcat/common/lib/tyrex-0.9.7.0.jar
file:/development/tomcat/common/lib/xalan.jar
file:/development/tomcat/common/lib/xerces.jar
file:/development/tomcat/common/lib/xercesImpl.jar
file:/development/tomcat/common/lib/xml-apis.jar
required:
----------> Parent Classloader:
sun.misc.Launcher$AppClassLoader@367a7f
Session.class.getClassLoader() == obj.getClass().getClassLoader() =
false
Now, the question is:
How do I get Tomcat to use the same ClassLoader for both
javax.mail.Session.class
and the Session Object that is looked up from
envCtx
?
<<Less