xsd schema not presented by wsdl
jax-ws, wsdl, xsd
Solution
I almost can't believe that this was such a difficult problem to solve!
I've been googling like mad to find a solution to exactly this problem! Then I've been struggling really hard to find a solution on my own. By debugger-stepping through the java-6-openjdk's default javax.xml.ws.spi.Provider implementation (the "factory" in the JRE that creates the javax.xml.ws.Endpoint objects that you use for publishing web services) I finally learnt some things, which helped me to craft a solution that at least works in Java SE, at least in my current JRE, which is:
java version "1.6.0_33"
OpenJDK Runtime Environment (IcedTea6 1.13.5) (6b33-1.13.5-1ubuntu0.12.04)
OpenJDK Server VM (build 23.25-b01, mixed mode)
Whether this solution is usable in Java EE I don't know yet.
Here is how I solved it:
package myservice;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Endpoint;
public class App
{
private static final String MY_SERVICE_XSD = "/wsdl/MyService.xsd";
public static void main( String[] args )
{
Endpoint ep = Endpoint.create(new MyEndpointImpl());
ep.setMetadata(Arrays.asList(sourceFromResource(MY_SERVICE_XSD)));
ep.publish("http://localhost:8080/svc/hello");
}
private static Source sourceFromResource(String name) {
URL resource = App.class.getResource(name);
String systemId = resource.toExternalForm();
InputStream inputStream;
try {
inputStream = resource.openStream();
} catch (IOException e) {
throw new RuntimeException("Failed to create InputStream from resource \""+ name +"\"", e);
}
return new StreamSource(inputStream, systemId);
}
}
The crucial thing is that I first use method Endpoint#create (not Endpoint#publish) to get an unpublished Endpoint. Then I add the XSD-file as "meta data" to the (still unpublished) Endpoint (code "ep.setMetaData(...)"). Then I publish the endpoint (code "ep.publish(...)").
Now when I access `http://localhost:8080/svc/hello?wsdl` I get:
<definitions targetNamespace="http://somewhere.net/my/namespace" name="MyService">
<types>
<xsd:schema>
<xsd:import namespace="http://somewhere.net/my/namespace"
schemaLocation="http://localhost:8080/svc/hello?xsd=1"/>
</xsd:schema>
</types>
...
</definitions>
and my XSD-file is available from `http://localhost:8080/svc/hello?xsd=1`!
Note that my MyService.wsdl file on disk still contains:
<xsd:schema>
<xsd:import namespace="http://somewhere.net/my/namespace"
schemaLocation="MyService.xsd"></xsd:import>
</xsd:schema>
Problem
I'm developing WebService with JAX-WS(i'm using wsimport goal on jaxws-maven-plugin). I wrote a WSDL that imports a XSD schema. ``` WEB-INF/wsdl/service.wsdl WEB-INF/wsdl/service.xsd ``` Also I generated web service classes and created endpoint and all. Everything worked great so far. When I ran my service on Tomcat 7 everything is ok. I can access a wsdl in my browser from: ``` http://localhost:8080/webService/servlet-url?wsdl ``` but I cannot get access to a xsd schema. The problem is in this wsdl: ``` <xsd:schema> <xsd:import namespace="http://ws.service/domain/1.0" schemaLocation="service.xsd"/> </xsd:schema> ``` Of course during generation of classes wsdl and xsd are on local path but i want them to be remotely accessible when web service is running. I know that schemaLocation should be something like this "http://localhost:8080/webService/servlet-url?xsd=1". In wsdl presented in browser import schould look like: ``` <xsd:schema> <xsd:import namespace="http://ws.service/domain/1.0" schemaLocation="http://localhost:8080/webService/servlet-url?wsdl&resource=service.xsd"/> </xsd:schema> ``` localhost:8080/webService/servlet?wsdl gives me: ``` wsdl:definitions targetNamespace="http://ws.serv.com/Service/1.0" name="emuiaService"> <wsdl:types> <xsd:schema> <xsd:import namespace="http://ws.serv.com/Service/domain/1.0" schemaLocation="schema.xsd"/> </xsd:schema> </wsdl:types> <wsdl:message name="halloMsg"> <wsdl:part name="parameters" element="dom:halloRequest"/> </wsdl:message> <wsdl:message name="halloResponseMsg"> <wsdl:part name="return" element="dom:halloResponse"/> </wsdl:message> ``` and so on...