Search code examples
gwterraierrai-4

ClassCastException When Trying to Make JAXRS Call in Errai 4


I am using Errai 4.0.0.Beta1, and I am trying to make a simple JAX RS call.

Here is the code I am using:

final RemoteCallback<List<Company>> remoteCallback = new RemoteCallback<List<Company>>() {
   @Override
   public void callback(List<Company> companies) {
  Window.alert("rpcServiceCaller - Callback");
  Window.alert("Number of companies returned: " + companies.size());
  }
};
final RestErrorCallback errorCallback = new RestErrorCallback() {
   @Override
   public boolean error(Request message, Throwable throwable) {
  Window.alert(throwable.getMessage());
   logger.error(throwable.getMessage(), throwable);
   return false;
  }
};
RestClient.create(ErraiJAXRSService.class,
  remoteCallback,
  errorCallback,
   200).getCompaniesJSON();

I am seeing the following exception in Super Dev Mode:

Error caused by: ClassCastException: undefined
    at f9b_g$ [as collect_0_g$] (StackTraceCreator.java:198)
    at H8b_g$ (StackTraceCreator.java:343)
    at Iz_g$ [as fillInStackTrace_0_g$] (Throwable.java:114)
    at Bz_g$ (Throwable.java:53)
    at Xz_g$ (Exception.java:25)
    at cA_g$ (RuntimeException.java:25)
    at Ymb_g$ (ClassCastException.java:23)
    at Mzg_g$ (InternalPreconditions.java:45)
    at Xzg_g$ (InternalPreconditions.java:33)
    at n1d_g$ (Cast.java:75)
    at rrh_g$ (RestClient.java:192)
    at srh_g$ (RestClient.java:158)
    at wrh_g$ (RestClient.java:113)
    at ynf_g$ [as erraiJSON_0_g$] (JAXRSPage.java:94)
    at gKh_g$ [as onClick_0_g$] (Type_factory__c_i_e_c_j_JAXRSPage__quals__j_e_i_Any_j_e_i_Default.java:76)
    at Exd_g$ [as dispatch_4_g$] (ClickEvent.java:56)
    at Fxd_g$ [as dispatch_1_g$] (ClickEvent.java:55)
    at Awd_g$ [as dispatch_0_g$] (GwtEvent.java:76)
    at ZGd_g$ (EventBus.java:40)
    at iHd_g$ [as doFire_0_g$] (SimpleEventBus.java:193)
    at oHd_g$ [as fireEvent_2_g$] (SimpleEventBus.java:88)
    at RGd_g$ [as fireEvent_1_g$] (HandlerManager.java:127)
    at Lve_g$ [as fireEvent_1_g$] (Widget.java:129)
    at Lwd_g$ (DomEvent.java:125)
    at Tve_g$ [as onBrowserEvent_0_g$] (Widget.java:177)
    at gne_g$ (DOM.java:1480)
    at fne_g$ (DOM.java:1419)
    at HTMLButtonElement.xte_g$ (DOMImplStandard.java:317)
    at k6b_g$ (Impl.java:233)
    at n6b_g$ (Impl.java:285)
    at HTMLButtonElement.<anonymous> (Impl.java:71)

The proxy is returned, but any line that attempts to cast it to an AbstractJaxrsProxy fails with the above exception.

The JaxrsProxyLoaderImpl.java has been created, and my JAX RS Service is there:

package org.jboss.errai.enterprise.client.jaxrs;

import com.google.gwt.http.client.RequestBuilder;
import com.insclix.erraiPOC.shared.domain.Company;
import com.insclix.erraiPOC.shared.service.jaxrs.ErraiJAXRSService;
import java.util.List;
import org.jboss.errai.common.client.api.ErrorCallback;
import org.jboss.errai.common.client.api.RemoteCallback;
import org.jboss.errai.common.client.framework.ProxyProvider;
import org.jboss.errai.common.client.framework.RemoteServiceProxyFactory;
import org.jboss.errai.security.client.local.interceptors.SecurityExceptionMapper;

public class JaxrsProxyLoaderImpl implements JaxrsProxyLoader { public void loadProxies() {
   class com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl extends AbstractJaxrsProxy implements ErraiJAXRSService {
   private RemoteCallback remoteCallback;
   private ErrorCallback errorCallback;
   public com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl() {
  setExceptionMapper(new SecurityExceptionMapper());
  }

   public RemoteCallback getRemoteCallback() {
   return remoteCallback;
  }

   public void setRemoteCallback(RemoteCallback callback) {
  remoteCallback = callback;
  }

   public ErrorCallback getErrorCallback() {
   return errorCallback;
  }

   public void setErrorCallback(ErrorCallback callback) {
  errorCallback = callback;
  }

   public List getCompaniesJSON() {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url.toString());
  requestBuilder.setHeader("Accept", "application/json");
  sendRequest(requestBuilder, null, new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, List.class, Company.class);
  }
  });
   return null;
  }

   public List getCompaniesXML() {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url.toString());
  requestBuilder.setHeader("Accept", "application/xml");
  sendRequest(requestBuilder, null, new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, List.class, Company.class);
  }
  });
   return null;
  }

   public Long createCompanyJSON(final Company a0) {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url.toString());
  requestBuilder.setHeader("Content-Type", "application/json");
  sendRequest(requestBuilder, MarshallingWrapper.toJSON(a0), new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, Long.class, null);
  }
  });
   return 0L;
  }

   public Long createCompanyXML(final Company a0) {
  StringBuilder url = new StringBuilder(getBaseUrl());
  url.append("company/jaxrs");
  RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url.toString());
  requestBuilder.setHeader("Content-Type", "application/xml");
  sendRequest(requestBuilder, MarshallingWrapper.toJSON(a0), new ResponseDemarshallingCallback() {
   public Object demarshallResponse(String response) {
   return MarshallingWrapper.fromJSON(response, Long.class, null);
  }
  });
   return 0L;
  }
  }
  RemoteServiceProxyFactory.addRemoteProxy(ErraiJAXRSService.class, new ProxyProvider() {
   public Object getProxy() {
   return new com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl();
  }
  });
  }
}

Solution

  • This turned out to be an issue with the way JAX-RS / Errai class and interface were configured. According to the JAX-RS specification, the @Path annotation needs to be on the implementation, but Errai needs it on the interface.

    So, the solution was to have the @Path annotation on BOTH the interface (for Errai), and the class that implements it (for JAX-RS).

    Note that if the annotation is on the interface, Wildfly allows for this, Jersey ignores the interface, and Resteasy fails (if running through the ResteasyServletInitializer.