You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Sebastiaan van Erk <se...@sebster.com> on 2007/11/21 10:39:30 UTC

Wicket + OSGI + Session

Hi,

When Wicket pages are serialized/deserialized to the page store, they 
are serialized/deserialized using the IObjectStreamFactory set in the 
Objects class, and (in trunk) the DefaultObjectStreamFactory overrides 
the resolveClass method of ObjectInputStream to consult the 
application's IClassResolver. This is all good. :-)

But, the problem is the session itself. The ObjectIn/OutputStreams that 
the session is serialized to and deserialized from are the ones provided 
by the container, which do not use the IObjectStreamFactory. This causes 
problems with session serialization/deserialization in an OSGI environment.

I'm not really deeply into the Wicket code, but it seems to me the only 
way to really solve this is to make sure the Wicket session is not 
directly put in the HTTP session, but instead of it, a SessionHolder 
object with a reference to the Wicket session. The SessionHolder can 
have readObject/writeObject methods which just read/write the session as 
a byte stream using Objects.byteArrayToObject/objectToByteArray.

That way, when the Session is deserialized the IClassResolver is 
consulted (and if the user provides their own IObjectStreamFactory 
implementation, it too is used).

Any comments?

Regards,
Sebastiaan

Re: Wicket + OSGI + Session

Posted by Sebastiaan van Erk <se...@sebster.com>.
Digging some more in the code, it seems to be the case that *pages* in 
the session are serialized like you say (writeObject in the Page class).

However, this still leaves all the other objects in the session 
serialized by the container. Thus if I extend WebSession and add my own 
fields, they will be serialized/deserialized by the container and bypass 
IObjectStreamFactory. This is a problem if you store objects with 
classes from different OSGI bundles in your session.

Regards,
Sebastiaan


Johan Compagner wrote:
> i though matej did already do something like that, because i think matej did
> try to avoid
> double serialization (by us and by the container) So i would say that it
> would go automatic already
> 
> Isn't this the case matej?
> 
> johan
> 
> 
> 
> On Nov 21, 2007 10:39 AM, Sebastiaan van Erk <se...@sebster.com> wrote:
> 
>> Hi,
>>
>> When Wicket pages are serialized/deserialized to the page store, they
>> are serialized/deserialized using the IObjectStreamFactory set in the
>> Objects class, and (in trunk) the DefaultObjectStreamFactory overrides
>> the resolveClass method of ObjectInputStream to consult the
>> application's IClassResolver. This is all good. :-)
>>
>> But, the problem is the session itself. The ObjectIn/OutputStreams that
>> the session is serialized to and deserialized from are the ones provided
>> by the container, which do not use the IObjectStreamFactory. This causes
>> problems with session serialization/deserialization in an OSGI
>> environment.
>>
>> I'm not really deeply into the Wicket code, but it seems to me the only
>> way to really solve this is to make sure the Wicket session is not
>> directly put in the HTTP session, but instead of it, a SessionHolder
>> object with a reference to the Wicket session. The SessionHolder can
>> have readObject/writeObject methods which just read/write the session as
>> a byte stream using Objects.byteArrayToObject/objectToByteArray.
>>
>> That way, when the Session is deserialized the IClassResolver is
>> consulted (and if the user provides their own IObjectStreamFactory
>> implementation, it too is used).
>>
>> Any comments?
>>
>> Regards,
>> Sebastiaan
>>
> 

Re: Wicket + OSGI + Session

Posted by Johan Compagner <jc...@gmail.com>.
i though matej did already do something like that, because i think matej did
try to avoid
double serialization (by us and by the container) So i would say that it
would go automatic already

Isn't this the case matej?

johan



On Nov 21, 2007 10:39 AM, Sebastiaan van Erk <se...@sebster.com> wrote:

