Containerized SOAP Service with Java 11 and Above
The effortless approach to crafting a basic SOAP web service with Java 11 and beyond
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.
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.
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