0

When I send an object of class which doesn't implement Serializable to remote EJB it handles it, but things change when one field of this class is a programmatic UIComponent used in binding attribute from a @ViewScoped backing bean. In second case java.io.NotSerializableException is thrown.

Form

<h:form>
    <p:panel binding="#{bean.notSerializableObj.pfPanel}"/>
    <h:inputText value="#{bean.notSerializableObj.someString}" />
    <p:commandButton value="GO" action="#{bean.sendToEjb}"/>
</h:form>

Backing bean

@Named(value = "bean")
@ViewScoped
public class Bean implements Serializable {

    @EJB
    private RemoteEjbService service;

    private NotSerializableClass notSerializableObj;

    public NotSerializableClass getNotSerializableObj() {
        return notSerializableObj;
    }

    public void setNotSerializableObj(NotSerializableClass notSerializableObj) {
        this.notSerializableObj = notSerializableObj;
    }

    @PostConstruct
    private void init() {
        Panel p = new Panel();
        System.out.println("INIT Panel: " + p);
        notSerializableObj = new NotSerializableClass("myObject", p);
    }

    public void sendToEjb() {
        System.out.println("Sending to EJB");
        trySending();
        System.out.println("Second try with new object");
        Panel p = new Panel();
        notSerializableObj.setPfPanel(p);
        trySending();
    }

    private void trySending() {
        try {
            System.out.println("Panel: " + notSerializableObj.getPfPanel());
            service.notSerializableTest(notSerializableObj);
            System.out.println("Sent correctly");
        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }
    }
}

NotSerializableClass

public class NotSerializableClass {

    private String someString;

    private Panel pfPanel; // PrimeFaces panel not implementing Serializable

    public NotSerializableClass(String someString, Panel pfPanel) {
        this.someString = someString;
        this.pfPanel = pfPanel;
    }

    //getters setters
}

Results

Info:   INIT Panel: org.primefaces.component.panel.Panel@9f68a9
Info:   Sending to EJB
Info:   Panel: org.primefaces.component.panel.Panel@9f68a9
Info:   Exception: javax.ejb.EJBException: java.rmi.MarshalException: CORBA BAD_PARAM 1398079494 Maybe; nested exception is: 
    java.io.NotSerializableException: WARNING: 00100006: Class test.NotSerializableClass is not Serializable
Info:   Second try with new object
Info:   Panel: org.primefaces.component.panel.Panel@e59fd7
Info:   Sent correctly

On the first try exception is thrown, on the second try object was successfully send despite not implementing Serializable. When I removed binding attribute there wasn't any exception thrown in the first trySending().

There is no difference if I set javax.faces.STATE_SAVING_METHOD to server or client. But it works if bean is @RequestScoped or @SessionScoped or remote interface is replaced with local one.

The question is: What changes in object when it is connected to binding attribute because somehow EJB can't handle it afterwards?

Panel wasn't serialized after creation because hashcode in @PostConstruct and submitting method is the same.

Full stack trace

Severe:   javax.ejb.EJBException: java.rmi.MarshalException: CORBA BAD_PARAM 1398079494 Maybe; nested exception is: 
    java.io.NotSerializableException: WARNING: 00100006: Class test.NotSerializableClass is not Serializable
    at mot.services._RemoteEjbService_Wrapper.notSerializableTest(mot/services/_RemoteEjbService_Wrapper.java)
    at test.MyBean.trySending(MyBean.java:104)
    at test.MyBean.sendToEjb(MyBean.java:92)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at test.CountingFilter.doFilter(CountingFilter.java:35)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.rmi.MarshalException: CORBA BAD_PARAM 1398079494 Maybe; nested exception is: 
    java.io.NotSerializableException: WARNING: 00100006: Class test.NotSerializableClass is not Serializable
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:300)
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.wrapException(Util.java:695)
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:257)
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:150)
    at com.sun.corba.ee.impl.presentation.rmi.codegen.CodegenStubBase.invoke(CodegenStubBase.java:226)
    at mot.services.__RemoteEjbService_Remote_DynamicStub.notSerializableTest(mot/services/__RemoteEjbService_Remote_DynamicStub.java)
    ... 54 more
Caused by: java.io.NotSerializableException: WARNING: 00100006: Class test.NotSerializableClass is not Serializable
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:292)
    ... 59 more
Caused by: org.omg.CORBA.BAD_PARAM: WARNING: 00100006: Class test.NotSerializableClass is not Serializable  vmcid: SUN  minor code: 6 completed: Maybe
    at com.sun.proxy.$Proxy209.notSerializable(Unknown Source)
    at com.sun.corba.ee.impl.misc.ORBUtility.throwNotSerializableForCorba(ORBUtility.java:783)
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.writeAny(Util.java:360)
    at com.sun.corba.ee.impl.io.ValueHandlerImpl.write_Array(ValueHandlerImpl.java:498)
    at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValueInternal(ValueHandlerImpl.java:232)
    at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValueWithVersion(ValueHandlerImpl.java:215)
    at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValue(ValueHandlerImpl.java:179)
    at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.callWriteValue(CDROutputStream_1_0.java:711)
    at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.writeArray(CDROutputStream_1_0.java:627)
    at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:808)
    at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:834)
    at com.sun.corba.ee.impl.encoding.CDROutputObject.write_value(CDROutputObject.java:500)
    at com.sun.corba.ee.impl.copyobject.ORBStreamObjectCopierImpl.copy(ORBStreamObjectCopierImpl.java:73)
    at org.glassfish.pfl.dynamic.copyobject.impl.FallbackObjectCopierImpl.copy(FallbackObjectCopierImpl.java:64)
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.copyObject(Util.java:770)
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.copyObjects(Util.java:741)
    at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl.copyArguments(DynamicMethodMarshallerImpl.java:438)
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:225)
    ... 57 more
Geinmachi
  • 1,251
  • 1
  • 8
  • 20
  • 1
    Use of `binding` bound to a bean property is fishy. ["*Using binding on a bean property is a bad practice. It indicates a design smell.*"](http://stackoverflow.com/a/14917453/1391249). (That exception is not caused by the remote EJB, by the way. `NotSerializableClass` needs to be `transient`). – Tiny Dec 27 '15 at 18:41
  • I know how to play around it but I want to know why this exception is thrown in case of `binding` usage. – Geinmachi Dec 27 '15 at 18:43
  • The exception will be thrown at a certain time (when the application is redeployed, for example) even though `binding` is not used, since `NotSerializableClass` does not implement the `java.io.Serializable` interface and is declared inside a passivation capable bean. – Tiny Dec 27 '15 at 18:47
  • Another design problem is that the service layer has apparently front-end specific dependencies. [This is wrong](http://stackoverflow.com/q/13011392). As to the technical problem, you're in the first try basically sending the **entire** JSF component tree including all attached converters/validators/behaviors/listeners to the service layer and in the second try a detached component instance. I'm not sure why the second try works fine as to serialization, seeing the full stack trace would be helpful to track and explain the process. – BalusC Dec 28 '15 at 12:43
  • @BalusC I provided full stack trace. In real case my `NotSerializableClass` implemented some interface and EJB took that interface as a parameter but still, object have to serialized and even though it didn't have access to `Panel` object exception was thrown. Additionally serialization process has impact on performance so now there is just a DTO. I'm not sure why EJB can't serialize `Panel` object after binding it to xhtml, maybe something changes inside and it can't be serialized then, like listeners etc. as you said. – Geinmachi Dec 28 '15 at 14:11

0 Answers0