GWT with App Engine (standard) and maven?

369 views
Skip to first unread message

dflorey

unread,
Mar 12, 2018, 7:55:22 AM3/12/18
to GWT Users
Hi folks,
after all those years I've decided to start migrating our GWT / App Engine (standard) projects from Ant to Maven.
The main app consists of several GWT libraries and multiple modules.
I'd also like to split the monolithic app into several "microservices" running on App Engine (frontend and backend).
Problem is that I've not used maven much in the past so there is a lot of new stuff to learn.
I've Googled a bit in the last days to get the big picture, but I did not find any tutorials how to put it all together.
So I though it would be a good idea to try to collect as much info from the experts as possible and write down a tutorial for others facing the same situation.

What I did so far:
I've created a maven parent project as I thought it may be a good idea to have a child project for each app engine module / service.
I've added the first maven module (frontend) and created an empty project from the appengine standard archetype.

I tried to add the gwt maven plugin to this project, but I had no clue how to do that.
I copy/pasted the definitions from here into the pom:

When running

maven gwt:compile

I just get this error:
[WARNING] Error: Could not find or load main class com.google.gwt.dev.Compiler

Any ideas?

Thanks a lot in advance,

Daniel

dflorey

unread,
Mar 12, 2018, 8:21:45 AM3/12/18
to GWT Users
This is the pom.xml that I've got so far:

<?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>
 
<artifactId>xxx-appengine</artifactId>
 
<groupId>com.floreysoft.xxx</groupId>
 
<version>0.0.1-SNAPSHOT</version>
 
</parent>
 
<packaging>gwt-app</packaging>
 
<version>0.0.1-SNAPSHOT</version>


 
<groupId>com.floreysoft.xxx</groupId>
 
<artifactId>xxx-frontend</artifactId>


 
<properties>
 
<!-- uncomment if you wish to set your project here project- gcloud is
 used otherwise -->

 
<!-- <app.deploy.project>xxx-dev</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>
 
<dependencyManagement>
 
<dependencies>
 
<dependency>
 
<groupId>com.google.gwt</groupId>
 
<artifactId>gwt</artifactId>
 
<version>2.8.2</version>
 
<type>pom</type>
 
<scope>import</scope>
 
</dependency>
 
</dependencies>
 
</dependencyManagement>
 
<dependencies>
 
<!-- GWT dependencies -->
 
<dependency>
 
<groupId>com.google.gwt</groupId>
 
<artifactId>gwt-user</artifactId>
 
</dependency>
 
<dependency>
 
<groupId>com.google.gwt</groupId>
 
<artifactId>gwt-dev</artifactId>
 
</dependency>
 
 
<!-- Compile/runtime dependencies -->
 
<dependency>
 
<groupId>com.google.appengine</groupId>
 
<artifactId>appengine-api-1.0-sdk</artifactId>
 
<version>1.9.63</version>
 
</dependency>
 
<dependency>
 
<groupId>javax.servlet</groupId>
 
<artifactId>javax.servlet-api</artifactId>
 
<version>3.1.0</version>
 
<type>jar</type>
 
<scope>provided</scope>
 
</dependency>


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


 
<dependency>
 
<groupId>com.google.appengine</groupId>
 
<artifactId>appengine-tools-sdk</artifactId>
 
<version>1.9.63</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>1.10.19</version>
 
<scope>test</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>net.ltgt.gwt.maven</groupId>
 
<artifactId>gwt-maven-plugin</artifactId>
 
<version>1.0-rc-9</version>
 
<extensions>true</extensions>
 
<configuration>
 
<moduleName>com.floreysoft.xxx.xxx</moduleName>
 
</configuration>
 
</plugin>
 
<plugin>
 
<groupId>com.google.cloud.tools</groupId>
 
<artifactId>appengine-maven-plugin</artifactId>
 
<version>1.3.1</version>
 
<configuration></configuration>
 
</plugin>


 
<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>
 
</plugins>
 
</build>
</project>



Thomas Broyer

unread,
Mar 12, 2018, 8:31:11 AM3/12/18
to GWT Users


On Monday, March 12, 2018 at 12:55:22 PM UTC+1, dflorey wrote:
Hi folks,
after all those years I've decided to start migrating our GWT / App Engine (standard) projects from Ant to Maven.
The main app consists of several GWT libraries and multiple modules.
I'd also like to split the monolithic app into several "microservices" running on App Engine (frontend and backend).
Problem is that I've not used maven much in the past so there is a lot of new stuff to learn.

If you can, you may want to try Gradle instead of Maven. Migration from Ant should be much easier, as both Gradle and Ant use graphs of dependent tasks, whereas Maven uses a linear lifecycle where you bind plugin "goals" to predefined "phases".
 
I've Googled a bit in the last days to get the big picture, but I did not find any tutorials how to put it all together.
So I though it would be a good idea to try to collect as much info from the experts as possible and write down a tutorial for others facing the same situation.

