1 2 Previous Next 15 Replies Latest reply: Jun 17, 2012 5:26 PM by Matthew Casperson RSS

NullPointerException when decoding generic list from JSON

Matthew Casperson Newbie

When decoding a generic list, I get the following exception.

 

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.doDermashall(MapMarshaller.java:59)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.demarshall(MapMarshaller.java:55)
          at org.jboss.errai.marshalling.client.marshallers.MapMarshaller.demarshall(MapMarshaller.java:1)
          at org.jboss.errai.marshalling.client.marshallers.QualifyingMarshallerWrapper.doNotNullDemarshall(QualifyingMarshallerWrapper.java:51)
          at org.jboss.errai.marshalling.client.marshallers.AbstractNullableMarshaller.demarshall(AbstractNullableMarshaller.java:19)
          at org.jboss.errai.marshalling.client.marshallers.AbstractCollectionMarshaller.marshallToCollection(AbstractCollectionMarshaller.java:77)
          at org.jboss.errai.marshalling.client.marshallers.ListMarshaller.doDemarshall(ListMarshaller.java:43)
          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:67)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$3.demarshall(MarshallerFactoryImpl.java:333)
          at org.jboss.errai.marshalling.client.api.MarshallerFactoryImpl$3.demarshall(MarshallerFactoryImpl.java:1)
          at org.jboss.errai.marshalling.client.Marshalling.fromJSON(Marshalling.java:157)
          at org.jboss.errai.enterprise.client.jaxrs.MarshallingWrapper.fromJSON(MarshallingWrapper.java:56)
          at org.jboss.errai.enterprise.client.jaxrs.JaxrsProxyLoaderImpl$1RESTImpl$1.onResponseReceived(JaxrsProxyLoaderImpl.java:85)
          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.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:616)
          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.GeneratedMethodAccessor33.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:616)
          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:679)

 

The List is held by a generic class.

 

package com.test.restserver;

import java.util.List;

public class RESTObject<T>
{
          private List<T> objects;

          public List<T> getObjects()
          {
                    return objects;
          }

          public void setObjects(List<T> objects)
          {
                    this.objects = objects;
          }
}

 

The objects being saved in the list are simple classes:

 

package com.test.restserver;


public class RESTChildObject
{
          private Integer id;

          public Integer getId()
          {
                    return id;
          }

          public void setId(Integer id)
          {
                    this.id = id;
          }
}

 

Converting a RESTObject<RESTChildObject> returned from a REST service where there is at least 1 item in the generic list "objects" held by the RESTObject class results in the error above.

 

