Dropwizard + App Engine Flexible

Deploying Dropwizard on App Engine Flex

A few months ago we started working on a project which involved deploying Dropwizard on Google Cloud Platform. We researched the feasible solutions and App Engine was one of the top contenders. Below, I’ll walk you through our progress trying to deploy Dropwizard on App Engine, the issues we faced and the solutions we found for them.

App Engine & Dropwizard

App Engine provides a lot of great features out of the box, including load-balancing, versioning and more. It can scale up/down very effectively which is why we decided to use it with Dropwizard – our favourite REST API development framework. Deploying Dropwizard on App Engine wasn’t a straight forward process, here’s why.

War vs Jar

Dropwizard usually deploys as a jar (Java Application Archive) file, which includes jetty (the web server) inside it. In other words, it’s a fully functioning web server that includes the app. App Engine on the other hand expects the app to be deployed as a war (Web Application Archive) file, and App Engine deploys the war files on a web server.

This means we needed to turn the Dropwizard into a war file and remove jetty from it. There are ways to deploy a Dropwizard as a war file, all of them involve things that look like hacks. The options we found are Wizard in a box and WizToWar.

Servlet 2.5 vs Servlet 3

We followed the steps described above and tried deploying on App Engine, but we weren’t getting anywhere. It took us a while to figure out the reason behind the errors we were getting. We had to download the source code for Dropwziard and dig into it to figure out something we should’ve figured out way sooner:

  • Dropwizard depends on Servlet API version 3 or higher.
  • App Engine standard environment is still on Servlet API version 2.5 (you can read this 7 year old thread on that topic)

With all of that information we were able to say that:

It’s impossible to deploy Dropwizard on App Engine standard environment

Flexible Environment to Rescue

Around then is when we learned about App Engine Flexible Environments. It’s a new service provided by Google App Engine, still in beta. It allows developers to have access to all the features of App Engine, without being tied to the limitations that come along with it. It has 2 Java Runtime Environments available: Java 8 with Jetty 9.3 and Java 8 (without any web server).

The Java 8 environment was the best fit to what we needed and is what we’ll walk you through below. To be able to use it, we had to ask the Google Cloud Platform team to add us to the beta program, though I’ve heard they are going to release it to public later this quarter.

App Engine Flex – How to

You can clone the sample project from github so you have all the code in one place. It’s a simple hello world Dropwziard application with Gradle as the build tool.

To run the app locally you can use this command:

./gradlew run

Then visit the http://localhost:8080/ and you should see hello world – dropwizard app engine flex

Now that you can run it locally, let’s try deploying it on App Engine Flex.

Preparation

All the code you need for deployment to App Engine is in a folder called appengine.

appengine
--app.yaml
--Dockerfile

As you can see the structure of that folder, there are only 2 files.

  • app.ayml is where we define App Engine related variables
  • Dockerfile contains what App Engine needs to deploy and run our app.

app.yaml

You can use the app.yaml file to configure your App Engine application. It has been used in App Engine standard environment as well. Here is a full reference you can use to get more familiar with it.

What we have in app.yaml is very minimal:

runtime: custom
env: flex
service: hello-world

We are setting only 3 variables:

  • env: flex means we are using the flexible environment, not the standard environment
  • runtime: custom means we are using Java 8 runtime, with no Jetty.
  • service: hello-world is just giving a name to the service we are going to deploy this app under.

Dockerfile

This is one of the main differences of the flexible environment and the standard environment. The flexible environment is based on Google Compute Engine. The deployment is happening on the Compute Engine although we are getting the benefits of having an App Engine service. The Dockerfile is how we define how our app should run on Compute Engine.

Let’s have a look at the Dockerfile:

FROM gcr.io/google_appengine/openjdk8
VOLUME /tmp
ADD app.jar app.jar
ADD config.yaml config.yaml
CMD [ "java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar", "server", "config.yaml"]

First of all, we are starting from gcr.io/google_appengine/openjdk8. It’s base docker image which is specific to Java 8 Runtime of the App Engine Flex. Then we are adding app.jar(our Dropwizard app) and config.yaml(the configuration file). In the last command we are telling docker how to run our app: Run app.jar with arguments server and config.yaml.

Jar vs ShadowJar

As we are going to run our Dropwizard app from a jar file, that jar file has to have all the dependencies required to run the app. Gradle’s java plugin doesn’t do this by default, that’s why we are using shadow-jar plugin.

To create a jar file with all the dependencies you can use this command:

./gradlew shadowJar

gcloud

gcloud is a tool that provides a command line interface for Google Cloud Platform. We are going to use it to deploy our app on App Engine Flexible environment.

Login

In order to be able to run commands on Google Cloud Platform using gcloud, you need to first login. You can do that via

gcloud auth login

This will redirect you to your browser to login. One other option is to login with service accounts. It’s what we use on for continuous deployment. You can read more about that here: Activate a Service Account

Get ready to deploy

As you saw in Dockerfile, you need to copy app.jar and config.yaml to the appengine folder for the deployment to be able to run successfully. In our continuous integration we do that with a script, but here you can just copy those files.

Deploy

You have everything ready! Now you just need to initiate the deployment process. First you need to set the project you are going to deploy to, and then deploy it with a version number. If version number is empty, it will generate a version number using the date and time of deployment. You have to run this commands from inside the appengine folder.

gcloud config set project my-dropwizard
gcloud app deploy --version=1.0

Check Deployment

If everything goes well, you should have your Dropwizard app deployed and can look at it in the cloud. For that you can use this command:

gcloud app browse -s hello-world

You can also look at your app logs via

gcloud app logs read

Results

It took us a while to figure out the ins and outs of deploying Dropwizard on App Engine, but the Google Cloud Platform team was super helpful and responsive throughout the process. We learned a lot along the way but the most important thing was that it is possible to deploy the Dropwizard application on the App Engine Flexible environment.

I hope sharing this with you will save you a bit of time and make the process easier. If you have any issues, feel free to comment here and we’ll answer as soon as we can.

Good luck!

Amin Yazdani

Amin Yazdani

Director of Technology at A.Y. Technologies
Founder of A.Y. Technologies, Amin is formerly Senior Software Architect at Dun & Bradstreet and Solutions Engineer at Indicee. He has a wealth of experience and understanding of the software and applications industry, particularly as it pertains to cloud computing, and web application solutions.
Amin Yazdani

Latest posts by Amin Yazdani (see all)

2 Comments
  1. Suvodeep Pyne 1 year ago

    This was a lifesaver! Thanks a ton!

    It is possible to do java8 directly without providing docker config. (It auto manages the docker config internally) However, if you want to send an argument to your executable or you have an exploded binary instead of a single fat (shadow) jar, then you have to choose the custom runtime.

    • Author
      Amin Yazdani 1 year ago

      Hi Suvodeep,
      You are completely correct. Google Cloud has added Java 8 support on App Engine Standard Environment as well, which means now you have multiple options for using Java 8 on App Engine.

Leave a reply

Your email address will not be published. Required fields are marked *

©2019 A.Y.Technologies

Log in with your credentials

Forgot your details?