What I did so far:
I've created a maven parent project as I thought it may be a good idea to have a child project for each app engine module / service.
I've added the first maven module (frontend) and created an empty project from the appengine standard archetype.

I tried to add the gwt maven plugin to this project, but I had no clue how to do that.
I copy/pasted the definitions from here into the pom:

You could have a look at the samples from the GWT SDK: https://gwt.googlesource.com/gwt/+/2.8.2/samples/mobilewebapp/
I strongly discourage putting client and server code inside the same Maven module though; so I'd suggest you rather take inspiration from my archetypes at https://github.com/tbroyer/gwt-maven-archetypes (disclosure: I don't use AppEngine, so I have no idea if it's easy, and what it takes, to run the AppEngine dev server within multi-module projects; IIRC, previous versions required you to "mvn install" the dependencies and start the dev server from your "server" module, but this may have –I hope it has– changed; even Jetty which had the same limitation for years eventually fixed their Maven plugin).
 
When running

maven gwt:compile

I just get this error:
[WARNING] Error: Could not find or load main class com.google.gwt.dev.Compiler

Any ideas?

First, you don't want to call those goals from the CLI, use the lifecycle phases instead. And in a multi-module project, as a rule of thumb, in addition to always run Maven from the root, stick to "mvn package" and "mvn verify" (and possibly use -DskipTests to skip the tests). So: mvn package -DskipTests

Wrt the error, make sure you have gwt-dev declared as a compile-time dependency.

Daniel Florey

unread,
Mar 12, 2018, 8:52:24 AM3/12/18
to google-we...@googlegroups.com
Hey Thomas,

Thanks for your instant reply!
I've been thinking about Gradle (as I'm new to both) as well, but I need a bunch of Google tools (like Cloud Endpoints) which come with a Maven plugin.
So I thought it would be easier to go with Maven (?).

Thanks for the link to the sample app! 
It is using the outdated appengine plugin instead of the current appengine plugin using the gcloud tools from "com.google.cloud.tools", but probably I can use that as a starting point.

I really feel as a really dumb user right now, but is there a way to "checkout" the sample app in a simple way or do I have to clone the full repository or download each file individually?
Never used the Google git...

...and what do you mean by "make sure you have gwt-dev declared as a compile-time dependency"
Is it in the pom.xml? 
All I have in there is this:

<!-- GWT dependencies -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
</dependency>

Do I have to set a "scope"?

Thanks again,
Daniel


--
You received this message because you are subscribed to a topic in the Google Groups "GWT Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit/-7o22adLgls/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

dflorey

unread,
Mar 12, 2018, 9:10:46 AM3/12/18
to GWT Users
I tried to leverage your archetypes to get the gwt part (without appengine) running as a starting point.
What I did:
I created a maven project from the archetype (using the eclipse maven wizard).
I can see a nice multi-module project client/shared/server in my workspace.
As per your suggestion I just typed "mvn package -DskipTests" in the root/parent project.
But I get the same error message as before:

[INFO] --- gwt-maven-plugin:1.0-rc-9:compile (default-compile) @ formeditor-client ---
[WARNING] Error: Could not find or load main class com.google.gwt.dev.Compiler
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] formeditor ......................................... SUCCESS [  0.000 s]
[INFO] formeditor-shared .................................. SUCCESS [  0.926 s]
[INFO] formeditor-client .................................. FAILURE [  0.614 s]
[INFO] formeditor-server .................................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.002 s
[INFO] Finished at: 2018-03-12T14:09:09+01:00
[INFO] Final Memory: 35M/761M

I guess I'm missing a basic step like setting a environment variable to point to my gwt installation or something?

Thomas Broyer

unread,
Mar 12, 2018, 11:55:21 AM3/12/18
to GWT Users
Check that the JAR (~/.m2/repository/com/google/gwt/gwt-dev/2.8.2/gwt-dev-2.8.2.jar) is not corrupt.
Delete ~/.m2/repository/com/google/gwt/gwt-dev/2.8.2/ and re-run a build to download it again.

dflorey

unread,
Mar 18, 2018, 2:42:10 PM3/18/18
to GWT Users
That helped a lot! Thanks!
I've removed the .m2/repository and started from scratch.
I made some progress in the meantime and learned a bit about how to setup a local repository on the way to find the right structure.

I noticed that I cannot use the IsSerializable interface in the shared module, I had to replace the interface with the Serializable interface.
Looks like IsSerializable is not part of the gwt-servlet dependency?

I started with our core library. As there is no archetype for a gwt-lib I tried to start from the webapp archetype.
Then I switched the packaging from "gwt-app" to "gwt-lib" in the client module and from "war" to "pom" in the server module.
I've also removed all the tomcat and jetty plugins and the folders with the config for the webservers as I just want to build a lib.

I'm now getting an error in Eclipse in the pom telling me that "web.xml is missing and <failOnMissingWebXml> is set to 
 true"

