Search code examples
javaweb-servicessoapwsdl

JAX-WS RI generates WSDL on runtime with public URL in schemaLocation attribute of import by default


While using JAX-WS RI for publishing SOAP endpoints implemented using generated stubs from predetermined .wsdl and .xsd files, it automatically generates corresponding WSDL files for the published endpoint. For example an endpoint published at http://localhost:8081/ep has its WSDL file at http://localhost:8081/ep?wsdl with it containing imports of other schema files which in turn can import more files.

Issue is that one such import in an .xsd file is automatically generated with a reference to public URL as such:

...
<xs:import namespace="http://www.w3.org/2005/08/addressing" 
           schemaLocation="http://www.w3.org/2006/03/addressing/ws-addr.xsd"/>
...

This can be an issue when trying to parse this endpoint's WSDL in an environment with no public internet connectivity. Generated stubs include classes from ws-addr.xsd, so JAX-WS RI should be able to generate and publish the .xsd from those stubs.

How could this be forced to generate the required .xsd schema itself as it does for other namespace schemas and why does this use a public location in the first place?


Solution

  • The issue is that some other dependency overwrites the default setting for the schema. As the project uses JAX-WS RI, it also includes a dependency for jakarta.xml.ws-api which includes a package-info.java file in javax.xml.ws.wsaddressing package containing the following titbit:

    @javax.xml.bind.annotation.XmlSchema(namespace=W3CEndpointReference.NS,
                                         location="http://www.w3.org/2006/03/addressing/ws-addr.xsd")
    package javax.xml.ws.wsaddressing;
    

    where W3CEndpointReference.NS is http://www.w3.org/2005/08/addressing.

    This, through some automatic configuration magic, tells JAX-WS RI to use the given public location when referencing the specified namespace. The default value for location is ##generate which makes the schema generator generate the required components.

    So in order to override this, we can add our own package-info.java file into our own codebase but in the same package, with the same annotation but with the default value for the location:

    @javax.xml.bind.annotation.XmlSchema(namespace=W3CEndpointReference.NS)
    package javax.xml.ws.wsaddressing;
    

    (no location key means default value is used)

    And result is that the generated schema uses a generated addressing .xsd file instead of a public one:

    <xs:import namespace="http://www.w3.org/2005/08/addressing"
               schemaLocation="http://localhost:8081/ep?xsd=10"/>