1
votes

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

1
Go to stackdriver and see the logs so we can know what errors you're receiving: cloud.google.com/logging/docs/view/overview - Victor M Herasme Perez
method: "GET" requestId: "5a551d2d00ff08353d5200ffd1dd0001687e6f652d6761652d746573740001323031383031303974313335353531000100" resource: "/products" startTime: "2018-01-09T19:51:09.537917Z" status: 404 traceId: "680d8d917491ccbe61c6e72c87dc2c0c" userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" versionId: "20180109t135551" - Oliver Eder
Sorry for the format of the pasted log. Simply, it is 404 not found for /products resource - Oliver Eder
I downloaded the app and I was able to deploy it. I can see the products page. Let's find out what the differences between our projects are - Victor M Herasme Perez
Great ! And how could we compare our source codes? - Oliver Eder

1 Answers

4
votes

Following this steps translates into the following for the code:

  1. In pom.xml, change <packaging>jar</packaging> to <packaging>war</packaging>

  2. 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);
    }
}    
  1. 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>
  1. 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>

  2. Add the App Engine Standard plugin:

    <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>appengine-maven-plugin</artifactId>
        <version>1.3.1</version>
    </plugin>
    
    1. 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>

    1. 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>
  1. 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.