gwtrequestfactory

GWT RequestFactory throws java.lang.UnsupportedOperationException: <Proxy interface class> from ValueCodex.getTypeOrDie


In our application we need to share domain code between GWT client and server. Because of that we are using common interfaces for GWT proxies and server-side entities. This approach was once described by @thomas-broyer here: https://stackoverflow.com/a/15852887/187241

Exception stacktrace:

    ERROR com.google.web.bindery.requestfactory.server.SimpleRequestProcessor - Error while processing request 
    java.lang.UnsupportedOperationException: se.homework.hwbs.domain.shared.model.IAppointment
        at com.google.web.bindery.autobean.shared.ValueCodex.getTypeOrDie(ValueCodex.java:388)
        at com.google.web.bindery.autobean.shared.ValueCodex.decode(ValueCodex.java:312)
        at com.google.web.bindery.requestfactory.shared.impl.EntityCodex.decode(EntityCodex.java:107)
        at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor$3.visitReferenceProperty(SimpleRequestProcessor.java:633)
        at com.google.web.bindery.autobean.vm.impl.ProxyAutoBean.traverseProperties(ProxyAutoBean.java:370)
        at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:162)
        at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:97)
        at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.processOperationMessages(SimpleRequestProcessor.java:623)

Shared code:

    public interface IAppointment {
        IPlace getPlace();
    }

    public interface AppointmentProxy extends EntityProxy, IAppointment {
        @Override
        PlaceProxy getPlace();
    }

    public interface PlaceProxy extends EntityProxy, IPlace {
        @Override
        Long getId();
    }

    public interface IPlace extends IDatabaseEntity {
        @Override
        Long getId();
    }

    public interface IDatabaseEntity {
        public Long getId();
    }

If we understtod GWT code correctly, the reason of the problem comes from ProxyAutoBean:

    for (Method method : beanType.getMethods()) {
        if (BeanMethod.GET.matches(method)) {
            toReturn.getters.add(method);

where beanType is AppointmentProxy.class. Java reflection returns two methods for such interface (happens only in Super Dev Mode...):

    public **abstract** PlaceProxy AppointmentProxy.getPlace()
    public **default** IPlace AppointmentProxy.getPlace()

The first one is expected and accepted by GWT RequestFactory code, the second one is not... And it causes java.lang.UnsupportedOperationException: IAppointment exception. The very weird fact is that we have this issue only in compiled GWT application. When we launch an application from IDE using Super Dev Mode, the second default ... method is not listed and application is working without errors.

Environment:

Do you have any ideas about how to fix or workaround the issue?


Solution

  • This could be https://github.com/gwtproject/gwt/issues/5925 which has been fixed in 2.7.