Search code examples
karaf

Application REST Client on Karaf


I'am writing a simple . application deploying on Karaf 4.1.0. It's role is sending a rest request to REST API. When I start my bundle I have an error:

javax.ws.rs.ProcessingException: org.apache.cxf.interceptor.Fault: No message body writer has been found for class package.QueueSharedDTO, ContentType: application/json
    at org.apache.cxf.jaxrs.client.WebClient.doResponse(WebClient.java:1149)
    at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1094)
    at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:894)
    at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:865)
    at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:428)
    at org.apache.cxf.jaxrs.client.WebClient$SyncInvokerImpl.method(WebClient.java:1631)
    at org.apache.cxf.jaxrs.client.WebClient$SyncInvokerImpl.method(WebClient.java:1626)
    at org.apache.cxf.jaxrs.client.WebClient$SyncInvokerImpl.post(WebClient.java:1566)
    at org.apache.cxf.jaxrs.client.spec.InvocationBuilderImpl.post(InvocationBuilderImpl.java:145)
    at package.worker.service.implementation.ConnectionServiceImpl.postCheckRequest(ConnectionServiceImpl.java:114)
    at package.worker.service.implementation.ConnectionServiceImpl.sendCheck(ConnectionServiceImpl.java:103)
    at package.worker.module.QueueSharedListener.run(QueueSharedListener.java:37)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.cxf.interceptor.Fault: No message body writer has been found for class package.QueueSharedDTO, ContentType: application/json
    at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1222)
    at org.apache.cxf.jaxrs.client.AbstractClient$AbstractBodyWriter.handleMessage(AbstractClient.java:1091)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:649)
    at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1093)
    ... 11 more
Caused by: javax.ws.rs.ProcessingException: No message body writer has been found for class com.emot.dto.QueueSharedDTO, ContentType: application/json
    at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:780)
    at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:494)
    at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1217)
    ... 15 more

Initialization WebTarget:

private ConnectionServiceImpl() {
    client = ClientBuilder.newClient();
    client.property(
            ClientProperties.CONNECT_TIMEOUT,
            snifferProperties.getProperty(SnifferProperties.PARAM_REST_API_CONNECTION_TIMEOUT));
    client.property(
            ClientProperties.READ_TIMEOUT,
            snifferProperties.getProperty(SnifferProperties.PARAM_REST_API_READ_TIMEOUT));
    System.out.println(2);
    webTarget = client.target(buildUrl());
}

Send requests :

private synchronized boolean postCheckRequest(String path, Object content) {
    boolean result = true;
    try {
        Response response = webTarget
                .path("check")
                .path("add/one")
                .request(MediaType.APPLICATION_JSON)
                .post(Entity.json(content));
        result = (response.getStatus() == 200);
    } catch (Exception e) {
        System.out.println("Error but working");
        e.printStackTrace();
        result = false;
    }
    return result;
}

I have always the problems with Karaf... i dont understand why it . couldn't working correctly...


Solution

  • The issue you are facing is mostly not a Karaf issue, but a typical issue you may face while working with some JAX-RS implementation in non-JavaEE environment.

    Exception literally says that your implementation misses message body writer. Message body writer is the class which implements class javax.ws.rs.ext.MessageBodyWriter and is responsible for serializing your data objects to some format (like JSON). There is another class named javax.ws.rs.ext.MessageBodyReader, which does the opposite thing. All these classes are registered to JAX-RS framework as providers, extending its capabilities. Details are here: https://jersey.java.net/documentation/latest/message-body-workers.html

    So, generally you must decide what you use for serializing/deserializing between your data objects and HTTP MediaType and register a proper JAX-RS provider.

    With Jackson, for example, your problem can be easily solved by using one of its standard implementation: either com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider, if you use JAXB annotations, or com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider, if you prefer Jackson annotations. Add this class in providers section of your Blueprint descriptor:

    <jaxrs:server id="restServer" address="/rest">
        <jaxrs:serviceBeans>
                ....
        </jaxrs:serviceBeans>
        <jaxrs:providers>
                ....
            <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
                ....
        </jaxrs:providers>
    </jaxrs:server>