Containerized SOAP Service with Java 11 and Above

Chameera Rupasinghe
5 min readApr 23, 2024

--

The effortless approach to crafting a basic SOAP web service with Java 11 and beyond

Generated using Gemini

With the removal of JAX-WS from JDK in Java 11, the landscape for beginners in Java SOAP services became more complex. Let’s explore a straightforward method to create a basic SOAP service that functions seamlessly with Java 11 and beyond.

What we are going to build..

We will construct an Echo Service, designed to return the same message as the one received in the request. You can find the complete source code for this implementation at https://github.com/chameerar/java-soap-service.

Echo Service (Generated using DiagramGPT)

Initially, we’ll implement the EchoService and run it locally. Following that, we’ll containerize it and conduct tests.

Prerequisites

To develop and run the Echo Service, you’ll need the following:

  • Java 11 (or newer)
  • Maven (version 3.6.3 or higher)
  • A Java-friendly IDE (preferably IntelliJ IDEA)
  • Docker (for containerized deployment)
  • Postman (or another tool for testing the service)

Implementing the Echo Service

First, let’s create a Maven project named “java-soap-serivce” using IDEA.

Setting up the Dependencies

For the web service, we’ll require the following dependencies:

Add these dependencies to the pom.xml file. The dependencies section of the pom.xml file will then appear as follows:

<dependencies>
<dependency>
<groupId>jakarta.jws</groupId>
<artifactId>jakarta.jws-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>rt</artifactId>
<version>4.0.2</version>
</dependency>
</dependencies>

I have used the latest available versions at the time of writing. Feel free to update the versions as necessary.

Implementing the Web Service Logic

With the dependencies configured, let’s proceed to create a class named EchoService.

import jakarta.jws.WebMethod;
import jakarta.jws.WebParam;
import jakarta.jws.WebService;
import jakarta.xml.ws.Endpoint;

@WebService
public class EchoService {
@WebMethod
public String echo(@WebParam(name = "message") String message) {
return message;
}

public static void main(String[] args) {
Endpoint.publish("http://0.0.0.0:8080/echoservice", new EchoService());
System.out.println("Service published at http://localhost:8080/echoservice");
}
}

The code defines a new WebMethod named echo, which returns the received message unchanged. In the main method of the EchoService class, an Endpoint is published to serve at 0.0.0.0:8080/echoservice.

Packaging the Project

With the logic now completed, let’s utilize the maven-dependency-plugin to bundle the dependencies and the maven-jar-plugin to create a .jar artifact from the project. To achieve this, let's add the following build plugins to the pom.xml file:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>io.github.chameerar.EchoService</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>

Ensure to update the value of <mainClass>io.github.chameerar.EchoService</mainClass> to match the package name of your project.

The final version of the pom.xml will be something like this.

<?xml version="1.0" encoding="UTF-8"?>
<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>io.github.chameerar</groupId>
<artifactId>java-soap-service</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>jakarta.jws</groupId>
<artifactId>jakarta.jws-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>rt</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>io.github.chameerar.EchoService</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

I’ve included the junit-jupiter-api dependency for testing purposes. Note that this dependency is not mandatory for the implementation.

Running the Echo Service Locally

Before executing the echo service locally, let’s build the project using Maven.

mvn clean package

This will generate java-soap-service-1.0-SNAPSHOT.jar in the target directory, along with a libs directory containing the necessary dependencies for the web service.

To run the Echo Service, use the following command:

java -jar target/java-soap-service-1.0-SNAPSHOT.jar

This command will initiate the Echo Service. If everything is set up correctly, you’ll see the following message printed in the terminal:

Service published at http://localhost:8080/echoservice

You can access the definition of the Echo Service using the following WSDL URL: http://localhost:8080/echoservice?wsdl.

WSDL of Echo Service

Testing the Echo Service

To test the Echo Service, you can use Postman or any other tool of your choice. Below is an example using Postman:

Send a POST request to http://localhost:8080/echoservice with the following payload:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cham="http://chameerar.github.io/">
<soapenv:Header/>
<soapenv:Body>
<cham:echo>
<message>Hello</message>
</cham:echo>
</soapenv:Body>
</soapenv:Envelope>

Please note that when using Postman, ensure to set the Content-Type header to text/xml.

You’ll receive a response similar to the following:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:echoResponse xmlns:ns2="http://chameerar.github.io/">
<return>Hello</return>
</ns2:echoResponse>
</S:Body>
</S:Envelope>

Containerizing the Echo Service

To containerize the Echo Service, let’s create a Dockerfile with the following content:

FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline

COPY src ./src
RUN mvn package

FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /app/target/*.jar ./app.jar
COPY --from=build /app/target/libs ./libs
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Execute the following command to build the Docker image:

docker build -t echo-service:1.0 .

Then, use the following command to run the Echo Service:

docker run -p 8080:8080 echo-service:1.0

This will initiate the Echo Service at http://localhost:8080/echoservice. You can use the same method as before to verify that the containerized version runs as expected.

Congratulations! You have successfully created a web service using Java 11.

Conclusion

In this guide, we’ve learned how to create a SOAP web service using Java 11. Despite the changes in Java 11, we’ve shown how to build a simple SOAP service step by step.

We started by setting up our development environment and writing the Echo Service logic. Then, we packaged our project with Maven and tested it locally. Finally, we containerized our service with Docker for easy deployment.

By following this tutorial, you now have the skills to create your own SOAP services with Java 11. Whether you’re new to programming or an experienced developer, this guide has equipped you to build robust web services efficiently.

References

https://mvnrepository.com/artifact/jakarta.jws/jakarta.jws-api

https://mvnrepository.com/artifact/com.sun.xml.ws/rt

https://docs.docker.com/reference/cli/docker/

--

--

Chameera Rupasinghe

Senior Software Engineer @WSO2 | Computer Science and Engineering