5 Replies Latest reply on Aug 23, 2012 4:30 PM by csa

    java.util.Map in Errai using Jackson

    froed

      Hi, I'am using in my EJB model a java.util.Map which is transfered to the client. Using Errai 2.1.0.Beta1 I get a NullPointerException in MapMarshaller.doDemarshall().

       

      INFO [RpcProxyLoaderGenerator] generating rpc proxy loader class.
      java.lang.NullPointerException
          at org.jboss.errai.marshalling.client.api.json.impl.gwt.GWTJSONValue.isObject(GWTJSONValue.java:60)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.doDemarshall(MapMarshaller.java:67)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.demarshall(MapMarshaller.java:63)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.demarshall(MapMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.QualifyingMarshallerWrapper.doNotNullDemarshall(QualifyingMarshallerWrapper.java:61)
          at org.jboss.errai.marshalling.client.marshallers.AbstractNullableMarshaller.demarshall(AbstractNullableMarshaller.java:19)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$9.demarshall(MarshallerFactoryImpl.java:648)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$9.demarshall(MarshallerFactoryImpl.java:1)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$24.demarshall(MarshallerFactoryImpl.java:1341)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$24.demarshall(MarshallerFactoryImpl.java:1)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.marshallToCollection(AbstractCollectionMarshaller.java:79)
          at org.jboss.errai.marshalling.client.marshallers.ListMarshaller.doDemarshall(ListMarshaller.java:55)
          at org.jboss.errai.marshalling.client.marshallers.ListMarshaller.doDemarshall(ListMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.doDemarshall(AbstractCollectionMarshaller.java:47)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.doDemarshall(AbstractCollectionMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.AbstractBackReferencingMarshaller.demarshall(AbstractBackReferencingMarshaller.java:76)
          at org.jboss.errai.marshalling.client.Marshalling.fromJSON(Marshalling.java:158)
          at org.jboss.errai.enterprise.client.jaxrs.MarshallingWrapper.fromJSON(MarshallingWrapper.java:56)
          at org.jboss.errai.enterprise.client.jaxrs.JaxrsProxyLoaderImpl$1MemberServiceImpl$1.onResponseReceived(JaxrsProxyLoaderImpl.java:87)
          at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
          at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
          at sun.reflect.GeneratedMethodAccessor47.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:601)
          at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
          at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
          at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
          at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)
          at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)
          at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
          at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
          at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
          at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
          at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
          at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)
          at sun.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:601)
          at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
          at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
          at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
          at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
          at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
          at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
          at java.lang.Thread.run(Thread.java:722)
      java.lang.RuntimeException: error demarshalling entity: org.jboss.testsample.model.CustomFieldData
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$9.demarshall(MarshallerFactoryImpl.java:653)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$9.demarshall(MarshallerFactoryImpl.java:1)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$24.demarshall(MarshallerFactoryImpl.java:1341)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$24.demarshall(MarshallerFactoryImpl.java:1)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.marshallToCollection(AbstractCollectionMarshaller.java:79)
          at org.jboss.errai.marshalling.client.marshallers.ListMarshaller.doDemarshall(ListMarshaller.java:55)
          at org.jboss.errai.marshalling.client.marshallers.ListMarshaller.doDemarshall(ListMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.doDemarshall(AbstractCollectionMarshaller.java:47)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.doDemarshall(AbstractCollectionMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.AbstractBackReferencingMarshaller.demarshall(AbstractBackReferencingMarshaller.java:76)
          at org.jboss.errai.marshalling.client.Marshalling.fromJSON(Marshalling.java:158)
          at org.jboss.errai.enterprise.client.jaxrs.MarshallingWrapper.fromJSON(MarshallingWrapper.java:56)
          at org.jboss.errai.enterprise.client.jaxrs.JaxrsProxyLoaderImpl$1MemberServiceImpl$1.onResponseReceived(JaxrsProxyLoaderImpl.java:87)
          at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
          at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
          at sun.reflect.GeneratedMethodAccessor47.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:601)
          at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
          at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
          at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
          at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)
          at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)
          at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
          at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
          at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
          at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
          at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
          at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)
          at sun.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:601)
          at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
          at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
          at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
          at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
          at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
          at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
          at java.lang.Thread.run(Thread.java:722)
      Caused by: java.lang.NullPointerException
          at org.jboss.errai.marshalling.client.api.json.impl.gwt.GWTJSONValue.isObject(GWTJSONValue.java:60)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.doDemarshall(MapMarshaller.java:67)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.demarshall(MapMarshaller.java:63)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.demarshall(MapMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.QualifyingMarshallerWrapper.doNotNullDemarshall(QualifyingMarshallerWrapper.java:61)
          at org.jboss.errai.marshalling.client.marshallers.AbstractNullableMarshaller.demarshall(AbstractNullableMarshaller.java:19)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$9.demarshall(MarshallerFactoryImpl.java:648)
          ... 38 more
      

       

       

      I attached the sample, which demostrates this problem. Is there a workaround for this issue?

        • 1. Re: java.util.Map in Errai using Jackson
          csa

          Hi Dave,

           

          Unfortunately, this is a known limitation with Errai's Jackson support. I have created a JIRA for it: https://issues.jboss.org/browse/ERRAI-374

           

          As a workaround, you can create your own portable object that serves as a replacement data structure for the map type. Errai's built-in JSON marshalling will support Maps just fine of course. It's only a problem when transforming to/from Jackson.

           

          Christian

          • 2. Re: java.util.Map in Errai using Jackson
            froed

            Hi Christian,

             

            thanks for your response.

            Using the Errai's JSON marshalling is not possible by my knowledge, since I have an existing server which is only able to deliver Jackson JSON and other clients depend on this format.

             

            I've tried using Custom Marshaller from https://docs.jboss.org/author/display/ERRAI/Marshalling, but I get other errors like

             

            Failed to bootstrap errai marshalling system!

            java.lang.RuntimeException: could not instantiate marshaller class: org.jboss.errai.marshalling.client.marshallers.DateMarshaller

            ...

             

            Do you have an example how to "create your own portable object that serves as a replacement"?

            • 3. Re: java.util.Map in Errai using Jackson
              csa

              The CustomFieldData class from your example could use a List<CustomField> instead of a Map and provide the methods to lookup fields by ID. I don't know if that will effect the performance of your app. Alternatively, you can create a transfer object for it. Then your JPA/Hibernate mappings can stay as they are.

              • 4. Re: java.util.Map in Errai using Jackson
                froed

                Ok, I changed the structure of my model to use List instead of Map.

                • 5. Re: java.util.Map in Errai using Jackson
                  csa

                  Hi Dave,

                   

                  I have found a way to implement this now. If you upgrade to the latest 2.1.0-SNAPSHOTs, you can now use maps in your @Portable types, as long as the map's key type does not require a custom Jackson KeySerializer.

                   

                  So, your CustomFieldData class should work fine now.

                   

                  Cheers,

                  Christian