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