Migrating a Java web app for deploy to AWS Elastic Beanstalk

This blog documents my experience in converting a Java web project in Eclipse. My start point is a Maven Java web project with a MySQL backend. My objective is to be able to deploy the site as a AWS Elastic Beanstalk application, using the AWS Toolkit for Eclipse.

Download and install AWS Eclipse Toolkit

The first step is to download and install AWS Eclipse Toolkit by following the documentation here.

Convert project into AWS Java web project

In order to deploy a web project to AWS, one can use the Eclipse Toolkit to create a AWS Java web project and work from there. For an already existing project, the following manual steps are needed.

First, create a dummy project by clicking on the AWS icon on the Eclipse toolbar, and then click on New AWS Java Web Project. Select the option to create the  Travel log sample web application. We only need the Eclipse WST settings of the project. Copy the following files from the .settings folder of the newly created project into the .settings folder of the maven web project:

  1. org.eclipse.wst.common.component
  2. org.eclipse.wst.common.project.facet.core.xml

Now modify the first file to use the maven project folder structure. For example, from

<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
 <wb-module deploy-name="aws-template">
 <wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
 <wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
 <property name="context-root" value="aws-template"/>
 <property name="java-output-path" value="/aws-template/build/classes"/>
 </wb-module>
</project-modules>

to

<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
 <wb-module deploy-name="myblog">
 <wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
 <wb-resource deploy-path="/" source-path="/target/myblog"/>
 <property name="context-root" value="myblog"/>
 <property name="java-output-path" value="/myblog/build/classes"/>
 </wb-module>
</project-modules>

Externalize JDBC properties for RDS

My project uses the bean post processor class org.springframework.beans.factory.config.PropertyPlaceholderConfigurer to load jdbc connection properties from a properties file to config the data source:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 destroy-method="close">
 <property name="driverClassName">
 <value>net.sf.log4jdbc.DriverSpy</value>
 </property>
 <property name="url">
 <value>${db.url}</value>
 </property>
 <property name="username">
 <value>${username}</value>
 </property>
 <property name="password">
 <value>${password}</value>
 </property>
 </bean>

and the properties file

# jdbc.properties
db.url=jdbc:log4jdbc:mysql://localhost:3306/blog
username=<app-user>
password=<app-password>

Instead of using a property file, the JDBC connection properties need to be externalised to be passed to the Elastic Beanstalk’s container (Tomcat). AWS Elastic Beanstalk provides a number of environment parameters for this and other purposes. You can find it by clicking the Environment Details -> Edit Configuration of the Elastic Beanstalk application environment and then choose the Container tab. Under the header Environment Properties, you will find a number of properties to use.  Below are the properties I use to store the JDBC properties:

AWS_ACCESS_KEY_ID – username

AWS_SECRET_KEY- password

JDBC_CONNECTION_STRING – JDBC connection string, e.g. jdbc:log4jdbc:mysql://<rds endpoint url>:3306/ebdb

Note by default, AWS Elastic Beanstalk use ebdb as the database name.

Update Spring bean definitions of datasource bean

The only thing left is to update the bean definition of the datasource using the above environment parameters to

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 destroy-method="close">
 <property name="driverClassName">
 <value>net.sf.log4jdbc.DriverSpy</value>
 </property>
 <property name="url">
 <value>${JDBC_CONNECTION_STRING}</value>
 </property>
 <property name="username">
 <value>${AWS_ACCESS_KEY_ID}</value>
 </property>
 <property name="password">
 <value>${AWS_SECRET_KEY}</value>
 </property>
 </bean>

That’s it, the PropertyPlaceholderConfigurer class will resolve the properties using the JVM environment properties passed into the Tomcat container. The jdbc.properties file is no longer used and can be deleted.

As an aside, My project uses jetty locally and I have to add the following to the JVM properties of the Eclipse Run Configuration (under JRE->VM arguments)

-DJDBC_CONNECTION_STRING=jdbc:log4jdbc:mysql://localhost:3306/blog
-DAWS_ACCESS_KEY_ID=root
-DAWS_SECRET_KEY=root

About Raymond Lee
Professional Java/EE Developer, software development technology enthusiast.

Comments are closed.