You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Sergey Beryozkin <sb...@gmail.com> on 2013/10/01 14:39:56 UTC

Re: NullPointerException in jaxrs.client.AbstractClient.setResponseBuilder when interceptor throws a fault

Hi Mandy

In this case, an exception is thrown from a custom CXF out interceptor 
(not part of the out JAX-RS chain) and as we discussed earlier, the 
mapping of such exceptions is not supported in earlier CXF versions, but 
only starting from CXF 2.7.8 (see the link I posted in another message).

However in this case in the default mapping won't help because 
RuntimeException is thrown, CXF JAX-RS only has a default 
WebApplicationException mapper.

Now, assuming it is CXF 2.7.8(-SNAPSHOT) and if no ExceptionMapper is 
available, or earlier CXF version, then we have a not-mapped exception 
escaping as per JAX-RS spec rules, with HTTP you'd get 500 indeed, but 
with LocalTransport you have that RuntimeException escaping directly 
into the client.

In my tests I was not getting NPE, I was getting the original 
RuntimeException wrapped in a client exception, but that is not good 
enough because I agree you should get a populated Response with 500 status,

Given that it is LocalTransport direct dispatch client which has an 
escaped server exception, the only way to intercept it internally and 
adapt to JAX-RS Response is to use in fault interceptors on the client 
side, which as it happens have not been supported by JAX-RS client 
runtime before :-), so we looked at how it can be done initially and now 
it is supported starting from CXF 2.7.8 as well, see this test:

http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLocalTransportTest.java

#testProxyServerInFaultDirectDispatch
#testProxyServerOutFault()

Note, the out fault is actually mapped correctly, the in fault 
interceptor is not even needed there, only needed in 
#testProxyServerInFaultDirectDispatch

Cheers, Sergey

On 29/09/13 22:37, Mandy Warren wrote:
> Hi,
>
> I am running some unit tests using local transport to see what happens when
> an interceptor throws a Fault. I was expecting to get a Response back with
> a status code of 500 but instead I get this:
>
> javax.ws.rs.client.ClientException: java.lang.NullPointerException
>>      at
>> org.apache.cxf.jaxrs.client.AbstractClient.setResponseBuilder(AbstractClient.java:374)
>>      at
>> org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:1101)
>>      at
>> org.apache.cxf.jaxrs.client.WebClient.doResponse(WebClient.java:1088)
>>      at
>> org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1038)
>>      at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:858)
>>      at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:832)
>>      at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:395)
>>      at org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:574)
>>
>
> My test setup is as follows:-
>
> I declare a DummyInterceptor which throws a Fault..
>
> public class DummyInterceptor extends AbstractPhaseInterceptor<Message> {
>>
>>      public DummyInterceptor() {
>>          super(Phase.MARSHAL);
>>      }
>>
>>      public void handleMessage(Message message) throws Fault {
>>          throw new Fault(new RuntimeException("hello from runtime
>> exception"));
>>      }
>> }
>>
>
> My test case configures local transport & registers the DummyInterceptor
>
>      @Before
>>      public void setup() {
>>          // enable local transport
>>          bus = BusFactory.newInstance().createBus();
>>          LocalTransportFactory localTransport = new LocalTransportFactory();
>>          DestinationFactoryManager dfm = bus
>>                  .getExtension(DestinationFactoryManager.class);
>>          dfm.registerDestinationFactory("
>> http://schemas.xmlsoap.org/soap/http",
>>                  localTransport);
>>          dfm.registerDestinationFactory(
>>                  "http://schemas.xmlsoap.org/wsdl/soap/http",
>> localTransport);
>>          dfm.registerDestinationFactory(
>>                  "http://cxf.apache.org/bindings/xformat", localTransport);
>>          dfm.registerDestinationFactory(
>>                  "http://cxf.apache.org/transports/local", localTransport);
>>
>>          ConduitInitiatorManager extension = bus
>>                  .getExtension(ConduitInitiatorManager.class);
>>          extension.registerConduitInitiator(
>>                  "http://cxf.apache.org/transports/local", localTransport);
>>          extension.registerConduitInitiator(
>>                  "http://schemas.xmlsoap.org/wsdl/soap/http",
>> localTransport);
>>          extension.registerConduitInitiator(
>>                  "http://schemas.xmlsoap.org/soap/http", localTransport);
>>          extension.registerConduitInitiator(
>>                  "http://cxf.apache.org/bindings/xformat", localTransport);
>>
>>          // create a local endpoint
>>          sf = new JAXRSServerFactoryBean();
>>          sf.setBus(bus);
>>          sf.setAddress(LOCAL_ADDRESS);
>>          sf.setServiceBean(new SimpleRestServiceImpl());
>>          sf.setServiceClass(SimpleRestServiceImpl.class);
>>      }
>>
>>      @After
>>      public void teardown() throws Exception {
>>          if (null != jaxrsServer) {
>>              // explicitly stop server
>>              jaxrsServer.destroy();
>>          }
>>          if (null != bus) {
>>              // shutdown the bus
>>              bus.shutdown(false);
>>          }
>>      }
>>
>>      @Test
>>      public void
>> testExceptionWhichOccursWithinAnOutboundFrameworkInterceptorReturnsAppropriateException()
>>              throws Exception {
>>
>>          // register the DummyInterceptor which throws an exception
>>          List<Interceptor<? extends Message>> outInterceptors = new
>> ArrayList<Interceptor<? extends Message>>(
>>                  1);
>>          outInterceptors.add(new DummyInterceptor());
>>
>>          sf.setOutInterceptors(outInterceptors);
>>
>>          // start the server
>>          jaxrsServer = sf.create();
>>
>>          WebClient client = WebClient.create(LOCAL_ADDRESS);
>>          WebClient.getConfig(client).getRequestContext()
>>                  .put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
>>
>>          try {
>>              Response response = client
>>                      .path("v1/greetings/aveeeeename")
>>                      .type(MediaType.APPLICATION_JSON)
>>                      .accept(MediaType.APPLICATION_JSON)
>>                      .get(Response.class);
>>              assertEquals(500, response.getStatus());
>>          } finally {
>>              if (null != client) {
>>                  client.close();
>>              }
>>          }
>>      }
>>
>
> I am using apache cxf version 2.7.4
>
> Any help much appreciated
>
> Thanks
>
> Mandy
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com