I am trying to build a basic MVC app using Spring boot with Hibernate as ORM and MySql as Database. The problem that I am facing is that the jsp views are not getting resolved.
I get a 404 error when I try to fetch the registration form using a GET request with the following URL:
http://localhost:9000/users/register/
This is the set-up that I have in my application.
Directory structure:
-src
-main
-java
-com
ApplicationStart.java
-controllers
UserController.java
-repositories
UserRepository.java
-webapp
-WEB-INF
-jsp
register.jsp
-resources
application.properties
UserController:
#RestController
public class UserController {
private UserRepository userRepository;
#Autowired
public UserController(UserRepository userRepository)
{
this.userRepository = userRepository;
}
#RequestMapping(value = "/users/register", method = RequestMethod.GET)
public String Register()
{
return "register";
}
}
Application.properties:
server.port: 9000
spring.datasource.url: jdbc:mysql://localhost/Contacts
spring.datasource.driverClassName: com.mysql.jdbc.Driver
spring.datasource.username: root
spring.datasource.password:
spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp
POM.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.3.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-data-jpa</artifactId>
</dependency>
<!-- HIBERNATE -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<!-- MYSQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
MAIN CLASS
#ComponentScan
#Configuration
#EnableAutoConfiguration
public class ApplicationStart {
public static void main(String[] args)
{
SpringApplication.run(ApplicationStart.class, args);
}
}
This is the current setup of my application. Any help on how to resolve the issue is much appreciated.
Please comment if more information is required.
Thanks-
Spring Boot has limited support for JSP, because of its use of an embedded servlet container. From the Spring Boot reference documentation:
When running a Spring Boot application that uses an embedded servlet container (and is packaged as an executable archive), there are some limitations in the JSP support.
With Tomcat it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to a standard container (not limited to, but including Tomcat). An executable jar will not work because of a hard coded file pattern in Tomcat.
Jetty does not currently work as an embedded container with JSPs.
There is a JSP sample so you can see how to set things up.
Start by making your app an executable war, and make sure that you use Tomcat (check the log when you start the application). Unless you explicitly have stated you Jetty should be included, you are using Tomcat since that is provided by default. Alternatively, try change your view technology, which probably requires more initial work, but can significantly reduce the turnaround time during development, see Hotswapping.
I ran into this problem recently while upgrading an old project that needed to have jsps as the view technology with tomcat as an embedded servlet-container. Caveat: Pick an alternative templating engine, and avoid jsps if you can. But if you can't avoid jsps, and your application is not able to resolve them, at the time of this writing (spring-boot 2.x.x), ensure the following:
Ensure that application packaged as a war and not a jar. Although it is not impossible to get jsps to work with a jar packaging, it is a little complicated due to certain limitations. You could just run them with a war package in a server or container just fine like: java -jar war-filename.war
Verify that your controllers have the #Controller annotation
BUT NOT the annnotation #EnableWebMvc. That's because you are using spring-boot to configure WebMVC for you.
Is your controller being scanned and injected as a component? If you have defined your controllers in a different package, maybe you are missing a #ComponentScan annotation?
Are you jsps located and configured correctly? For example, let's say your jsps are located in /src/main/webapp/WEB-INF/jsp/, then your application.properties should have something like so:
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
Also, since you are using spring-boot, there is no need for your Application to extend the SpringBootServletInitializer. It will work too, but to keep it simple, all you need is a class like below:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
FYI, the minimal set of dependencies needed are mentioned below (Maven Example):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<!-- spring-boot dependencies below -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- jstl and jsp compilation support below -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
Agree with #code4kix, If all of this doesn't work, try adding below property in your application.properties file
spring.thymeleaf.enabled=false
In my case that solved my problem
Location of JSP file: src/main/resources -> /META-INF/resources/WEB-INF/jsp/sayHello.jsp
In pom.xml :
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
In application.properties:
spring.mvc.view.prefix= /WEB-INF/jsp/
spring.mvc.view.suffix= .jsp
#For debug reason
logging.level.org.springframework=debug
In Contoller:
#Controller
public class HelloController {
#RequestMapping("say-hello-jsp")
public String sayHelloJsp() {
return "sayHello";
}
}
Intellij still show it as error, but it works
In IntelliJ, if you have the same configurations and it still doesn't work do this:
File -> Invalidate Caches -> mark first 2 lines -> Invalidate and Restart. Then it will work fine
Related
I'm writing a Spring Boot application with several #Configuration classes for rest APIs and for Kafka consumers/producers depending on which #Profile it chooses to initialize.
The first configuration class uses the REST interface, and I have these dependencies added.
This starts up an embedded Tomcat instance and runs fine.
Here the problem is the other profiles should not spin a tomcat server, it should act only as a Kafka consumer.
Is there any way to stop spinning the #SpringBootApplication from starting up Tomcat based on profiles?
I created 2 configuration classes, one for Kafka and one for rest endpoints, and added #Profile annotation for each config class. Can someone guide me on how to stop spin tomcat from my app?
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Main application:
#SpringBootApplication
#Import(value = {RestScanConfiguration.class, KafkaScanConfiguration.class})
public class MainApp {
public static void main(final String[] args) {
SpringApplication.run(MainApp.class, args);
}
}
RestScanConfiguration class:
#Configuration
#EnableAutoConfiguration
#ComponentScan(basePackages = "package.app.rest")
#Profile("!kafka")
public class RestScanConfiguration {
}
KafkaScanConfiguration class:
#Configuration
#EnableAutoConfiguration(
exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
ElasticsearchDataAutoConfiguration.class
})
#ComponentScan(basePackages = {"package.app.kafka"})
#Profile("kafka")
public class KafkaScanConfiguration {
}
can someone guide me on this?
How to stop spinning the tomcat server in Kafka consumer/producer profile. Any help would be appreciated.
First you have to disbale the auto configuration for the embeded tomcat in the starter class to avoid deploying the tomcat:
#SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class,
WebMvcAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and then add the following property to your kafka config (non-Rest profiles):
spring.main.web-environment=false
now you have disabled auto-deployment of the integrated tomcat in spring boot. Now add the following configuration to your Rest profile to enable tomcat (only for this profile):
#Profile({"REST"})
#Configuration
// importing EmbeddedServletContainerAutoConfiguration delays the autoconfiguration until the profile load into context
#Import(EmbeddedServletContainerAutoConfiguration.class)
public class HttpConfiguration {
// ...
}
and afterwards you have configure your kafka dynamically. You can find a solution for that in Control enabling/disabling Kafka consumers in Spring Boot
Instead of configuring this in code I'd suggest you to create application-kafka.properties (or application-kafka.yml) and add the following line into it:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
This disables ServletWebServerFactoryAutoConfiguration which is a root configuration class for Web environment.
-kafka suffix in properties file name tells Spring to pick it up only when kafka profile is active.
Even better solution is to exclude
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
from built jar. In other words you could have a pom.xml two profiles with only required dependencies (shared ones are located in main dependencies section). See https://stackoverflow.com/a/167284/12473843. Using this approach you don't even need specifying excluded autoconfigurations as without spring-boot-starter-web in the classpath corresponding started is never activated.
I created a Spring Boot demo app with Maven using Spring Initializr (that's my almost the very first usage of Spring). It works, but for some reason doesn't show any pages besides index.html. If I'm right, that's because of configuration in application.properties, but I just don't know, what have I add there.
My project's sources structure:
src
main
java
irimi
springbootdemo
SpringBootDemoApplication.java
SpringBootDemoApplicationController.java
resources
static
index.html
templates
test-form.html
test-page.jsp
application.properties
I tried to add different prefixes and suffixes into application.properties, but nothing works. Just as an example:
spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix=.html
Again, index.html opens perfectly.
Maybe, it would be good to show here my dependences too:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
That's an error page:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Jan 15 11:49:12 MSK 2022
There was an unexpected error (type=Not Found, status=404).
No message available
If my error is really in application.properties, what have I put there?
With Default Rendering with template
If you are using default "/resources/templates" for rendering view.Spring Boot only includes auto-configuration support for the following templating engines:
FreeMarker
Groovy
Thyme-leaf
Velocity
Example:
Step1:
For using thymeleaf you should add dependency either with gradle and maven
Gradle:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '2.5.4'
OR
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.5.4</version>
</dependency>
Step2:
Add below code with properties file
(Optional)spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
With MVC support
By default, this handler serves static content from any of /static, /public, /resources, and /META-INF/resources directories that are on the classpath. Since src/main/resources is typically on the classpath by default, we can place any of these directories there.
Only static folder is available for rendering view.You can customise using below code with properties file.By default Spring Boot will serve static content from a folder called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext. It uses the ResourceHttpRequestHandler from Spring MVC so you can modify that behavior by adding your own WebMvcConfigurerAdapter and overriding the addResourceHandlers method.
spring.mvc.static-path-pattern=/content/**
spring.web.resources.static-locations=classpath:/files/,classpath:/static-files
More information visit
https://docs.spring.io/spring-boot/docs/1.1.5.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-static-content
https://www.baeldung.com/spring-mvc-static-resources
This is a Simple Microservice built using spring-boot. The application is working fine when I execute as Java Application. But when I run on Server i.e. Tomcat Server v8.5 the Server shows Started & Syncnorized but in console, the spring-boot logo doesn't appear and the application doesn't start. Other Projects on my IDE are working fine.
I tried following but didn't work:
1)Delete Server and add again.
2)Clean the Project using Maven.
3)Changed BuildPath Settings(JDK Version, Facets, etc).
Screenshot to refer
1) https://i.imgur.com/fVFLhNK.png
2)https://i.imgur.com/nTSWEGd.png
Main App
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
#SpringBootApplication
public class ShUsersApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ShUsersApplication.class, args);
}
}
Controller
package com.logituit.sitehawk.Controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.gson.Gson;
import com.logituit.sitehawk.Model.Contract;
import com.logituit.sitehawk.Service.UserService;
#RestController
#RequestMapping("/sitehawk")
public class UserController {
private UserService userService;
private Gson gson;
#Autowired
public UserController(#NonNull final UserService userService, #NonNull Gson gson) {
this.userService = userService;
this.gson = gson;
}
#PostMapping("/save")
public String saveDetails(HttpEntity<String> httpEntity) {
final Contract contract = gson.fromJson(httpEntity.getBody(), Contract.class);
if (contract != null) {
userService.createTicketBySite(contract);
return "Success";
} else
return "Failed";
}
#GetMapping("/ticketsfromsite/{siteId}")
public List<Contract> getAllTicketsBySite(HttpEntity<String> httpEntity, #PathVariable("siteId") final int siteId) {
return userService.getTicketsBySite(siteId);
}
}
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.logituit.sitehawk</groupId>
<artifactId>SH_Users</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SH_Users</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
</project>
application.properties
#Local Database
spring.datasource.url = jdbc:mysql://localhost:3306/site_hawk
spring.datasource.username = root
spring.datasource.password = admin123
server.port=8089
Please help me how can I run my spring-boot App.I'm want to see Spring boot running on the console. But the Big Logo of Spring Boot doesn't appear on the console.
The normal deployment format for application containers (Tomcat included) is .war however Spring Boot by default packages a runnable jar file.
You can change the packaging format in pom.xml file.
<packaging>war</packaging>
You may also need to add an additional dependency for Tomcat specific classes.
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Such setup should yield a .war file to $project_dir/target/classes which most servlet containers can successfully run.
Server doesn't simple print everything in the console, since there will be a lot of applications running at the same time, the console is going to be a big confuse messy with so many "System.out", so the solution to the servers is put on log to each application. Try to find you application logs, maybe the spring logo will be there.
Be sure also that you are uploading a .war file. The jar package is for running is you pc. For Tomcat you need to send the .war file. You can simple change the packaging type in your pom.xml.
Usage - Apache Maven WAR Plugin
To run your application in tomcat server you should exclude the embedded one via :
<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>
And as käyrätorvi said package your application as war
Spring boot applications include an embedded web server and can be run in a number of ways. Tomcat is included by default which can be overridden by other servers. You can find the reference here and here.
Spring boot applications, unlike traditional java web applications, are simplified in terms of running and deploying. As a developer, you can focus on developing the core logic, exposing the endpoints etc. Once built, these applications are ready to run and do not need to be deployed on an explicit server as they run on an embedded server that comes from spring boot starter web dependency.
I am considering modifying an existing java web app (with web.xml and applicationContext.xml files and Spring 2.5) to use Spring Boot. What are the implications of this process? I know I will need to create an #Configuration file to declare all of the beans (to eliminate the applicationContext.xml files), but would love some additional insight. Any suggestions are appreciated!
Migration would take several steps. Some of them are:-
Add Spring Boot dependencies to your pom.xml or gradle file.
Define all the XML beans using Java Configuration by #Bean
Define Spring Security if used through Java Configuration
Add application.properties to resources directory and defines all the configuration values like database host,username,password etc
Define your views inside resources/templates
You've to include all the dependencies required. Some of the dependencies are:-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
You could have some other dependencies too like Spring Security. If your application uses Spring Security you have to provide java configuration for it.
http://www.baeldung.com/spring-boot-security-autoconfiguration
https://spring.io/blog/2014/01/30/migrating-from-spring-framework-3-2-to-4-0-1
I was trying to deploy Spring Boot application on Google App Engine (standard environment). At first I cloned example app from this nice tutorial https://springframework.guru/spring-boot-web-application-part-4-spring-mvc/
For example I called http://localhost:8080/products and template with data was displayed.
So everything ran without problems, I was able to call all controller methods locally. Then I decided as experiment to deploy it on GAE. I adjusted pom.xml according to instructions from here https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/appengine-standard-java8/springboot-appengine-standard
It means I excluded Tomcat dependency, changed packaging from jar to war, created appengine-web.xml file etc. As next step, I created GAE project in GAE console and copied APP ID into appengine-web.xml. Then I ran mvn clean package and war was created in target folder. Finally I started with GAE deployment and it also went smoothly without errors.
My app is now deployed on this URL https://20180109t135551-dot-oe-gae-test.appspot.com/
If you try it, you will see Hello World in browser. But if I try to call /products controller method like this https://20180109t135551-dot-oe-gae-test.appspot.com/products I get "not found" error.
Can you give me advice on which URL should I call my controller methods? Did I forget to implement something like web.xml servlet mapping? Or is it some specific Spring Boot - Google App Engine problem?
I will be grateful for any hint.
Thank you all in advance
Following this steps translates into the following for the code:
In pom.xml, change <packaging>jar</packaging> to <packaging>war</packaging>
In the package guru.springframework add this class:
Code:
package guru.springframework;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringBootWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebApplication.class, args);
}
}
Remove Tomcat Starter:
Find this dependency in the POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
And add these lines:
<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>
Exclude Jetty dependencies and include the Servlet API dependency:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
Add the App Engine Standard plugin:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.1</version>
</plugin>
Add a file called appengine-web.xml in src/webapp/WEB-INF with these contents:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
</system-properties>
</appengine-web-app>
Exclude JUL to SLF4J Bridge by locating this dependency in the pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
and modifying it this way:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
Avoiding out of memory errors:
In src/main/resources add a logging.properties file with:
.level = INFO
and inside src/main/webapp/WEB-INF/appengine-web.xml paste this:
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties" />
</system-properties>
EDIT:
For steps 3 and 7 you can also go to the project explorer (in case you're using Eclipse) and navigate to Libraries -> Maven dependencies and select each library individually (jul-to-slf4j-1.7.25 and spring-boot-starter-tomcat-1.5.3.RELEASE in my case). Right click on each library and go to Maven -> Exclude Maven artifact... And click Ok. This will have the same effect on the POM as editing.