== JAX-WS Tools

The JAX-WS tools provided by JBossWS can be used in a variety of ways.
First we will look at server-side development strategies, and then
proceed to the client.

=== Server side

When developing a Web Service Endpoint (the server-side) you have the
option of starting from Java ( _bottom-up development_ ), or from the
abstact contract (WSDL) that defines your service ( _top-down
development_ ). If this is a new service (no existing contract), the
bottom-up approach is the fastest route; you only need to add a few
annotations to your classes to get a service up and running. However, if
developing a service with an already defined contract, it is far
simpler to use the top-down approach, since the provided tool will
generate the annotated code for you.

Bottom-up use cases:

* Exposing an already existing EJB3 bean as a Web Service
* Providing a new service, and wanting the contract to be generated for
you

Top-down use cases:

* Replacing the implementation of an existing Web Service, and you can't
break compatibility with older clients
* Exposing a service that conforms to a contract specified by a third
party (e.g. a vendor that calls back using an already defined
protocol).
* Creating a service that adheres to the XML Schema and WSDL you
developed by hand up front

The following JAX-WS command line tools are included in JBossWS:

[cols=",",options="header",]
|===
|Command |Description
|wsprovide |Generates JAX-WS portable artifacts, and provides the
abstract contract. Used for bottom-up development.

|wsconsume |Consumes the abstract contract (WSDL and Schema files), and
produces artifacts for both a server and client. Used for top-down and
client development
|===

==== Bottom-Up (Using wsprovide)

The bottom-up strategy involves developing the Java code for your
service, and then annotating it using JAX-WS annotations. These
annotations can be used to customize the contract that is generated for
the service. For example, you can change the operation name to map to
anything you like. However, all of the annotations have sensible
defaults, so only the @WebService annotation is required.

This can be as simple as creating a single class:

....
package echo;

@jakarta.jws.WebService
public class Echo
{
   public String echo(String input)
   {
      return input;
   }
}
....

A JSE or EJB3 deployment can be built using this class, and it is the
only Java code needed to deploy on JBossWS. The WSDL, and all other Java
artifacts called "wrapper classes" will be generated at deploy
time. This actually goes beyond the JAX-WS specification, which requires
that wrapper classes be generated using an offline tool. The reason for
this requirement is purely a vendor implementation problem, and since we
do not believe in burdening a developer with a bunch of additional
steps, we generate these as well. However, if you want your deployment
to be portable to other application servers, you will need
to use a tool and add the generated classes to your deployment.

This is the primary purpose of the _wsprovide_ tool, to generate
portable JAX-WS artifacts. Additionally, it can be used to "provide" the
abstract contract (WSDL file) for your service. This can be obtained by
invoking _wsprovide_ using the "-w" option:

....
$ javac -d . Echo.java
$ wsprovide -w echo.Echo
Generating WSDL:
EchoService.wsdl
Writing Classes:
echo/jaxws/Echo.class
echo/jaxws/EchoResponse.class
....

Inspecting the WSDL reveals a service called _EchoService_ :

....
<service name='EchoService'>
 <port binding='tns:EchoBinding' name='EchoPort'>
  <soap:address location='REPLACE_WITH_ACTUAL_URL'/>
 </port>
</service>
....

As expected, this service defines one operation, " _echo_ ":

....
<portType name='Echo'>
 <operation name='echo' parameterOrder='echo'>
  <input message='tns:Echo_echo'/>
  <output message='tns:Echo_echoResponse'/>
 </operation>
</portType>
....

[NOTE]
====
Remember that when deploying on JBossWS you do not need to run this
tool. It is only needed for generating portable artifacts and/or the
abstract contract for the service.
====

Let's create a POJO endpoint for deployment on WildFly. A simple
_web.xml_ needs to be created:

....
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
  version="5.0">

  <servlet>
    <servlet-name>Echo</servlet-name>
    <servlet-class>echo.Echo</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Echo</servlet-name>
    <url-pattern>/Echo</url-pattern>
  </servlet-mapping>
</web-app>
....

The _web.xml_ and the single class can now be used to create a war:

....
$ mkdir -p WEB-INF/classes
$ cp -rp echo WEB-INF/classes/
$ cp web.xml WEB-INF
$ jar cvf echo.war WEB-INF
added manifest
adding: WEB-INF/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/echo/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/echo/Echo.class(in = 340) (out= 247)(deflated 27%)
adding: WEB-INF/web.xml(in = 576) (out= 271)(deflated 52%)
....

