Using JAX-WS with Maven
(Copied from: http://java.sun.com/mailers/techtips/enterprise/2008/TechTips_Jan08.html)
Welcome to the Enterprise Java Technologies Tech Tips for January 18, 2008. Here you'll get tips on using enterprise Java technologies and APIs, such as those in Java Platform, Enterprise Edition (Java EE).
You can now read the Enterprise Java Technologies Tech Tips online as a web log.
This issue covers using JAX-WS with Maven.
This tip was developed using an open source reference implementation of Java EE 5 called GlassFish v2 and the open source NetBeans IDE 6.0. You can download GlassFish v2 from the GlassFish Community Downloads page. You can download NetBeans IDE 6.0 from the NetBeans page.
Any use of this code and/or information below is subject to the license terms.
Using JAX-WS with Maven
Java API for XML-Based Web Services, JAX-WS, is a fundamental technology for developing SOAP-based and RESTful Java Web services, and is a key part of project Metro, the web services technology stack in GlassFish. In addition to providing a high performance runtime, JAX-WS offers the wsimport
and wsgen
tools for creating web services and web service clients. The wsimport
tool takes as input a Web Services Definition Language (WSDL) file and generates JAX-WS portable artifacts such as a service endpoint interface (SEI). The wsgen
tool reads a web service endpoint class and generates all the required artifacts for web service deployment and invocation.
You can access wsimport
and wsgen
through the GlassFish command line interface (CLI). You can also access the tools through Ant
tasks or through a Maven plugin. In this tip, you'll learn how to use the JAX-WS Maven plugin to develop web services.
Maven
Maven is a highly configurable framework that you can use to manage various aspects of a project's life cycle, from building and deploying an application to document generation and project management. Maven, like Ant
, is a very popular development tool due to its standardized project layout and dependency management mechanism. By following standard conventions for project layout and using common defaults for building lifecycle phases such as compilation and packaging, you can create projects that are easy to understand and manage. Maven uses Project Object Model (POM) to describe project-related information. Unlike Ant
, in which you need to define how projects are built and deployed, all Maven projects implicitly share a set of plugins for doing well-defined tasks such as building and packaging. These plugins can also be configured to change default behavior and change build order as needed.
For more information about Maven, see Welcome to Maven and Building Web Applications with Maven 2.
JAX-WS Maven Plugin
As mentioned previously, JAX-WS provides two tools for web services development: wsimport
and wsgen
. The JAX-WS Maven plugin provides Maven adapters for these tools. The plugin offers the tools' functionality as two goals jaxws:wsimport
and jaxws:wsgen
. A goal is roughly the Maven equivalent of an Ant
task. For each of the two goals, the plugin accepts all the configuration options that can be passed to corresponding CLI or Ant
tasks.
For the jaxws:wsimport
goal, the plugin reads a WSDL file and generates Java classes required for web service creation, deployment, and invocation. The jaxws:wsimport
goal is automatically executed within the life cycle phase generate-sources. By default, the plugin looks for WSDL files in the ${basedir}/src/wsdl
directory. You can optionally specify the location of the WSDL files by configuring the wsdlLocation
parameter. You can see descriptions of all the jaxws:wsimport
configuration parameters on the JAX-WS commons page for jaxws:wsimport
.
For the jaxws:wsgen
goal, the plugin reads an SEI class and generates all of the portable artifacts for the JAX-WS web service. The jaxws:wsgen
goal is automatically executed within the life cycle phase process-classes. The plugin requires that you set the sei
parameter for the jaxws:wsgen
goal, which specifies the service endpoint implementation class name. The plugin can optionally generate a service description, that is a WSDL file, from the service endpoint implementation class if you specify the genWsdl
parameter. However, the genWsdl
parameter is optional -- the JAX-WS runtime can dynamically generate the WSDL after deployment. You can see descriptions of all the jaxws:wsgen
parameters on the JAX-WS commons page for jaxws:wsgen
.
The jaxws:wsimport
and jaxws:gen
goals are executed implicitly when the corresponding life cycle phase is run. Optionally, the plugin can be explicitly run by specifying a goal such as jaxws-maven-plugin:wsimport
. You can get more information about the Maven build life cycle phases and execution in Introduction to the Build Lifecycle.
Why Use the JAX-WS Maven Plugin Instead of Ant
?
The advantage of using the JAX-WS Maven plugin instead of Ant
tasks is that you don't have to get the JAX-WS dependencies, set up the classpath, and configure and invoke the tool tasks for compilation and packaging -- steps required by the Ant
tasks. Maven automatically downloads all dependencies, makes them available to your application, and plugs them into the build life cycle phase. You might however need to do some tweaking of the configuration to make the plugins behave in a preferred way.
For more information about the JAX-WS Maven plugin as well as other JAX-WS tools, see the Metro Tools page.
JAX-WS Maven Sample
Now that you've learned some of the basics of the JAX-WS Maven plugin, let's look at a sample application that uses the plugin to create a web service and web service client. The NetBeans IDE supports Maven 2 project management (Maven 2 is the current version of Maven) through a plugin. You can use the plugin within the IDE to create Maven-based projects, execute Maven commands by associating IDE actions to Maven goals, browse a repository, add dependencies, and do hot deployment of web applications with a few mouse clicks.
You can also perform some of these tasks manually by running Maven and editing the configuration in the POM file. However, the NetBeans IDE offers an easier, more automated way to generate and configure POMs. Because of this the sample in this tip uses NetBeans IDE 6.0.
A package that contains the code for the sample application accompanies the tip. As you build the sample application using the instructions below, you can compare the files that you create to those in the package.
Initial Setup
Before you install and run the sample, you need to do some initial setup as follows:
- If you haven't already done so, download and install the following:
- NetBeans IDE 6.0
- GlassFish V2.
GlassFish v2 is also available as part of the NetBeans IDE 6.0 Web and Java EE bundle.
Also, to run the sample with JDK 6 prior to the JDK 6 Update 4 release, you need use the endorsed override mechanism by copying thejaxb-api.jar
andjaxws-api.jar
files to<java-home>/lib/endorsed
, where<java-home>
refers to the directory in which the runtime software is installed -- this is the top-level directory of the Java SE Runtime Environment or thejre
directory in the JDK. If you run the sample with JDK 6 Update 4 or later, you do not need to use the override mechanism. - If you downloaded GlassFish v2 separately, register it in NetBeans as follows:
- Right-click on the Servers node in the Services window.
- Select Add Server.
- Leave the Server as Sun Java System Application Server.
- Click the Next button.
- Click the Browse button and browse to the location that you installed GlassFish V2.
- Click the Choose button.
- Click the Next button.
- Set the Admin Password to the default, adminadmin, unless you chose a different password for GlassFish v2.
- Click the Finish button.
- Install the Mevenide2-Netbeans plugin, which provides support in NetBeans for Maven 2 projects, as follows:
- Select Plugins from the Tools menu.
- Select the Available plugins tab in the Plugins window.
- Select the Maven plugin.
- Click the Install button.
Creating the Project and Subprojects
In this sample, you create a main project, that is, a parent project, named jaxws-maven-sample
. The parent project has two subprojects: HelloService
, for the web service, and HelloClient
, for the web service client. Here is what the project structure looks like:
jaxws-maven-sample (POM Project)
helloservice (WAR project)
helloclient (JAR Project)
To reduce redundancy, the parent project POM holds configuration parameters that are in common between HelloService
and HelloClient
. To create the project and subprojects, do the following:
- Create the parent (POM project),
jaxws-maven-sample
.- Select New Project from the File menu.
- Choose the Maven category then the Maven project.
- Click the Next button.
- Select the Maven Quickstart Project archetype (the default).
- On the next screen specify the following project settings, also known as Maven project coordinates:
- ProjectName:jaxws-maven-sample
- ProjectLocation: Specify a directory to contain the project, for example,Users/ramapulavarthi
.
- Version: 1.0-SNAPSHOT
- GroupId:com.example.maven.jaxws
- Package:com.example.maven.jaxws
- Click the Finish button to create the project.
You should now see the project in NetBeans Projects window. - Change the project properties from
jar
topom
.- Right-click the
jaxws-maven-sample
in the Projects window. - Select the Properties option from the menu.
- In the General category, change the Packaging value from
jar
topom
. - Click the OK button. Notice that the entry in the Projects window now shows
jaxws-maven-sample (pom)
.
- Right-click the
- Remove unwanted dependencies and files created by default. Because this is a POM project, it will have submodules instead of sources/tests. So you need to remove sources from the project. Also, there are no unit tests in this project so you need to remove any JUnit dependencies.
- Click the Files tab (next to Projects tab).
- In the Files window, right-click the
src
directory belowjaxws-maven-sample
and choose Delete. - In the Projects window, expand the
TestLibraries
node ofjaxws-maven-sample
, right-click on thejunit-3.8.1.jar
, and select Remove Dependency.
- Change the source to Java 5. You need Java 5 to create web services. However, the default is Java 1.4.
- Right-click the
jaxws-maven-sample
in the Projects window. - Select the Properties option from the menu.
- In the Sources category, change the Source/Binary Format value from 1.4 to 1.5.
- Click the OK button.
If you examine thepom.xml
file in the Project Files belowjaxws-maven-sample
, you'll notice the configuration source and target values are changed to 1.5. - Right-click the
- Create the subproject (WAR project),
helloservice
.
Repeat the steps in step 1, "Create the parent (POM project),jaxws-maven-sample
" except instead of selecting the Maven Quickstart Project archetype, select Maven WebApp archetype. Also specify the settings as follows:
- ProjectName:helloservice
- ProjectLocation: Specify the directory that contains thejaxws-maven-sample
project, for example,/Users/ramapulavarthi/jaxws-maven-sample
.
- Version: 1.0-SNAPSHOT
- GroupId:com.example.maven.jaxws
- Package:com.example.maven.jaxws.helloservice
- Click the Finish button to create the project.
You should now seehelloservice
Maven Webapp (war) in the NetBeans Projects window. Notice that thepom.xml
file forhelloservice
has a reference to the parent project,jaxws-maven-sample
, and thepom.xml
file forjaxws-maven-sample
now specifies a module forhelloservice
.
- Click the Finish button to create the project.
- Remove unwanted dependencies and files for
helloservice
.- Click the Files tab (next to Projects tab).
- In the Files window, expand the src directory below
helloservice
Maven webapp, right-click the test directory and choose Delete. - In the Projects window, expand the TestLibraries node of
helloservice
Maven webapp, right-click onjunit-3.8.1.jar
, and select Remove Dependency.
- Create the subproject (JAR project),
helloclient
.
Repeat the steps in step 1, "Create the parent (POM project),jaxws-maven-sample
" except specify the settings as follows:
- ProjectName:helloclient
- ProjectLocation: Specify the directory that contains thejaxws-maven-sample
project, for example,/Users/ramapulavarthi/jaxws-maven-sample
.
- Version: 1.0-SNAPSHOT
- GroupId:com.example.maven.jaxws
- Package:com.example.maven.jaxws.helloclient
- Click the Finish button to create the project.
You should now seehelloclient
(jar) in the NetBeans Projects window. Notice that thepom.xml
file forhelloclient
has a reference to the parent project,jaxws-maven-sample
, and thepom.xml
file forjaxws-maven-sample
now specifies a module forhelloclient
.
- Click the Finish button to create the project.
- Remove unwanted dependencies and files for
helloclient
.- Click the Files tab (next to Projects tab).
- In the Files window, expand the src directory below
helloclient
, right-click the test directory and choose Delete. - In the Projects window, expand the TestLibraries node of
helloclient
, right-click onjunit-3.8.1.jar
, and select Remove Dependency. - Remove
com.example.maven.jaxws.App.java
from the SourcePackages directory.
Add JAX-WS JARs and Repositories
Now that you've created the project and its subprojects, you need to couple them with needed JAX-WS jar files and repositories.
- Add a dependency on
jaxws-rt.jar
.- Expand
jaxws-maven-sample
in the Projects window and right-click on Libraries. - Select "Add Library..." and then enter the following information in the Add Library popup window:
- GroupId:com.sun.xml.ws
- ArtifactId:jaxws-rt
- Version: 2.1.3
- Scope: compile (The scope determines if the artifact is required for compile time or runtime). - Click the OK button.
Notice that thepom.xml
file forjaxws-maven-sample
now has a compile-time dependency onjaxws-rt.jar
and specifies a scope of compile -- thejaxws-rt.jar file
is required to be available for the service and client at runtime.
GlassFish includes JAX-WS, so if you use GlassFish as the deployment container, you can set the Scope value to "provided". In this case, Maven creates a "skinny" WAR file, that is, it doesn't bundle thejax-ws jar
files into the WAR. - Expand
- Add repository information for the JAX-WS JARs. Maven uses this information to get the
jaxws-maven-plugin
and its dependent artifacts.- Expand the Project Files node for
jaxws-maven-sample
and open thepom.xml
file. - Add the following repository information for downloading JAX-WS JARs:
<repositories>
<repository>
<id>maven-repository.dev.java.net</id>
<name>Java.net Repository for Maven 1</name>
<url>http://download.java.net/maven/1/</url>
<layout>legacy</layout>
</repository>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven 2</name>
<url>http://download.java.net/maven/2/</url>
</repository>
</repositories>
This adds information for both the Maven 1 and Maven 2 repositories. (Some of the JAX-WS dependencies exist in both repositories.) - Expand the Project Files node for
- Add plugin repository information for the
jaxws-maven-plugin
to thepom.xml file
, as follows:<pluginRepositories>
<pluginRepository>
<id>maven2-repository.dev.java.net</id>
<url>http://download.java.net/maven/2/</url>
</pluginRepository>
</pluginRepositories>
Because all the configuration specifications are in thepom.xml
file of the parent project, the configuration is shared by the subprojectshelloservice
andhelloclient
.
Build the Web Service
- Add logic to
helloservice
.- Right-click the SourcePackages node in the
helloservice
project. - Select New, then Java Class.
- In the New Java Class window, specify:
- Class Name: Hello
- Package:com.example.maven.jaxws.helloservice
- Click the Finish button.
- Update the source code for the
Hello
class to annotate it as a WebService and include a methodsayHello
. The updated source code should look as follows:package com.example.maven.jaxws.helloservice;
import javax.jws.WebService;
@WebService
public class Hello {
public String sayHello(String param) {
return "Hello " + param;
}
}
- Right-click the SourcePackages node in the
- Run the
jaxws-maven-plugin:wsgen
on the SEI class.- Open the
pom.xml
file ofhelloservice
. - Add the following code under the build section in the
pom.xml
file:<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsgen</goal>
</goals>
<configuration>
<sei>com.example.maven.jaxws.helloservice.Hello
</sei>
<!--for demo purpose only, the webapp does not-->
<!--need the generated wsdl files-->
<genWsdl>true</genWsdl>
<keep>true</keep>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
As mentioned earlier, thejaxws-maven-plugin:wsgen
goal is automatically invoked during the process-classes life cycle phase. The<sei>
element valuecom.example.maven.jaxws.helloservice.Hello
will be passed to the goal as a parameter. - Open the
Deploy the Web Service
- Specify deployment information.
- If you use GlassFish or any other Java EE 5 container to deploy the web service, change the default
web.xml
file to use version "2.5". To do that:
- Expand the Web Pages node in thehelloservice
project.
- Expand the WEB-INF node and select theweb.xml
file.
- Click the XML view button above the source editor window to view the XML contents of the file.
- Replace the contents of theweb.xml
file with the following:<web–app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema–instance"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web–app_2_5.xsd">
<welcome–file–list>
<welcome–file>index.jsp</welcome–file>
</welcome–file–list>
</web–app>
Make sure to remove the <!DOCTYPE> element at the beginning of the file.
- Save the file.
- If you use GlassFish or any other Java EE 5 container to deploy the web service, change the default
- Deploy the artifacts to GlassFish.
- Right-click the
helloservice
project and select Properties. - In the Run category, specify the following:
- Server: GlassFish v2
- Context Path:/helloservice
- Click the OK button.
HelloService?wsdl
in the Relative URL field. If you make these optional specifications, NetBeans will open a browser showing thehelloservice
WSDL after thehelloservice
service is deployed.
In response, thepom.xml
file forhelloservice
is updated to deploy the artifacts to GlassFish. - Right-click the
Run the Service
- Right-Click on
helloservice
and select Run.
NetBeans runs Maven to build the web application and automatically deploys the WAR file to GlassFish. You can see the process in the NetBeans Output window. You can access the WSDL for the service to check if the service is successfully deployed. If you checked the Display Browser on Run checkbox as described in previous step, NetBeans opens a browser showing the WSDL of the deployed web service. If you did not check the Display Browser on Run checkbox, you can display the WSDL for the web service by openinghttp://localhost:8080/helloservice/HelloService?wsdl
in your browser.
Create a Client to Invoke the Web Service
- Run
jaxws-maven-plugin:wsimport
on thehelloservice
WSDL:- Open the
pom.xml
file ofhelloclient
. - Add the following code to the
pom.xml
file:<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlUrls>
<wsdlUrl>
http://localhost:8080/helloservice/HelloService?wsdl
</wsdlUrl>
</wsdlUrls>
<packageName>com.example.maven.jaxws.helloclient
</packageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<bulid>
Thejaxws-maven-plugin:wsimport
goal is run during the life cycle phase generate-sources. As you can see in the above configuration,wsimport
is run on the WSDL located athttp://localhost:8080/helloservice/HelloService?wsdl
to generate Java classes in thecom.example.maven.jaxws.helloclient
package. - Open the
- Build the client.
- Right-click on the
helloclient
project and select build. Maven builds the project, runswsimport
, and generates all the Web Service artifacts that you see in the target folder. (To see the generated files, open then Files window and expandhelloclient/target
). - Expand the Source packages node in the
helloclient
project and right-click oncom.example.maven.jaxws.helloclient
- Select New, then Java class.
- Specify the class name as
HelloClient
. - Click the Finish button.
- Update the
HelloClient
class with the following source code:package com.example.maven.jaxws.helloclient;
public class HelloClient {
public static void main(String[] args) {
HelloService service = new HelloService();
Hello port= service.getHelloPort();
System.out.println(port.sayHello("Duke"));
}
}
- Right-click on the
- Associate the NetBeans IDE action "Run" to build the jar and run
HelloClient
.- Right-click on
helloclient
and select Properties. - Under Run category, enter
com.example.maven.jaxws.helloclient.HelloClient
as theMain
class. - Click the OK button.
- Right-click on
Run the Client
- Right click on
helloclient
and choose Run.
Maven runswsimport
on the WSDL file, creates Java classes, compilesHelloClient
, and runs it. In the NetBeans Output window you should see the following result of the web service invocation:
Hello Duke
Summary
Using Maven you can easily create JAX-WS-based web services. Although this tip showed you how to do that using NetBeans, you can also can create JAX-WS-based web services using Maven manually, that is, without using NetBeans. To do so, use the mvn
CLI and edit the pom files as needed. However, NetBeans makes it easier to use Maven for your projects and saves you from having to worry about configuration syntax.
For more information about using Maven to create JAX-WS-based web services, see the Metro User's Guide.
0 Comments:
Post a Comment
<< Home