Spring Boot War deployed to Tomcat
This guide explains in detail how to deploy Spring Boot app on Tomcat:
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file
Essentially I needed to add following class:
public class WebInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
}
Also I added following property to POM:
<properties>
<start-class>mypackage.App</start-class>
</properties>
Hey make sure to do this changes to the pom.xml
<packaging>war</packaging>
in the dependencies section make sure to indicated the tomcat is provided so you dont need the embeded tomcat plugin.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
This is the whole pom.xml
<?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>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>com.example.Application</start-class>
</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
And the Application class should be like this
Application.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
/**
* Used when run as JAR
*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
/**
* Used when run as WAR
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
And you can add a controller for testing MyController.java
package com.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@RequestMapping("/hi")
public @ResponseBody String hiThere(){
return "hello world!";
}
}
Then you can run the project in a tomcat 8 version and access the controller like this
http://localhost:8080/demo/hi
If for some reason you are not able to add the project to tomcat do a right click in the project and then go to the Build Path->configure build path->Project Faces
make sure only this 3 are selected
Dynamic web Module 3.1 Java 1.8 Javascript 1.0
I think you're confused by different paradigms here. First, war files and server deployment -- those things belong to Java Enterprise Edition (Java EE). These concepts have no real place in a spring-boot application, which follows a different model.
Spring-boot is responsible for creating an embedded container and running your services within it directly from standard jar files (although it can do a lot more). I think the intent of this model is to support micro-service development -- where each service has its own container and is completely self contained. You can use your code to generate Java EE apps too, but that would be silly considering that spring-boot is a lot easier (for certain types of application/service).
So, given this information you now have to decide what paradigm you're going to follow, and you need to follow that and only that.
Spring-boot is executable -- you just have to run the main method in the App class which you can do from the command line or using your favourite IDE or maven or gradle (tip: maven is the right answer). This will bring up a tomcat server (by default) and your service will be available within it. Given the configuration you posted above your service should be available at: http://localhost:7777/context/help
-- the context
is meant to be replaced with your context name, which you haven't shared.
You aren't meant to be creating a war, running tomcat, or deploying anything. None of that is necessary in spring-boot. The packaging in your pom should be jar
, not war
and the scope
of the spring-boot-starter-tomcat
should be removed -- it certainly isn't provided.
When you run your main method, the console output should tell you the context that you've registered; use that to get the URL right.
Having said all that, spring-boot has to exist in a JEE world for now (until it is widely adopted). For that reason, the spring people have documented an approach to building a war rather than an executable jar, for deployment to a servlet or JEE container. This allows a lot of the spring-boot tech to be used in environments where there are restrictions against using anything but wars (or ears). However, this is a just a response to the fact that such environments are quite common, and is not seen as a necessary, or even desirable, part of the solution.