The war can then be deployed to the JBoss Application Server; this will internally
invoke wsprovide, which will generate the WSDL. If deployment was
successful, and you are using the default settings, it should be
available in the server management console.

For a portable JAX-WS deployment, the wrapper classes generated earlier
could be added to the deployment.

==== Down (Using wsconsume)

The top-down development strategy begins with the abstract contract for
the service, which includes the WSDL file and zero or more schema files.
The _wsconsume_ tool is then used to consume this contract, and produce
annotated Java classes (and optionally sources) that define it.

[NOTE]
====
wsconsume may have problems with symlinks on Unix systems
====

Using the WSDL file from the bottom-up example, a new Java
implementation that adheres to this service can be generated. The "-k"
option is passed to _wsconsume_ to preserve the Java source files that
are generated, instead of providing just classes:

....
$ wsconsume -k EchoService.wsdl
echo/Echo.java
echo/EchoResponse.java
echo/EchoService.java
echo/Echo_Type.java
echo/ObjectFactory.java
echo/package-info.java
echo/Echo.java
echo/EchoResponse.java
echo/EchoService.java
echo/Echo_Type.java
echo/ObjectFactory.java
echo/package-info.java
....

The following table shows the purpose of each generated file:

[cols=",",options="header",]
|===
|File |Purpose
|Echo.java |Service Endpoint Interface
|Echo_Type.java |Wrapper bean for request message
|EchoResponse.java |Wrapper bean for response message
|ObjectFactory.java |JAXB XML Registry
|package-info.java |Holder for JAXB package annotations
|EchoService.java |Used only by JAX-WS clients
|===

Examining the Service Endpoint Interface reveals annotations that are
more explicit than in the class written by hand in the bottom-up
example, however, these evaluate to the same contract:

....
@WebService(name = "Echo", targetNamespace = "http://echo/")
public interface Echo {
    @WebMethod
    @WebResult(targetNamespace = "")
    @RequestWrapper(localName = "echo", targetNamespace = "http://echo/", className = "echo.Echo_Type")
    @ResponseWrapper(localName = "echoResponse", targetNamespace = "http://echo/", className = "echo.EchoResponse")
    public String echo(
        @WebParam(name = "arg0", targetNamespace = "")
        String arg0);

}
....

The only missing piece (for packaging) is the implementation
class, which can now be written, using the above interface.

....
package echo;

@jakarta.jws.WebService(endpointInterface="echo.Echo")
public class EchoImpl implements Echo
{
   public String echo(String arg0)
   {
      return arg0;
   }
}
....

=== Client Side

Before going into detail on the client-side it is important to understand
the decoupling concept that is central to Web Services. Web Services are
not the best fit for internal RPC, even though they can be used in this
way. There are much better technologies for this (CORBA, and RMI for
example). Web Services was designed specifically for interoperable
coarse-grained correspondence. There is no expectation or guarantee that
any party participating in a Web Service interaction will be at any
particular location, running on any particular OS, or written in any
particular programming language, because of this, it is important to
clearly separate client and server implementations. The only thing they
should have in common is the abstract contract definition. If, for
whatever reason, your software does not adhere to this principal, then
you should not be using Web Services. For the above reasons, the
*_recommended methodology for developing a client is_* to follow *_the
top-down approach_* , even if the client is running on the same server.

Let's repeat the process of the top-down section, although using the
deployed WSDL, instead of the one generated offline by _wsprovide_ . The
reason we do this is to get the right value for soap:address.
This value must be computed at deploy time, since it is based on
container configuration specifics. You could of course edit the WSDL
file yourself, although you need to ensure that the path is correct.

Offline version:

....
<service name='EchoService'>
  <port binding='tns:EchoBinding' name='EchoPort'>
   <soap:address location='REPLACE_WITH_ACTUAL_URL'/>
  </port>
</service>
....

Online version:

....
<service name="EchoService">
  <port binding="tns:EchoBinding" name="EchoPort">
    <soap:address location="http://localhost.localdomain:8080/echo/Echo"/>
  </port>
</service>
....

Using the online deployed version with _wsconsume_ :

....
$ wsconsume -k http://localhost:8080/echo/Echo?wsdl
echo/Echo.java
echo/EchoResponse.java
echo/EchoService.java
echo/Echo_Type.java
echo/ObjectFactory.java
echo/package-info.java
echo/Echo.java
echo/EchoResponse.java
echo/EchoService.java
echo/Echo_Type.java
echo/ObjectFactory.java
echo/package-info.java
....

