Originally published on 2010-03-10; fully revised and updated.
This article explains a classic pattern for running Java EE applications on Amazon EC2 using a Groovy framework called EC2Deploy. If you maintain legacy deployment automation or want to understand early cloud-era deployment design, this walkthrough shows the end-to-end flow: infrastructure launch, database and app server setup, WAR deployment, load testing, and environment teardown.
Why this approach mattered for Java EE teams
The original post addressed a real pain point: performance and environment testing required hardware that was expensive and slow to obtain. EC2 made on-demand servers possible, and EC2Deploy wrapped that capability into a developer-friendly API for multi-node test environments.
The source article also referenced then-current EC2 pricing and server-count limits, plus selectable server types. Treat those figures as historical context, not current AWS pricing or quotas.
EC2Deploy workflow and architecture
At a high level, EC2Deploy reads AWS properties, builds a cluster specification, starts EC2 instances, configures MySQL/Tomcat/Apache, deploys the application, runs JMeter tests, and then stops the instances.
flowchart TD
A[Groovy test script] --> B[Load aws.properties]
B --> C[Build ClusterSpec]
C --> D[Call cluster.start]
D --> E[Launch EC2 instances]
E --> F[Init MySQL master and slave]
F --> G[Upload DML and WAR to S3 cache]
G --> H[Deploy app on Tomcat]
H --> I[Configure Apache load balancer]
I --> J[Run cluster.loadTest with JMeter]
J --> K[Collect CPU latency throughput report]
K --> L[Call cluster.stop]
Core API objects and methods
The original code uses a small set of objects and fluent methods to describe both infrastructure and application behavior.
| Object or method | Role in the workflow |
|---|---|
| AWSProperties(“/path/to/aws.properties”) | Loads AWS credentials and AMI-related properties. |
| new EC2(awsProperties) | Creates the EC2 client wrapper used by EC2Deploy. |
| ClusterSpec.schema(…) | Defines DB schema name, user/password map, and DML scripts. |
| ClusterSpec.slaves(1) | Specifies the number of MySQL slave nodes. |
| ClusterSpec.tomcats(1) | Specifies the number of Tomcat nodes. |
| ClusterSpec.webApp(explodedWar, “ptrack”) | Declares exploded WAR path and context root. |
| ClusterSpec.catalinaOptsBuilder(…) | Builds Tomcat JVM and app properties, including DB host wiring. |
| cluster.start() | Provisions instances and performs configuration/deployment steps. |
| cluster.loadTest(“…SimpleTest.jmx”, [1,2]) | Runs JMeter tests at multiple thread counts. |
| cluster.stop() | Stops the EC2 instances when testing is complete. |
Annotated Groovy example
The following script is a cleaned-up version of the original example, preserving the same structure and intent.
class ClusterTest extends GroovyTestCase {
void testSomething() {
AWSProperties awsProperties = new AWSProperties("/path/to/aws.properties")
def ec2 = new EC2(awsProperties)
def explodedWar = "/path/to/projecttrack/webapp/target/ptrack"
ClusterSpec clusterSpec = new ClusterSpec()
.schema("ptrack", ["ptrack": "ptrack"], [
"src/test/resources/testdml1.sql",
"src/test/resources/testdml2.sql"
])
.slaves(1)
.tomcats(1)
.webApp(explodedWar, "ptrack")
.catalinaOptsBuilder({ builder, databasePrivateDnsName ->
builder.arg("-Xmx500m")
builder.prop("com.sun.management.jmxremote")
builder.prop("com.sun.management.jmxremote.port", 8091)
builder.prop("com.sun.management.jmxremote.authenticate", false)
builder.prop("com.sun.management.jmxremote.ssl", false)
builder.prop("ptrack.application.environment", "ec2")
builder.prop("log4j.configuration", "log4j-minimal.properties")
builder.prop("jdbc.db.server", databasePrivateDnsName)
})
SimpleCluster cluster = new SimpleCluster(ec2, clusterSpec)
cluster.start()
cluster.loadTest("/path/to/functionalTests/jmeter/SimpleTest.jmx", [1, 2])
cluster.stop()
}
}Code language: JavaScript (javascript)
What happens during cluster.start()
- 1) Launch EC2 instances from the configured appliance AMI.
- 2) Initialize the MySQL master database.
- 3) Create the MySQL slave.
- 4) Create schema and users.
- 5) Run DML scripts.
- 6) Cache deployment artifacts in Amazon S3.
- 7) Deploy web applications on each Tomcat node.
- 8) Configure Apache to balance traffic across Tomcat nodes.
In the original description, DML files were cached in a bucket named tmp–dml, and web apps were cached in -tmp-war to avoid repeatedly uploading unchanged files.
Running JMeter load tests with thread ramps
EC2Deploy can execute a JMeter plan multiple times using different thread counts. In the source example, it runs once with one thread and then with two threads.
cluster.loadTest("/path/to/functionalTests/jmeter/SimpleTest.jmx", [1, 2])Code language: JavaScript (javascript)
Per the original article, each run produced metrics including CPU utilization, average response time, and throughput.
EC2Deploy-era pattern vs common modern alternatives
| Need in this workflow | EC2Deploy-era implementation | Common modern option |
|---|---|---|
| Provision test infrastructure | Groovy wrapper around EC2 APIs | Terraform or AWS CloudFormation |
| Configure node software stack | Custom appliance AMI and startup logic | Immutable images plus config automation |
| Distribute deployment artifacts | S3 cache buckets for DML and exploded WAR files | Artifact repositories and object storage pipelines |
| Run load tests programmatically | JMeter invoked by cluster.loadTest() | JMeter in CI/CD jobs or dedicated test runners |
| Tear down temporary environments | cluster.stop() | Automated destroy stages in CI/CD |
Common pitfalls and best practices
- Do not reuse historical EC2 price or quota assumptions for planning.
- Keep credentials out of source-controlled property files; use secret management.
- Treat performance environments as ephemeral and automate full teardown to control cost.
- Validate old S3 bucket naming and permissions against current security policies.
- Prefer reproducible infrastructure definitions over long-lived manually tuned instances.
Historical note preserved from the source: EC2Deploy and an associated Maven plugin were announced as available in this post: EC2Deploy and the Cloud Tools Maven plugin are now available.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services — all in one place.
Explore Hospitals