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.deserializ ePage(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