Java

building .deb/.rpm installers for Java applications using jpackage on Docker containers on macOS/Windows

jpackage

jpackage is a command-line tool to create OS native installers/packages which is generally available since Java 16.

jpackage doesn’t offer any cross-building features, which means you need Red Hat/CentOS to build .rpm packages, Debian/Ubuntu to build .deb packages, macOS to build .dmg/.pkg packages, and Windows to build .exe/.msi packages in general.

But of course, you can build .rpm/.deb packages on macOS/Windows using Docker.

Here are working examples:

.dockerfile for building .rpm packages

FROM centos:centos8

RUN yum install rpm-build -y

RUN curl --output java17.tar.gz https://download.bell-sw.com/java/17+35/bellsoft-jdk17+35-linux-amd64-full.tar.gz \
    && tar -xvf ./java17.tar.gz -C /opt/ \
    && rm java17.tar.gz

ENV PATH $PATH:/opt/jdk-17-full/bin
ENV JAVA_HOME /opt/jdk-17-full

WORKDIR /root

.dockerfile for building .deb packages

FROM debian:bullseye

RUN apt-get update \
    && apt-get install -y curl \
    && apt-get install -y fakeroot

RUN curl --output java17.tar.gz https://download.bell-sw.com/java/17+35/bellsoft-jdk17+35-linux-amd64-full.tar.gz \
    && tar -xvf ./java17.tar.gz -C /opt/ \
    && rm java17.tar.gz

ENV PATH $PATH:/opt/jdk-17-full/bin
ENV JAVA_HOME /opt/jdk-17-full

WORKDIR /root

jpackage on Docker in action

https://github.com/yusuke/samurai is a perfect example which you can try building rpm and deb packages.

% docker build -t centosrpm -f package/centos.dockerfile .                                             
[+] Building 2.3s (8/8) FINISHED                                                                                                                                                       
 => [internal] load build definition from centos.dockerfile                                                                                                                       0.0s
 => => transferring dockerfile: 44B                                                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                                                 0.0s
 => => transferring context: 2B                                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/centos:centos8                                                                                                                 2.1s
 => [1/4] FROM docker.io/library/centos:centos8@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177                                                           0.0s
 => CACHED [2/4] RUN yum install rpm-build -y                                                                                                                                     0.0s
 => CACHED [3/4] RUN curl --output java17.tar.gz https://download.bell-sw.com/java/17+35/bellsoft-jdk17+35-linux-amd64-full.tar.gz     && tar -xvf ./java17.tar.gz -C /opt/       0.0s
 => CACHED [4/4] WORKDIR /root                                                                                                                                                    0.0s
 => exporting to image                                                                                                                                                            0.0s
 => => exporting layers                                                                                                                                                           0.0s
 => => writing image sha256:e80e0c04786da2d70f2f3bd9defc328d5df55206e7acbf2352d77b090b8f0b7e                                                                                      0.0s
 => => naming to docker.io/library/centosrpm         
% docker build -t debiandeb -f package/debian.dockerfile .                                             
[+] Building 2.3s (8/8) FINISHED                                                                                                                                                       
 => [internal] load build definition from debian.dockerfile                                                                                                                       0.0s
 => => transferring dockerfile: 428B                                                                                                                                              0.0s
 => [internal] load .dockerignore                                                                                                                                                 0.0s
 => => transferring context: 2B                                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/debian:bullseye                                                                                                                2.1s
 => [1/4] FROM docker.io/library/debian:bullseye@sha256:4d6ab716de467aad58e91b1b720f0badd7478847ec7a18f66027d0f8a329a43c                                                          0.0s
 => CACHED [2/4] RUN apt-get update     && apt-get install -y curl     && apt-get install -y fakeroot                                                                             0.0s
 => CACHED [3/4] RUN curl --output java17.tar.gz https://download.bell-sw.com/java/17+35/bellsoft-jdk17+35-linux-amd64-full.tar.gz     && tar -xvf ./java17.tar.gz -C /opt/       0.0s
 => CACHED [4/4] WORKDIR /root                                                                                                                                                    0.0s
 => exporting to image                                                                                                                                                            0.0s
 => => exporting layers                                                                                                                                                           0.0s
 => => writing image sha256:f25a867e8dab2338f3847e417a44a77e7266ac997f7a42307ef7d7d044930fc1                                                                                      0.0s
 => => naming to docker.io/library/debiandeb   
 % docker run -it --rm -v  /path/to/project/:/root/ centosrpm /bin/sh -c "./gradlew jar packageRpm"
Starting a Gradle Daemon, 1 busy and 3 incompatible and 2 stopped Daemons could not be reused, use --status for details

> Configure project :
snip…
[14:07:42.209] Succeeded in building RPM Bundle package

BUILD SUCCESSFUL in 1m 3s
13 actionable tasks: 1 executed, 12 up-to-date
% docker run -it --rm -v  /path/to/project/:/root/ debiandeb /bin/sh -c "./gradlew jar packageDeb"
Starting a Gradle Daemon, 1 busy and 3 incompatible and 2 stopped Daemons could not be reused, use --status for details

> Configure project :
…snip…
[14:09:21.914] Returned: 0

[14:09:21.922] Succeeded in building DEB Bundle package

BUILD SUCCESSFUL in 1m 5s
13 actionable tasks: 1 executed, 12 up-to-date
% ls app
samurai-2021.9-1.x86_64.rpm samurai_2021.9-1_amd64.deb