Skip to main content

Play with Docker and Java

Learn how to compile and run Java applications using Docker. Set up a Java development environment quickly without local installation, perfect for developers new to Java and Docker.

· 5 min read
View raw
Christophe
Markdown, WSL and Docker lover ~ Insatiable curious.
Cet article existe aussi en français — lire la version française.

Changelog

Latest
Replaced deprecated openjdk:11 Docker Hub image (deprecated Dec 2022) with eclipse-temurin:21 (official Adoptium LTS successor)

Play with Docker and Java

⚡
TL;DR

This article shows how to compile and run Java with zero local install, using the official openjdk Docker image: docker run ... eclipse-temurin:21 javac Main.java to compile, then docker run ... eclipse-temurin:21 java Main to execute, including a second example that calls a REST API from Java and prints the JSON response.

In this post, we'll play with Docker and Java, using the ready-to-use Java images published on Docker Hub. The only thing you need on your machine is Docker itself.

The same "zero install, just an image" approach is used on this blog for PHP, Python and Quarto.

I don't know Java at all

You just need to know that I have absolutely no skills in Java. Which software should be installed, how to run a script and so on? I will just rely on a few Docker commands and, about the installation, yes, using Docker, it is easy: nothing to install, nothing to configure.

Two commands, and Java runs​

One command to compile, one to execute:

>user@machine: ~/yourproject

No JDK on the machine, no JAVA_HOME, no PATH to fix.

Why it works​

  • The eclipse-temurin:21 image already ships the full JDK, so javac and java are there, in the exact version the image tag names.
  • -v ${PWD}:/app shares your current folder with the container: the container reads your .java file and writes the .class file back into your own folder.
  • -u 1000:1000 runs the container as you, so the generated Main.class belongs to your user and not to root.

The source​

Please start a Linux shell and run mkdir -p /tmp/java && cd $_ to create a folder called java in your Linux temporary folder and enter it.

Please create a new file called Main.java with this content:

class Main {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}

This is a basic Java program that prints the text "Hello, World" to the console. It's the simplest possible Java application—just a main method that runs when you execute the program.

After the first command, your Main.java source has been compiled into a Main.class file. By running ls -alh you can verify that, yes, the java script has been compiled:

>user@machine: ~/yourproject

A slightly more difficult example, calling a REST API​

Please create a new file called API.java with this content:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class API {
public static void main(String[] args) {
try {
URL url = new URL("https://jsonplaceholder.typicode.com/todos/1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP Error code : "
+ conn.getResponseCode());
}
InputStreamReader in = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(in);
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (Exception e) {
System.out.println("Exception in NetClientGet:- " + e);
}
}
}

This program makes an HTTP GET request to a public API endpoint and prints the JSON response line by line. It opens a connection to the URL, checks that the request succeeded (HTTP 200 status), then reads and outputs the response before closing the connection.

Compile it by running docker run --rm -v $PWD:/app -w /app -u 1000:1000 eclipse-temurin:21 javac API.java; get the API.class file.

Finally, call docker run --rm -v $PWD:/app -w /app eclipse-temurin:21 java API to execute the API call and display the result on the screen:

>user@machine: ~/yourproject
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}

This example will use the sample https://jsonplaceholder.typicode.com/todos/1 to generate a fake TODO. The JSON will be displayed on the command line.

Under the Hood: the docker run flags (skip this if you just want to use it)​

The Docker run commands used above are (almost always the same):

  • -it to start Docker interactively, this will allow the script running in the container to ask you for some prompts for example,
  • --rm to ask Docker to kill and remove the container as soon as the script has been executed (otherwise you will have a lot of exited but not removed Docker containers; you can check this by not using the --rm flag then running docker container list on the console),
  • -v ${PWD}:/app to share your current folder with a folder called /app in the Docker container,
  • -w /app to tell Docker that the current directory, in the container, will be the /app folder,
  • -u 1000:1000 ask Docker to reuse our local credentials so when a file is updated/created in the container, the file will be owned by our user,
  • then eclipse-temurin:21 which is the name and the version of the Docker image to use, and, finally,
  • javac Main.java i.e. the command line to start within the container.

Conclusion​

Compiling and running Java, including a program that calls a REST API, without a single line of setup on the host: the image carries the toolchain, your folder carries the code, and the container disappears when the command ends. You are ready to start your Java coding journey. Have fun.

Same idea, different language: I've also played with Pascal, Assembly, and Python using this same "zero local install" Docker approach.


Was this article helpful?
Did you try the steps in this article?