NullPointerException in MethodPropertyContext

201 vistas
Ir al primer mensaje no leído

Tiago Rinck Caveden

no leída,
15 sept 2011, 10:51:27 a.m.15/9/2011
para google-we...@googlegroups.com
Hello all,

I'm having a NPE on MethodPropertyContext. The error message doesn't provide any additional information to help me understand what I'm doing wrong. By looking at the source code, it seems that the method traverse is indeed not protecting itself against a null value that may be the return of TypeUtils.parameterization. Take a look:

  private void traverse(ParameterizationVisitor visitor, Type type) {
    Class<?> base = TypeUtils.ensureBaseType(type);
    if (visitor.visitType(base)) {
      Type[] params = TypeUtils.getParameterization(base, type);
      for (Type t : params) {
        if (visitor.visitParameter()) {
          traverse(visitor, t);
        }
        visitor.endVisitParameter();
      }
    }
    visitor.endVisitType(base);
  }

The error is raised when the response of a particular request is treated. The request is particular because it receives a proxy which uses java generics in its declaration. It's the only case so far in my application.

This is the GWT part of the stack trace:

SEVERE: Unexpected error
java.lang.NullPointerException
at com.google.web.bindery.autobean.vm.impl.MethodPropertyContext.traverse(MethodPropertyContext.java:102)
at com.google.web.bindery.autobean.vm.impl.MethodPropertyContext.accept(MethodPropertyContext.java:75)
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl$PropertyCoderCreator.maybeCreateCoder(AutoBeanCodexImpl.java:353)
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl$PropertyCoderCreator.visitReferenceProperty(AutoBeanCodexImpl.java:341)
at com.google.web.bindery.autobean.vm.impl.ProxyAutoBean.traverseProperties(ProxyAutoBean.java:295)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:166)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:101)
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.doCoderFor(AutoBeanCodexImpl.java:521)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.setProperty(AbstractAutoBean.java:276)
at com.google.web.bindery.autobean.vm.impl.ProxyAutoBean.setProperty(ProxyAutoBean.java:224)
at com.google.web.bindery.autobean.vm.impl.BeanPropertyContext.set(BeanPropertyContext.java:44)
at com.google.web.bindery.requestfactory.server.Resolver$1.visitValueProperty(Resolver.java:371)
at com.google.web.bindery.autobean.vm.impl.ProxyAutoBean.traverseProperties(ProxyAutoBean.java:260)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:166)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:101)
at com.google.web.bindery.requestfactory.server.Resolver.resolveClientProxy(Resolver.java:323)
at com.google.web.bindery.requestfactory.server.Resolver.resolveClientValue(Resolver.java:418)
at com.google.web.bindery.requestfactory.server.Resolver.resolveClientValue(Resolver.java:442)
at com.google.web.bindery.requestfactory.server.Resolver.resolveClientValue(Resolver.java:196)
at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.processInvocationMessages(SimpleRequestProcessor.java:451)
at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:217)
at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:125)
at com.google.web.bindery.requestfactory.server.RequestFactoryServlet.doPost(RequestFactoryServlet.java:118)

Is this a GWT bug or am I doing something I shouldn't?

Thank you,
--
Tiago Rinck Caveden

Tiago Rinck Caveden

no leída,
15 sept 2011, 11:42:27 a.m.15/9/2011
para google-we...@googlegroups.com
A little bit more information I've gathered with a debugger:

At a certain moment, TypeUtils.getParametrization is called with a type that is a TypeVariable of value T. That method doesn't deal with such types, and returns null.

The result of the request where this happens is a List<AValueProxy<AnEntityProxy>> where the entities are declared as such:

@ProxyFor(AnAbstractDomainEntity.class)
public interface AGenericEntityProxy extends EntityProxy {...}

@ProxyFor(AConcreteDomainEntity.class)
public interface AnEntityProxy extends AGenericEntityProxy {...}

@ProxyFor(ADomainClass.class)
public interface AValueProxy<T extends AGenericEntityProxy> extends ValueProxy {...}

In the server:

public class AnAbstractDomainEntity {...}

public class AConcreteDomainEntity extends AnAbstractDomainEntity {...}

public class ADomainClass<T extends AnAbstractDomainEntity> {...}


When the TypeVariable T is given as type to TypeUtils.getParametrization, the base parameter is the AGenericEntityProxy.class.

Is this generics construction I'm making illegal? Is there another way I can implement a similar thing?

Thank you, and sorry for the annoyance.
--
Tiago Rinck Caveden

Thomas Broyer

no leída,
15 sept 2011, 11:52:45 a.m.15/9/2011
para google-we...@googlegroups.com
I think it is (illegal).

You should make one sub-interface of AValueProxy per type of AGenericEntityProxy that you'd use for its T type parameter; remove the type parameter (making AValueProxy no longer generic), and using @ExtraTypes (GWT 2.4 onwards) for polymorphism, listing the sub-interfaces you previously created.

It's probably possible to enhance RF to make this work, but for now I don't think RF is designed to handle such things.

Tiago

no leída,
15 sept 2011, 12:05:23 p.m.15/9/2011
para Google Web Toolkit
The issue you point me to is probably related, since I have a
Request<List<AValueProxy<AnEntityProxy>>>...

Thank you for the fast response. I'll look the docs for what you
suggest me and see how it fits. Currently the project I'm working with
is using GWT 2.3, so I don't even know if I'll be able to use it,
let's see.

Thanks again!

Tiago

no leída,
16 sept 2011, 8:14:05 a.m.16/9/2011
para Google Web Toolkit
On Sep 15, 5:52 pm, Thomas Broyer <t.bro...@gmail.com> wrote:
> You should make one sub-interface of AValueProxy per type of
> AGenericEntityProxy that you'd use for its T type parameter; remove the type
> parameter (making AValueProxy no longer generic), and using @ExtraTypes (GWT
> 2.4 onwards) for polymorphism, listing the sub-interfaces you previously
> created.

Hello again Thomas,

I tried to do as you suggest, but I'm having a hard time understanding
how this ExtraTypes is supposed to be used. The RequestFactory doc
page doesn't say much...

What I'm trying to make is a generic widget to deal with Hibernate
Envers audited entities. On my server side, I have a type Revision<T
extends AuditedEntity>, where AuditedEntity is an abstract class
extended by every entity which is supposed to be audited by Envers.

So, as you suggested, I created an interface RevisionProxy which is a
@ProxyFor(Revision.class). I also created an interface
EntityARevisionProxy which is supposed to be a proxy for
Revision<EntityA>, so I added @ProxyFor(Revision.class) as well. This
interface extends RevisionProxy.

Now, you say that I should add
@ExtraTypes({EntityARevisionProxy.class}) to RevisionProxy, is that
it? That didn't work, I got a stack overflow during compilation time.
The stack overflow goes away if I remove the @ProxyFor from
EntityARevisionProxy, but then the compiler complains about this
@ProxyFor absence.

As you can see, I'm lost here... can you say what I'm doing wrong, or
point me to an example I could follow?

Thank you in advance
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos