How to Deploy Java Application JAR to AWS Beanstalk with Gradle

Vladimír Oraný
Stories by Agorapulse
3 min readNov 9, 2017

--

A long time ago, deploying WAR files to Tomcat was the only Java option for Elastic Beanstalk. Nowadays, you can run whatever application you want if you can wrap it into Docker. For Java applications this could be an overkill as running from a JAR is supported out of the box.

There are plenty of JVM frameworks which supports running from a JAR. For example:

There is also easy to use Gradle Beanstalk Plugin which currently is a bit misleading as on the first sight it may look it is only capable of deploying WAR files. Here is an excerpt of configuration from the README:

plugins {
id "fi.evident.beanstalk" version "0.1.1"
}

beanstalk {
s3Endpoint = "s3-eu-west-1.amazonaws.com"
beanstalkEndpoint = "elasticbeanstalk.eu-west-1.amazonaws.com"

deployments {
// Example to deploy to the same env
staging {
war = tasks.war
application = 'my-app'
environment = 'my-app-staging'
}
}
}

Luckily the war configuration property accepts anything you can pass to Project.file(Object) method. The actual behaviour depends on the platform which you have selected when you have created the environment (or the environment template).

Frameworks distributing applications as JAR usually already provides Gradle tasks for bundling applications to single archive such as bootRepackage or shadowJar so you can use them instead of war task:

staging {
war = tasks.shadowJar
application = 'my-app'
environment = 'my-app-staging'
}

Now you can only run deployStaging to deploy your application to Beanstalk.

You may not see the result immediately after deployment as by default Beanstalk listens on port 5000. You have to set the actual port as environment variable PORT in Configuration / Software Configuration. You can also add a configuration file to your deployment so you don't have to update the port manually from the UI for each new environment. Create file env.config in directory src/main/eb:

option_settings:
aws:elasticbeanstalk:application:environment:
PORT: 8080 # application port

Then you can create simple Zip task to create an application archive:

task beanstalkArchive(type: Zip, dependsOn: jar) {
from 'src/main/eb'
from tasks.shadowJar
}

And update your deployment configuration:

staging {
war = tasks.beanstalkArchive
application = 'my-app'
environment = 'my-app-staging'
}

Another use case for deploying JAR inside ZIP archive could be that your application requires running the application with some flags. In that case, you have to create a file called Procfile inside src/main/eb directory containing the full java command with all argument:

web: java -jar application.jar -Dwhatever=anything

It is important to keep the name of the application web as you can actually run more than one application using Procfile. It also requires that your JAR file has immutable name which can be easily achieved setting the archiveName on the Jar task e.g.

shadowJar {
archiveName = 'application.jar'
}

--

--

Vladimír Oraný
Stories by Agorapulse

Full Stack Developer and Test Facilitator at @agorapulse