The one class that was not examined in the top-down section, was
`EchoService.java` . Notice how it stores the location the WSDL was
obtained from.

....
@WebServiceClient(name = "EchoService", targetNamespace = "http://echo/", wsdlLocation = "http://localhost:8080/echo/Echo?wsdl")
public class EchoService extends Service
{
    private final static URL ECHOSERVICE_WSDL_LOCATION;

    static {
        URL url = null;
        try
        {
           url = new URL("http://localhost:8080/echo/Echo?wsdl");
        }
        catch (MalformedURLException e)
        {
           e.printStackTrace();
        }
        ECHOSERVICE_WSDL_LOCATION = url;
    }

    public EchoService(URL wsdlLocation, QName serviceName)
    {
         super(wsdlLocation, serviceName);
    }

    public EchoService()
    {
         super(ECHOSERVICE_WSDL_LOCATION, new QName("http://echo/", "EchoService"));
    }

    @WebEndpoint(name = "EchoPort")
    public Echo getEchoPort()
    {
         return (Echo)super.getPort(new QName("http://echo/", "EchoPort"), Echo.class);
    }
}
....

This generated class extends the main client entry point
in JAX-WS, `jakarta.xml.ws.Service` . While `Service` can be used
directly, this is far simpler since it provides the configuration info
for you. The only method we really care about is the `getEchoPort()`
method, which returns an instance of the Service Endpoint Interface. Any
WS operation can then be called by just invoking a method on the
returned interface.

[NOTE]
====
It's not recommended to refer to a remote WSDL URL in a production
application. This causes network I/O every time you instantiate the
Service Object. Instead, use the tool on a saved local copy, or use the
URL version of the constructor to provide a new WSDL location.
====

All that is left to do, is write and compile the client:

....
import echo.*;

public class EchoClient
{
   public static void main(String args[])
   {
      if (args.length != 1)
      {
          System.err.println("usage: EchoClient <message>");
          System.exit(1);
      }

      EchoService service = new EchoService();
      Echo echo = service.getEchoPort();
      System.out.println("Server said: " + echo.echo(args[0]));
   }
}
....

It is easy to change the endpoint address of your operation at runtime,
setting the _ENDPOINT_ADDRESS_PROPERTY_ as shown below:

....
      EchoService service = new EchoService();
      Echo echo = service.getEchoPort();

      /* Set NEW Endpoint Location */
      String endpointURL = "http://NEW_ENDPOINT_URL";
      BindingProvider bp = (BindingProvider)echo;
      bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);

      System.out.println("Server said: " + echo.echo(args[0]));
....


=== WS binding customization

An introduction to binding customizations:

* http://java.sun.com/webservices/docs/2.0/jaxws/customizations.html[]
* https://jax-ws.dev.java.net/source/browse/jax-ws/guide/docs/wsdl-customization.xsd?rev=1.2&view=log[binding
schema]

The schema for the binding customization files can be found here:

* https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html[]

=== wsconsume

_wsconsume_ is a command line tool and ant task that "consumes" the
abstract contract (WSDL file) and produces portable JAX-WS service and
client artifacts.

==== Command Line Tool

The command line tool has the following usage:

....
usage: wsconsume [options] <wsdl-url>
options:
  -h, --help                  Show this help message
  -b, --binding=<file>        One or more JAX-WS or JAXB binding files
  -k, --keep                  Keep/Generate Java source
  -c  --catalog=<file>        Oasis XML Catalog file for entity resolution
  -j  --clientjar=<name>      Create a jar file of the generated artifacts for calling the webservice
  -p  --package=<name>        The target package for generated source
  -w  --wsdlLocation=<loc>    Value to use for @WebServiceClient.wsdlLocation
  -o, --output=<directory>    The directory to put generated artifacts
  -s, --source=<directory>    The directory to put Java source
  -q, --quiet                 Be somewhat more quiet
  -v, --verbose               Show full exception stack traces
  -l, --load-consumer         Load the consumer and exit (debug utility)
  -e, --extension             Enable SOAP 1.2 binding extension
  -a, --additionalHeaders     Enables processing of implicit SOAP headers
  -d, --encoding=<charset>    The charset encoding to use for generated sources
  -n, --nocompile             Do not compile generated sources
