This article shows the changes needed to the Maven version of the WSDL-first DoubleIt tutorial to convert it to a start-from-Java process. Follow along with the original tutorial except for these changes:
In Step #3, the service-war/pom.xml file will need to be changed to now use the web service stack's Java-to-WSDL utility. Also, the Assembly plugin's jaxws-jar.xml file will need modification for the different classes used by the client. Replace these files with the following:
DoubleIt/service-war/pom.xml:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.mycompany.webservice</groupId> <artifactId>WebServiceSample</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>service-war</artifactId> <name>Web Application for WebServiceSample</name> <packaging>war</packaging> <url>http://maven.apache.org</url> <build> <plugins> <plugin><!--use mvn tomcat:deploy or mvn tomcat:undeploy --> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.0-beta-1</version> <configuration> <server>myTomcat</server> <path>/${project.build.finalName}</path> <!--url>Place URL if different from http://localhost:8080/manager</url --> </configuration> </plugin> <!-- Below plugin provides a separate JAR for the JAX-WS artifacts (i.e., the Java classes created by running wsdl2java or wsimport), as this JAR will also be used by the SOAP client. --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-1</version> <configuration> <descriptors> <descriptor>src/assembly/jaxws-jar.xml</descriptor> </descriptors> <appendAssemblyId>true</appendAssemblyId> <attach>true</attach> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> <!-- Name of the generated WAR file --> <finalName>doubleit</finalName> </build> <profiles> <profile> <id>CXF</id> <!-- To use Metro by default, move activation element to its profile below --> <build> <plugins> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-java2ws-plugin</artifactId> <version>${cxf.version}</version> <executions> <execution> <id>process-classes</id> <phase>process-classes</phase> <configuration> <className>service.DoubleItPortTypeImpl </className> <genWsdl>true</genWsdl> <verbose>true</verbose> </configuration> <goals> <goal>java2ws</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>Metro</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxws-maven-plugin</artifactId> <executions> <execution> <goals> <goal>wsgen</goal> </goals> <configuration> <sei>service.DoubleItPortTypeImpl</sei> <genWsdl>true</genWsdl> <keep>true</keep> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
DoubleIt/service-war/src/assembly/jaxws-jar.xml:<assembly> <id>jaxws</id> <formats> <format>jar</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <files> <file> <source>target/classes/service/DoubleItPortType.class</source> <outputDirectory>/service</outputDirectory> </file> </files> </assembly>
Skip Step #4, as there is no WSDL for Java-first development.
For Step #5, use the following web service interface and implementation class instead:
DoubleItPortType.java:
package service; import javax.jws.WebService; import javax.jws.WebMethod; @WebService public interface DoubleItPortType { public int doubleIt(int numberToDouble); }DoubleItPortTypeImpl.java:
package service; import javax.jws.WebService; @WebService(targetNamespace = "http://www.example.org/contract/DoubleIt", endpointInterface = "service.DoubleItPortType", serviceName = "DoubleItService", portName = "DoubleItPort") public class DoubleItPortTypeImpl implements DoubleItPortType { public int doubleIt(int numberToDouble) { return numberToDouble * 2; } }
For Step #7, remove Metro's wsdl
or CXF's wsdlLocation
attribute from the configuration file.
For Step #9, use the following client class instead:
package client; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.soap.SOAPBinding; import java.net.URL; import service.DoubleItPortType; public class WSClient { private static final QName SERVICE_NAME = new QName("http://www.example.org/contract/DoubleIt", "DoubleItService"); private static final QName PORT_NAME = new QName("http://www.example.org/contract/DoubleIt", "DoubleItPort"); public static void main (String[] args) throws Exception { String endpointAddress = "http://localhost:8080/doubleit/services/doubleit"; Service service = Service.create(new URL(endpointAddress +"?wsdl"), SERVICE_NAME); DoubleItPortType port = service.getPort(DoubleItPortType.class); doubleIt(port, 10); doubleIt(port, 0); doubleIt(port, -10); } public static void doubleIt(DoubleItPortType port, int numToDouble) { int resp = port.doubleIt(numToDouble); System.out.println("The number " + numToDouble + " doubled is " + resp); } }
Additional Resources
- Documentation on Maven java-first plugins: (CXF) (Metro). Also see this Metro/Maven Enterprise Tech Tip.
- Additional Java-first development information (primarily CXF-related) is available in Chapter 1 (Bottom Up Services Development) of FUSE Source's Developing Applications Using JAX-WS guide.
- See my blog index for more web service related articles.