This article has been updated and tested with WildFly 14 and Spring Boot 2.2.0 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.2.0.BUILD-SNAPSHOT</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 if you are using a snapshot version (as in this case) 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.2.0.BUILD-SNAPSHOT</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>
      </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>

Now compile as usual the project with:

$ mvn clean package

You will generate a SpringBootBasic.war file which can be deployed with:

$ cp target/springbootwildfly.war %JBOSS_HOME/standalone/deployments

You will notice from the application server logs that Spring Boot has been started:

11:28:34,664 INFO  [io.undertow.servlet] (ServerService Thread Pool -- 83) 2 Spring WebApplicationInitializers detected on classpath
11:28:35,197 INFO  [stdout] (ServerService Thread Pool -- 83) 
11:28:35,211 INFO  [stdout] (ServerService Thread Pool -- 83)   .   ____          _            __ _ _
11:28:35,212 INFO  [stdout] (ServerService Thread Pool -- 83)  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
11:28:35,212 INFO  [stdout] (ServerService Thread Pool -- 83) ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
11:28:35,212 INFO  [stdout] (ServerService Thread Pool -- 83)  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
11:28:35,212 INFO  [stdout] (ServerService Thread Pool -- 83)   '  |____| .__|_| |_|_| |_\__, | / / / /
11:28:35,212 INFO  [stdout] (ServerService Thread Pool -- 83)  =========|_|==============|___/=/_/_/_/
11:28:35,213 INFO  [stdout] (ServerService Thread Pool -- 83)  :: Spring Boot ::  (v2.2.0.BUILD-SNAPSHOT)
11:28:35,213 INFO  [stdout] (ServerService Thread Pool -- 83) 

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 !

0
0
0
s2smodern