# External Web Service Metadata

It's one of goals of JAX-WS RI to make development of web services as simple as possible, so using of java annotations perfectly makes sense. However there are usecases where it is impossible to use them. For example if we need to expose existing component as a web service, but we have no source code, just binaries. In such scenarios we need not to rely on annotations and JAX-WS RI framework needs a different way how to obtain necessary metadata. The solution is to provide metadata in xml files and to configure JAX-WS RI framework in a way it's aware of them.

## Configuration files

To specify classes' metadata externally, each java class requires separate file. The way how JAX-WS RI framework handles this metadata depends on attributes of xml root element `java-wsdl-mapping`:

`webservices.war/WEB-INF/classes/external-metadata.xml`

    <?xml version="1.0" encoding="UTF-8"?>
    <java-wsdl-mapping xmlns="http://xmlns.oracle.com/webservices/jaxws-databinding"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://xmlns.oracle.com/webservices/jaxws-databinding jaxws-ri-external-metadata.xsd"
           java-type-name="org.example.BlackBoxImpl"
           existing-annotations="ignore"
           databinding="glassfish.jaxb">

        <web-service name="" target-namespace="mynamespace"/>

    </java-wsdl-mapping>

- `java-type-name="org.example.BlackBoxImpl"`

  attribute defines what class is the definition file for. Having this information in xml file allows us to provide just list of xml files and framework itself knows what to do with those.

- `existing-annotations="ignore"`

  This attribute says if and how should be java annotations found in the java class handled. Possible values are:

  - `ignore`

    - annotations found in java class are ignored; JAX-WS RI framework behaves as if there was no other metadata than one in xml file

  - `merge`

    - annotations found in java class are considered, but metadata in xml file is overriding them; if an annotation is present in java file only, framework uses it, if found in both annotation and xml file, the latter one is hiding the first one.

## XSD Schema

As you probably noticed in an example above, there is a new schema for configuration files: http://xmlns.oracle.com/webservices/jaxws-databinding. The schema is designed to reflect Web Service Metadata (JSR-181) and JAX-WS Annotations (JSR-224) so structure should be really intuitive to developers - see following table:

Mapping java `@Annotation`-s to xml elements examples

@Annotation | corresponding xml element
--- | ---
`javax.jws.WebService(name="AddNumbers", portName="AddNumbersPort")` | `<web-service name="AddNumbers" port-name="AddNumbersPort" />`
`javax.xml.ws.WebServiceProvider( targetNamespace="urn:test", serviceName="Endpoint", portName="EndpointPort")` | `<web-service-provider target-namespace="urn:test" service-name="Endpoint" port-name="EndpointPort" />`
`javax.xml.ws.ServiceMode(Service.Mode.MESSAGE)` | `<service-mode value="MESSAGE" />`

## Passing Configuration Files to JAX-WS RI

There are different stages where we need to pass the collection of files to JAX-WS RI framework:

- wsgen: when starting "from java" - better to say if we have no wsdl prepared, we need to pass the classpath to implementations to be used together with a list of external metadata files to wsgen. Therefore wsgen tool has a new option `-x <path>`. If there are several such files, the option must be repeated before each path. Corresponding ant task supports new nested element "external-metadata", see following example:

  wsgen ant task example: `build.xml`

      <wsgen  sei="org.example.server.BlackboxService"
                      destdir="${build.classes.home}"
                      resourcedestdir="${build.classes.home}"
                      sourcedestdir="${build.classes.home}"
                      keep="true"
                      verbose="true"
                      genwsdl="true"
                      protocol="soap1.1"
                      extension="false"
                      inlineSchemas="false">

                  <externalmetadata file="${basedir}/etc/external-metadata.xml" />
                  <classpath>
                      <pathelement location="${build.classes.home}"/>
                  </classpath>

              </wsgen>

- wsimport - if you start from wsdl, no extra parameter is necessary - artifacts are generated on wsdl only and external metadata are required later, in runtime.

- runtime - in runtime, it's necessary to tell somehow to container (Servlet or JEE) what xml files to load. Currently, JAX-WS RI Servlet deployment is supported - `sun-jaxws.xml` schema has been updated to support new elements - `<external-metadata>`, saying to a container to parse the resources when doing a deployment:

  `webservice-module.war/WEB-INF/sun-jaxws.xml`

      <?xml encoding="UTF-8" version="1.0" ?>
      <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
          <endpoint implementation="org.example.server.BlackboxService" url-pattern="/WS" name="WS">
              <external-metadata resource="external-metadata.xml" />
          </endpoint>
      </endpoints>

For more complete example see samples.