> Hi,
>
> When Wicket pages are serialized/deserialized to the page store, they
> are serialized/deserialized using the IObjectStreamFactory set in the
> Objects class, and (in trunk) the DefaultObjectStreamFactory overrides
> the resolveClass method of ObjectInputStream to consult the
> application's IClassResolver. This is all good. :-)
>
> But, the problem is the session itself. The ObjectIn/OutputStreams that
> the session is serialized to and deserialized from are the ones provided
> by the container, which do not use the IObjectStreamFactory. This causes
> problems with session serialization/deserialization in an OSGI
> environment.
>
> I'm not really deeply into the Wicket code, but it seems to me the only
> way to really solve this is to make sure the Wicket session is not
> directly put in the HTTP session, but instead of it, a SessionHolder
> object with a reference to the Wicket session. The SessionHolder can
> have readObject/writeObject methods which just read/write the session as
> a byte stream using Objects.byteArrayToObject/objectToByteArray.
>
> That way, when the Session is deserialized the IClassResolver is
> consulted (and if the user provides their own IObjectStreamFactory
> implementation, it too is used).
>
> Any comments?
>
> Regards,
> Sebastiaan
>

Re: Wicket + OSGI + Session

Posted by Daniel Stoch <da...@gmail.com>.
Hi,

Thank you for your suggestion. I have no time to look at this earlier,
but Wicket 1.3.0-rc2 is out now and after upgrade the error message I
have has changed to:
java.lang.IllegalStateException: spring application context locator
returned null
     at org.apache.wicket.spring.SpringBeanLocator.getSpringContext(SpringBeanLocator.java:180)
     at org.apache.wicket.spring.SpringBeanLocator.locateProxyTarget(SpringBeanLocator.java:162)
     at org.apache.wicket.proxy.LazyInitProxyFactory$JdkHandler.invoke(LazyInitProxyFactory.java:412)
     at org.apache.wicket.proxy.$Proxy82.getAction(Unknown Source)

So it seems there is a problem with deserialization of spring
application context locator. I have used my own locator implementation
(OsgiSpringContextLocator). There is one locator created for each
application context and there was a map of locators and app contexts.
Locator reference was the key in this map (very, very bad thing :)):

private static Map<OsgiSpringContextLocator, ApplicationContext>
applicationContexts = new HashMap<OsgiSpringContextLocator,
ApplicationContext>();

I have changed this now to:

public class OsgiSpringContextLocator implements ISpringContextLocator {

  private static Map<Integer, ApplicationContext> applicationContexts
= new HashMap<Integer, ApplicationContext>();
  private static int appContextCounter = 0;

  private Integer appContextId;

  OsgiSpringContextLocator(ApplicationContext applicationContext) {
    appContextCounter++;
    appContextId = new Integer(appContextCounter);
    applicationContexts.put(appContextId, applicationContext);
  }

  public ApplicationContext getSpringContext() {
    ApplicationContext result = applicationContexts.get(appContextId);
    return result;
  }

}

So each appCtxt has its own unique index (appContextId) which is
stored in locator, so locator is able to find a proper appCtxt by this
id (even after deserialization)
This is a quick fix that works, maybe in the future I will implement
this in a more elegant way ;).

Daniel

On Nov 26, 2007 3:33 PM, Sebastiaan van Erk <se...@sebster.com> wrote:
> Yep, I've seen though before.
>
> 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).
>
> Regards,
> Sebastiaan
>
>
> Daniel Stoch wrote:
> > Hi,
> >
> > You have written: "This causes problems with session
> > serialization/deserialization in an OSGI environment." I don't know is
> > it a related problem, but I have the following situation (of course
> > app is running in OSGi environment):
> > I have a page with DataView displaying products list with images. Each
> > product has AjaxLink, when I click this link product should be
> > selected (highlighted). But sometimes after click I have an error with
> > serialization:
> >
> > Root cause:
> > java.io.StreamCorruptedException: invalid type code: 01
> >      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
> >      at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1945)
> >      at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1869)

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wicket + OSGI + Session

Posted by Sebastiaan van Erk <se...@sebster.com>.
Yep, I've seen though before.

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).

