Home » Enterprise Java » jws » JAX-WS Dependencies Example

About Gilbert Lopez

Gilbert Lopez
Gilbert Lopez is an application developer and systems integration developer with experience building business solutions for large and medium-sized companies. He has worked on many Java EE projects. His roles have included lead developer, systems analyst, business analyst and consultant. Gilbert graduated from from California State University in Los Angeles with a Bachelor of Science degree in Business.

JAX-WS Dependencies Example

In this post, we present a JAX-WS web services example using Maven dependency configuration.

1. Introduction

Java API for XML Web Services (JAX-WS) uses XML files for configuring services and for exchanging data. JAX-WS is generally used for SOAP-based messaging. It relies on Java API for XML Binding (JAXB) to marshal and unmarshal Java objects to XML documents and the reverse.

You have choices when developing and deploying JAX-WS web services.  You can take a minimalist approach and simply use the JAX-WS runtime libraries that are part of the reference implementation provided by the JAVA EE platform.  For robust applications, you probably want to use a web services stack such as Metro or Apache CXF.

In this example, we will show the unique Maven dependencies required for developing and deploying JAX-WS web services with the JAX-WS runtime libraries from the reference implementation, the Metro web services stack, and the Apache CXF web services stack, respectively.

1.1 Tools Used in this Example

  • Eclipse Oxygen
  • Maven 3.2.1
  • Tomcat 9.0
  • SoapUI 5.3.0

To set up a Tomcat server for use in Eclipse, see Tomcat in Eclipse: 6 popular how to questions.

2. JAX-WS Dependencies Example

In this example, we’ll develop a “Get Quote” web service that returns random quotes.  Let’s begin by creating a simple Maven project.

2.1 Create the Maven Project

  1. Select New -> Other… Maven Project. Click Next.
  2. Select  the “Create a simple project (skip archetype selection)” checkbox and click Next.
JAX-WS Dependencies - Creating a new Maven Project
Creating a new Maven Project

Enter a Group Id and Artifact Id, select “war” for Packaging and click Finish.

JAX-WS Dependencies - Group and Artifact ID
Group and Artifact ID

At this point, you will see the following problem: “web.xml is missing and<failOnMissingWebXml> is set to true”, since we elected to package the application as a war file.  To fix this, right-click on the project and select Java EE Tools -> Generate Deployment Descriptor Stub.

Open the pom.xml and add the following Maven plugins just above the closing </project> tag:

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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.examples</groupId>
	<artifactId>JAXWS-Dependencies</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>JAXWS-Dependencies</name>
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.6.1</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>3.0.0</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
						<warName>JaxWsDepencencies</warName>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
</project>

The Maven compiler plugin will compile the source code and the Maven war plugin will package the application in a deployable WAR file.

Save the changes and select Maven->Update Project… from the project context menu.

2.2 Create the Web Service

First we’ll create a Java interface for our web service.


RandomQuoteService.java

package com.javacodegeeks.examples.jaxws;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style=Style.DOCUMENT)
public interface RandomQuoteService {
	
	@WebMethod
	public String getQuote();
}

Next, create the implementation for the interface.

RandomQuoteServiceImpl.java

package com.javacodegeeks.examples.jaxws;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.annotation.PostConstruct;
import javax.jws.WebService;

@WebService(endpointInterface = "com.javacodegeeks.examples.jaxws.RandomQuoteService")
public class RandomQuoteServiceImpl implements RandomQuoteService {
	
	private static List<String> quoteList;
	
	@PostConstruct
	private void createList() {
		quoteList = new ArrayList<String>();
		quoteList.add("You cannot escape the responsibility of tomorrow by evading it today");
		quoteList.add("I think therefore I am");
		quoteList.add("It was the best of times, it was the worst of times...");
		quoteList.add("Don't cry because it's over, smile because it happened");
		quoteList.add("Be yourself; everyone else is already taken");
		quoteList.add("So many books, so little time");
	}

	@Override
	public String getQuote() {
		Random random = new Random();
		int index = random.nextInt(quoteList.size());
		return (String) quoteList.get(index);
	}
}

2.3 Update the Deployment Descriptor

Open the web.xml file and add the following elements:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
	<display-name>JAXWS-Dependencies</display-name>

	<listener>
		<listener-class>
			com.sun.xml.ws.transport.http.servlet.WSServletContextListener
		</listener-class>
	</listener>

	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