It seems to build just fine though.

dflorey

unread,
Mar 19, 2018, 8:45:06 AM3/19/18
to GWT Users
I've migrated one of our smaller apps.
The module.gwt.xml is generated, nice!

I'm now trying to run the gwt-app.

In the old ant / Eclipse plugin days I could just click on Run and it launched all the required stuff in the background (app engine, code server etc.) so I'm a bit lost how to start the app.
We have some static resources in the the war directory (css, html launcher page), I don't know where to put these files so that they get picked up by the webserver.
I tried by putting them into the src/main/webapp directory, but this did not make it into the target war.

I tried both gwt:devmode and gwt:codeserver, both without luck.

Am I missing something obvious?

dflorey

unread,
Mar 19, 2018, 9:31:34 AM3/19/18
to GWT Users
As I test I just created a blank test project from the archetype.
I did not manage to run it either using "maven gwt:devmode".
Is there some additional configuration required to tell the plugin where to find the webapp?
The server launches just fine, an ancient swing window pops up, but the index.html is not there when going to 127.0.0.1:8888

Any ideas?

Thomas Broyer

unread,
Mar 19, 2018, 10:41:15 AM3/19/18
to GWT Users


On Monday, March 19, 2018 at 2:31:34 PM UTC+1, dflorey wrote:
As I test I just created a blank test project from the archetype.
I did not manage to run it either using "maven gwt:devmode".
Is there some additional configuration required to tell the plugin where to find the webapp?
The server launches just fine, an ancient swing window pops up, but the index.html is not there when going to 127.0.0.1:8888

Any ideas?

gwt:devmode will not package the app, you need to first do a "mvn package" to prepare the webapp; and do a "mvn package" again anytime you change any source file and/or dependency (you can configure Maven and/or your IDE to directly place classes from the module into the webapp's WEB-INF/classes; this saves you a few "mvn package").

When using external servers (recommended), you can configure them to automatically reload the webapp when a class is changed, and to pick web resources right from src/main/webapp.
Webapp will be on http://localhost:8080 (by default), served by the jetty-maven-plugin (or tomcat7-maven-plugin), configured to pick up the shared classes right from *-shared/target/classes (where your IDE will put them).

Daniel Florey

unread,
Mar 19, 2018, 11:03:50 AM3/19/18
to google-we...@googlegroups.com
Thanks, that was the missing info I was looking for (just checked the maven-plugin help etc.)!!
What is the recommended setup nowadays when using Eclipse?
Is it recommended to use the Eclipse plugin(s) for GWT/GAE or is it better to run everything from the command line?

Thanks again, you are the man!

dflorey

unread,
Mar 19, 2018, 12:41:01 PM3/19/18
to GWT Users
I've been trying to create a gwt-lib that contains some static web resources (fonts, css, ...) to be used in depending projects.
Where should I place these files? They used to be in the "public" directory on the same level as client/server/shared in the old days when there way just a single project layout.
I'd like to find them in the resulting war when declaring the library as a dependency.
Is this still possible or do I have to replicate the static web resources in each project that requires the gwt-lib?

Jens

unread,
Mar 19, 2018, 12:49:12 PM3/19/18
to GWT Users

I've been trying to create a gwt-lib that contains some static web resources (fonts, css, ...) to be used in depending projects.
Where should I place these files? They used to be in the "public" directory on the same level as client/server/shared in the old days when there way just a single project layout.
I'd like to find them in the resulting war when declaring the library as a dependency.
Is this still possible or do I have to replicate the static web resources in each project that requires the gwt-lib?

You can still do the same I guess. Your gwt-lib module should contain a GWT module (*.gwt.xml) and you can place resources into the public folder of that GWT module. The GWT compiler / SuperDevMode should pick that up and copy the resources to the GWT compile output folder once you have inherited your gwt-lib GWT module in other apps.

-- J.

Thomas Broyer

unread,
Mar 19, 2018, 1:43:07 PM3/19/18
to GWT Users


On Monday, March 19, 2018 at 4:03:50 PM UTC+1, dflorey wrote:
Thanks, that was the missing info I was looking for (just checked the maven-plugin help etc.)!!
What is the recommended setup nowadays when using Eclipse?
Is it recommended to use the Eclipse plugin(s) for GWT/GAE or is it better to run everything from the command line?

I certainly prefer to launch everything from Maven (whether on the command line or through the IDE; if only because developers can help one another whichever their IDE), but I don't think there's any "recommended setup", and the GWT Eclipse Plugin should (hopefully) work just as well. My personal take is: it must work without any IDE, and once that works, why both replicating things in an IDE where they most likely won't run the same and need to be debugged again.

For GAE, I really can't tell.
Also, IIRC, GWT Eclipse Plugin has a feature to launch both the server and GWT codeserver in a single click.
(I must say I haven't used Eclipse in a while, and never actually used the GWT Eclipse Plugin)
Reply all
Reply to author
Forward
0 new messages