I am trying to deploy a Spring Boot app to Tomcat, because I want to deploy to AWS. I created a WAR file, but it does not seem to run on Tomcat, even though it is visible.
Details:
0. Here is my app:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class App {
public static void main(String[] args) {
SpringApplication.run(SampleController.class, args);
}
}
@Controller
@EnableAutoConfiguration
public class SampleController {
@RequestMapping("/help")
@ResponseBody
String home() {
String input = "Hi! Please use 'tag','check' and 'close' resources.";
return input;
}
}
application.properties has following:
server.port=${port:7777}
After reading a number of pages and question-answers I added following to my POM:
http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0
<groupId>com.niewlabs</groupId>
<artifactId>highlighter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
I ran"mvn package"and got WAR file (size 250Mb), which I put into "webapps" folder.
Update: There is another reference. Not sure how useful it is.
This question is related to
spring
maven
tomcat
spring-boot
After following the guide (or using Spring Initializr), I had a WAR that worked on my local computer, but didn't work remote (running on Tomcat).
There was no error message, it just said "Spring servlet initializer was found", but didn't do anything at all.
17-Aug-2016 16:58:13.552 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.4
17-Aug-2016 16:58:13.593 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /opt/tomcat/webapps/ROOT.war
17-Aug-2016 16:58:16.243 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
and
17-Aug-2016 16:58:16.301 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
17-Aug-2016 16:58:21.471 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
17-Aug-2016 16:58:25.133 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log ContextListener: contextInitialized()
17-Aug-2016 16:58:25.133 INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log SessionListener: contextInitialized()
Nothing else happened. Spring Boot just didn't run.
Apparently I compiled the server with Java 1.8, and the remote computer had Java 1.7.
After compiling with Java 1.7, it started working.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version> <!-- added this line -->
<start-class>myapp.SpringApplication</start-class>
</properties>
Update 2018-02-03 with Spring Boot 1.5.8.RELEASE.
In pom.xml, you need to tell Spring plugin when it is building that it is a war file by change package to war, like this:
<packaging>war</packaging>
Also, you have to excluded the embedded tomcat while building the package by adding this:
<!-- to deploy as a war in tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
The full runable example is in here https://www.surasint.com/spring-boot-create-war-for-tomcat/
If your goal is to deploy your Spring Boot application to AWS, Boxfuse gives you a very easy solution.
All you need to do is:
boxfuse run my-spring-boot-app-1.0.jar -env=prod
This will:
All images are generated in seconds and are immutable. They can be run unchanged on VirtualBox (dev) and AWS (test & prod).
All updates are performed as zero-downtime blue/green deployments and you can also enable auto-scaling with just one command.
Boxfuse also understands your Spring Boot config will automatically configure security groups and ELB health checks based upon your application.properties
.
Here is a tutorial to help you get started: https://boxfuse.com/getstarted/springboot
Disclaimer: I am the founder and CEO of Boxfuse
Add plugin to build.gradle
apply plugin: 'war'
Add provided dependency to tomcat
dependencies {
// other dependencies
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}
Your Application.java
class should extend the SpringBootServletInitializer
class
ex:
public class Application extends SpringBootServletInitializer {}
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
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
If you are creating a new app instead of converting an existing one, the easiest way to create WAR based spring boot application is through Spring Initializr.
It auto-generates the application for you. By default it creates Jar, but in the advanced options, you can select to create WAR. This war can be also executed directly.
Even easier is to create the project from IntelliJ IDEA directly:
File ? New Project ? Spring Initializr
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.
public class Application extends SpringBootServletInitializer {}
just extends the SpringBootServletInitializer. It will works in your AWS/tomcat
I had same problem and i find out solution by following this guide . I run with goal in maven.
clean package
Its worked for me Thanq
Source: Stackoverflow.com