....

[IMPORTANT]
====
The wsdlLocation is used when creating the Service to be used by clients
and will be added to the @WebServiceClient annotation, for an endpoint
implementation based on the generated service endpoint interface you
will need to manually add the wsdlLocation to the @WebService annotation
on your web service implementation and not the service endpoint
interface.
====

===== Examples

Generate artifacts in Java class form only:

....
wsconsume Example.wsdl
....

Generate source and class files:

....
wsconsume -k Example.wsdl
....

Generate source and class files in a custom directory:

....
wsconsume -k -o custom Example.wsdl
....

Generate source and class files in the org.foo package:

....
wsconsume -k -p org.foo Example.wsdl
....

Generate source and class files using multiple binding files:

....
wsconsume -k -b wsdl-binding.xml -b schema1-binding.xml -b schema2-binding.xml
....

==== Maven Plugin

The wsconsume tools is included in the
*org.jboss.ws.plugins:jaxws-tools-* *maven-* *plugin* plugin. The plugin
has two goals for running the tool, _wsconsume_ and _wsconsume-test_ ,
which basically do the same during different maven build phases (the
former triggers the source generation during _generate-sources_ phase,
the latter during the _generate-test-sources_ one).

The _wsconsume_ plugin has the following parameters:

[cols=",,",options="header",]
|===
|Attribute |Description |Default
|bindingFiles |JAXWS or JAXB binding file |true

|classpathElements |Each classpathElement provides a library file to be
added to classpath |$\{project.compileClasspathElements} or
$\{project.testClasspathElements}

|catalog |Oasis XML Catalog file for entity resolution |none

|targetPackage |The target Java package for generated code. |generated

|bindingFiles |One or more JAX-WS or JAXB binding file |none

|wsdlLocation |Value to use for @WebServiceClient.wsdlLocation
|generated

|outputDirectory |The output directory for generated artifacts.
|$\{project.build.outputDirectory} or
$\{project.build.testOutputDirectory}

|sourceDirectory |The output directory for Java source.
|$\{project.build.directory}/generated-sources/wsconsume

|verbose |Enables more informational output about command progress.
|false

|wsdls |The WSDL files or URLs to consume |n/a

|extension |Enable SOAP 1.2 binding extension. |false

|encoding |The charset encoding to use for generated sources.
|$\{project.build.sourceEncoding}

|argLine |An optional additional argline to be used when running in fork
mode; can be used to set endorse dir, enable debugging, etc. *_Example_*
`<argLine>-Djava.endorsed.dirs=...</argLine>` |none

|fork |Whether or not to run the generation task in a separate VM.
|false

|===

===== Examples

_wsconsume_ can be used in your own project build by simply referencing the
_jaxws-tools-_ _maven-_ _plugin_ in the configured plugins in the projects
pom.xml file.

The following example makes the plugin consume the test.wsdl file and
generate SEI and wrappers' java sources. The generated sources are then
compiled together with the other project classes.

....
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Final</version>
      <configuration>
        <wsdls>
          <wsdl>${basedir}/test.wsdl</wsdl>
        </wsdls>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsconsume</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
....

You can also specify multiple wsdl files, as well as force the target
package, enable SOAP 1.2 binding and turn the tool's verbose mode on:

....
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Final</version>
      <configuration>
       <wsdls>
        <wsdl>${basedir}/test.wsdl</wsdl>
        <wsdl>${basedir}/test2.wsdl</wsdl>
       </wsdls>
       <targetPackage>foo.bar</targetPackage>
       <extension>true</extension>
       <verbose>true</verbose>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsconsume</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
....

If the wsconsume invocation is required for consuming a wsdl to
be used in the testsuite only, you might want to use the
_wsconsume-test_ goal as follows:

....
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Final</version>
      <configuration>
        <wsdls>
          <wsdl>${basedir}/test.wsdl</wsdl>
        </wsdls>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsconsume-test</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
....

===== Plugin stack dependency
The plugin itself does not have an explicit
dependency on a JBossWS stack, as it's meant for use with
implementations of any supported version of the _JBossWS SPI_ . The
user is expected to set a dependency in his own `pom.xml` to the desired
_JBossWS_ stack version. The plugin will rely on that in using the
proper tooling.

....
<dependencies>
  <dependency>
    <groupId>org.jboss.ws.cxf</groupId>
    <artifactId>jbossws-cxf-client</artifactId>
    <version>5.1.0.Final</version>
  </dependency>