</web-app>

When the servlet container starts the web application, WSServletContextListener will set up HTTP adapters for the endpoints specified in the sun-jaxws.xml file

2.4 Create the sun-jaxws.xml Configuration File

Create the sun-jaxws.xml file in the WEB-INF directory with the following content:

sun-jaxws.xml

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
	version="2.0">
	<endpoint name="RandomQuoteServiceImpl"
		implementation="com.javacodegeeks.examples.ws.RandomQuoteServiceImpl"
		url-pattern="/getQuote" />
</endpoints>

This file is used to configure the endpoint, its implementation class, and URL pattern to use for its invocation..

If you try to run the web service on the Tomcat server at this point you will see the following exception: 

java.lang.ClassNotFoundException: com.sun.xml.ws.transport.http.servlet.WSServletContextListener

That is because we need to add the proper Maven dependencies in order to invoke the web service.  Let’s add the JAX-WS runtime dependency.

2.5 Use the JAX-WS RT Maven Dependencies

Open pom.xml and add the following dependency:

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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.examples</groupId>
	<artifactId>JAXWS-Dependencies</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>JAXWS-Dependencies</name>
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.6.1</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>3.0.0</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
						<warName>JAXWS-rt</warName>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	<dependencies>
        <!-- jax-ws maven dependency -->
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-rt</artifactId>
            <version>2.2.8</version>
        </dependency>
	</dependencies>
</project>	

Save the changes and select Maven->Update Project… from the project context menu.

While in the Maven POM editor, select the “Dependency Hierarchy” tab.  

JAX-WS Dependencies - Dependency Hierarchy
Dependency Hierarchy

You can view the transitive dependencies for jaxws-rt:2.2.8 (in the left side pane under Dependency Hierarchy) by double-clicking on its icon.

jaxws-rt/pom.xml
    <parent>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>bundles</artifactId>
        <version>2.2.8</version>
    </parent>

    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.2.8</version>
    <packaging>pom</packaging>
    <name>JAX-WS RI Runtime Bundle</name>

    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.xml.ws</groupId>
            <artifactId>jaxws-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.xml.soap</groupId>
            <artifactId>javax.xml.soap-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.jws</groupId>
            <artifactId>jsr181-api</artifactId>
        </dependency>
        <!-- Provided dependencies -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>policy</artifactId>
        </dependency>
        <dependency>
            <groupId>org.glassfish.gmbal</groupId>
            <artifactId>gmbal-api-only</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jvnet.staxex</groupId>
            <artifactId>stax-ex</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.stream.buffer</groupId>
            <artifactId>streambuffer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jvnet.mimepull</groupId>
            <artifactId>mimepull</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.fastinfoset</groupId>
            <artifactId>FastInfoset</artifactId>
        </dependency>
        <dependency>
            <groupId>org.glassfish.ha</groupId>
            <artifactId>ha-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.messaging.saaj</groupId>
            <artifactId>saaj-impl</artifactId>
        </dependency>

        <dependency>
            <artifactId>woodstox-core-asl</artifactId>
            <groupId>org.codehaus.woodstox</groupId>
        </dependency>
        <dependency>
            <groupId>org.codehaus.woodstox</groupId>
            <artifactId>stax2-api</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.org.apache.xml.internal</groupId>
            <artifactId>resolver</artifactId>
        </dependency>
        
        <!-- Test dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Of these dependencies, the bare minimum you need for JAX-WS web services development and deployment are:

  • gmbal-api-only.jar
  • jaxb-impl.jar
  • jaxws-api.jar
  • jaxws-rt.jar
  • policy.jar
  • stax-ex.jar
  • streambuffer.jar

Right-click the project and select Run As -> Run on Server. Select the Tomcat server and click “Finish”. When the application starts, you will see a 404 error in the browser, since we do not have a welcome page specified in web.xml. Enter /getQuote at the end of the URL and hit Enter. You will see a link to the WSDL file on the “Available SOAP services” page.  Copy the link for WSDL file.

JAX-WS Dependencies - The Get Quote Web Service
The Get Quote Web Service

Now start SoapUI and create a new SOAP project by clicking the SOAP button on the top bar.  Enter a name for your project and paste the WSDL URL link you copied in the Initial WSDL text box, for example, http://localhost:8080/JaxWsDepencencies/getQuote?wsdl. Make sure “Create Requests” is selected and click OK.

