I have further investigated this issue. I now know where the NotSerializableException comes from, but I can't explain why this occurs nor how to solve it.
Let me try to explain what happens:
On Websphere 8.0.0.3, I have a filterable overview screen (JSF/MyFaces) supported by a SearchController in ViewScope (Seam Faces). This SearchController maintains state throughout the view and is Serializable. In order to query and filter the database, the controller uses a stateless EJB PersonRepository. This PersonRepository is injected in the controller (CDI/OpenWebbeans). The repository is not serializable, since it doesn't make sense because it is stateless and because it contains a reference to JPA (entitymanager, datasource, ...). Since PersonRepository is not serializable, the field is marked transient. The code:
@Named
@ViewScoped
public class SearchController implements Serializable {
@Inject private transient PersonRepository personRepository;
}
@Stateless
public class PersonRepository {
}
When I try to access my search page, I get the following stacktrace:
[28/06/12 13:34:16:852 CEST] 00000067 JspStateManag E Exiting serializeView - Could not serialize state: domain.EJSLocalNSLPersonRepository_ad8f34be
java.io.NotSerializableException: domain.EJSLocalNSLPersonRepository_ad8f34be
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at org.apache.webbeans.ejb.common.proxy.EjbBeanProxyHandler.writeExternal(EjbBeanProxyHandler.java:422)
at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1449)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1418)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1537)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1502)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
(4) at org.apache.webbeans.context.creational.DependentCreationalContext.writeObject(DependentCreationalContext.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1012)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.ArrayList.writeObject(ArrayList.java:720)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1012)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.HashMap.writeObject(HashMap.java:861)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1012)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
(3) at org.apache.webbeans.context.creational.CreationalContextImpl.writeObject(CreationalContextImpl.java:396)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1012)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.concurrent.ConcurrentHashMap.writeObject(ConcurrentHashMap.java:1258)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1012)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
(2) at java.util.HashMap.writeObject(HashMap.java:861)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1012)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1420)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1366)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1366)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at org.apache.myfaces.application.jsp.JspStateManagerImpl.serializeView(JspStateManagerImpl.java:814)
at org.apache.myfaces.application.jsp.JspStateManagerImpl.saveSerializedViewInServletSession(JspStateManagerImpl.java:699)
(1) at org.apache.myfaces.application.jsp.JspStateManagerImpl.saveSerializedView(JspStateManagerImpl.java:497)
at javax.faces.application.StateManager.saveView(StateManager.java:114)
at org.apache.myfaces.application.jsp.JspStateManagerImpl.saveView(JspStateManagerImpl.java:460)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1335)
at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:263)
at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:163)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:59)
at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:85)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1214)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:774)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:456)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:125)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:92)
at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:145)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:62)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
at org.jboss.solder.servlet.event.ServletEventBridgeFilter.doFilter(ServletEventBridgeFilter.java:74)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:192)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:89)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:926)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1023)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:87)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:895)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:195)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305)
at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1659)
(1) org.apache.myfaces.application.jsp.JspStateManagerImpl wants to serialize the viewRoot.
This viewRoot contains two maps, put there by org.jboss.seam.faces.context.ViewScopedContext:
org.jboss.seam.faces.viewscope.componentInstanceMap={org.apache.webbeans.container.SerializableBean@41776b62=web.controller.SearchController@1e0f7bbc}
=> This map contains the actual component for every CDI bean in view scope.
org.jboss.seam.faces.viewscope.creationalInstanceMap={org.apache.webbeans.container.SerializableBean@41776b62=org.apache.webbeans.context.creational.CreationalContextImpl@1e099b4a}
=> This map contains the creational context for every CDI bean in view scope.
(2) In order to serialize the ViewRoot, the two hashMaps are serialized
(3) Here he starts to serialize the creational context of my SearchController. This org.apache.webbeans.context.creational.CreationalContextImpl has the following fields:
contextual: [1098345314,Name:searchController,WebBeans Type:MANAGED,API Types:[java.lang.Object,java.io.Serializable,web.controller.SearchController],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default,javax.inject.Named]]
=> This is information on my CDI bean searchController
dependentObjects: web.controller.SearchController@1e0f7bbc=[org.apache.webbeans.context.creational.DependentCreationalContext@1e10b3b0]
(4) Here he wants to serialize this DependentCreationalContext: org.apache.webbeans.context.creational.DependentCreationalContext with fields:
contextual: WSEjbBean [businessLocals=[class domain.PersonRepository], ejbName=PersonRepository-784528839,Name:null,WebBeans Type:ENTERPRISE,API Types:[java.lang.Object,domain.PersonRepository],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]
depedentType: DependentCreationalContext$DependentType.BEAN
instance: PersonRepository_$$_javassist_29 - domain.EJSLocalNSLPersonRepository_ad8f34be@dae4cfc6
Finally he tries to serialize the instance field which refers to a dynamic EJB/CDI proxy which is not serializable, resulting in the NotSerializableException.
This explains the where the exception comes from.
Now the question is: why and how to prevent/solve this?
Kind regards and thanks in advance for all help!
Kris