You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Brandon Knitter <kn...@blandsite.org> on 2003/05/04 11:11:30 UTC
Weblogic6.1sp4/Struts1.1rc1/TilesPlugin - deserialize error
We're having an issue whereby the Weblogic servlet container appears to be using
a different classloader for unloading the Servlet than the one which loaded it,
or the objects in the ServletContext were loaded by a different classloader.
I'm getting the following exception stack trace:
<May 3, 2003 7:29:55 AM PDT> <Error> <HTTP> <[WebAppServletContext(2892280,tivo-
register,/tivo-register)] Could not deserialize context attribute
java.io.NotSerializableException: org.apache.struts.tiles.TilesPlugin
at java.io.ObjectOutputStream.outputObject(ObjectOutputStream.java:1143)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:361)
at java.io.ObjectOutputStream.outputArray(ObjectOutputStream.java:1093)
at java.io.ObjectOutputStream.checkSubstitutableSpecialClasses(ObjectOut
putStream.java:451)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:356)
at weblogic.servlet.internal.AttributeWrapper.getObject(AttributeWrapper
.java:94)
at weblogic.servlet.internal.AttributeWrapper.getObject(AttributeWrapper
.java:65)
at weblogic.servlet.internal.WebAppServletContext.getAttribute(WebAppSer
vletContext.java:316)
at org.apache.struts.action.ActionServlet.destroyModules(ActionServlet.j
ava:715)
at org.apache.struts.action.ActionServlet.destroy(ActionServlet.java:428
)
at weblogic.servlet.internal.ServletStubImpl.destroyServlet(ServletStubI
mpl.java:453)
at weblogic.servlet.internal.ServletStubImpl.checkForReload(ServletStubI
mpl.java:516)
at weblogic.servlet.internal.ServletStubImpl.getServlet(ServletStubImpl.
java:374)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubIm
pl.java:240)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubIm
pl.java:198)
at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispat
cherImpl.java:250)
at weblogic.servlet.jsp.PageContextImpl.forward(PageContextImpl.java:112
)
at org.apache.struts.taglib.logic.ForwardTag.doEndTag(ForwardTag.java:17
3)
at jsp_servlet.__index._jspService(__index.java:111)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:27)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubIm
pl.java:262)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubIm
pl.java:198)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppSe
rvletContext.java:2637)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestIm
pl.java:2359)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:139)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)
>
Due to the DMCA law, I am not allowed to decompile the weblogic code, but if I
were to decompile it I may find an implementation which would point to the
AttributeWrapper trying to marshall the ServletContext attribute from another
classloader because it has determined that the classloader used to putAttribute
the object is not the same as the one which is trying to getAttribute the object
in the ServletContext. Perhaps it changed during undeploy?
It's kinda hard to understand why the classloader is reloading the servlet, but
it is, and it appears that when it's trying to unload the servlet it's calling
the destroy method, and this is forcing the Struts ActionServlet to clean up (as
it should). The problem is at
org.apache.struts.action.ActionServlet.destroyModules(ActionServlet.java:715)
where the ActionServlet is trying to flip through all the attributes and clean
them up. In this routine the Weblogic implementation is trying to get them, and
alas the classloader has changed, and it trys to marshall them, and whamo the
java.io.NotSerializableException shows up.
I've tried to replicate this, but I cannot. In a test case I put a
java.lang.Object object in the servlet context via the init() and processGet()
methods, and then in destroy I'm doing just what the ActionServlet does, I
basically flip through all the vars and print them out. But mine does not break
if I force the webapp to reload, or just the class to reload.
So there are a couple of fixes:
1. figure out how Struts puts the vars in the ServletContext and figure out why
it could lead to the classloader change.
2. make the TilesPlugin serializable, but all the variables transient
3. get BEA to tell me why it's a different classloader
I'm trying 3 right now, but I'm unable to provide them with a test case to prove
that something is jacked up. Number 2 shouldn't be a requirement as the
ServletContext is never replicated, it's only doing serialization in Weblogic
due to the implementation of WL and its need to marshall the object from a
different classloader. Number 1 would be really cool if someone could help me
understand more what Struts may be introducing.
My theory is that the TilesPlugin is loaded by a parent classloader to the one
which is destroying the servlet upon a reload of some sort. I get this error in
production after a "long time" (sometimes weeks).
Setup: Weblogic 6.1sp4, JDK 1.3.1_07, Solaris 8, Struts 1.1rc1 (binary no mods),
TilesPlugin (binary, no mods).
Any help would be great, and I'd be willing to provide as much detail as would
be helpful to everyone. Perhaps our implementation is wrong?
Thanks,
--
-bk
---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org