Spring Boot Hello World on WildFly

This article has been updated and tested with WildFly 20 and Spring Boot 2.3.3 release.

Spring Boot offers a new paradigm for developing Spring applications with more agility while focusing on your business methods rather than the thought of configuring Spring itself. Spring Boot does not require complex configuration files as it is able to discover classes by looking in the classpath of your applications and building a single runnable JAR of it, which makes it convenient to make your service portable too.

Creating a Spring Boot project

The simplest way to get started with Spring Boot is via the Spring Boot inizializer that is available on http://start.spring.io/

From there, choose the Spring Boot starters that you want to be included and artifactId and groupId. Also you can opt for a Maven project or a Gradle project.

Spring boot to wildfly tutorial

As you can see, we have added only the “web” dependencies that will enable us to create a simple Web application with a REST endpoint.

Your first application

The Spring Boot Initilizer has created for us a sample application named SpringbootwildflyApplication. We will add some simple logic in it to map a GET request with a REST text resource. Copy in it the following text:

package com.mastertheboss.springboot.springbootwildfly;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@SpringBootApplication
public class SpringbootwildflyApplication   {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringbootwildflyApplication.class, args);
    }
}
 
 
@RestController
class HelloController {
 
    @RequestMapping("/hello/{name}")
    String hello(@PathVariable String name) {
         
             return "Hi "+name+" !";
              
    }
}

Let’s see more in detail. The class is annotated with a @SpringBootAnnotation annotation. This is equivalent to applying the following Spring annotations:

  • @Configuration which identifies the class as a source of bean definitions for the application context.
  • @EnableAutoConfiguration which enables Spring Boot to add beans based on the application’s classpath, and various property settings.
  • @ComponentScan which tells Spring to look for other beans,configurations, and services in the same package as your application class so that you will be able to find the SimpleBean class.

Next, we have used the @RestController annotation to annotate a class that will encompass all of our REST APIs.  We will also use the @RequestMapping annotation to define the URL path to our API as well as HTTP method and path parameters for our APIs.

The is the pom.xml file used to build and package our first Project:

<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.3.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.mastertheboss.springboot</groupId>
	<artifactId>springbootwildfly</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>springbootwildfly</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>
</project>

As you can see, the list of dependencies is really minimal. You will find some extra repository configuration in case you are using a snapshot version of Spring Boot. All you have to do, in order to create the runnable JAR file is:

$ mvn clean package

You will generate a simple SpringBootBasic.jar file which can be run with:

$ java -jar target/springbootwildfly-0.0.1-SNAPSHOT.jar

The embedded Tomcat Web server will start, we can test that our application is working as follows:

Spring Boot Hello World JBoss

Porting SpringBoot on a Java EE Container

Porting the Hello World application on a Java EE Container such as WildFly requires a few tweaks, mostly due to the fact that the application must be initialized and run by a Servlet container which is embedded into the application server. The first change will be extending the org.springframework.boot.web.servlet.support.SpringBootServletInitializer which is a WebApplicationInitializer to run a SpringApplication from a traditional WAR deployment:

package com.mastertheboss.springboot.springbootwildfly;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// Spring Boot 2.x
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

// Spring Boot 1.x
//import org.springframework.boot.web.support.SpringBootServletInitializer;
 
@SpringBootApplication
public class SpringbootwildflyApplication extends SpringBootServletInitializer {
 
    public static void main(String[] args) {
        SpringApplication.run(applicationClass, args);
    }
 
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(applicationClass);
    }
 
    private static Class<SpringbootwildflyApplication> applicationClass = SpringbootwildflyApplication.class;
}
 
@RestController
class HelloController {
 
    @RequestMapping("/hello/{name}")
    String hello(@PathVariable String name) {
 
        return "Hi " + name + " !";
 
    }
}

Please note that we are using the org.springframework.boot.web.servlet.support.SpringBootServletInitializer and not the org.springframework.boot.web.support.SpringBootServletInitializer that has been deprecated in Spring Boot 2!

Next, some changes are also required in the pom.xml, in order to exclude the default Tomcat embedded Web server initializer and include the Servlet dependency in order to be able to compile the project:

<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>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.3.3.RELEASE</version>
      <relativePath />
      <!-- lookup parent from repository -->
   </parent>
   <groupId>com.mastertheboss.springboot</groupId>
   <artifactId>springbootwildfly</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>war</packaging>
   <name>springbootwildfly</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
         <exclusions>
            <exclusion>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>javax.servlet-api</artifactId>
         <version>3.1.0</version>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <finalName>springbootwildfly</finalName>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
        <plugin>
           <groupId>org.wildfly.plugins</groupId>
           <artifactId>wildfly-maven-plugin</artifactId>
           <version>2.0.0.Final</version>
      </plugin>
      </plugins>
   </build>
   <repositories>
      <repository>
         <id>spring-snapshots</id>
         <name>Spring Snapshots</name>
         <url>https://repo.spring.io/snapshot</url>
         <snapshots>
            <enabled>true</enabled>
         </snapshots>
      </repository>
      <repository>
         <id>spring-milestones</id>
         <name>Spring Milestones</name>
         <url>https://repo.spring.io/milestone</url>
         <snapshots>
            <enabled>false</enabled>
         </snapshots>
      </repository>
   </repositories>
   <pluginRepositories>
      <pluginRepository>
         <id>spring-snapshots</id>
         <name>Spring Snapshots</name>
         <url>https://repo.spring.io/snapshot</url>
         <snapshots>
            <enabled>true</enabled>
         </snapshots>
      </pluginRepository>
      <pluginRepository>
         <id>spring-milestones</id>
         <name>Spring Milestones</name>
         <url>https://repo.spring.io/milestone</url>
         <snapshots>
            <enabled>false</enabled>
         </snapshots>
      </pluginRepository>
   </pluginRepositories>
</project>

As we have included WildFly plugin into the configuration, in order to build and deploy the application on WildFly it is sufficient to run from the shell:

$ mvn clean package wildfly:deploy

You will notice from the application server logs that Spring Boot has been started and the Web application springbootwildfly.war has been deployed:

08:57:06,601 INFO  [stdout] (ServerService Thread Pool -- 88) 
08:57:06,602 INFO  [stdout] (ServerService Thread Pool -- 88)   .   ____          _            __ _ _
08:57:06,602 INFO  [stdout] (ServerService Thread Pool -- 88)  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
08:57:06,602 INFO  [stdout] (ServerService Thread Pool -- 88) ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
08:57:06,602 INFO  [stdout] (ServerService Thread Pool -- 88)  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
08:57:06,602 INFO  [stdout] (ServerService Thread Pool -- 88)   '  |____| .__|_| |_|_| |_\__, | / / / /
08:57:06,602 INFO  [stdout] (ServerService Thread Pool -- 88)  =========|_|==============|___/=/_/_/_/
08:57:06,604 INFO  [stdout] (ServerService Thread Pool -- 88)  :: Spring Boot ::        (v2.3.3.RELEASE)
08:57:06,604 INFO  [stdout] (ServerService Thread Pool -- 88) 
08:57:06,688 INFO  [com.mastertheboss.springboot.springbootwildfly.SpringbootwildflyApplication] (ServerService Thread Pool -- 88) Starting SpringbootwildflyApplication on fedora with PID 5909 (started by francesco in /home/francesco/jboss/wildfly-20.0.0.Final/bin)
08:57:06,690 INFO  [com.mastertheboss.springboot.springbootwildfly.SpringbootwildflyApplication] (ServerService Thread Pool -- 88) No active profile set, falling back to default profiles: default
08:57:07,282 INFO  [io.undertow.servlet] (ServerService Thread Pool -- 88) Initializing Spring embedded WebApplicationContext
08:57:07,282 INFO  [org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext] (ServerService Thread Pool -- 88) Root WebApplicationContext: initialization completed in 565 ms
08:57:07,637 INFO  [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] (ServerService Thread Pool -- 88) Initializing ExecutorService 'applicationTaskExecutor'
08:57:07,802 INFO  [com.mastertheboss.springboot.springbootwildfly.SpringbootwildflyApplication] (ServerService Thread Pool -- 88) Started SpringbootwildflyApplication in 1.471 seconds (JVM running for 48.732)
08:57:07,853 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (ServerService Thread Pool -- 88) Initializing Mojarra 2.3.9.SP10 for context '/springbootwildfly'
08:57:08,332 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 88) WFLYUT0021: Registered web context: '/springbootwildfly' for server 'default-server'
08:57:08,390 INFO  [org.jboss.as.server] (management-handler-thread - 1) WFLYSRV0010: Deployed "springbootwildfly.war" (runtime-name : "springbootwildfly.war")

We can test that our application is working as follows:

Spring Boot Hello World JBoss

Troubleshooting

A frequent issue when building your Spring Boot to WildFly project is the following error:

java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig

 This can happen if you are using a Servlet API dependencies pre 3.x. Update your pom.xml with the 3.1.0 (or newer) javax.servlet-api !

Source code

You can check the source code for this article at: https://github.com/fmarchioni/mastertheboss/tree/master/spring/springbootwildfly

That’s all! In the next tutorial SpringBoot with JPA on WildFly we will learn how to use JPA with a Spring Boot application.

Do you want some more Spring stuff ? check Spring Boot Tutorials !