A test case server that demonstrates the problem above can be found at https://github.com/mcasperson/TestCase-RESTServer, and a test case client can be found at https://github.com/mcasperson/TestCase-ErraiRESTClient.

  • 1. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    This will work now using the latest 2.1 snaphots. You have to mark your RESTObject and RESTChildObject as @Portable though to make them visible to Errai's marshaller.

  • 2. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    That has fixed the issue. Thanks Christian.

  • 3. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    A different issue has come up. When you have a generic list (lets call this "generic list 1") that holds objects that in turn hold another generic list (lets call this "generic list 2"), generic list 2 is populated with the object type held by generiic list 1 (even though the two lists are clearly constructed with different types).

  • 4. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    I updated to the latest 2.1 snapshot, and also saw this error on startup. No code was changed, so do I have to import a new GWT module or something?

     

    java.lang.NoSuchMethodError: org.jboss.errai.codegen.util.GenUtil.setPermissiveMode(Z)V
        at org.jboss.errai.ioc.rebind.ioc.bootstrapper.QualiferEqualityFactoryGenerator.generate(QualiferEqualityFactoryGenerator.java:58)
        at com.google.gwt.core.ext.GeneratorExtWrapper.generate(GeneratorExtWrapper.java:48)
        at com.google.gwt.core.ext.GeneratorExtWrapper.generateIncrementally(GeneratorExtWrapper.java:60)
        at com.google.gwt.dev.javac.StandardGeneratorContext.runGeneratorIncrementally(StandardGeneratorContext.java:647)
        at com.google.gwt.dev.cfg.RuleGenerateWith.realize(RuleGenerateWith.java:41)
        at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.rebind(StandardRebindOracle.java:78)
        at com.google.gwt.dev.shell.StandardRebindOracle.rebind(StandardRebindOracle.java:268)
        at com.google.gwt.dev.shell.ShellModuleSpaceHost.rebind(ShellModuleSpaceHost.java:141)
        at com.google.gwt.dev.shell.ModuleSpace.rebind(ModuleSpace.java:585)
        at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:455)
        at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:49)
        at com.google.gwt.core.client.GWT.create(GWT.java:97)
        at org.jboss.errai.ioc.client.QualifierUtil.<clinit>(QualifierUtil.java:16)
        at org.jboss.errai.ioc.client.container.BeanRef$AnnotationHashWapper.<init>(BeanRef.java:101)
        at org.jboss.errai.ioc.client.container.BeanRef$AnnotationHashWapper.<init>(BeanRef.java:96)
        at org.jboss.errai.ioc.client.container.BeanRef.wrapAnnotations(BeanRef.java:68)
        at org.jboss.errai.ioc.client.container.BeanRef.<init>(BeanRef.java:62)
        at org.jboss.errai.ioc.client.container.CreationalContext.getBeanReference(CreationalContext.java:103)
        at org.jboss.errai.ioc.client.BootstrapperImpl$1.getInstance(BootstrapperImpl.java:43)
        at org.jboss.errai.ioc.client.BootstrapperImpl$1.getInstance(BootstrapperImpl.java:1)
        at org.jboss.errai.ioc.client.BootstrapperImpl.bootstrapContainer(BootstrapperImpl.java:48)
        at org.jboss.errai.ioc.client.Container.boostrapContainer(Container.java:49)
        at org.jboss.errai.ioc.client.Container.onModuleLoad(Container.java:34)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:396)
        at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
        at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525)
        at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
        at java.lang.Thread.run(Thread.java:722)
    java.lang.ExceptionInInitializerError
        at org.jboss.errai.ioc.client.container.BeanRef$AnnotationHashWapper.<init>(BeanRef.java:101)
        at org.jboss.errai.ioc.client.container.BeanRef$AnnotationHashWapper.<init>(BeanRef.java:96)
        at org.jboss.errai.ioc.client.container.BeanRef.wrapAnnotations(BeanRef.java:68)
        at org.jboss.errai.ioc.client.container.BeanRef.<init>(BeanRef.java:62)
        at org.jboss.errai.ioc.client.container.CreationalContext.getBeanReference(CreationalContext.java:103)
        at org.jboss.errai.ioc.client.BootstrapperImpl$1.getInstance(BootstrapperImpl.java:43)
        at org.jboss.errai.ioc.client.BootstrapperImpl$1.getInstance(BootstrapperImpl.java:1)
        at org.jboss.errai.ioc.client.BootstrapperImpl.bootstrapContainer(BootstrapperImpl.java:48)
        at org.jboss.errai.ioc.client.Container.boostrapContainer(Container.java:49)
        at org.jboss.errai.ioc.client.Container.onModuleLoad(Container.java:34)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:396)
        at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
        at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525)
        at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
        at java.lang.Thread.run(Thread.java:722)
    Caused by: java.lang.RuntimeException: Deferred binding failed for 'org.jboss.errai.ioc.client.QualifierEqualityFactory' (did you forget to inherit a required module?)
        at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:53)
        at com.google.gwt.core.client.GWT.create(GWT.java:97)
        at org.jboss.errai.ioc.client.QualifierUtil.<clinit>(QualifierUtil.java:16)
        ... 19 more
    Caused by: com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
        at com.google.gwt.dev.shell.ModuleSpace.rebind(ModuleSpace.java:595)
        at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:455)
        at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:49)
        ... 21 more
    
  • 5. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    I just re-published all 2.1 snapshots. So, this error should be gone now.

  • 6. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    Thanks for the quick response Christian. The module bug has gone, and I have updated the test case at https://github.com/mcasperson/TestCase-RESTServer and https://github.com/mcasperson/TestCase-ErraiRESTClient to demonstrate the issue with the generic marshalling.

     

    As you will see, the server returns an object of type RESTObject<RESTChildObject<RESTGrandchildObject>>, but the marshalled response is of the type RESTObject<RESTChildObject<RESTChildObject>>.

     

    erraibug.png

  • 7. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    Yes, you're hitting an edge case with our new JacksonTransformer (transforms between Errai's JSON and Jackson). This will not be a problem using Errai's native JSON format. In any case, I would not recommend nesting parameterized types like this.

     

    So, rather than having a List<List<T>>, I'd use a List<MyType> where MyType has a List<T>. This will also work using our JacksonTransfomer.

  • 8. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    So I can use List<MyType<T>> over List<T>, where MyType is something like

     

    public class MyType<T>
    {
         public List<T> list;
    }
    

     

    Is this correct?

  • 9. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    Yes, the Jackson transformation should work in this case.

  • 10. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    I tried modifing the test case above with a wrapper class around the list, but the same problem appears to remain.

     

    You can see in the screenshot below the ListWrapper class is used instead of a standard List.

     

    erraibug2.png

  • 11. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    Well, it seems you still have nested parameterized types here, or am I missing something? ListWrapper<T> defines a List<T> where T is RestChildObject<T> which results in a List<RestChildObject<T>>. So, that's basically the same problem as before.

     

    I can create a JIRA to investigate that for Jackson transformation (like I said in Errai JSON this will work). The workaround I am suggesting is to not nest parameterized types.

  • 12. Re: NullPointerException when decoding generic list from JSON
    Matthew Casperson Newbie

    So as it currently stands, in order to interoperate with a Jackson based REST server, you can have no more that one level of parameterized objects (i.e. no nesting) in the returned object?

  • 13. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    Yes, here's the JIRA: https://issues.jboss.org/browse/ERRAI-319

     

    Errai's JSON marshaller is more powerful than Jackson. It adds type information to the payload which we don't get when consuming Jackson generated JSON. To use the same marshaller for both types of payload is not a straightforward process. This is one of the edge cases, another one are maps. Jackson support is a new feature which covers basic cases but isn't on par with Errai's default JSON marshalling.

  • 14. Re: NullPointerException when decoding generic list from JSON
    Christian Sadilek Master

    Hi Matthew,

     

    This issue has a low priority for us as a workaround exists that actually makes the code more readable (introducing a new type): So let's say you have List<List<User>>, depending on your use case, you could use a List<Group> (where Group has a List<User> field) or Table<User> instead.

     

    If you need the feature/fix right away we will happily accept a pull request ! In any case, we know how to implement it, it is just a matter of time....

     

    Cheers,

    Christian

1 2 Previous Next