Deployment guide

OpenJDK on AWS with Support by Sac

Overview

OpenJDK (Open Java Development Kit) is the official open-source reference implementation of the Java Platform, Standard Edition (Java SE). It provides the Java Runtime Environment (JRE), the Java compiler (javac) and the full set of Java development tools you need to build, test and run Java applications.

The SecureAnyCloud OpenJDK AMI gives developers and operations teams a clean, supported Java environment on Amazon EC2, without manual installation and configuration. OpenJDK is installed at /usr/java and is updated on first boot, so you run the latest version available from the system package repositories.

What you get:

  • A preconfigured OpenJDK installation at /usr/java, with the JRE, the compiler and the development tools
  • An initial boot update that applies the latest operating system patches and brings OpenJDK up to date
  • A foundation for Java application servers, microservices, batch processing jobs and Java development
  • 24/7 SecureAnyCloud support

Visit secureanycloud.com to explore the full catalogue of preconfigured AMIs available on the AWS Marketplace.

Prerequisites

Before you launch the OpenJDK AMI, make sure you have the following in place.

  • AWS account: an active account with permissions to launch EC2 instances and manage security groups.
  • EC2 key pair: a new or existing key pair in the Region where you plan to launch the instance. SSH authentication requires it.
  • Security group: a group that allows inbound SSH (TCP, port 22) for remote administration. Restrict SSH to your own IP address or a trusted CIDR range.

If your Java application 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.

Minimum system requirements: 1 vCPU, 1 GB RAM and 20 GB of disk space.

For Java applications with significant memory requirements, choose an instance type with enough RAM. The JVM heap size is typically set to a portion of the available system memory, so plan according to your application's needs.

Step by Step Setup

Step 1: Launch the Instance

  • Open the AWS Marketplace listing for OpenJDK on AWS by SecureAnyCloud.
  • Choose Continue to Subscribe, then Continue to Configuration.
  • Select your preferred AWS Region and instance type.
  • On the launch page, choose your VPC and subnet, and assign the security group you prepared above.
  • Select your EC2 key pair and launch the instance.

Step 2: Wait for Status Checks

Wait until the EC2 instance shows 2/2 status checks passed before you connect. The instance runs an initial boot update script that applies the latest operating system patches and brings OpenJDK up to date. The first boot can take a few minutes longer than usual.

If you 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 during early boot. Wait for the status checks to complete, then try again.

Step 3: Connect via SSH

Connect to the instance with 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

After you connect 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

The output shows the OpenJDK version, the runtime environment and the VM details. The version may be newer than you expect if the initial boot update script installed a more recent release.

Step 6: Verify the Java Compiler

Confirm that the Java compiler is available:

javac -version

This confirms that the full JDK, not just the JRE, is installed and ready to compile Java source code.

Step 7: Check JAVA_HOME

Verify that the JAVA_HOME environment variable is set:

echo $JAVA_HOME

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

export JAVA_HOME=/usr/java

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

Server Components

The AMI includes one preconfigured component: OpenJDK, with its software home at /usr/java. It is the open-source Java Development Kit, including the JRE, the compiler and the development tools.

The installation includes these tools:

  • java: runs Java applications
  • javac: compiles Java source code
  • jar: creates and manages JAR archives
  • jdb: debugs Java programs
  • javadoc: generates API documentation
  • keytool: manages cryptographic keys and certificates
  • jps: lists running Java processes
  • jstack: prints Java thread stack traces
  • jmap: prints memory maps of Java processes
  • jstat: monitors JVM statistics

Filesystem Layout

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

Mount points:

  • / : the root filesystem, containing the operating system and all software
  • /boot : the operating system kernel files

Key directories:

  • /usr/java : the 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 : SecureAnyCloud provisioning scripts and log files

Managing Services

OpenJDK is a development platform and runtime, not a service. The Java applications you deploy on this instance can run as services or as 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

SecureAnyCloud adds two files to the AMI, both in /stage/scripts:

  • initial_boot_update.sh: updates the operating system with the latest available patches on first boot
  • initial_boot_update.log: the output log from the initial boot update script

Disabling the Initial Boot Update Script

The OS update script runs automatically on every reboot through crontab. If you prefer to manage updates manually, 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, then compile and run it:

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 several Java versions are installed, switch between them with:

alternatives --config java

Setting JVM Memory Options

When you run Java applications, set the heap size according to 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 the build tools you need.

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 that the instance has reached 2/2 status checks in the EC2 console.
  • Verify that your security group allows inbound TCP traffic on port 22 from your IP address.
  • Make sure you are using the correct key pair and connecting as ec2-user.
  • Check the key file permissions: chmod 400 /path/to/your-key.pem.

Java command not found

  • Verify that OpenJDK is installed: ls -la /usr/java.
  • Check whether the Java binary is on the PATH: which java.
  • If it is 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 the alternatives: alternatives --config java.

JAVA_HOME is not set

  • Set JAVA_HOME manually: export JAVA_HOME=/usr/java.
  • To make it permanent, add the following 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 moving to an instance type with more RAM.
  • Monitor memory usage with jstat -gc <PID> 1000 or jmap -heap <PID>.
  • Check for memory leaks with heap dump analysis: jmap -dump:format=b,file=heap.hprof <PID>.

Java application fails to bind to a port

  • Check whether the port is already in use: netstat -tlnp | grep <PORT>.
  • Make sure the application is not binding to a privileged port (below 1024) without root permissions.
  • Verify that 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

Update OpenJDK regularly to receive the latest security patches:

yum update java* -y

Alternatively, keep the initial boot update script enabled so that updates are applied automatically on reboot.

Restrict SSH Access

Limit SSH (port 22) to specific trusted IP addresses in your security group. Consider 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 the 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 you run 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 it 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

Back Up Your Applications

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

Support

If you hit an issue that this guide does not cover, or you need further help, the SecureAnyCloud support team is available 24/7.

  • Email: sales@secureanycloud.com
  • Phone: (+44) 02045382725
  • Website: secureanycloud.com
  • Address: 3rd Floor, 86 90 Paul Street, London, EC2A 4NE

When you contact support, include your EC2 instance ID, the AWS Region, a description of the issue and any relevant log output.

Deploy on AWS

Launch OpenJDK on AWS with Support by SecureAnyCloud with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS

Launch OpenJDK on AWS with Support by SecureAnyCloud with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com