Development Tools

OpenJDK on AWS with Support by cloudimg User Guide

| Product: OpenJDK on AWS with Support by cloudimg

Overview

The OpenJDK on AWS AMI by cloudimg provides a fully preconfigured OpenJDK (Open Java Development Kit) installation ready to run on Amazon EC2. OpenJDK is the official open source reference implementation of the Java Platform, Standard Edition (Java SE), providing the Java Runtime Environment (JRE), the Java compiler (javac), and the complete set of Java development tools needed to build, test, and run Java applications.

This AMI is designed for developers and operations teams who need a clean, supported Java environment on AWS without the overhead of manual installation and configuration. OpenJDK is installed at /usr/java and is automatically updated on first boot to ensure you are running the latest available version from the system package repositories.

Whether you are running Java application servers, building microservices, executing batch processing jobs, or developing Java applications, this AMI provides a solid foundation with cloudimg's 24/7 support backing.

Visit www.cloudimg.co.uk to explore the full catalogue of preconfigured AMIs available on the AWS Marketplace.


Prerequisites

Before launching the OpenJDK AMI, ensure you have the following in place.

AWS Account You need an active AWS account with permissions to launch EC2 instances and manage security groups.

EC2 Key Pair Create or select an existing EC2 key pair in the region where you plan to launch the instance. This key pair is required for SSH authentication.

Security Group Configuration Your security group must allow inbound traffic on the following ports:

Protocol Type Port Description
SSH TCP 22 SSH connectivity for remote administration

If you plan to run a Java application that listens on additional ports (such as a web server on port 8080 or an API on a custom port), add those ports to your security group as needed.

Restrict SSH access to your own IP address or a trusted CIDR range.

Minimum System Requirements

Minimum CPU Minimum RAM Required Disk Space
1 vCPU 1 GB 20 GB

For Java applications with significant memory requirements, choose an instance type with sufficient RAM. The JVM heap size is typically configured to use a portion of available system memory, so plan accordingly based on your application's needs.


Step by Step Setup

Step 1: Launch the Instance

  1. Open the AWS Marketplace listing for OpenJDK on AWS by cloudimg.
  2. Click Continue to Subscribe, then Continue to Configuration.
  3. Select your preferred AWS Region and instance type.
  4. On the launch page, choose your VPC, subnet, and assign the security group you prepared above.
  5. Select your EC2 key pair and launch the instance.

Step 2: Wait for Status Checks

Allow the EC2 instance to reach 2/2 status checks passed before attempting to connect. The instance runs an initial boot update script that applies the latest operating system patches and ensures OpenJDK is up to date, so the first boot may take a few minutes longer than usual.

If you attempt to connect before both status checks have passed, you may see errors such as:

Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
ec2-user@your-instance-ip's password:

This is expected behaviour during early boot. Wait for the status checks to complete and try again.

Step 3: Connect via SSH

Connect to the instance using your private key:

ssh -i /path/to/your-key.pem ec2-user@<PUBLIC_IP>

Replace <PUBLIC_IP> with the public IP address or public DNS name shown in the EC2 console.

Step 4: Switch to the Root User

Once connected as ec2-user, switch to the root user for administrative tasks:

sudo su -

Step 5: Verify the Java Installation

Check the installed Java version:

java -version

This will display the OpenJDK version, runtime environment, and VM details. The version may be newer than expected if the initial boot update script installed a more recent release.

Step 6: Verify the Java Compiler

Confirm the Java compiler is available:

javac -version

This verifies that the full JDK (not just the JRE) is installed and ready for compiling Java source code.

Step 7: Check JAVA_HOME

Verify the JAVA_HOME environment variable is set:

echo $JAVA_HOME

If JAVA_HOME is not set in your shell session, you can set it manually:

export JAVA_HOME=/usr/java

To make this permanent, add the export line to your shell profile file (~/.bashrc or ~/.bash_profile).


Server Components

The OpenJDK AMI includes the following preconfigured component.

Component Software Home Description
OpenJDK /usr/java Open source Java Development Kit including JRE, compiler, and development tools

The OpenJDK installation includes: - java command for running Java applications - javac compiler for compiling Java source code - jar tool for creating and managing JAR archives - jdb debugger for debugging Java programs - javadoc tool for generating API documentation - keytool for managing cryptographic keys and certificates - jps for listing running Java processes - jstack for printing Java thread stack traces - jmap for printing memory maps of Java processes - jstat for monitoring JVM statistics