Regards,
Sebastiaan

Daniel Stoch wrote:
> Hi,
> 
> You have written: "This causes problems with session
> serialization/deserialization in an OSGI environment." I don't know is
> it a related problem, but I have the following situation (of course
> app is running in OSGi environment):
> I have a page with DataView displaying products list with images. Each
> product has AjaxLink, when I click this link product should be
> selected (highlighted). But sometimes after click I have an error with
> serialization:
> 
> Root cause:
> java.io.StreamCorruptedException: invalid type code: 01
>      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
>      at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1945)
>      at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1869)
>      at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
>      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
>      at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
>      at org.apache.wicket.util.lang.Objects.byteArrayToObject(Objects.java:392)
>      at org.apache.wicket.protocol.http.pagestore.AbstractPageStore.deserializePage(AbstractPageStore.java:229)
>      at org.apache.wicket.protocol.http.pagestore.DiskPageStore.getPage(DiskPageStore.java:604)
>      at org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLevelCachePageMap.get(SecondLevelCacheSessionStore.java:318)
>      at org.apache.wicket.Session.getPage(Session.java:741)
>      at org.apache.wicket.request.AbstractRequestCycleProcessor.resolveRenderedPage(AbstractRequestCycleProcessor.java:443)
>      at org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebRequestCycleProcessor.java:139)
>      at org.apache.wicket.RequestCycle.step(RequestCycle.java:1152)
>      at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1248)
>      at org.apache.wicket.RequestCycle.request(RequestCycle.java:489)
>      at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:343)
>      at org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:121)
>      at javax.servlet.http.HttpServlet.service(HttpServlet.java:596)
> 
> Complete stack:
> 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:406)
>      at org.apache.wicket.protocol.http.pagestore.AbstractPageStore.deserializePage(AbstractPageStore.java:229)
>      at org.apache.wicket.protocol.http.pagestore.DiskPageStore.getPage(DiskPageStore.java:604)
>      at org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLevelCachePageMap.get(SecondLevelCacheSessionStore.java:318)
>      at org.apache.wicket.Session.getPage(Session.java:741)
>      at org.apache.wicket.request.AbstractRequestCycleProcessor.resolveRenderedPage(AbstractRequestCycleProcessor.java:443)
>      at org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebRequestCycleProcessor.java:139)
>      at org.apache.wicket.RequestCycle.step(RequestCycle.java:1152)
>      at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1248)
>      at org.apache.wicket.RequestCycle.request(RequestCycle.java:489)
>      at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:343)
> 
> Do you have similar problems with serialization/deserialization?
> 
> PS. The strange thing is that in Firefox this is an undeterministic
> error but in Opera it occurs every time I've clicked the link.
> 
> Best regards,
> Daniel
> 
> On Nov 21, 2007 10:39 AM, Sebastiaan van Erk <se...@sebster.com> wrote:
>> Hi,
>>
>> When Wicket pages are serialized/deserialized to the page store, they
>> are serialized/deserialized using the IObjectStreamFactory set in the
>> Objects class, and (in trunk) the DefaultObjectStreamFactory overrides
>> the resolveClass method of ObjectInputStream to consult the
>> application's IClassResolver. This is all good. :-)
>>
>> But, the problem is the session itself. The ObjectIn/OutputStreams that
>> the session is serialized to and deserialized from are the ones provided
>> by the container, which do not use the IObjectStreamFactory. This causes
>> problems with session serialization/deserialization in an OSGI environment.
>>
>> I'm not really deeply into the Wicket code, but it seems to me the only
>> way to really solve this is to make sure the Wicket session is not
>> directly put in the HTTP session, but instead of it, a SessionHolder
>> object with a reference to the Wicket session. The SessionHolder can
>> have readObject/writeObject methods which just read/write the session as
>> a byte stream using Objects.byteArrayToObject/objectToByteArray.
>>
>> That way, when the Session is deserialized the IClassResolver is
>> consulted (and if the user provides their own IObjectStreamFactory
>> implementation, it too is used).
>>
>> Any comments?
>>
>> Regards,
>> Sebastiaan
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
> 

