GWT and AppEngine Convention, without IDE Configuration
A Maven seed project for GWT, Google App Engine and JDO
This project offers a conventional seed project for a full-stack application that is pre-configured and ready-to-go. The goal is to offer a simple, working example of a CRUD application, using an entity relationship framework, enterprise-level validation, which sits atop a cloud-based, schemaless, high-replication datastore that has zero dependency on an IDE. How is this done? The entire dependency management and build lifecycle configuration is done solely through Maven.
This project currently supports the following:
- Google Web Toolkit 2.7.0
- Google App Engine 1.9.18 through a schemaless high-replication datastore (HRD)
- DataNucleus JDO 3.0
- JUnit 4.12
- Google Chrome. Due to the limitations for symbol-map support in IE and Firefox, you need to test with Google Chrome to see error log messages logged by the UI.
This project is licensed under Apache License 2.0
A few years ago, I was working for a company who let developers use their preferred IDE, using a BYOD approach to the authoring environment. I thought that was very cool, and I also believe it’s an approach likely to gain favor as more companies move to a Docker containers for development.
Some developers kept their own lifecycle mappings for Eclipse, some developers worked purely from the command line, and others benefitted from how IntelliJ introspected parent POMs to understand dependencies. Some developers kept their own m2e configurations.
At the time, I didn’t have any experience with Maven. Lots of developers lack Maven experience, and there’s a steep learning curve with Maven, especially if you need to create an environment-specific configuration, such as working in Eclipse with m2e.
I prefer IntelliJ it for development, but my preferences shouldn’t dictate the team’s preferences. Lots of people prefer Eclipse or Netbeans. For my most recent application, I had a hard time finding a starting point for my GWT/GAE/JDO project that didn’t include IDE specific configuration, and I had a harder time finding documentation and examples which didn’t omit the intricacies between the different SDKs and frameworks.
So, when my company decided to move from Eclipse to IntelliJ, we came across a few issues with our migration. First, it became difficult to share a project between Eclipse and IntelliJ. We had been using Maven for dependency management, but not lifecycle management.
Issues migrating a GWT/GAE project from Eclipse to IntelliJ:
- I couldn’t find anyone who knew both IDEs well enough to help support the switch using Module configuration. How many developers work in two different IDEs on a regular basis?
- The default output folders are different between IntelliJ and Eclipse.
- Eclipse automatically adds the necessary dependencies to the classpath. IntelliJ requires you specify which dependencies get added to the classpath when creating Modules and adding framework support.
- IntelliJ natively supports GWT up to version 2.4 with module configuration (although it works beautifully with newer versions of GWT through Maven). However, when I first tried to set-up our project with IntelliJ modules, I received prompts to export GWT jars onto the classpath, and when I did export the jars to the classpath, I found some jar versions were out-of-synch with the version of GWT we specified.
- I found it difficult to find documentation on integrating GWT with Google App Engine.
There were the issues trying to configure Maven:
- There was too much research necessary to try and understand which Datanucleus libraries were required to work with the latest version of Google App Engine. Once I realized which libraries I needed, I couldn’t find an example showing which dependencies I could omit and which we needed if I used the appengine-maven-plugin.
- I spent a few hours trying to understand why there was a “datanucleus-appengine-maven” group ID, and an “appengine-datanucleus-maven” group ID.
- In the maven-gwt-project version 2.7, the mojo made it easier to integrate Google App Engine, but the brevity of the documentation caused a bloating of the classpath since I copied and pasted straight from the documentation. Ispent awhile trying to figure out which dependency was bloating the classpath (and when I say “bloated”, I’m really talking about a classpath that looks like a bag a toddler just ripped wide open a bag of Peanut M&Ms on a Twister Mat).
There were environmental issues with JDO
- On Windows, I ran into issues with memory allocation unless the entity path for enhancement was specific.
Sample Code vs Seed Project
This project is really a hybrid between a sample project and a seed project. Plaid Suit adds in some conventional code, configuration files, and assets to save you from having to incorporate “stuff” you’re 90% likely to write or include at one point or another, and it tries to remove any ambiguity by explicitly adding configuration files with default values, that would otherwise be unfamiliar, forgotten or missed.
A list of the assets added to the project is maintained in the project’s ReadMe.
When you approach a project like this, there are different frameworks which can be included. My goal is to deliver a project that works well across Eclipse, Maven or a Virtual envrionment such as Codenvy, that includes a conventional combination of Google platforms and APIs, and show how they work together using Maven. The goal is to deliver a project that takes into account the libraries, code, and files which make up 90% of the projects that use the stack utlized.
This seed project uses GWT for the UI, with a complete Model-View-Presenter approach. The example code comes from the GWT Examples, and has been tweaked to serve the purposes of this project.
This project uses GWT RPC services, instead of web services based on SOAP or REST. You’re welcome to fork the project and add examples of a different service-oriented-architecture.
- Google App-Engine error pages for each of the Google App-Engine error handlers
- Google App-Engine denial of service configuration, set-up with default values
- Google App Engine cron-job configuration, set-up with default values
- Google App Engine Task Queue configuration, set-up with default values
- HTML5 Boilerplate (H5BP) assets, such as favicon, robots.txt. humans.txt
- Google App-Engine datastore-indexes configuration is added with an explicit autoGenerate attribute
The seed project tries to address issues you might run into when building an application atop a fault-tolerant system. Namely, I try to catch common Google App Engine Datastore issues and report back to the user when an error might be resolved with a retry. I’ve added an exception which can carry messages from the server to the user.
Since the seed project uses App Engine’s schemaless, high-replication datastore, I decided to configure the App Engine tests around the absolute worst-case scenario available when setting up a project for eventual consistency. The lag time is the maximum lag time App Engine allows. The tests are limited to a single unit-test scenario, so you don’t have to deconstruct the seed project to begin setting up tests for your own project.
I find most projects lack the logging necessary to track down critical issues that surface for end-users in predictable workflows. I like the approach SaaS Exception logging tools such as AirBrake.io are pursuing, and with enough data and the addition of Artificial intelligence modeling, the SaaS exeption services should provide a wealth of information when it comes to helping teams sort out defects. However, those services need as much data as possible.
I spent a good deal of time trying to figure out the best way to set-up logging for a project that uses GWT (which logs to the client and potentially, the server), Google App Engine, and the requirements of the various dependencies (such as Datanucleus). For example, the Hibernate Validation dependencies for GWT specify an older version of the Hibernate Validation libraries, as well as SLF4J. Since I was forced to use the SLF4J, I didn’t see a reason to use other logging frameworks on the server, and set-up logging accordingly.
In addition, I believe a good seed project that utilizes an UncaughtExceptionHandler, so nothing goes unreported. So this project uses an explicit Uncaught Exception Handler at the root, with a delayed module creation to ensure the exception handler catches exceptions that may happen when the module is first instantiated.
I also wanted to find a logger that for GWT that didn’t add another logging framework to the classpath, but was able to log the entire exception as a simple parameter. I’ve seen code where the logging is done on the GWT UI by logging the exception’s cause and message independently because the logger only supported strings.
The seed project comes with GWT’s ServerSide Reporting enabled by default.
I believe each project needs some degree of reporting. I’ve added reporting tools inside of Maven to check for the following:
The PMD library is a static rule-set based code analyzer. To paraphrase, it helps identify:
- bugs-empty try, catch, finally, switch blocks
- Dead code-unused local variables, parameters and private methods
- Empty if/while statements
- Overcomplicated expressions-unnecessary “if” statements, “for” loops that could be ehanced loops
- Suboptimal code-wasteful string/stringbuffer usage
- Cases with high cyclomatic complexity measurements
- Duplicate code-copied, pasted code
One of my clients adopted a Silent Author approach to coding. It was truly lovely, because you would move from story to story, module to module, and immediately understand the underlying logic because it was familiar, contained sufficient vocabulary and semantics to understand the intent of the code, and it was a stress reducer because the consistency and quality of the code reduced the burden to come up to speed with an assignment and to bring on other developers if needed.
I have included Checkstyle to help enforce a Silent Author approach.
This project includes the Maven dependency for Checkstyle, but does not break a build if the code fails to adhere to a standard (a task better left to your integration platform). Since Checkstyle can be configured to use Google’s Code Standard, this project is configured to use Google’s Code Standard.
If you’re using Eclipse or IntelliJ, you can download the settings from google code:
To import the settings into IntelliJ
One of the nicest parts about building an application which uses Java for the UI and Server, is the ability to use the JSR-303 Bean Validation, and including consistent error messages and validation. I’ve added various classes for message fragments, which are shared between the client-side UI and JDO Entities.
Setting up a Maven project is pretty simple, but you’ll need to ensure your IDE supports Maven. If you’re using a modern version of Eclipse or IntellIJ, you already have Maven installed. Checkout the project from GitHub.
In Eclipse, you should note that the M2E and m-e-p are not compatible. I have designed this project to work without M2E, and to omit Eclipse artifacts. There are lots of popular Eclipse Maven plugins, but they may not be compatible with a pure Maven approach, so you may wish to try this project with a clean Eclipse install.
In IntelliJ, open the Maven Projects Tool Window
Once the project is checked out, you will only need to execute the following goals to launch the application:
Please let me know all suggestions or comments you have, or fork the project and submit a pull-request, and I’ll happily review changes and provide contributor credit.