JAX-WS webservice with Spring Boot and JAX-WS RI

Learn how to create a SOAP webservice with JAX-WS RI and Spring Boot.

Download source code

What to do

Use spring initializr to create a Spring Boot application with Spring Web dependency.

Open your pom.xml and include jaxws-rt (the runtime) and jaxws-spring (a helper library for integrating jaxws-rt with Spring). Exclude the Spring dependencies from jaxws-spring to avoid conflicts.

<!– JAX-WS –>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
<!– Spring JAX-WS Integration –>
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.9</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
view raw pom.xml hosted with ❤ by GitHub

Configure the Application class, by importing an xml config file (jaxwsconfig.xml) which contains bean wiring for JAX-WS RI and register WSSpringServlet to receive incoming requests.

@SpringBootApplication
@ImportResource(locations = "jaxwsconfig.xml")
public class TutorialJavaJaxwsApplication {
public static void main(String[] args) {
SpringApplication.run(TutorialJavaJaxwsApplication.class, args);
}
@Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new WSSpringServlet(), "/hello");
}
}

Create a GreetingService class which greets the client upon being called. You will reference the service by the name later to let it handle the web service requests.

@Component(value = "greetingService")
@WebService
public class GreetingService {
@WebMethod
public String greeting() {
return "Hello World!";
}
}
view raw GreetingService.java hosted with ❤ by GitHub

Lastly, you have to add an xml file for wiring the service on the endpoint:

Now open http:/localhost:8080/hello?wsdl to see the generated wsdl file. Your webservice has been deployed, and you could now create a client for it.

What to do next?

Here are some hints what topics you could explore next.

Use packer to create a VM image on Hetzner cloud

Learn how to use packer to create a VM image to use it as a base template.

What do you need to complete this tutorial?

  • packer
  • A Hetzner cloud account and a Hetzner API token
  • Basic knowledge about cloud-init

What is packer?

Hashicorp packer is a tool to automatically create VM images. You can start from a base image, configure it (e.g. installing software or hardening) and store it in the Hetzner cloud for further usage. By using template scripts to automatically create images, it provides a reproducible and versionable way of creating base images for your cloud infrastructure.

A simple packer template

Here is a very simple template script starts from a Ubuntu 18.04 base image and uses a cloud-init script to install some packages and create a user.

Create a cloud-init script:

#cloud-config
groups:
ninjaturtles
users:
name: raphael
groups: ninjaturtles
lock-passwd: false
# created with 'openssl passwd -1 -salt 12345 test'
# password=test
passwd: $1$12345$CQruoOSylf9ItA76Hhqh2.
package_upgrade: true
package_update: true
packages:
git
htop
vim
view raw cloud_config.yaml hosted with ❤ by GitHub

Create a packer template:

{
"variables": {
"hcloud_token": "{{env `HCLOUD_TOKEN`}}"
},
"sensitive-variables": ["hcloud_token"],
"builders": [{
"type": "hcloud",
"token": "{{user `hcloud_token`}}",
"image": "ubuntu-18.04",
"location": "nbg1",
"server_type": "cx11",
"ssh_username": "root",
"user_data_file": "cloud_config.yaml",
"snapshot_name": "basetemplate_ubuntu_18_04",
"snapshot_labels": { "name": "packer_ubuntu_18_04_docker" }
}]
}
view raw base_template.json hosted with ❤ by GitHub

Setting your API token:

export HCLOUD_TOKEN="your_Hetzner_cloud_token"

Run packer:

packer build base_template.json

Use cloud-init to prepare your cloud VMs

Learn what cloud-init is and how to use it.

What do you need to complete this tutorial?

To test your cloud-init script, you can use any of the big cloud providers (Azure, AWS, Hetzner…).

What is cloud-init?

Cloud-init is a tool to prepare your cloud Linux VMs before using. For example, you could install necessary software to create a CI/CD pipeline like Docker, Nomad by installing the corresponding packages or harden your VM by configuring intrusion detection software, disabling root login and setting a non-standard SSH port. You can also read metadata about the cloud environment and configure your VM based on that.

It is available on all major Linux distributions and cloud platforms.

A simple cloud-init script

Here is a very simple and self-explanatory cloud-configuration which creates a user and installs some packages. You can test it by creating a VM on the cloud platform of your choice which should give you an option to provide it for initialization.

Log in to the new VM with the configured user and password and browse the cloud-init logs, which can be found under /var/log/cloud-init.log

#cloud-config
groups:
ninjaturtles
users:
name: raphael
groups: ninjaturtles
lock-passwd: false
# created with 'openssl passwd -1 -salt 12345 test'
# password=test
passwd: $1$12345$CQruoOSylf9ItA76Hhqh2.
package_upgrade: true
package_update: true
packages:
git
htop
vim

CI/CD pipeline to deploy a Java app to Hetzner cloud with Gitlab, Terraform and Nomad

Learn how to use Gitlab, Packer, Terraform and Nomad to create a CI/CD pipeline which deploys to Hetzner cloud!

What do you need to complete this tutorial?

  • Accounts for Gitlab, Hetzner Cloud, Terraform Cloud

Steps:

  1. Implement minimal Kotlin web app with Spring Boot
  2. Create a base VM image with Docker and Nomad installed using Packer
  3. Create Terraform script
  4. Create Nomad script
  5. Configure pipeline