JAX-WS Dependencies - New SOAP Project
New SOAP Project

Expand RandomQuoteServiceImplPortBinding and getQuote in the Navigator and double-click Request 1. Click the green submit arrow on the upper-left corner of the Request window. You should see a successful response.

JAX-WS Dependencies - Successful Response
Successful Response


2.6 Use the Metro Maven Dependencies

Open pom.xml and replace the existing dependency with the following dependencies and save the changes:

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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.examples</groupId>
	<artifactId>JAXWS-Dependencies</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>JAXWS-Dependencies</name>
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.6.1</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>3.0.0</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
						<warName>JAXWS-Metro</warName>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	<dependencies>
		<!-- jax-ws metro maven dependencies -->
		<dependency>
			<groupId>org.glassfish.metro</groupId>
			<artifactId>webservices-rt</artifactId>
			<version>2.4.2</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.metro</groupId>
			<artifactId>webservices-api</artifactId>
			<version>2.4.2</version>
			<scope>provided</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
		<dependency>
			<groupId>com.sun.xml.bind</groupId>
			<artifactId>jaxb-core</artifactId>
			<version>2.3.0</version>
		</dependency>
	</dependencies>	
</project>

While in the Maven POM editor, select the “Dependency Hierarchy” tab. 

JAX-WS Dependencies - Metro Dependency Hierarchy
Metro Dependency Hierarchy

The right pane of the editor shows the resolved dependencies of the project.  So why are they different from the JAX-WS runtime resolved dependencies?  In actuality, many of the same packages are in the Metro jar files, as can be seen in the project navigator.  Also, the Metro stack includes additional features that are not in the reference implementation.  (Note that we also added the jaxb-core dependency as these libraries are not part of the Metro dependencies.)

JAX-WS Dependencies - Project Explorer
Project Explorer

You can restart the server and test using SoapUI.

2.7 Use the Apache CXF Maven Dependencies

Open pom.xml and replace the existing dependencies with the following dependencies and save the changes:

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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.examples</groupId>
	<artifactId>JAXWS-Dependencies</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>JAXWS-Dependencies</name>
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.6.1</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>3.0.0</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
						<warName>JaxWsDepencencies</warName>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	<dependencies>
		<!-- jax-ws CXF maven dependencies -->
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>3.2.7</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>3.2.7</version>
		</dependency>
		<!--  Spring framework dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>5.0.7.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.0.7.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>5.0.7.RELEASE</version>
		</dependency>
	</dependencies>
</project>

While it is possible to use CXF without Spring (by extending CXFNonSpringServlet) we are showing the more typical configuration that includes the Spring dependencies.

While in the Maven POM editor, select the “Dependency Hierarchy” tab.   Again, many of the required packages are in the CXF jar files.

Open the web.xml file.  Remove the <listener> element and add the following elements :

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">
	<display-name>JAXWS-Dependencies</display-name>
	<servlet>
		<servlet-name>cxfservlet</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>cxfservlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
</web-app>

We map CXFServlet to handle all requests coming through “/*”.

Next, create a cxf-servlet.xml file in the WEB-INF directory with the following content.

cxf-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:cxf="http://cxf.apache.org/core"
	xmlns:soap="http://cxf.apache.org/bindings/soap"
	xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<jaxws:server id="quoteService" serviceClass="com.javacodegeeks.examples.jaxws.RandomQuoteService" address="/getQuote">
		<jaxws:serviceBean>
			<bean class="com.javacodegeeks.examples.jaxws.RandomQuoteServiceImpl" />
		</jaxws:serviceBean>
	</jaxws:server>

</beans>

Apache CXF with Spring configuration uses the cxf-servlet.xml file to configure the endpoint, implementation, and URL of the web service.

You can restart the server and test using SoapUI.

3. Summary

In this example, we demonstrated how to add the required Maven dependencies to a JAX-WS web service project.

4. Download the Source Code

This was a JAX-WS Dependencies Example.

Download
You can download the full source code of this example here: JAX-WS Dependencies Example
(+3 rating, 3 votes)
Start the discussion Views Tweet it!

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area

 

Leave a Reply

avatar
  Subscribe  
Notify of