Re: Wicket + OSGI + Session

Posted by Daniel Stoch <da...@gmail.com>.
Hi,

You have written: "This causes problems with session
serialization/deserialization in an OSGI environment." I don't know is
it a related problem, but I have the following situation (of course
app is running in OSGi environment):
I have a page with DataView displaying products list with images. Each
product has AjaxLink, when I click this link product should be
selected (highlighted). But sometimes after click I have an error with
serialization:

Root cause:
java.io.StreamCorruptedException: invalid type code: 01
     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
     at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1945)
     at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1869)
     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
     at org.apache.wicket.util.lang.Objects.byteArrayToObject(Objects.java:392)
     at org.apache.wicket.protocol.http.pagestore.AbstractPageStore.deserializePage(AbstractPageStore.java:229)
     at org.apache.wicket.protocol.http.pagestore.DiskPageStore.getPage(DiskPageStore.java:604)
     at org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLevelCachePageMap.get(SecondLevelCacheSessionStore.java:318)
     at org.apache.wicket.Session.getPage(Session.java:741)
     at org.apache.wicket.request.AbstractRequestCycleProcessor.resolveRenderedPage(AbstractRequestCycleProcessor.java:443)
     at org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebRequestCycleProcessor.java:139)
     at org.apache.wicket.RequestCycle.step(RequestCycle.java:1152)
     at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1248)
     at org.apache.wicket.RequestCycle.request(RequestCycle.java:489)
     at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:343)
     at org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:121)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:596)

Complete stack:
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:406)
     at org.apache.wicket.protocol.http.pagestore.AbstractPageStore.deserializePage(AbstractPageStore.java:229)
     at org.apache.wicket.protocol.http.pagestore.DiskPageStore.getPage(DiskPageStore.java:604)
     at org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLevelCachePageMap.get(SecondLevelCacheSessionStore.java:318)
     at org.apache.wicket.Session.getPage(Session.java:741)
     at org.apache.wicket.request.AbstractRequestCycleProcessor.resolveRenderedPage(AbstractRequestCycleProcessor.java:443)
     at org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebRequestCycleProcessor.java:139)
     at org.apache.wicket.RequestCycle.step(RequestCycle.java:1152)
     at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1248)
     at org.apache.wicket.RequestCycle.request(RequestCycle.java:489)
     at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:343)

Do you have similar problems with serialization/deserialization?

PS. The strange thing is that in Firefox this is an undeterministic
error but in Opera it occurs every time I've clicked the link.

Best regards,
Daniel

On Nov 21, 2007 10:39 AM, Sebastiaan van Erk <se...@sebster.com> wrote:
> Hi,
>
> When Wicket pages are serialized/deserialized to the page store, they
> are serialized/deserialized using the IObjectStreamFactory set in the
> Objects class, and (in trunk) the DefaultObjectStreamFactory overrides
> the resolveClass method of ObjectInputStream to consult the
> application's IClassResolver. This is all good. :-)
>
> But, the problem is the session itself. The ObjectIn/OutputStreams that
> the session is serialized to and deserialized from are the ones provided
> by the container, which do not use the IObjectStreamFactory. This causes
> problems with session serialization/deserialization in an OSGI environment.
>
> I'm not really deeply into the Wicket code, but it seems to me the only
> way to really solve this is to make sure the Wicket session is not
> directly put in the HTTP session, but instead of it, a SessionHolder
> object with a reference to the Wicket session. The SessionHolder can
> have readObject/writeObject methods which just read/write the session as
> a byte stream using Objects.byteArrayToObject/objectToByteArray.
>
> That way, when the Session is deserialized the IClassResolver is
> consulted (and if the user provides their own IObjectStreamFactory
> implementation, it too is used).
>
> Any comments?
>
> Regards,
> Sebastiaan
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org