Hi,

I did some more research (since I am intrigued by the subject) with the
following results:

- If you have enhanced cglib classes in your session and they are serialized
and later deserialized by a different jvm (for instance after restart)
you'll get a ClassNotFoundException. Since it can't find the enhanced class.
- Like the explanation on the cglib site you'll need to override the
writeReplace method in the object containing the cglib enhanced classes to
replace them with non enhanced counterparts.

Here is testcode to proof it:
======================================
Dummy Session object containing the cglib enhanced class
======================================

public class Session implements Serializable {
    private static final long serialVersionUID = 7348708008236878630L;
    private TestObject testObject;

    public void setTestObject(TestObject testObject) {
        this.testObject = testObject;
    }
}
======================================
TestObject that will be enhanced by cglib
======================================
public class TestObject implements Serializable {
    private static final long serialVersionUID = -5780038574171745351L;
    private String text = "hallo";

    public String getText() {
        return text;
    }
}


======================================
The serializer
======================================

import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;

public class Serializer {

    static final File TEST_FILE = new File("/tmp/Session.obj");

    public static void main(String[] args) throws Exception {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(TestObject.class);
        enhancer.setCallbackType(MethodInterceptor.class);
        Object object = enhancer.createClass().newInstance();
        TestObject testObject = TestObject.class.cast(object);

        System.out.println("Text: " + testObject.getText());
        if(TEST_FILE.exists()) {
            System.out.println("Deleting existing file");
            TEST_FILE.delete();
        }
        Session session = new Session();
        session.setTestObject(testObject);

        FileOutputStream fileOutputStream = new FileOutputStream(TEST_FILE);
        ObjectOutputStream outputStream = new
ObjectOutputStream(fileOutputStream);
        outputStream.writeObject(session);
        outputStream.close();


        if(TEST_FILE.exists()) {
            System.out.println("File created!");
        } else {
            System.out.println("File NOT created!");

        }
    }

}

======================================
The deserializer
======================================
public class DeSerializer {

    public static void main(String[] args) throws Exception {
        if(!Serializer.TEST_FILE.exists()) {
            System.out.println("Test file does not exist.");
            return;
        }

        FileInputStream fileInputStream = new FileInputStream(
Serializer.TEST_FILE);
        ObjectInputStream inputStream = new
ObjectInputStream(fileInputStream);
        Object object = inputStream.readObject();
        System.out.println("Object: "+ object.getClass() + " read from
disk");

    }

}


If you'll first run the Serializer and then the DeSerializer you'll see the
ClassNotFoundException with a mesage something like:
TestObject$$EnhancerByCGLIB$$

If you add the following method in the Session:

    private Object writeReplace() throws ObjectStreamException {
        System.out.println("in write replace");
        this.testObject = new TestObject();
        return this;
    }

And run it again it will work smoothly. The object returned by writeReplace
will actually be stored in the stream.

This does not exactly solve your problem I guess (no
StreamCorruptedException here...), but it does mean you can't have cglib
enhanced classes in your session. Or was this already a known issues?

Lars

On Thu, Mar 27, 2008 at 12:19 PM, lars vonk <[EMAIL PROTECTED]> wrote:

> Hi,
>
> Assuming you use CGLib:
>
> CGLib classes could cause this problem, it makes sense since:
>
> - It does not occur in a single jvm, the enhanced classes are available
> there.
> - It does occur when read from a different jvm *or* restarted jvm: The
> enhanced classes are no longer available there.
>
> According to the CGLib site there is a way around this. See
> http://cglib.sourceforge.net/howto.html
>
>  CGLIB and JAVA Serialization
> >
> > JAVA objects can be serialized to binary streams, it is used to
> > implement RMI too. Serialization needs to load class before to deserialize
> > object data. It is possible there is no generated class on client or server
> > for unmarshaled object, but serialization lets to replace objects in stream
> > (writeReplace/readResolve contract). To add "writeReplace" method to proxy
> > class declare this method in interface with exact signature specified by
> > JAVA serialization. Implement writeReplace in interceptor. Proxy object can
> > be replaced by handle, object stream invokes "readResolve" before to
> > deserialize hanle. Generate or find proxy class in "readResolve" method
> > before to deserialize hanle and return proxy instance.
> >
>
> The description is a bit cryptic though.... But my understanding is that
> when you implement the writeReplace and readResolve methods in your enhanced
> class it should work.
>
> Hopes this helps.
>
> Lars
>
>
>
> On Wed, Mar 26, 2008 at 5:36 PM, Scott Swank <[EMAIL PROTECTED]>
> wrote:
>
> > That did not take care of our problem.  We are examining our session
> > to see whether it mistakenly contains some sort of cglib proxy -- our
> > typesafe model, or maybe something from Hibernate.
> >
> > Thank you again for the help.
> >
> > Scott
> >
> > On Tue, Mar 25, 2008 at 9:55 AM, Scott Swank <[EMAIL PROTECTED]>
> > wrote:
> > > Thank you.  We'll give that a try and let you know the results.
> > >
> > >
> > >
> > >  On Mon, Mar 24, 2008 at 11:43 PM, Igor Vaynberg <
> > [EMAIL PROTECTED]> wrote:
> > >  > see WICKET-1445. upgrade wicket to trunk and try again.
> > >  >
> > >  >  -igor
> > >  >
> > >  >
> > >  >
> > >  >
> > >  >  On Mon, Mar 24, 2008 at 3:15 PM, Scott Swank <
> > [EMAIL PROTECTED]> wrote:
> > >  >  > We are trying to get clustering working with Wicket 1.3.2 (on
> > JBoss
> > >  >  >  4.3.0) and we get the following exception when one node fails
> > over to
> > >  >  >  another node.  Has anyone seen anything like this before?  Any
> > >  >  >  suggestions/guesses?
> > >  >  >
> > >  >  >  Thank you,
> > >  >  >  Scott
> > >  >  >
> > >  >  >  15:02:17,320 ERROR [RequestCycle] Could not deserialize object
> > using `org.apache
> > >  >  >
> >  .wicket.util.io.IObjectStreamFactory$DefaultObjectStreamFactory` object
> > factory
> > >  >  >  java.lang.RuntimeException: Could not deserialize object using
> > `org.apache.wicke
> > >  >  >  t.util.io.IObjectStreamFactory$DefaultObjectStreamFactory`object 
> > > factory
> > >  >  >         at org.apache.wicket.util.lang.Objects.byteArrayToObject
> > (Objects.java:40
> > >  >  >  6)
> > >  >  >         at
> > org.apache.wicket.protocol.http.pagestore.AbstractPageStore.deseriali
> > >  >  >  zePage(AbstractPageStore.java:228)
> > >  >  >         at
> > org.apache.wicket.protocol.http.pagestore.DiskPageStore.getPage(DiskP
> > >  >  >  ageStore.java:706)
> > >  >  >         at
> > org.apache.wicket.protocol.http.pagestore.DiskPageStore.convertToPage
> > >  >  >  (DiskPageStore.java:1218)
> > >  >  >         at
> > org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLe
> > >  >  >  velCachePageMap.getLastPage(SecondLevelCacheSessionStore.java
> > :228)
> > >  >  >         at
> > org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLe
> > >  >  >  velCachePageMap.get(SecondLevelCacheSessionStore.java:296)
> > >  >  >         at org.apache.wicket.Session.getPage(Session.java:751)
> > >  >  >         at
> > org.apache.wicket.request.AbstractRequestCycleProcessor.resolveRender
> > >  >  >  edPage(AbstractRequestCycleProcessor.java:448)
> > >  >  >         at
> > org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebR
> > >  >  >  equestCycleProcessor.java:139)
> > >  >  >         at org.apache.wicket.RequestCycle.step(RequestCycle.java
> > :1224)
> > >  >  >         at org.apache.wicket.RequestCycle.steps(
> > RequestCycle.java:1330)
> > >  >  >         at org.apache.wicket.RequestCycle.request(
> > RequestCycle.java:493)
> > >  >  >         at org.apache.wicket.protocol.http.WicketFilter.doGet(
> > WicketFilter.java:
> > >  >  >  358)
> > >  >  >         at org.apache.wicket.protocol.http.WicketServlet.doGet(
> > WicketServlet.jav
> > >  >  >  a:124)
> > >  >  >         at javax.servlet.http.HttpServlet.service(
> > HttpServlet.java:690)
> > >  >  >         at javax.servlet.http.HttpServlet.service(
> > HttpServlet.java:803)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
> > >  >  >  icationFilterChain.java:290)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
> > >  >  >  ilterChain.java:206)
> > >  >  >         at
> > com.vegas.ui.filter.CustomerFacingClientContextFilter.doFilter(Custom
> > >  >  >  erFacingClientContextFilter.java:42)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
> > >  >  >  icationFilterChain.java:235)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
> > >  >  >  ilterChain.java:206)
> > >  >  >         at com.vegas.ui.filter.HibernateFilter.doFilter(
> > HibernateFilter.java:37)
> > >  >  >
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
> > >  >  >  icationFilterChain.java:235)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
> > >  >  >  ilterChain.java:206)
> > >  >  >         at
> > org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFi
> > >  >  >  lter.java:96)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
> > >  >  >  icationFilterChain.java:235)
> > >  >  >         at
> > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
> > >  >  >  ilterChain.java:206)
> > >  >  >         at org.apache.catalina.core.StandardWrapperValve.invoke
> > (StandardWrapperV
> > >  >  >  alve.java:230)
> > >  >  >         at org.apache.catalina.core.StandardContextValve.invoke
> > (StandardContextV
> > >  >  >  alve.java:175)
> > >  >  >         at
> > org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(Securit
> > >  >  >  yAssociationValve.java:179)
> > >  >  >         at
> > org.jboss.web.tomcat.service.session.ClusteredSessionValve.invoke(Clu
> > >  >  >  steredSessionValve.java:87)
> > >  >  >         at
> > org.jboss.web.tomcat.service.session.JvmRouteValve.invoke(JvmRouteVal
> > >  >  >  ve.java:84)
> > >  >  >         at org.jboss.web.tomcat.security.JaccContextValve.invoke
> > (JaccContextValv
> > >  >  >  e.java:84)
> > >  >  >         at org.apache.catalina.core.StandardHostValve.invoke(
> > StandardHostValve.j
> > >  >  >  ava:128)
> > >  >  >         at org.apache.catalina.valves.ErrorReportValve.invoke(
> > ErrorReportValve.j
> > >  >  >  ava:104)
> > >  >  >         at
> > org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedC
> > >  >  >  onnectionValve.java:157)
> > >  >  >         at org.apache.catalina.core.StandardEngineValve.invoke
> > (StandardEngineVal
> > >  >  >  ve.java:109)
> > >  >  >         at org.apache.catalina.connector.CoyoteAdapter.service(
> > CoyoteAdapter.jav
> > >  >  >  a:241)
> > >  >  >         at org.apache.coyote.ajp.AjpProcessor.process(
> > AjpProcessor.java:437)
> > >  >  >         at
> > org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpPro
> > >  >  >  tocol.java:381)
> > >  >  >         at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(
> > JIoEndpoint.java:44
> > >  >  >  7)
> > >  >  >         at java.lang.Thread.run(Unknown Source)
> > >  >  >  Caused by: java.io.StreamCorruptedException: invalid type code:
> > B8
> > >  >  >         at java.io.ObjectInputStream.readObject0(Unknown Source)
> > >  >  >         at java.io.ObjectInputStream.defaultReadFields(Unknown
> > Source)
> > >  >  >         at java.io.ObjectInputStream.readSerialData(Unknown
> > Source)
> > >  >  >         at java.io.ObjectInputStream.readOrdinaryObject(Unknown
> > Source)
> > >  >  >         at java.io.ObjectInputStream.readObject0(Unknown Source)
> > >  >  >         at java.io.ObjectInputStream.readObject(Unknown Source)
> > >  >  >         at org.apache.wicket.util.lang.Objects.byteArrayToObject
> > (Objects.java:39
> > >  >  >  2)
> > >  >  >         ... 41 more
> > >  >  >
> > >  >
> > >  >
> > >  > >
> >  ---------------------------------------------------------------------
> > >  >  >  To unsubscribe, e-mail: [EMAIL PROTECTED]
> > >  >  >  For additional commands, e-mail: [EMAIL PROTECTED]
> > >  >  >
> > >  >  >
> > >  >
> > >  >
> >  ---------------------------------------------------------------------
> > >  >  To unsubscribe, e-mail: [EMAIL PROTECTED]
> > >  >  For additional commands, e-mail: [EMAIL PROTECTED]
> > >  >
> > >  >
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
> >
>

Reply via email to