How to deploy SOAP Web Services in Jakarta EE applications

This tutorial covers how to build and deploy SOAP based Web services in Jakarta EE applications, also discussing the changes in the Java SE that removed the JAX-WS API from the default Java modules.

First of all a bit of history. The JAX-WS API used to be bundled in JDK until Java 8. JAX-WS was then deprecated in Java 9 and 10 and finally removed in Java 11 as you can read from the release notes:

java.xml.ws (JAX-WS, plus the related technologies SAAJ and Web Services Metadata) - REMOVED

This mean, that if you used to build an application which included, for example, javax.xml.soap, with Java 11 (and nothing else in the classpath) the following error will be returned:

package javax.xml.soap does not exist

There are a couple of simple ways to get around this issue:

Check if the application server supports Jakarta SOAP Web Services

Since Jakarta EE 9, SOAP Web services are marked as optional technology. As you can see from the following picture, technologies in gray are optional, which means that not all vendors might implement this feature.

How to manage SOAP Web Services in Jakarta EE applications

In our case, if we have a look at WildFly 22 application server’s module, the javax.xml.soap modules are bundled in the server modules. For example:

$ grep -r javax.xml.soap.SOAPMessage
Binary file system/layers/base/javax/xml/soap/api/main/jboss-saaj-api_1.4_spec-1.0.2.Final.jar matches

On the other hand, if you want to check against a Jakarta EE 9 compatible application server (as WildFly Preview), the classes will be moved to the package “jakarta.xml.soap”

grep -r jakarta.xml.soap.SOAPMessage
Binary file system/layers/base/jakarta/xml/soap/api/main/jboss-saaj-api_1.4_spec-1.0.2.Final-ee9.jar matches

Buiding a Jakarta EE application that uses SOAP Web services

That being said, in order to deploy a SOAP Web Services application to a Jakarta EE container like WildFly, which includes the SOAP libraries, it is sufficient to add the jakarta.jakartaee-api bundle:

<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-api</artifactId>
    <version>8.0.0</version>
    <scope>provided</scope>
</dependency>

or for Jakarta EE 9:

<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-api</artifactId>
    <version>9.0.0</version>
    <scope>provided</scope>
</dependency>

On the other hand, if your application server does not include the SOAP Web services API, you need to add a dependency for jakarta.xml.ws-api and one compatible implementation for it.

For Jakarta 8 EE you can add:

<dependency>
  <groupId>jakarta.xml.ws</groupId>
  <artifactId>jakarta.xml.ws-api</artifactId>
  <version>2.3.3</version>
</dependency>
<dependency>
  <groupId>com.sun.xml.ws</groupId>
  <artifactId>jaxws-rt</artifactId>
  <version>2.3.3</version>
  <scope>runtime</scope>
</dependency>

For Jakarta EE 9, that would be:

<dependency>
  <groupId>jakarta.xml.ws</groupId>
  <artifactId>jakarta.xml.ws-api</artifactId>
  <version>3.0.0</version>
</dependency>
<dependency>
  <groupId>com.sun.xml.ws</groupId>
  <artifactId>jaxws-rt</artifactId>
  <version>3.0.0</version>
  <scope>runtime</scope>
</dependency>

That’s it. As bonus tip, you can check a Jakarta EE 9 SOAP Web service:

import jakarta.inject.Inject;
import jakarta.jws.WebParam;
import jakarta.jws.WebResult;
import jakarta.jws.WebService;
import jakarta.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style= SOAPBinding.Style.RPC)
public class AccountWS implements AccountWSItf{
	@Inject
	AccountManager ejb;

 
	public void newAccount(@WebParam(name = "name") String name) {
		ejb.createAccount(name);

	}

 
	public void withdraw(@WebParam(name = "name") String name,
			@WebParam(name = "amount") long amount) throws RuntimeException {
		ejb.withdraw(name, amount);
	}

 
	public void deposit(@WebParam(name = "name") String name,
			@WebParam(name = "amount") long amount) {
		ejb.deposit(name, amount);
	}

	@WebResult(name = "BankAccount")
	public Account findAccountByName(String name) {
		return ejb.findAccount(name);
	}
}

The full source code for the Jakarta EE 9 Web Service is available here: https://github.com/fmarchioni/mastertheboss/tree/master/jax-ws/jakartaee-ws-basic

Found the article helpful? if so please follow us on Socials