</dependencies>
....

[TIP]
====
Be careful when using this plugin with the Maven War Plugin as that
includes project dependencies into the generated application war
archive. To avoid that situation set `<scope>provided</scope>` for the
_JBossWS_ stack dependency.
====

[IMPORTANT]
====
Up to version 1.1.2.Final, the _artifactId_ of the plugin was
*maven-jaxws-tools-plugin* .
====

==== Ant Task

The _wsconsume_ Ant task ( _org.jboss.ws.tools.ant.WSConsumeTask_ ) has
the following attributes:

[cols=",,",options="header",]
|===
|Attribute |Description |Default
|fork |Whether or not to run the generation task in a separate VM. |true

|keep |Keep/Enable Java source code generation. |false

|catalog |Oasis XML Catalog file for entity resolution |none

|package |The target Java package for generated code. |generated

|binding |A JAX-WS or JAXB binding file |none

|wsdlLocation |Value to use for @WebServiceClient.wsdlLocation
|generated

|encoding |The charset encoding to use for generated sources |n/a

|destdir |The output directory for generated artifacts. |"output"

|sourcedestdir |The output directory for Java source. |value of destdir


|verbose |Enables more informational output about command progress.
|false

|wsdl |The WSDL file or URL |n/a

|extension |Enable SOAP 1.2 binding extension. |false

|additionalHeaders |Enables processing of implicit SOAP headers |false
|===

[NOTE]
====
Users also need to put streamBuffer.jar and stax-ex.jar in the classpath
of the ant task to generate the appropriate artefacts.
====

[NOTE]
====
The wsdlLocation is used when creating the Service to be used by clients
and will be added to the @WebServiceClient annotation.  For an endpoint
implementation based on the generated service endpoint interface, you
will need to manually add the wsdlLocation to the @WebService annotation
on your web service implementation and not the service endpoint
interface.
====

Also, the following nested elements are supported:

[cols=",,",options="header",]
|===
|Element |Description |Default
|binding |A JAXWS or JAXB binding file |none
|jvmarg |Allows setting of custom jvm arguments | 
|===

===== Examples

The following command generates JAX-WS sources and classes in a separate
JVM with separate directories, a custom wsdl location attribute, and a list of binding files from foo.wsdl:

....
<wsconsume
  fork="true"
  verbose="true"
  destdir="output"
  sourcedestdir="gen-src"
  keep="true"
  wsdllocation="handEdited.wsdl"
  wsdl="foo.wsdl">
  <binding dir="binding-files" includes="*.xml" excludes="bad.xml"/>
</wsconsume>
....

=== wsprovide

_wsprovide_ is a command line tool, Maven plugin and Ant task that
generates portable JAX-WS artifacts for a service endpoint
implementation. It also has the option to "provide" the abstract
contract for offline usage.

==== Command Line Tool

The command line tool has the following usage:

....
usage: wsprovide [options] <endpoint class name>
options:
  -h, --help                  Show this help message
  -k, --keep                  Keep/Generate Java source
  -w, --wsdl                  Enable WSDL file generation
  -a, --address               The generated port soap:address in wsdl
  -c. --classpath=<path>      The classpath that contains the endpoint
  -o, --output=<directory>    The directory to put generated artifacts
  -r, --resource=<directory>  The directory to put resource artifacts
  -s, --source=<directory>    The directory to put Java source
  -e, --extension             Enable SOAP 1.2 binding extension
  -q, --quiet                 Be somewhat more quiet
  -t, --show-traces           Show full exception stack traces
....

===== Examples

Generates wrapper classes for portable artifacts in the "generated"
directory:

....
wsprovide -o generated foo.Endpoint
....

Generates wrapper classes and WSDL in the "generated" directory

....
wsprovide -o generated -w foo.Endpoint
....

Using an endpoint that references other jars

....
wsprovide -o generated -c application1.jar:application2.jar foo.Endpoint
....

==== Maven Plugin

The _wsprovide_ tools is included in the
*org.jboss.ws.plugins:jaxws-tools-* *maven-* *plugin* plugin. The plugin
has two goals for running the tool, _wsprovide_ and _wsprovide-test_ ,
which basically do the same during different Maven build phases (the
former triggers the sources generation during _process-classes_ phase,
the latter during the _process-test-classes_ one).

