0

I am trying to use the Java based appengine for a hobby project but I cannot get the hot reload/swap of my app to work when developing. I've tried several things but no luck.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>

  <groupId>grocerymonkey</groupId>
  <artifactId>grocerymonkeyapp</artifactId>

  <properties>
    <!-- uncomment if you wish to set your project here project- gcloud is used otherwise -->
    <!-- <app.deploy.project>your-app-id</app.deploy.project> -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
    <archiveClasses>true</archiveClasses>
  </properties>

  <prerequisites>
    <maven>3.5</maven>
  </prerequisites>

  <dependencies>
    <!-- Compile/runtime dependencies -->
    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-1.0-sdk</artifactId>
      <version>1.9.59</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <type>jar</type>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- Test Dependencies -->
    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-testing</artifactId>
      <version>1.9.59</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-stubs</artifactId>
      <version>1.9.59</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-tools-sdk</artifactId>
      <version>1.9.59</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>0.33</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>2.0.2-beta</version>
      <scope>test</scope>
    </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
      <version>2.8.5</version>
      <scope>compile</scope>
        </dependency>
  </dependencies>

  <build>
    <!-- for hot reload of the web application-->
    <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
    <plugins>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>versions-maven-plugin</artifactId>
        <version>2.3</version>
        <executions>
          <execution>
            <phase>compile</phase>
            <goals>
              <goal>display-dependency-updates</goal>
              <goal>display-plugin-updates</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <excludes>
            <exclude>javax.servlet:javax.servlet-api</exclude>
            <exclude>com.google.guava:guava</exclude> <!-- avoid android version -->
          </excludes>
        </configuration>
      </plugin>

      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.1.0</version>
      </plugin>

      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.1</version>
      </plugin>

      <plugin>
        <artifactId>maven-clean-plugin</artifactId>
        <version>3.0.0</version>
      </plugin>

      <plugin>
        <artifactId>maven-install-plugin</artifactId>
        <version>2.5.2</version>
      </plugin>

      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.20</version>
      </plugin>

      <plugin>
        <artifactId>maven-site-plugin</artifactId>
        <version>3.6</version>
      </plugin>

      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.0.2</version>
      </plugin>

      <plugin>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>3.1</version>
      </plugin>

      <plugin>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.4.1</version>
        <executions>
          <execution>
            <id>enforce-maven</id>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>
                <requireMavenVersion>
                  <version>3.5</version>
                </requireMavenVersion>
                <requirePluginVersions>
                   <message>Best Practice is to always define plugin versions!</message>
                   <banLatest>true</banLatest>
                   <banRelease>true</banRelease>
                   <phases>clean,deploy,verify,appengine:run,appengine:deploy,appengine:update,appengine:devappaserver,site</phases>
                </requirePluginVersions>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>

            <!-- https://cloud.google.com/appengine/docs/standard/java/building-app/environment-setup //-->
            <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>appengine-maven-plugin</artifactId>
        <version>1.3.1</version>
      </plugin>

            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.14.v20181114</version>
            </plugin>
    </plugins>
  </build>
</project>

I cannot use mvh appengine:devserver, when I try I get the following error message

Could not find goal 'devserver' in plugin com.google.cloud.tools:appengine-maven-plugin:1.3.1 among available goals deploy, deployCron, deployDispatch, deployDos, deployIndex, deployQueue, genRepoInfoFile, help, run, stage, start, stop -> [Help 1]

I have tried setting fullscanseconds=5 and less but it doesn't matter if I change an HTML file or a servlet, I still have to stop the server and start it up again manually using mvn appengine:run. This makes it really, really time consuming to develop anything locally. I also tried using jetty, but this failed and then I realised appengine is apparently running on jetty when tested locally.

When I try to use jetty when developing I run into problems due to security constraints.

web.xml

<security-constraint>
            <web-resource-collection>
                <url-pattern>/*</url-pattern>
            </web-resource-collection>
            <user-data-constraint>
                <transport-guarantee>CONFIDENTIAL</transport-guarantee>
            </user-data-constraint>
        </security-constraint>

and jetty gives me a 403 error message.

kristian nissen
  • 2,809
  • 5
  • 44
  • 68

1 Answers1

1

You raised three different issues: hot reload on App Engine flexible, deployment issue when using mvh appengine:devserver and Jetty 403 error message.

Regarding hot reload, it is only possible in Java for certain cases, as explained by Patrice (googler) in this post.

Regarding Jetty, 403 errors are mostly related to permissions, as described in wikipedia:

The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource, or may need an account of some sort.

Regarding mvn development environment, is difficult to evaluate based only on your pom.xml but based on this SO post, I would review the groupIds, the goals and parameters described here (shouldn't you use appengine-web.xml instead of web.xml?) and the official documentation for Apache Maven.

Rubén C.
  • 1,098
  • 6
  • 16