I've problem with initiation of JAXWSProperties in MessageContext of example webservice described on following blog

There is the helper class initiating HeaderList object in getHeaders() method:

import com.sun.xml.internal.ws.api.SOAPVersion;
import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
import com.sun.xml.internal.ws.api.message.HeaderList;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.JAXWSProperties;
import com.sun.xml.internal.ws.developer.WSBindingProvider;

import javax.xml.ws.EndpointReference;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceContext;

public final class CorrelationHelper<S extends Service> {

private WebServiceContext wsc;
private S service;

public CorrelationHelper(S service, WebServiceContext wsc) {
    this.service = service;
    this.wsc = wsc;
}

private HeaderList getHeaders() {
    return (HeaderList)wsc.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
}

public <P> P getCorrelatedPort(Class<P> portType) {
    P port = service.getPort(getReplyTo(), portType);
    ((WSBindingProvider)port).setOutboundHeaders(Headers.create(AddressingVersion.W3C.relatesToTag,
                                                                getMessageId()));
    return port;
}

private EndpointReference getReplyTo() {
    return getHeaders().getReplyTo(AddressingVersion.W3C,
                                   SOAPVersion.SOAP_11).toSpec();
}


private String getMessageId() {
    return getHeaders().getMessageID(AddressingVersion.W3C,
                                     SOAPVersion.SOAP_11);
}
}

this helper is called from service implementation as:

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.soap.Addressing;

import dev.home.examples.jobprocessor.client.JobProcessorNotify;
import dev.home.examples.jobprocessor.client.JobProcessorNotify_Service;
import dev.home.examples.jobprocessor.client.JobReplyType;
import dev.home.examples.jobprocessor.handlers.CorrelationHelper;
import dev.home.examples.jobprocessor.types.JobType;

@WebService(serviceName = "JobProcessor",
            targetNamespace = "http://examples.home.dev/jobprocessor",
            portName = "jobProcessor",
            endpointInterface = "dev.home.examples.jobprocessor.ws.JobProcessor")
@HandlerChain(file = "JobProcessor-HandlerChain.xml")
@Addressing(required = true)
public class JobProcessorImpl {
//...
public void processJob(JobType job) {

    // do processing
    int seconds = doJob();

    // prepare reply message
    JobReplyType jobReply = new JobReplyType();
    jobReply.setJobId(job.getJobId());
    jobReply.setResult(String.format("Job payload %s processed in %d seconds!",
                                     job.getPayload(), seconds));

    // do correlation and perform the callback
    JobProcessorNotify jobProcessorNotify =
        correlationHelper.getCorrelatedPort(JobProcessorNotify.class);
    jobProcessorNotify.replyFinishedJob(jobReply);
}
}

HeaderList is not initiated during getReplyTo() and than is returned as null:

(HeaderList)wsc.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)


Caused by: java.lang.NullPointerException
    at dev.home.examples.jobprocessor.handlers.CorrelationHelper.getReplyTo(CorrelationHelper.java:67)
    at dev.home.examples.jobprocessor.handlers.CorrelationHelper.getCorrelatedPort(CorrelationHelper.java:56)
    at dev.home.examples.jobprocessor.ws.JobProcessorImpl.processJob(JobProcessorImpl.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)
    at org.apache.cxf.jaxws.JAXWSMethodInvoker.performInvocation(JAXWSMethodInvoker.java:66)
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
    ... 17 more

although the SOAP data Header contains all data:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://examples.home.dev/jobprocessor/types">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>http://examples.home.dev/jobprocessor/processJob</wsa:Action><wsa:ReplyTo><wsa:Address>http://CZ407032:8088/mockJobProcessorNotify</wsa:Address></wsa:ReplyTo><wsa:MessageID>uuid:96dd09e2-c448-47c0-902f-7eb95421e232</wsa:MessageID><wsa:To>http://CZ407032:8088/JobProcessor</wsa:To></soapenv:Header>
   <soapenv:Body>
      ...
   </soapenv:Body></soapenv:Envelope>
1

There are 1 best solutions below

6
pedrofb On

You are using the property INBOUND_HEADER_LIST_PROPERTY. Reading JAX-WS documentation, shows an unpleasant warning

THIS PROPERTY IS EXPERIMENTAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE IN FUTURE.

HeaderList and JAXWSProperties are classes in com.sun.xml.internal.ws.* package. Do you really want to use this? The blog is dated in 2012, may be the behaviour has changed

Check if this simple code return a not null object (after injecting messageContext as @Resource in your service)

HeaderList hl = (HeaderList) messageContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);