The _wsprovide_ plugin has the following parameters:

[cols=",,",options="header",]
|===
|Attribute |Description |Default
|testClasspathElements |Each classpathElement provides a library file to
be added to classpath |$\{project.compileClasspathElements} or
$\{project.testClasspathElements}

|outputDirectory |The output directory for generated artifacts.
|$\{project.build.outputDirectory} or
$\{project.build.testOutputDirectory}

|resourceDirectory |The output directory for resource artifacts
(WSDL/XSD). |$\{project.build.directory}/wsprovide/resources

|sourceDirectory |The output directory for Java source.
|$\{project.build.directory}/wsprovide/java

|extension |Enable SOAP 1.2 binding extension. |false

|generateWsdl |Whether or not to generate WSDL. |false

|verbose |Enables more informational output about command progress.
|false

|portSoapAddress |The generated port soap:address in the WSDL | 

|*endpointClass* |*Service Endpoint Implementation.* | 
|===

===== Examples

_wsprovide_ can be used in your own project build by simply referencing the
_jaxws-tools-_ _maven-_ _plugin_ in the configured plugins in the
_pom.xml_ file.

The following example makes the plugin provide the wsdl file and
artifact sources for the specified endpoint class:

....
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Final</version>
      <configuration>
        <verbose>true</verbose>
        <endpointClass>org.jboss.test.ws.plugins.tools.wsprovide.TestEndpoint</endpointClass>
        <generateWsdl>true</generateWsdl>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsprovide</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
....

The following example does the same, but is meant for use in your own
testsuite:

....
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Final</version>
      <configuration>
        <verbose>true</verbose>
        <endpointClass>org.jboss.test.ws.plugins.tools.wsprovide.TestEndpoint2</endpointClass>
        <generateWsdl>true</generateWsdl>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsprovide-test</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
....

===== Plugin stack dependency
The plugin itself does not have an explicit
dependency on a JBossWS stack, as it's meant for uses with
implementations of any supported version of the _JBossWS SPI_ . The
user is expected to set a dependency in his own `pom.xml` to the desired
_JBossWS_ stack version. The plugin will rely on the that for using the
proper tooling.

....
<dependencies>
  <dependency>
    <groupId>org.jboss.ws.cxf</groupId>
    <artifactId>jbossws-cxf-client</artifactId>
    <version>5.1.0.Final</version>
  </dependency>
</dependencies>
....

[TIP]
====
Be careful when using this plugin with the Maven War Plugin as that
includes project dependencies in the generated application war
archive. Set `<scope>provided</scope>` on the
_JBossWS_ stack dependency to avoid that.
====

[IMPORTANT]
====
Up to version 1.1.2.Final, the _artifactId_ of the plugin was
*maven-jaxws-tools-plugin* .
====

==== Ant Task

The wsprovide ant task ( _org.jboss.ws.tools.ant.WSProvideTask_ ) has
the following attributes:

[cols=",,",options="header",]
|===
|Attribute |Description |Default
|fork |Whether or not to run the generation task in a separate VM. |true

|keep |Keep/Enable Java source code generation. |false

|destdir |The output directory for generated artifacts. |"output"

|resourcedestdir |The output directory for resource artifacts
(WSDL/XSD). |value of destdir

|sourcedestdir |The output directory for Java source. |value of destdir

|extension |Enable SOAP 1.2 binding extension. |false

|genwsdl |Whether or not to generate WSDL. |false

|address |The generated port soap:address in wsdl. | 

|verbose |Enables more informational output about command progress.
|false

|*sei* |*Service Endpoint Implementation.* | 

|classpath |The classpath that contains the service endpoint
implementation. |"."
|===

===== Examples

The following command executes wsprovide in verbose mode with separate output directories for source, resources, and classes:

....
<target name="test-wsproivde" depends="init">
  <taskdef name="wsprovide" classname="org.jboss.ws.tools.ant.WSProvideTask">
    <classpath refid="core.classpath"/>
  </taskdef>
  <wsprovide
    fork="false"
    keep="true"
    destdir="out"
    resourcedestdir="out-resource"
    sourcedestdir="out-source"
    genwsdl="true"
    verbose="true"
    sei="org.jboss.test.ws.jaxws.jsr181.soapbinding.DocWrappedServiceImpl">
    <classpath>
      <pathelement path="${tests.output.dir}/classes"/>
    </classpath>
  </wsprovide>
</target>
....
