I think I've found the solution for my StreamCorruptedException problem.
Inside the org.apache.wicket.Page, there is a constant LATEST_VERSION which
value is  -1. In my application, the versionNumber passed as parameter to
the method getVersion(final int versionNumber) inside Page is never -1, the
initial versionNumber of a page is always 0. When this versionNumber is
different from 0, the versionManager object inside Page is not null, so the
flow goes to the else block inside the getVersion() method.

If LATEST_VERSION is -1, the flow of my application is always going to the
if block below, never to else block, as my versionNumber is always >= 0, so
depending on the versionNumber, no page will be recovered, which was leading
to the StreamCorruptedException, maybe because wicket was trying to
de-serialize the wrong version of my page.

if (versionNumber != LATEST_VERSION) {
  page = versionManager.getVersion(versionNumber);
}
else {
  page = versionManager.getVersion(getCurrentVersionNumber());
}

I've changed LATEST_VERSION value to 0, and now my application works
perfectly. Are these assumptions correct? Does anytime versionNumber assumes
the -1 value?

On Thu, Apr 3, 2008 at 8:43 PM, Daniel Wu <[EMAIL PROTECTED]> wrote:

> I debugged my application and it really doesn't have a
> ClassNotFoundException eaten by ObjectInputStream. I compared the flow of
> two screens of my application, one that works and another that doesn't:
>
> 1) The line 298 of SecondLevelCacheSessionStore =>
> getLastPage().getVersion(versionNumber) is returning the correct page,
> because inside the getVersion() method, the versionManager object is null.
> In this case, the screen that I'm testing works perfectly.
>
> 2) For the screen that throws the StackOverFlow and
> StreamCorruptedException, for some reason the versionManager object is not
> null, and it returns a null page object.
>
> Another strange thing is that after the line 393 of Objects.java => return
> ois.readObject(); => while debugging it using Eclipse, after this method
> call the flow goes straight to the line 363 of AbstractPageStore.java,
> without entering the finally block. So, an infinite loop starts, causing the
> StackOverflow.
>
> During the tab switch of the screen that works, the line 393 of
> Objects.java is never reached, meaning that this screen was not serialized,
> right? This code is only reached during a tab switch of the screen that
> throws StackOverFlow exception.
>
> What defines if a page should be serialized/deserialized? Does anyone know
> what could be causing these problems?
>
>
> On Wed, Apr 2, 2008 at 7:28 PM, Daniel Stoch <[EMAIL PROTECTED]>
> wrote:
>
> > Hi,
> >
> > It seems that this could be an OSGi related issue. We have the similar
> > problem in our applications.
> > You can look at the thread: Wicket + OSGI + Session (november 2007).
> > Then Sebastiaan gave me a tip that this can be ClassNotFoundException:
> >
> > "It's probably a ClassNotFoundException on deserialization which gets
> > eaten by ObjectInputStream (there's a bug report at Sun for this). To be
> > sure you can debug trapping on ClassNotFoundException (caught and uncaught)
> > when this problem occurs.
> >
> > However, since it's in a page you can easily fix this one: either
> > upgrade to trunk and implement your own IClassResolver and register it with
> > the application, or write your own IObjectStreamFactory implementation and
> > register it with the Objects class.
> >
> > In either case, have a look at the DefaultObjectStreamFactory to see how
> > to write a hook to look up classes in an ObjectInputStream implementation
> > (resolveClass method)."
> >
> >
> > Inside OSGI environment each bundle has its own class loader, so this
> > could leeds to problem when you try to use in your app a class defined in
> > another bundle.
> > I've solved this problem by implementing my own IClassResolver. The
> > default Wicket DefaultClassResolver is a final class, so we must make a copy
> > of it and make a little change at the end of resolveClass method.
> >
> > The default implementation (DefaultClassResolver):
> >
> >        synchronized (classes)
> >        {
> >                ClassLoader loader =
> > Thread.currentThread().getContextClassLoader();
> >                if (loader == null)
> >                {
> >                        loader =
> > DefaultClassResolver.class.getClassLoader();
> >                }
> >                clazz = loader.loadClass(classname);
> >        }
> >
> > When there is a ClassLoader attached to the current thread as context
> > class loader, then Wicket uses it. The problem is under OSGi, that the
> > related class (with classname) can be located inside another bundle and can
> > be loaded by another class loader, not this from current thread. So
> > DefaultClassResolver fails to find this class. The solution is to try in
> > such situation use the class loader which loads DefaultClassResolver class
> > (= which loads all Wicket classes). In our CustomClassResolver this block
> > was changed to something like this:
> >
> >        synchronized (classes) {
> >                ClassLoader loader =
> > Thread.currentThread().getContextClassLoader();
> >                if (loader == null) {
> >                        loader =
> > DefaultClassResolver.class.getClassLoader();
> >                        clazz = loader.loadClass(classname);
> >                } else {
> >                        try {
> >                                clazz = loader.loadClass(classname);
> >                        } catch (ClassNotFoundException e) {
> >                                loader =
> > DefaultClassResolver.class.getClassLoader();
> >                                clazz = loader.loadClass(classname);
> >                        }
> >                }
> >        }
> >
> > Then in your Application class init() method add the following line:
> > getApplicationSettings().setClassResolver(new CustomClassResolver());
> >
> > But there is a one assumption, that bundle with Wicket classes (you
> > probably have a Wicket bundled somehow in your app, don't you? :)), should
> > have a dynamic import for all classes which can be located in many different
> > bundles:
> > DynamicImport-Package: *
> >
> > Maybe such change could be done in Wicket core (in DefaultClassResolver
> > class)?
> >
> > --
> > Daniel Stoch
> >
> >
> > On 2008-03-29, at 22:22, Daniel Wu wrote:
> >
> > >
> > > I've updated my wicket application to Wicket 1.3.2, but now, when I
> > > try to
> > > switch between my application tabs (my tabs extend
> > > org.apache.wicket.extensions.markup.html.tabs.AbstractTab) I'm getting
> > > this
> > > error:
> > >
> > > 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.wicket.util.io.IObjectStreamFactory$DefaultObjectStreamFactory`
> > > object factory
> > >        at
> > > org.apache.wicket.util.lang.Objects.byteArrayToObject(Objects.java:411)
> > >        at
> > >
> > > org.apache.wicket.protocol.http.pagestore.AbstractPageStore.deserializePage(AbstractPageStore.java:228)
> > >        at
> > >
> > > org.apache.wicket.protocol.http.pagestore.DiskPageStore.getPage(DiskPageStore.java:706)
> > >        at
> > >
> > > org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLevelCachePageMap.get(SecondLevelCacheSessionStore.java:311)
> > >        at org.apache.wicket.Session.getPage(Session.java:751)
> > > ...
> > > Caused by: java.io.StreamCorruptedException: invalid type code: 29
> > >        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:393)
> > >
> > > I've already downloaded and used the latest wicket 1.3 snapshot, which
> > > was
> > > suggested to me here: https://issues.apache.org/jira/browse/WICKET-1445
> > > ,
> > > but I'm still having this error.
> > >
> > > I'm still using an old release of wicket-extensions. Since I updated
> > > to
> > > wicket 1.3, I'm also having this warning:
> > >
> > > WARN  AbstractTextComponent () - Couldn't resolve model type of
> > > Model:classname=[...], please set the type yourself.
> > >
> > > Could any of these be related to the Serialization error? Does anyone
> > > have
> > > any idea of what is causing it?
> > >
> > > Daniel
> > >
> > > --
> > > View this message in context: http://www.nabble.com/
> > > java.io.StreamCorruptedException%3A-invalid-type-code%3A-29-tp16374745p16374745.html
> > > Sent from the Wicket - User mailing list archive at Nabble.com.
> > >
> > >
> > > ---------------------------------------------------------------------
> > > 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