Filesystem Layout

The AMI uses a straightforward filesystem layout with the operating system and Java installed on the root volume.

Mount Point Description
/ Root filesystem containing the operating system and all software
/boot Operating system kernel files

Key directories and their purposes:

Path Purpose
/usr/java OpenJDK installation directory (JAVA_HOME)
/usr/java/bin Java binaries including java, javac, jar, and other tools
/usr/java/lib Java libraries and runtime support files
/usr/java/conf Java configuration files including security settings
/usr/java/include C header files for the Java Native Interface (JNI)
/stage/scripts cloudimg provisioning scripts and log files

Managing Services

OpenJDK itself is not a service but a development platform and runtime. Java applications that you deploy on this instance may be run as services or background processes.

Running a Java Application

java -jar /path/to/your-application.jar

Running a Java Application in the Background

nohup java -jar /path/to/your-application.jar > /var/log/myapp.log 2>&1 &

Running a Java Application as a Systemd Service

For production deployments, create a systemd service unit to manage your Java application:

cat > /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=My Java Application
After=network.target

[Service]
Type=simple
User=ec2-user
ExecStart=/usr/java/bin/java -jar /opt/myapp/application.jar
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

Enable and start the service:

systemctl daemon-reload
systemctl enable myapp
systemctl start myapp

Manage the service:

# Check status
systemctl status myapp

# Stop the service
systemctl stop myapp

# Restart the service
systemctl restart myapp

# View logs
journalctl -u myapp -f

Scripts and Log Files

The AMI includes the following scripts and log files created by cloudimg.

Script or Log Path Description
initial_boot_update.sh /stage/scripts Updates the operating system with the latest available patches on first boot
initial_boot_update.log /stage/scripts Output log from the initial boot update script

Disabling the Initial Boot Update Script

The OS update script runs automatically on every reboot via crontab. If you prefer to manage updates manually, you can disable it:

rm -f /stage/scripts/initial_boot_update.sh

crontab -e
# DELETE THE BELOW LINE, SAVE AND EXIT THE FILE:
@reboot /stage/scripts/initial_boot_update.sh

Common Java Operations

Compiling and Running a Java Program

Create a simple Java file to test the installation:

cat > HelloWorld.java << 'EOF'
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello from OpenJDK on AWS!");
    }
}
EOF

javac HelloWorld.java
java HelloWorld

Checking Available Java Alternatives

If multiple Java versions are installed, you can switch between them:

alternatives --config java

Setting JVM Memory Options

When running Java applications, configure the heap size based on your instance's available memory:

# Set initial and maximum heap to 2GB
java -Xms2g -Xmx2g -jar application.jar

# Set heap as a percentage of available RAM (Java 10+)
java -XX:MaxRAMPercentage=75.0 -jar application.jar

Creating a JAR File

