The purpose of this article is to demonstrate how to run a Java process in Docker. Java can be developed in congruence with a number of frameworks, but that isn’t necessary in every case. Out of the box Java supports the execution of a scheduled task with just a packaged jar (Java archive) file. To improve the deployment of the executable jar, we will be running it in a docker container. This does NOT require the jar to be executed as a cron job nor as a Windows scheduled task.
Follow these steps to run your Java process in a Docker container.
Create your executable jar to be ran.
An executable jar can be created any number of ways. This example is a maven project that uses the maven-shade-plugin for packing the executable jar. The pom file below demonstrates how to build an executable jar file with the maven-shade-plugin.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>task-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>ExecuteTimer</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Note that this is just one way of building an executable jar, but not the only or recommended way.
Create a scheduled task in Java
You can schedule tasks in Java any number of ways. This example will use the TimerTask class.
import java.util.Date;
import java.util.TimerTask;
public class TimerExample extends TimerTask {
private String name;
public TimerExample(String n) {
this.name = n;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + name + " the task has executed successfully " + new Date());
}
}
Now execute this run method from within your main method.
import java.util.Timer;
public class ExecuteTimer {
public static void main(String[] args) {
TimerExample te1 = new TimerExample("Task1");
Timer t = new Timer();
t.scheduleAtFixedRate(te1, 0, 1000);
}
}
Note that in the maven-shade-plugin example above, the ExecuteTimer class is defined as the class having the main method to run.
Create a docker compose file using a Java image
There are a variety of java docker images available. This example will use an amazon corretto image for Java 11.
version: '3.8'
services:
task-test:
image: amazoncorretto:11-alpine3.15
container_name: task-test
restart: always
volumes:
- .:/usr/local/scripts/task-test/
command: java -jar /usr/local/scripts/task-test/target/task-test-1.0-SNAPSHOT.jar
task-test
is the name of the service being started.
image
is the image to pull from the docker repository at https://hub.docker.com/
container_name
is the custom name you are giving the container. We recommend setting a container name so that you can reference it by a known name if needed.
restart: always
means to restart the container any time it does unless it was explicitly killed. If the server is restarted, this docker container will also restart which is almost always the desired behavior of a scheduled task.
volumes
in this example is mounting the project directory to a location on the server. The project directory contains the executable jar which will be ran using the next option.
command
is the command to execute the Java process in Docker.
Conclusion – Java process in Docker
In conclusion, after running docker-compose up
the java process will now run as scheduled. To kill the process, just kill the docker container with docker kill task-test
.
Let us know in the comments if you have any questions or would like us to provide more examples on how to run a Java process in a docker container.
Read more of our posts on Java, Docker, and security centric programming.
Leave a Reply