Skip to main content

How to use the Provider interface with JAX-WS

4 replies [Last post]
madwright
Offline
Joined: 2005-08-23

Please can someone give me advice on this? I can use the sample that comes with the JAX-WS download, and also send the prepared client and get the expected response. But, I cannot use the WSDL to generate a SOAP message that receives a proper response - I just get the exception thrown from the server class. Is it possible to use the wsdl to generate a client? I tried, for instance, to generate both C# and Java clients, but couldn't do it because I couldn't work out what to do. I've also tried sending a straight XML message over HTTP, with the message conforming to the types section in the WSDL - but that got the response "Unable to create envelope from given source". When I Googled for that, it seemed to be a namespace issue but I was using the namespace given in the WSDL. I'd really like to make this work!

I would be so grateful to have more details about how to use this and how it's actually working (in addition to the documentation with the JAX-WS and the javadocs, both of which I've read). Because some of the classes used in the client are generated artefacts (ServiceFactory, AddNumbersService, AddNumbersPortType), it's not easy to see what's going on.

Thanks.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
madwright
Offline
Joined: 2005-08-23

I started again from scratch, ran the wsimport against the wsdl to generate files and extracted the synchronous parts from the Dispatch client, importing the generated classes. I'm trying to do it without Ant so that I can follow one step at a time (e.g. to be able to create a client in another language). The class is:

import javax.xml.ws.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.rmi.RemoteException;
import javax.xml.soap.SOAPException;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPBinding;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.bind.JAXBContext;
import javax.xml.ws.ServiceFactory;
import javax.xml.soap.MessageFactory;
import org.duke.*;

public class AddNumbersRest {
private static String request = "1020";
private static String endpointAddress = "http://localhost:8080/jaxws-provider/addnumbers";
private static Service service;
private static final QName portQName = new QName("http://duke.org", "AddNumbersPort");
private static final QName serviceQName = new QName("http://duke.org", "AddNumbersService");

public static void main(String [] args) {
AddNumbersRest client = new AddNumbersRest();
try {
URI soapBindingURI = null;
soapBindingURI = new URI(SOAPBinding.SOAP11HTTP_BINDING);
ServiceFactory serviceFactory = ServiceFactory.newInstance();
service = serviceFactory.createService(serviceQName);
service.createPort(portQName, soapBindingURI, endpointAddress);
} catch (URISyntaxException e) {
e.printStackTrace();
}

try {
client.invokeAddNumbers(request, Service.Mode.PAYLOAD);
} catch (RemoteException ex) {
ex.printStackTrace();
} catch (ProtocolException jex) {
jex.printStackTrace();
}
}

private void invokeAddNumbers(String request, Service.Mode mode) throws RemoteException {
Dispatch sourceDispatch = null;
sourceDispatch = service.createDispatch(portQName, Source.class, mode);
System.out.println("\nInvoking xml request: " + request);
Source result = sourceDispatch.invoke(new StreamSource(new StringReader(request)));

InputStream in = null;
OutputStream out = null;

String xmlResult = sourceToXMLString(result);
System.out.println("Received xml response: " + xmlResult);
}

private String sourceToXMLString(Source result) {

String xmlResult = null;
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
OutputStream out = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult();
streamResult.setOutputStream(out);
transformer.transform(result, streamResult);
xmlResult = streamResult.getOutputStream().toString();
} catch (TransformerException e) {
e.printStackTrace();
}
return xmlResult;
}
}

It compiles OK but when I try to run it, I get the error:

Exception in thread "main" java.lang.NoSuchMethodError: javax.xml.soap.MessageFactory.newInstance(Ljava/lang/String;)Lja
vax/xml/soap/MessageFactory;
at com.sun.xml.ws.encoding.soap.message.SOAPMessageContext.createMessageFactory(SOAPMessageContext.java:215)
at com.sun.xml.ws.encoding.soap.message.SOAPMessageContext.(SOAPMessageContext.java:227)
at com.sun.xml.ws.client.dispatch.impl.DispatchContactInfoList.iterator(DispatchContactInfoList.java:33)
at com.sun.xml.ws.client.dispatch.impl.DispatchDelegate.send(DispatchDelegate.java:46)
at com.sun.xml.ws.client.dispatch.DispatchBase.sendAndReceive(DispatchBase.java:274)
at com.sun.xml.ws.client.dispatch.DispatchBase.invoke(DispatchBase.java:98)
at AddNumbersRest.invokeAddNumbers(AddNumbersRest.java:51)
at AddNumbersRest.main(AddNumbersRest.java:39)

Don't know what I've missed here? I can see it thinks it's got parameters when it shouldn't have any - but this works in the original class with the Ant run target. I tried importing the dispatch classes from the build directory but that didn't help (e.g.import dispatch.client.*;). Sorry to be so obtuse!

jitu
Offline
Joined: 2003-06-14

you have a wrong/old saaj-impl.jar in the classpath. Use the saaj-impl.jar that comes with jax-ws.

jitu
Offline
Joined: 2003-06-14

Infact, the WSDL is used to generate client side artifacts in the sample(like AddNumbersService).

You can use the Provider based endpoint when the endpoint itself deals with XML. All you require is write the endpoint implmentation and package WSDL, and schema documents.

Clients can access a provider based webservice just like any other service. You run wsimport on the published wsdl and write the client using those portable artifacts.

Have you checked the samples from recent nightly builds ? They are better organized and all the related ant targets for the sample are included in the sample directory's build.xml

Let me know if you have any questions.

madwright
Offline
Joined: 2005-08-23

> Infact, the WSDL is used to generate client side
> artifacts in the sample(like AddNumbersService).

OK. Thanks. That happens with wsimport. So the service really starts with the wsdl. That's nice.

> You can use the Provider based endpoint when the
> endpoint itself deals with XML.

I get it now. So the Provider-based endpoint can receive straight XML?

All you require is
> write the endpoint implmentation and package WSDL,
> and schema documents.

OK. I deployed this on the Sun AppServer 8.1 and I can see that it's deployed the AddNumbersImpl and AddNumbersService classes along with the wsdl. The web.xml file has to refer to those servlets every time? The "provider" mentioned several times in the web.xml file - does that refer to the package or to the "provider style"?
>
> Clients can access a provider based webservice just
> like any other service. You run wsimport on the
> published wsdl and write the client using those
> portable artifacts.

OK. Thanks. I did try that but didn't succeed. I'll try again.

>
> Have you checked the samples from recent nightly
> builds ? They are better organized and all the
> related ant targets for the sample are included in
> the sample directory's build.xml

Thanks. No. I'm using the ea2 release. I did download the pr release (for the javadocs, which weren't in the ea release) but that didn't seem to have the same files for installing it on the AppServer 8.1?
>
> Let me know if you have any questions.

Thanks again. It would be really nice to see another example of a Provider service - maybe one that receives a document? With a Dispatch client? I did alter the Dispatch client to make it run on the Provider service and it worked.