---
title: Java Programming with Docker
description: Explore how to use Docker when programming with the Java development language.
image: https://blog.rheinwerk-computing.com/hubfs/Java%20Programming%20with%20Docker.png
---

[![Rheinwerk Computing Logo](https://blog.rheinwerk-computing.com/hubfs/computing_logo-header.svg)](https://blog.rheinwerk-computing.com/) [Blog](https://blog.rheinwerk-computing.com)

- Books 
    - Get an overview of our wide selection of books on every relevant computing topic. 
          - [General Computing](https://www.sap-press.com/rheinwerk-computing/general-computing/)
          - [DevOps](https://www.sap-press.com/rheinwerk-computing/devops/)
          - [Programming Languages](https://www.sap-press.com/rheinwerk-computing/programming-languages/)
          - [Security](https://www.sap-press.com/rheinwerk-computing/security/)
          - [Software Development](https://www.sap-press.com/rheinwerk-computing/software-development/)
- Book Subscription 
    - Get unlimited access to all Rheinwerk Computing books! 
          - [Programming Subscription](https://sap-press.com/subscriptions/)

[Java](https://blog.rheinwerk-computing.com/tag/java)

# Java Programming with Docker

![Rheinwerk Computing](https://blog.rheinwerk-computing.com/hubfs/RW-logo-300x300.png)  by [Rheinwerk Computing](https://blog.rheinwerk-computing.com/author/rheinwerk-computing)

For many years, Java has been the number one in the *TIOBE index* of the most commonly used programming languages.

 

[Java](https://learning.rheinwerk-computing.com/java) is an [object-oriented language](https://blog.rheinwerk-computing.com/the-principles-of-object-oriented-programming) that was developed with great attention to portability. Today, Java code runs virtually everywhere: on mainframes as well as on smartphones. Java is well suited for programming novices but lacks a more elegant notation in many areas. In that context, modern programming languages such as Ruby or current [JavaScript](https://learning.rheinwerk-computing.com/javascript) versions are more convenient to use.

 

Java, as a compiled language with huge libraries, is actually not predestined for [Docker](https://learning.rheinwerk-computing.com/devops#docker) use. But since Oracle had the glorious idea to drive developers and Linux distributors crazy with semiannual major releases, Docker is a good way to run or further develop individual projects independently in suitable Java releases.

 

The official Java images on Docker Hub include the OpenJDK implementation of the Java Developer Kit ([*https://hub.docker.com/\_/eclipse-temurin*](https://hub.docker.com/_/eclipse-temurin)). In July 2021, the major versions 8, 11, 16, 17, and 18 were available for selection there, with 16 marked as the *latest* as it was considered to be the most stable version at that time. The number of different build variants for the five versions is so large that it’s no longer even displayed on the Docker Hub website. Among them are builds based on different versions of WindowsServerCore and various Linux distributions (Debian and Oracle Linux).

 

The decision as to whether you want the entire development environment or just the runtime has at least been taken away from you by the developers in the more recent versions: current Docker images of OpenJDK are only available complete with the compiler. The space requirements of the OpenJDK images are considerable.

![Image Sizes of Some OpenJDK Image Variants](https://blog.rheinwerk-computing.com/hs-fs/hubfs/2383_table_11_001.png?width=933&height=303&name=2383_table_11_001.png)

## “printheadlines” Example

Unfortunately, we couldn’t find an easy-to-install and up-to-date RSS library for Java. For this reason, we’ll extract the news directly from the Slashdot news ticker website in the following example. We’ll do this by using an add-on library, *jsoup*, which allows you to search the Document Object Model (DOM) tree of an HTML document using tags and Cascading Style Sheet ([CSS](https://learning.rheinwerk-computing.com/html-and-css#css)) classes. The drawback of this approach is that this program stops working as soon as the website owner changes the design, that is, renames the CSS classes. Here you can see the Java class for extracting the message list:

 

`// File: prog/java/printheadlines.java`

`import org.jsoup.Jsoup;`

`import org.jsoup.nodes.Document;`

`import org.jsoup.nodes.Element;`

`import org.jsoup.select.Elements;`

`import java.io.IOException;`

 

`public class printheadlines {`

`   private static String url = "https://slashdot.org/";`

 

`   public static void main(String[] args) throws IOException {`

`       Document doc = Jsoup.connect(url).get();`

`       Elements news = doc.select("article h2.story>span.story-title>a");`

 

`       for (Element item : news) {`

`           System.out.println("* "+ item.text());`

`       }`

`   }`

`}`

 

In the main function of our small Java program, we first load the [HTML](https://learning.rheinwerk-computing.com/html-and-css#html)page with the jsoup function connect(url).get(). The following doc.select call creates a list of HTML elements that match the CSS statement. In the for loop, the elements are output to the screen, with the text() function of jsoup removing spaces and other HTML tags within the element.

 

In Java, it’s common for external libraries to be downloaded as jar files and specified in the classpath both at compile time and at execution time. In our *Dockerfile*, we’ll download the library in the currently current version 1.11.3 from the project’s website and store it in the Docker image. In addition, when creating the Docker image, we’ll translate the source code so that a derived container has access to the final compiled program.

 

`# File: prog/java/Dockerfile (docbuc/printheadlines:java)`

`FROM openjdk:16`

`RUN adduser -r java`

`WORKDIR /src`

`RUN chown java /src`

`USER java`

`ENV JSOUP_VER 1.13.1`

`RUN curl -SL https://jsoup.org/packages/jsoup-$JSOUP_VER.jar \`

`   -o jsoup-$JSOUP_VER.jar`

`COPY printheadlines.java /src/`

`RUN javac -verbose -cp /src/jsoup-$JSOUP_VER.jar:. \`

`   printheadlines.java`

`CMD java -cp jsoup-$JSOUP_VER.jar:. printheadlines`

 

For security reasons, we don’t want to run the container as root user. Because there’s no suitable unprivileged user in the Oracle Linux system, we’ll create the user via the adduser command, where the -r parameter specifies that the user becomes a system user and thus won’t get a normal login.

 

Specifying an environment variable, in this case, JSOUP\_VER, is handy if you want to update the library at a later time. As long as the structure of the download links remains the same, it’s then sufficient to adjust the version number.

 

For the first attempt, we use version 16 of the Java Developer Kit (JDK), which as of July 2021 was marked as latest. This has probably changed since this post was written: Oracle has significantly accelerated the development cycle and releases new major versions once every six months.

 

No matter how this evolution continues, Docker gives you the ideal tool to test and deliver your software with different Java versions. You just need to change the version number of the official Docker image in your *Dockerfile* from 16 to 17, and you’ll be testing with the latest developer version. Parallel installations of different versions of the JDK in one operating system are basically possible, but, in practice, they always cause difficulties. Docker is made to save you trouble in the process.

 

What you should do here is build the Docker image using docker build -t docbuc/printheadlines: java ., and then run it via docker run docbuc/printheadlines:java. Here you can see the slightly shortened output of the build process:

 

`Sending build context to Docker daemon 3.584kB`

`Step 1/10 : FROM openjdk:16`

`---> f4f1dadedfab`

`Step 2/10 : RUN adduser -r java`

`---> Running in ac0ca27aee3c`

`Removing intermediate container ac0ca27aee3c`

`---> 0cef2ee2d7f2`

`[...]`

`Step 9/10 : RUN javac -cp /src/jsoup-$JSOUP_VER.jar:. printh...`

`---> Running in 232ab7613846`

`Removing intermediate container 232ab7613846`

`---> d6bc5ff51cba`

`Step 10/10 : CMD java -cp jsoup-$JSOUP_VER.jar:. printheadlines`

`---> Running in ee090202f84b`

`Removing intermediate container ee090202f84b`

`---> 5cafad4b0f90`

`Successfully tagged docbuc/printheadlines:java`

 

Try changing the Java version in your *Dockerfile*. Our tests with version 18 were successful.

## Resource Management

Older Java versions were known to be too wasteful with RAM and CPU power. [This blog post](https://developers.redhat.com/blog/2017/03/14/java-inside-docker)describes the problem and some suggested solutions.

 

If you use Linux as a Docker host, the Java Virtual Machine (JVM) of OpenJDK 8 and 9 can detect the limits provided in Docker for the container when you invoke the Java interpreter with the following options:

 

`java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap`

 

Starting with OpenJDK 11, you can save yourself the trouble. As of this version, Java itself recognizes the restrictions that apply to containers on Linux.

 

The situation is different if you use Windows as a Docker host. In that case, you can use the start command in Windows to control which resources java is allowed to use via options:

- *https://hub.docker.com/\_/eclipse-temurin*
- *https://ss64.com/nt/start.html*

Editor’s note: This post has been adapted from a section of the book [*Docker:*](https://www.sap-press.com/docker_5650/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2383_chapter11&utm_content=2383)*[Practical Guide for Developers and DevOps Teams](https://www.sap-press.com/docker_5650/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2383_chapter11&utm_content=2383)* by Bernd Öggl and Michael Kofler. Bernd is an experienced system administrator and web developer. Since 2001 he has been creating websites for customers, implementing individual development projects, and passing on his knowledge at conferences and in publications. Michael studied telematics at Graz University of Technology and is one of the most successful German-language IT specialist authors. In addition to Linux, his areas of expertise include IT security, [Python](https://learning.rheinwerk-computing.com/python), Swift, [Java](https://learning.rheinwerk-computing.com/java), and the Raspberry Pi. He is a developer, advises companies, and works as a lecturer.

 

This blog post was originally published 9/2023.

## Recommendation

[![Docker: Practical Guide for Developers and DevOps Teams](https://blog.rheinwerk-computing.com/hs-fs/hubfs/social-suggested-images/2383-Jul-26-2023-03-38-45-4039-PM-1.jpg?width=170&name=2383-Jul-26-2023-03-38-45-4039-PM-1.jpg)](https://www.sap-press.com/docker_5650/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2383_chapter11&utm_content=2383)

**Docker: Practical Guide for Developers and DevOps Teams**

Learn the ins and outs of containerization in Docker with this practical guide! Begin by installing and setting up the platform. Then master the basics: get to know important terminology, understand how to run containers, and set up port redirecting and communication. You’ll learn to create custom images, work with commands, and use key containerization tools. Gain essential skills by following exercises that cover common tasks from packaging new applications and modernizing existing applications to handling security and operations.

[Learn More](https://www.sap-press.com/docker_5650/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2383_chapter11&utm_content=2383)

![Rheinwerk Computing](https://blog.rheinwerk-computing.com/hubfs/RW-logo-300x300.png)

**by [Rheinwerk Computing](https://blog.rheinwerk-computing.com/author/rheinwerk-computing)**

Rheinwerk Computing is an imprint of Rheinwerk Publishing and publishes books by leading experts in the fields of programming, administration, security, analytics, and more.

[Java](https://blog.rheinwerk-computing.com/tag/java) [Programming Languages](https://blog.rheinwerk-computing.com/tag/programming-languages) [DevOps](https://blog.rheinwerk-computing.com/tag/devops)

[![Share on facebook](https://7528309.fs1.hubspotusercontent-na1.net/hub/7528309/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/facebook-color.png?width=24&name=facebook-color.png)](https://www.facebook.com/share.php?u=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fjava-programming-with-docker%3Futm_medium%3Dsocial%26utm_source%3Dfacebook) [![Share on linkedin](https://7528302.fs1.hubspotusercontent-na1.net/hub/7528302/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/linkedin-color.png?width=24&name=linkedin-color.png)](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fjava-programming-with-docker%3Futm_medium%3Dsocial%26utm_source%3Dlinkedin) [![Share on twitter](https://7528304.fs1.hubspotusercontent-na1.net/hub/7528304/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/twitter-color.png?width=24&name=twitter-color.png)](https://twitter.com/intent/tweet?original_referer=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fjava-programming-with-docker%3Futm_medium%3Dsocial%26utm_source%3Dtwitter&url=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fjava-programming-with-docker%3Futm_medium%3Dsocial%26utm_source%3Dtwitter&source=tweetbutton&text=) [![Share on email](https://7528311.fs1.hubspotusercontent-na1.net/hub/7528311/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/email-color.png?width=24&name=email-color.png)](mailto:?subject=Check+out+https%3A%2F%2Fblog.rheinwerk-computing.com%2Fjava-programming-with-docker%3Futm_medium%3Dsocial%26utm_source%3Demail&body=Check+out+https%3A%2F%2Fblog.rheinwerk-computing.com%2Fjava-programming-with-docker%3Futm_medium%3Dsocial%26utm_source%3Demail)

### Comments

### Latest Blog Posts

[![The Grafana-Docker Setup](https://blog.rheinwerk-computing.com/hs-fs/hubfs/The%20Grafana-Docker%20Setup.png?height=600&name=The%20Grafana-Docker%20Setup.png)](https://blog.rheinwerk-computing.com/the-grafana-docker-setup)

[DevOps](https://blog.rheinwerk-computing.com/tag/devops)

## [The Grafana-Docker Setup](https://blog.rheinwerk-computing.com/the-grafana-docker-setup)

[Read More](https://blog.rheinwerk-computing.com/the-grafana-docker-setup)

[![Characteristics of Alpine Linux](https://blog.rheinwerk-computing.com/hs-fs/hubfs/Characteristics%20of%20Alpine%20Linux.png?height=600&name=Characteristics%20of%20Alpine%20Linux.png)](https://blog.rheinwerk-computing.com/characteristics-of-alpine-linux)

[DevOps](https://blog.rheinwerk-computing.com/tag/devops)

## [Characteristics of Alpine Linux](https://blog.rheinwerk-computing.com/characteristics-of-alpine-linux)

[Read More](https://blog.rheinwerk-computing.com/characteristics-of-alpine-linux)

**Subscribe to our blog!**Get notified about future blog updates.

- <https://www.linkedin.com/showcase/rheinwerk-computing/>
- <https://www.youtube.com/channel/UChj-U-uWGM7qRlHXSFU93ew>
- <https://blog.rheinwerk-computing.com/rss.xml>

### The official Rheinwerk Computing Blog

Rheinwerk Computing is an imprint of Rheinwerk Publishing and publishes resources that will help you accelerate your computing journey. The Rheinwerk Computing Blog is designed to provide helpful, actionable information on a variety of topics, including programming, administration, security, and analytics!

### Blog Topics

- [All Topics](https://blog.rheinwerk-computing.com)
- [Programming Languages](https://blog.rheinwerk-computing.com/tag/programming-languages)
- [How To](https://blog.rheinwerk-computing.com/tag/how-to)
- [JavaScript](https://blog.rheinwerk-computing.com/tag/javascript)
- [DevOps](https://blog.rheinwerk-computing.com/tag/devops)
- [Web Development](https://blog.rheinwerk-computing.com/tag/web-development)
- [Python](https://blog.rheinwerk-computing.com/tag/python)
- [What Is?](https://blog.rheinwerk-computing.com/tag/what-is)
- [Cybersecurity](https://blog.rheinwerk-computing.com/tag/cybersecurity)
- [Software Development](https://blog.rheinwerk-computing.com/tag/software-development)
- [Java](https://blog.rheinwerk-computing.com/tag/java)

### Blog curated by

[![Rheinwerk Computing Logo](https://blog.rheinwerk-computing.com/hubfs/computing_logo-header.svg)](https://www.sap-press.com/rheinwerk-computing/) [Visit Rheinwerk Computing Store](https://www.sap-press.com/rheinwerk-computing/)

### About

- [Home](https://sap-press.com/)
- [About Us](https://sap-press.com/the-publisher/)
- [Contact](mailto:info@rheinwerk-publishing.com)
- [Legal Notes](https://sap-press.com/legal-notes/)
- [Privacy Policy](https://sap-press.com/privacy/)
- [Terms of Use](https://sap-press.com/terms/)

© 2026 Rheinwerk Publishing, Inc. | Change Privacy Options

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Rheinwerk Computing",
    "url" : "https://blog.rheinwerk-computing.com/author/rheinwerk-computing"
  },
  "dateModified" : "2025-04-23T13:55:12.316Z",
  "datePublished" : "2023-09-21T13:00:00.000Z",
  "headline" : "Java Programming with Docker",
  "image" : [ "https://blog.rheinwerk-computing.com/hubfs/Java%20Programming%20with%20Docker.png" ],
  "mainEntityOfPage" : {
    "@id" : "https://blog.rheinwerk-computing.com/java-programming-with-docker",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://blog.rheinwerk-computing.com/hubfs/Logo-1.jpg"
    },
    "name" : "Rheinwerk Publishing, Inc."
  }
}
```