OS : Sun Solaris 2.8 (Intel) java version "1.4.1" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21) Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode) Tomcat 4.1.24 w/ Apache 2.0.45 When reloading a context with the manager app, serializing the session fails if there is an array of a class I have created in the session object. Serialization of a single instance of the class succeeds. There is one instance where the serialization of the array succeeds, and that is if the class is in a package that is read from $TOMCAT_BASE/common/lib. This is not an ongoing option for me due to file system privileges. If I place the package in either WEB-INF/lib (as a jar) or expanded into WEB-INF/classes I get the exception listed below. Another observation, a String[] can be serialized successfully. There is no problem with the class being found for compiling a jsp or servlet, it is only the classloader used for session persistence that has a problem. The exception produced (twice) is : 2003-05-05 10:48:12 StandardManager[] ClassNotFoundException while loading persisted sessions: java.lang.ClassNotFoundExcept ion: [Lextras.SearchResult; java.lang.ClassNotFoundException: [Lextras.SearchResult; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1443) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1289) at org.apache.catalina.util.CustomObjectInputStream.resolveClass(CustomObjectInputStream.java:119) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1513) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435) at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1560) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1271) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324) at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1369) at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:864) at org.apache.catalina.session.StandardManager.load(StandardManager.java:440) at org.apache.catalina.session.StandardManager.start(StandardManager.java:655) at org.apache.catalina.core.StandardContext.reload(StandardContext.java:2572) at org.apache.catalina.servlets.ManagerServlet.reload(ManagerServlet.java:802) at org.apache.catalina.servlets.HTMLManagerServlet.reload(HTMLManagerServlet.java:501) at org.apache.catalina.servlets.HTMLManagerServlet.doGet(HTMLManagerServlet.java:151) at javax.servlet.http.HttpServlet.service(HttpServlet.java:740) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:551) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223) at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:261) at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:360) at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:604) at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:562) at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:679) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619) The class that produced this error is shown below. Any of my classes fail to be serialized when in arrays, but succeed when serialized as single objects. SearchResult.java ****************** package extras; import java.io.Serializable; import com.bigredwire.util.Utility; public class SearchResult implements Serializable, Cloneable { private String memberId; private String firstName; private String lastName; private String emailAddress; /** * Creates a new instance of SearchResult */ public SearchResult() { memberId = ""; firstName = ""; lastName = ""; emailAddress = ""; } public String getMemberId() { return memberId; } public String getEmailAddress() { return emailAddress; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public void setMemberId(String memberId) { this.memberId = Utility.ensureLength(memberId, 20, false); } public void setEmailAddress(String emailAddress) { this.emailAddress = Utility.ensureLength(emailAddress, 60, false); } public void setFirstName(String firstName) { this.firstName = Utility.ensureLength(firstName, 50, false); } public void setLastName(String lastName) { this.lastName = Utility.ensureLength(lastName, 50, false); } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException ex) { throw new InternalError(ex.getMessage()); } } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("member id = " + memberId); sb.append(Utility.EOL); sb.append("first name = " + firstName); sb.append(Utility.EOL); sb.append("last name = " + lastName); sb.append(Utility.EOL); sb.append("email address = " + emailAddress); sb.append(Utility.EOL); return sb.toString(); } }
Well, [Lextras.SearchResult; is not the proper classname. Where is it specified that CL must parse it because apparently one JDK component can submit garbage instead of the proper classname ? I haven't seen that parsing code in the JDK classloading code, but maybe I didn't look hard enough.
remy, were those comments directed to me, or the tomcat developers? i can't actually answer them as i am just a user, and have no knowledge about the internals of tomcat (my project schedule doesn't lend support to me investigating either). should i be waiting for this to get looked at, or just rewrite everything affected to use vectors instead of arrays?
Hey guys, is this being looked into at all? Is more info needed? Or am I doing something wrong and this really isn't a bug at all - in which case can someone point me in the right direction please? Thanks Chris
To clarify Remy's comment he believes that this is a JDK issue where java.io.ObjectInputStream passes an invalid classname to Tomcat. Hence this is not a tomcat bug. Given that String[] works it is likely that there is something in your class - through no fault of yours - that is hitting some form of JDK bug. Have you tried searching the sun JDK bug list? How about trying a later version of the JDK?
This is actually a duplicate of bug 22146 that affects Tomcat 4.1.x. It was fixed in Tomcat 5, but Remy couldn't reproduce it in 4.1 so he didn't apply the same fix for 4.1. I'm seeing this bug in 4.1.27, and it looks like it should still affect the latest 4.1. Can you apply this patch to 4.1? http://cvs.apache.org/viewcvs.cgi/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/CustomObjectInputStream.java?r1=1.1&r2=1.2 I have verified in my working copy that it does fix the problem for Tomcat 4.1.27. Thanks.
OK. I have ported the patch and it will be included in the upcoming 4.1.31 release.