# Compile source files
javac -d build src/*.java

# Create a JAR archive
jar cf myapp.jar -C build .

# Create an executable JAR with a manifest
jar cfe myapp.jar com.example.Main -C build .

Monitoring Java Processes

# List running Java processes
jps -lv

# Show thread dump for a Java process
jstack <PID>

# Show heap usage summary
jmap -heap <PID>

# Monitor JVM statistics
jstat -gc <PID> 1000

Working with Build Tools

This AMI provides a clean Java environment that you can extend with build tools as needed.

Installing Apache Maven

cd /opt
wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz
tar xzf apache-maven-3.9.6-bin.tar.gz
ln -s apache-maven-3.9.6 maven

echo 'export M2_HOME=/opt/maven' >> /etc/profile.d/maven.sh
echo 'export PATH=$M2_HOME/bin:$PATH' >> /etc/profile.d/maven.sh
source /etc/profile.d/maven.sh

mvn --version

Installing Gradle

cd /opt
wget https://services.gradle.org/distributions/gradle-8.5-bin.zip
unzip gradle-8.5-bin.zip
ln -s gradle-8.5 gradle

echo 'export GRADLE_HOME=/opt/gradle' >> /etc/profile.d/gradle.sh
echo 'export PATH=$GRADLE_HOME/bin:$PATH' >> /etc/profile.d/gradle.sh
source /etc/profile.d/gradle.sh

gradle --version

Troubleshooting

Cannot connect via SSH

  • Confirm the instance has reached 2/2 status checks in the EC2 console.
  • Verify your security group allows inbound TCP traffic on port 22 from your IP address.
  • Ensure you are using the correct key pair and connecting as ec2-user.
  • Check that the key file permissions are set correctly: chmod 400 /path/to/your-key.pem.

Java command not found

  • Verify OpenJDK is installed: ls -la /usr/java.
  • Check if the Java binary is on the PATH: which java.
  • If not on the PATH, add it manually: export PATH=/usr/java/bin:$PATH.
  • The initial boot update may have changed the Java installation location. Check alternatives: alternatives --config java.

JAVA_HOME is not set

  • Set JAVA_HOME manually: export JAVA_HOME=/usr/java.
  • To make it permanent, add to /etc/profile.d/java.sh: echo 'export JAVA_HOME=/usr/java' > /etc/profile.d/java.sh echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile.d/java.sh source /etc/profile.d/java.sh

Java application runs out of memory

  • Increase the JVM heap size: java -Xmx4g -jar application.jar.
  • Consider upgrading to an instance type with more RAM.
  • Monitor memory usage with jstat -gc <PID> 1000 or jmap -heap <PID>.
  • Check for memory leaks using heap dump analysis: jmap -dump:format=b,file=heap.hprof <PID>.

Java application fails to bind to a port

  • Check if the port is already in use: netstat -tlnp | grep <PORT>.
  • Ensure the application is not trying to bind to a privileged port (below 1024) without root permissions.
  • Verify the security group allows inbound traffic on the port your application uses.

Initial boot update is taking a long time

  • The first boot runs a full OS update which can take several minutes.
  • Monitor progress: tail -f /stage/scripts/initial_boot_update.log.

Security Recommendations

Keep Java Updated

Regularly update OpenJDK to receive the latest security patches:

yum update java* -y

Alternatively, keep the initial boot update script enabled to automatically apply updates on reboot.

Restrict SSH Access

Limit SSH (port 22) to specific trusted IP addresses in your security group. Consider using AWS Systems Manager Session Manager as an alternative to direct SSH access.

Apply Operating System Updates

Keep the full operating system up to date:

yum update -y

Run Java Applications as Non Root Users

Never run production Java applications as the root user. Create a dedicated service account:

useradd -r -s /sbin/nologin myappuser
chown -R myappuser:myappuser /opt/myapp

Use systemd service units (as shown in the Managing Services section) to run applications under the dedicated user.

Configure Java Security Settings

Review and configure Java security settings in /usr/java/conf/security/java.security. Key settings include: - Disabling weak TLS protocols - Configuring trusted certificate authorities - Setting secure random number generator algorithms

Use Security Manager for Untrusted Code

If running untrusted or third party Java code, consider using the Java Security Manager to restrict permissions:

java -Djava.security.manager -Djava.security.policy=myapp.policy -jar application.jar

Enable TLS for Network Applications

When your Java application serves network traffic, always configure TLS. Use the keytool command to manage keystores and certificates:

# Generate a self-signed certificate for testing
keytool -genkeypair -alias myapp -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365

For production, use certificates from a trusted certificate authority.

Monitor and Audit

Enable Java Management Extensions (JMX) monitoring for production applications and integrate with your monitoring infrastructure:

java -Dcom.sun.management.jmxremote \
     -Dcom.sun.management.jmxremote.port=9010 \
     -Dcom.sun.management.jmxremote.authenticate=true \
     -Dcom.sun.management.jmxremote.ssl=true \
     -jar application.jar

Backup Your Applications

Use AWS EBS snapshots for volume level backups. For application specific backups, regularly archive your deployment directories and configuration files.


Support

If you encounter any issues not covered in this guide or need further assistance, the cloudimg support team is available 24/7.

Email: support@cloudimg.co.uk Phone: (+44) 02045382725 Website: www.cloudimg.co.uk Address: 3rd Floor, 86 90 Paul Street, London, EC2A 4NE

When contacting support, please include your EC2 instance ID, the AWS region, and a description of the issue along with any relevant log output.