JavaFx Maven Docker Image

Recently when setting up a Jenkins build environment to use a Docker Image with Maven that could build a JavaFX project.  Thanks to some searching and a bit of hunting I was able to create a Docker image to perform just what I needed: OpenJDK, OpenJFX(JavaFX), and Maven. I wanted the DockerFile to be a part of my project so that if changes were necessary down the road I could make them in Git and my build environment would pick them up.

  1. I began by creating a docker directory in my maven project.  This gives me the ability to modify the Dockerfile as needed for my project.
  2. Next, you need to download the official package of files for Maven.  I choose to use the maven:jdk-8 as my base image. When you download this Dockerfile, do not make the mistake I did and miss the mvn-entrypoint.sh and settings-docker.xml files you will need these.  Place all three files in your docker directory.
  3. Now you need to modify the Dockerfile to include in OpenJFX on top OpenJDK in the environment. Add the lines I have highlighted below:
    FROM openjdk:8-jdk
    
    RUN apt-get update \
        && apt-get install --no-install-recommends -y \
            openjfx \
            unzip \
        && apt-get clean \
        && rm -f /var/lib/apt/lists/*_dists_*
    
    ARG MAVEN_VERSION=3.5.0
    ARG USER_HOME_DIR="/root"
    ARG SHA=beb91419245395bd69a4a6edad5ca3ec1a8b64e41457672dc687c173a495f034
    ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
    
    RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
      && curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-$MAVEN_VERSION-bin.tar.gz \
      && echo "${SHA}  /tmp/apache-maven.tar.gz" | sha256sum -c - \
      && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
      && rm -f /tmp/apache-maven.tar.gz \
      && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
    
    ENV MAVEN_HOME /usr/share/maven
    ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"
    
    COPY mvn-entrypoint.sh /usr/local/bin/mvn-entrypoint.sh
    COPY settings-docker.xml /usr/share/maven/ref/
    
    VOLUME "$USER_HOME_DIR/.m2"
    
    ENTRYPOINT ["/usr/local/bin/mvn-entrypoint.sh"]
    CMD ["mvn"]
  4. Next, since you put these files in a subdirectory you need to make another slight change:
    FROM openjdk:8-jdk
    
    RUN apt-get update \
        && apt-get install --no-install-recommends -y \
            openjfx \
            unzip \
        && apt-get clean \
        && rm -f /var/lib/apt/lists/*_dists_*
    
    ARG MAVEN_VERSION=3.5.0
    ARG USER_HOME_DIR="/root"
    ARG SHA=beb91419245395bd69a4a6edad5ca3ec1a8b64e41457672dc687c173a495f034
    ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
    
    RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
      && curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-$MAVEN_VERSION-bin.tar.gz \
      && echo "${SHA}  /tmp/apache-maven.tar.gz" | sha256sum -c - \
      && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
      && rm -f /tmp/apache-maven.tar.gz \
      && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
    
    ENV MAVEN_HOME /usr/share/maven
    ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"
    
    COPY docker/mvn-entrypoint.sh /usr/local/bin/mvn-entrypoint.sh
    COPY docker/settings-docker.xml /usr/share/maven/ref/
    
    VOLUME "$USER_HOME_DIR/.m2"
    
    ENTRYPOINT ["/usr/local/bin/mvn-entrypoint.sh"]
    CMD ["mvn"]
  5. For completeness I will include the code for the other two files here as well:
    #! /bin/bash -eu
    
    set -o pipefail
    
    # Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}
    # So the initial ~/.m2 is set with expected content.
    # Don't override, as this is just a reference setup
    copy_reference_file() {
      local root="${1}"
      local f="${2%/}"
      local logfile="${3}"
      local rel="${f/${root}/}" # path relative to /usr/share/maven/ref/
      echo "$f" >> "$logfile"
      echo " $f -> $rel" >> "$logfile"
      if [[ ! -e ${MAVEN_CONFIG}/${rel} || $f = *.override ]]
      then
        echo "copy $rel to ${MAVEN_CONFIG}" >> "$logfile"
        mkdir -p "${MAVEN_CONFIG}/$(dirname "${rel}")"
        cp -r "${f}" "${MAVEN_CONFIG}/${rel}";
      fi;
    }
    
    copy_reference_files() {
      local log="$MAVEN_CONFIG/copy_reference_file.log"
    
      if (touch "${log}" > /dev/null 2>&1)
      then
          echo "--- Copying files at $(date)" >> "$log"
          find /usr/share/maven/ref/ -type f -exec bash -eu -c 'copy_reference_file /usr/share/maven/ref/ "$1" "$2"' _ {} "$log" \;
      else
        echo "Can not write to ${log}. Wrong volume permissions? Carrying on ..."
      fi
    }
    
    export -f copy_reference_file
    copy_reference_files
    
    exec "$@"
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      <localRepository>/usr/share/maven/ref/repository</localRepository>
    </settings>

     

With this, you now have a Dockerfile that supports JavaFX compilations in Maven.

  • Ghostprogrammer
  • I am known for being able to quickly decipher difficult problems to assist development teams in producing a solution. I have been called upon to be the Team Lead for multiple large-scale projects. I have a keen interest in learning new technologies, always ready for a new challenge.

One Comment

  • This does not really work for me.
    I have a docker jenkins image where I want to add javaxfx support.

    But adding the code as mentioned by “OpenJFX on top OpenJDK” results into the following when building the docker image. The very base image is
    FROM jenkins/jenkins:lts
    which is
    FROM openjdk:8-jdk

    here is what happens:

    $> sudo docker build -t greyshine/jenkins_jfx .
    Sending build context to Docker daemon 695.8kB
    Step 1/14 : FROM jenkins/jenkins:lts
    —> e6b6a36fca5a
    Step 2/14 : RUN apt-get update && apt-get install –no-install-recommends -y openjfx unzip && rm -f /var/lib/apt/lists/*_dists_*
    —> Running in 9f4ed98e2b91
    Reading package lists…
    E: List directory /var/lib/apt/lists/partial is missing. – Acquire (13: Permission denied)
    The command ‘/bin/sh -c apt-get update && apt-get install –no-install-recommends -y openjfx unzip && rm -f /var/lib/apt/lists/*_dists_*’ returned a non-zero code: 100

One Pingback

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: