diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 95417045..00ddab02 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,18 +6,19 @@ on: env: image-name: ubuntu/jre:test - build-image-name: temurin-jdk17-builder:test - maven-image-name: temurin-jdk17-maven:test - maven-image-base: maven:3.9.1-eclipse-temurin-17 + build-image-name: ubuntu/jre:test-builder + maven-image-name: ubuntu/jre:test-maven + maven-image-base: maven:3.9.9-eclipse-temurin-21 jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 name: Build and Test strategy: fail-fast: false matrix: - ubuntu-release: ["22.04"] + ubuntu-release: ["24.04"] + arch: ["amd64"] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 @@ -25,7 +26,18 @@ jobs: - uses: actions/setup-java@v4 with: distribution: 'temurin' # See 'Supported distributions' for available options - java-version: '17' + java-version: '21' + + - name: Setup LXD + uses: canonical/setup-lxd@main + with: + channel: 5.21/candidate + + - name: Setup rockcraft + run: | + rm -rf /home/runner/.local/state/rockcraft/log/* + sudo snap remove rockcraft || true + sudo snap install rockcraft --classic - name: Tests Maven cache uses: actions/cache@v4 @@ -35,14 +47,6 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: Tests PDFBox - uses: actions/cache@v4 - with: - path: tests/pdfbox/pdfbox - key: tests-pdfbox-pdfbox-3.0.0-alpha3 - restore-keys: | - tests-pdfbox-pdfbox-3.0.0-alpha3 - - name: Tests Petclinic uses: actions/cache@v4 with: @@ -53,17 +57,16 @@ jobs: - name: Build the jre image run: | - docker build \ - -t ${{ env.image-name }} \ - --build-arg UID=$(id -u ${USER}) \ - --build-arg GID=$(id -g ${USER}) \ - -f jre/Dockerfile.${{ matrix.ubuntu-release }} \ - jre + set -ex + cd jre/ubuntu-24.04-headless + rockcraft pack --build-for amd64 + rockcraft.skopeo copy oci-archive:jre_21-edge_${{ matrix.arch }}.rock docker-daemon:${{ env.image-name }} - name: Build the JDK docker image run: | docker build \ -t ${{ env.build-image-name }} \ + --build-arg ARCH=${{ matrix.arch }} \ --build-arg UID=$(id -u ${USER}) \ --build-arg GID=$(id -g ${USER}) \ -f tests/containers/builder/Dockerfile.${{ matrix.ubuntu-release }} \ @@ -73,6 +76,7 @@ jobs: run: | docker build \ -t ${{ env.maven-image-name }} \ + --build-arg ARCH=${{ matrix.arch }} \ --build-arg UID=$(id -u ${USER}) \ --build-arg GID=$(id -g ${USER}) \ --build-arg BASE_IMAGE=${{ env.image-name }} \ @@ -92,12 +96,12 @@ jobs: ${{ runner.temp }}/.m2 \ ${{ env.maven-image-name }} multi-arch-build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 name: Multi Architecture Build strategy: fail-fast: false matrix: - ubuntu-release: ["22.04"] + ubuntu-release: ["24.04"] arch: ["amd64", "arm64"] steps: @@ -109,17 +113,18 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - # Lint the Dockerfiles - - name: Lint the Dockerfile - uses: hadolint/hadolint-action@v3.1.0 + - name: Setup LXD + uses: canonical/setup-lxd@main with: - dockerfile: jre/Dockerfile.${{ matrix.ubuntu-release }} - ignore: DL3008,DL3015,SC3028 + channel: 5.21/candidate + + - name: Setup rockcraft + run: | + rm -rf /home/runner/.local/state/rockcraft/log/* + sudo snap remove rockcraft || true + sudo snap install rockcraft --classic - name: Build the jre image run: | - docker buildx build \ - --tag=${{ env.image-name }} \ - --file=jre/Dockerfile.${{ matrix.ubuntu-release }} \ - --platform=linux/${{ matrix.arch }} \ - jre + cd jre/ubuntu-24.04-headless + rockcraft pack diff --git a/.gitignore b/.gitignore index 4fe9fa44..284422c5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ pdfbox-2.0.27 sh *.war *.jar +.embedmongo +*.class diff --git a/README.md b/README.md index 2ead314a..f5a7d4a8 100644 --- a/README.md +++ b/README.md @@ -6,250 +6,6 @@ channel branches (e.g. `channels/17/edge`). Read more about the repository structure and build automation [here](). -## Image Characteristics - -According to JetBrains' 2022 [Java Developer Ecosystem](https://www.jetbrains.com/lp/devecosystem-2022/java/) survey, 30% of the developers still regularly use Java 17, 59% developed applications for Apache Tomcat and 67% used Spring Boot as an alternative to an application server. We will use those application platforms for the comparison of the image characteristics. - -New Relic 2022 [Java Ecosystem report](https://newrelic.com/resources/report/2022-state-of-java-ecosystem) listed the following top JDK vendors: - - Oracle Corporation 34.48% - - Amazon 22.04% - - Eclipse Adoptium 11.48% - - Azul Zulu build of OpenJDK 16% - -Snyk 2021 [JVM Ecosystem](https://snyk.io/jvm-ecosystem-report-2021/) had the following breakdown: - - Eclipse Adoptium 44% - - Oracle Corporation OpenJDK 28% - - Oracle Corporation JDK 23% - - Azul Zulu build of OpenJDK 16% - - Amazon Coretto 8% - -The differences in vendor distribution could be attributed to the audience providing survey responses. - -The cloud vendors traditionally offered `amd64`-based virtual machines, though recently they have started to provide `arm64` offerings, such as [Amazon Graviton](https://aws.amazon.com/ec2/graviton/). This image evaluation will focus on the `amd64` and `arm64` platforms. - -The Ubuntu JRE container is built based on the Ubuntu 22.04 version of Java 17 runtime - `17.0.7+7`. In - -This section provides a comparison with readily-available Java 17 runtime images from the most popular distributions: - - Eclipse Adoptium publishes multiple [Java runtime images](https://github.com/adoptium/containers/tree/main/17/jre) for Java 17. We will evaluate Ubuntu Jammy [`eclipse-temurin:17.0.7_7-jre-jammy`](https://github.com/adoptium/containers/blob/main/17/jre/ubuntu/jammy/Dockerfile.releases.full) and Alpine-based [`eclipse-temurin:17.0.7_7-jre-alpine`](https://github.com/adoptium/containers/blob/main/17/jre/alpine/Dockerfile.releases.full) images. - - Amazon Corretto publishes Java 17 image based on Amazon Linux 2023 [`amazoncorretto:17.0.7-al2023-headless`](https://github.com/corretto/corretto-docker/tree/main/17/headless/al2023) - - Azul Zulu publishes multiple [Java runtime images](https://github.com/zulu-openjdk/zulu-openjdk) for Java 17. Will will evaluate distroless [`azul/zulu-openjdk-distroless:17.0.7-17.42.19`](https://github.com/zulu-openjdk/zulu-openjdk/tree/master/distroless/17.0.7-17.42.19). - - [Oracle](https://github.com/oracle/docker-images/tree/main/OracleJava) only publishes JDK image. - - Google provides distroless [`gcr.io/distroless/java17-debian11`](https://github.com/GoogleContainerTools/distroless/tree/main/java) Java 17 image. - -### Image size - -The evaluated images are built using the different processes and this affects the resulting image size. - -Eclipse Temurin uses `ubuntu:22.04` or `alpine:3.18` base images. The image contains Adoptium's build of Java 17 Runtime built with OpenJDK `legacy-jre-image` target. It has hotspot binaries and a base list of modules required for the runtime. It includes a class data-sharing cache. -Note: `legacy-jre-image` uses `jlink` to produce runtime image from the full JDK image. - -Azul Zulu packages a limited set of binaries and a full set of JDK modules. It includes a class data-sharing cache. It only installs base dependencies (`libc` and `libnss`) and none of the Abstract Window Toolkit (AWT) such as `fontconfig` despite having AWT binaries present in the Java runtime. - -Amazon Corretto installs the Java JDK package in `amazonlinux:2023` with all package dependencies. It packages a limited set of binaries and a full set of JDK modules. - -The Google distroless image is built by installing the Debian openjdk-17-jre-headless package and its dependencies and copying them into a scratch container. It contains a limited set of binaries and a full set of JDK modules. - -Java 17 in chiselled Ubuntu is built by running `jlink` with a base list of modules required for the runtime in the `ubuntu:22.04` container. The dependencies are chiselled and copied into a scratch container along with the generated Java runtime. - -As shown in the tables below the best space efficiency is achieved by Java 17 in chiselled Ubuntu with both approaches combined. `jlink` provides the best space saving and it is further augmented by having only Java library dependencies in the resulting image. - -### AMD64 - -|Tag|Uncompressed Size(MB)| Compressed Size (MB)| % Compressed | -|---|----| ----------------------------| -------------| -|eclipse-temurin:17.0.7_7-jre-jammy |259| 89 |100| -|eclipse-temurin:17.0.7_7-jre-alpine |156 |55 |61.79| -|amazoncorretto:17.0.7-al2023-headless |356| 127 |142.69| -|azul/zulu-openjdk-distroless:17.0.7-17.42.19| 185| 63| 70.78| -|gcr.io/distroless/java17-debian11 |223| 82| 92.13| -|ubuntu/jre:17_edge| 125| 44| 49.43| - - -### ARM64 - -|Tag|Uncompressed Size (MB)| Compressed Size(MB)| % Compressed | -|-----|----| ----------------------------| -------------| -|eclipse-temurin:17-jre-jammy| 254| 87 |100| -|gcr.io/distroless/java17-debian11| 218| 80 |91.9540229885057| -|ubuntu/jre:17_edge| 121| 42 |48.2758620689655| - - -Below are image sizes of the deployed `acmeair` benchmark application - -#### `acmeair` as a standalone Spring Boot application - -### AMD64 -|Tag|Uncompressed Size| Compressed Size| % Compressed | -|---|----| ----------------------------|----| -|standalone-eclipse-temurin:17.0.7_7-jre-jammy| 282| 109| 100| -|standalone-eclipse-temurin:17.0.7_7-jre-alpine| 179| 76| 69.72| -|standalone-amazoncorretto:17.0.7-al2023-headless| 379 |147 |134.86| -|standalone-azul/zulu-openjdk-distroless:17.0.7-17.42.19| 208| 83| 76.14| -|standalone-gcr.io/distroless/java17-debian11 |246| 102| 93.57| -|standalone-ubuntu/jre:17_edge |147| 65 |59.63| - - -### ARM64 -|Tag|Uncompressed Size| Compressed Size| % Compressed | -|---|----| ----------------------------|----| -|standalone-eclipse-temurin:17.0.7_7-jre-jammy| 277 |108| 100| -|standalone-gcr.io/distroless/java17-debian11| 241 |101| 93.51| -|standalone-ubuntu/jre:17_edge|143| 63|58.33| - - -### Test Environment - -The tests were performed using the following setup: -| Machine | Description | -|---------|-------------| -| mongodb | amd64 m1.small cloud instance (1 vCPU, 2048MB RAM, 10GB disk) | -| acmeair amd| amd64 m1.medium cloud instance (2 vCPUs, 4096MB RAM, 10GB disk) | -| acmeair arm| arm64 m1.medium cloud instance (2 vCPU, 2048MB RAM, 10GB disk) | -| load machine| amd64 m1.medium cloud instance (2 vCPUs, 4096MB RAM, 10GB disk) | - -[load machine] <-http-> [acmeair] <--> [mongodb] - -
- -AMD64 vCPU details - - -``` -vendor_id : GenuineIntel -cpu family : 6 -model : 60 -model name : Intel Core Processor (Haswell, no TSX, IBRS) -stepping : 1 -microcode : 0x1 -cpu MHz : 2599.994 -cache size : 16384 KB -physical id : 1 -siblings : 1 -core id : 0 -cpu cores : 1 -apicid : 1 -initial apicid : 1 -fpu : yes -fpu_exception : yes -cpuid level : 13 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm cpuid_fault invpcid_single pti ssbd ibrs ibpb tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt arat md_clear -vmx flags : vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid pml -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown -bogomips : 5199.98 -clflush size : 64 -cache_alignment : 64 -address sizes : 40 bits physical, 48 bits virtual -power management: -``` - -
- -
- ARM64 vCPU details - -``` -processor : 0 -BogoMIPS : 100.00 -Features : fp asimd evtstrm cpuid -CPU implementer : 0x50 -CPU architecture: 8 -CPU variant : 0x0 -CPU part : 0x000 -CPU revision : 1 -``` - -
- - - - -### Startup time - -The startup times were evaluated by starting a Spring Boot standalone container and sampling 30 times the total JVM time until the start of the application as per Spring Boot logs. - -### AMD64 -|Image| Minimum (seconds) | Average (seconds) | Maximum (seconds) | Standard Error| -|-----|-------------------|-------------------|-------------------|-------------------| -|standalone-eclipse-temurin:17.0.7_7-jre-jammy|2.98|3.35|3.72|0.04| -|standalone-eclipse-temurin:17.0.7_7-jre-alpine|3.25|3.66|4.09|0.05| -|standalone-amazoncorretto:17.0.7-al2023-headless|2.97|3.35|3.82|0.04| -|standalone-azul/zulu-openjdk-distroless:17.0.7-17.42.19 |3.17|3.55|3.96|0.04| -|standalone-gcr.io/distroless/java17-debian11|2.80|3.37|3.68|0.04| -|standalone-ubuntu/jre:17_edge|2.93|3.36|3.75|0.03| - -The Ubuntu JRE and Temurin images have no statistical differences in the startup time. - -### ARM64 -|Image| Minimum (seconds) | Average (seconds) | Maximum (seconds) | Standard Error| -|-----|-------------------|-------------------|-------------------|-------------------| -|standalone-eclipse-temurin:17.0.7_7-jre-jammy|10.92|11.82|12.75|0.09| -|standalone-gcr.io/distroless/java17-debian11|10.85|11.68|13.37|0.13| -|standalone-ubuntu/jre:17_edge|11.14|11.97|13.51|0.09| - -The Ubuntu JRE and Temurin images have no statistical differences in the startup time. - -### Throughput tests - -The throughput tests were performed using Apache JMeter 5.5 on the `acmeair` application with the following command: ``jmeter -n -t AcmeAir-v5.jmx -DusePureIDs=true -JHOST=${HOST} -JPORT=9080 -j `pwd`/performance${i}.log -JTHREAD=1 -JUSER=10 -JDURATION=60 -JRAMP=0 ;``. The command was executed 33 times against the running container and the database was cleared between commands. The result of the first three commands was ignored to account for the virtual machine warmup. - -## `acmeair` Standalone Spring Application - -### AMD64 - -| Image | Min(requests/second)| Average (requests/seconds) | Max(requests/second)| Standard Error | -| ------|----------------------|------|----------------| --| -|standalone-eclipse-temurin:17.0.7_7-jre-jammy|394.80|413.23|438.70|2.10| -|standalone-eclipse-temurin:17.0.7_7-jre-alpine|374.00|421.81|450.00|3.24| -|standalone-amazoncorretto:17.0.7-al2023-headless|413.20|422.91|434.30|1.03| -|standalone-azul/zulu-openjdk-distroless:17.0.7-17.42.19 |393.80|409.33|425.80|1.64| -|standalone-gcr.io/distroless/java17-debian11|413.90|424.52|438.40|1.29| -|standalone-ubuntu/jre:17_edge|410.90|418.38|430.10|0.93| - -### ARM64 - -| Image | Min(requests/second)| Average (requests/seconds) | Max(requests/second)| Standard Error | -| ------|----------------------|------|----------------| --| -|standalone-eclipse-temurin:17.0.7_7-jre-jammy|138.10|163.10|170.70|1.48| -|standalone-gcr.io/distroless/java17-debian11|141.40|165.35|172.00|1.09| -|standalone-ubuntu/jre:17_edge|136.10|163.68|172.50|1.24| - - -The data shows no statistical difference for the standalone Spring Application. - -## `acmeair` on Apache Tomcat - -In this test, the official tomcat images were used for Temurin: - - `tomcat:10.1.9-jre17-temurin-jammy` - -Other images were built by compiling Apache Tomcat 10.1.9 with native extensions and copying it into the source container - -### AMD64 - -| Image | Min(requests/second)| Average (requests/seconds) | Max(requests/second)| Standard Error | -| ------|----------------------|------|----------------| --| -|tomcat:10.1.9-jre17-temurin-jammy|383.30|403.51|416.70|1.27| -|tomcat-eclipse-temurin:17.0.7_7-jre-alpine|387.50|395.27|405.70|0.91| -|tomcat-amazoncorretto:17.0.7-al2023-headless|368.00|401.13|410.80|1.54| -|tomcat-azul/zulu-openjdk-distroless:17.0.7-17.42.19 |375.50|401.53|412.80|1.44| -|tomcat-gcr.io/distroless/java17-debian11|397.30|408.76|421.60|1.10| -|tomcat-ubuntu/jre:17_edge|384.10|402.82|415.90|1.53| - -### ARM64 - -| Image | Min(requests/second)| Average (requests/seconds) | Max(requests/second)| Standard Error | -| ------|----------------------|------|----------------| --| -|tomcat:10.1.9-jre17-temurin-jammy|136.80|165.68|174.20|1.58| -|tomcat-gcr.io/distroless/java17-debian11|130.00|157.62|168.40|1.76| -|tomcat-ubuntu/jre:17_edge|138.50|157.71|166.70|1.42| - -The data shows no statistical difference for the standalone Spring Application between Ubuntu JRE and Temurin images, with a slightly lower performance of the Corretto image. - -### Conclusion - -The Ubuntu JRE image of OpenJDK 17 provides a ~51% reduction in the size of the compressed image compared to Temurin Java 17 runtime image. -The Ubuntu JRE image does not degrade throughput or startup performance compared to the evaluated images. - ## License The source code in this project is licensed under the [Apache 2.0 LICENSE](./LICENSE). diff --git a/jre/.dockerignore b/jre/.dockerignore deleted file mode 100644 index e69de29b..00000000 diff --git a/jre/Dockerfile.22.04 b/jre/Dockerfile.22.04 deleted file mode 100644 index 73416e8a..00000000 --- a/jre/Dockerfile.22.04 +++ /dev/null @@ -1,75 +0,0 @@ -ARG UBUNTU_RELEASE=22.04 -ARG USER=app -ARG UID=101 -ARG GROUP=app -ARG GID=101 -ARG CHISEL_VERSION=1.0.0 - -FROM public.ecr.aws/ubuntu/ubuntu:$UBUNTU_RELEASE@sha256:1582c29f34a48752e406f1a261fe9545fad895da3f6bb4be55bc82485557564e AS builder -ARG USER -ARG UID -ARG GROUP -ARG GID -ARG TARGETARCH -ARG CHISEL_VERSION -SHELL ["/bin/bash", "-oeux", "pipefail", "-c"] -ADD https://github.com/canonical/chisel/releases/download/v${CHISEL_VERSION}/chisel_v${CHISEL_VERSION}_linux_${TARGETARCH}.tar.gz chisel.tar.gz -RUN tar -xvf chisel.tar.gz -C /usr/bin/ -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates \ - ca-certificates-java \ - binutils \ - openjdk-17-jdk \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* - -RUN jlink --no-header-files --no-man-pages --strip-debug \ - --add-modules \ -java.base,java.datatransfer,java.desktop,java.instrument,\ -java.logging,java.management,java.management.rmi,java.naming,\ -java.prefs,java.rmi,java.security.sasl,java.xml,jdk.incubator.foreign,\ -jdk.incubator.vector,jdk.internal.vm.ci,jdk.jfr,jdk.management,\ -jdk.management.jfr,jdk.management.agent,jdk.net,jdk.nio.mapmode,\ -jdk.sctp,jdk.unsupported,jdk.naming.rmi,java.se,java.net.http,\ -java.scripting,java.security.jgss,java.smartcardio,java.sql,\ -java.sql.rowset,java.transaction.xa,java.xml.crypto,jdk.accessibility,\ -jdk.charsets,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.dynalink,jdk.httpserver,\ -jdk.jsobject,jdk.localedata,jdk.naming.dns,jdk.security.auth,\ -jdk.security.jgss,jdk.xml.dom,jdk.zipfs,java.compiler,\ -jdk.internal.vm.compiler,jdk.internal.vm.compiler.management,\ -jdk.jdwp.agent \ - --output /opt/java - -WORKDIR /opt/java -RUN tar zcvf legal.tar.gz legal && rm -r legal - -RUN mkdir -p /rootfs \ - && chisel cut --root /rootfs \ - libc6_libs \ - libgcc-s1_libs \ - libstdc++6_libs \ - zlib1g_libs \ - libgraphite2-3_libs \ - libglib2.0-0_core \ - base-files_bin \ - base-files_chisel -RUN install -d -m 0755 -o $UID -g $GID /rootfs/home/$USER \ - && mkdir -p /rootfs/etc \ - && echo -e "root:x:0:\n$GROUP:x:$GID:" >/rootfs/etc/group \ - && echo -e "root:x:0:0:root:/root:/noshell\n$USER:x:$UID:$GID::/home/$USER:/noshell" >/rootfs/etc/passwd -RUN mkdir -p /rootfs/opt \ - && cp -r /opt/java/ /rootfs/opt/java/ - -WORKDIR /rootfs -RUN ln -s --relative opt/java/bin/java usr/bin/ - -FROM scratch -ARG USER -ARG UID -ARG GID -USER $UID:$GID -COPY --from=builder /rootfs / -# Workaround for https://github.com/moby/moby/issues/38710 -COPY --from=builder --chown=$UID:$GID /rootfs/home/$USER /home/$USER -ENV JAVA_HOME /opt/java/ -ENTRYPOINT ["/opt/java/bin/java"] diff --git a/jre/ubuntu-24.04-headless/rockcraft.yaml b/jre/ubuntu-24.04-headless/rockcraft.yaml new file mode 100644 index 00000000..3733f73d --- /dev/null +++ b/jre/ubuntu-24.04-headless/rockcraft.yaml @@ -0,0 +1,98 @@ +name: jre +version: 21-edge +base: bare +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + build-on: [ amd64 ] + +summary: OpenJDK 21 headless runtime environment +description: | + This rock provides OpenJDK 21 runtime environment including the following modules: + - java.base + - java.instrument + - java.logging,java.management + - java.management.rmi + - java.naming + - java.prefs + - java.rmi + - java.security.sasl + - java.xml, + - jdk.internal.vm.ci + - jdk.jfr,jdk.management + - jdk.management.jfr + - jdk.management.agent + - jdk.net + - jdk.nio.mapmode + - jdk.sctp + - jdk.unsupported + - jdk.naming.rmi + - java.se + - java.net.http + - java.scripting + - java.security.jgss + - java.smartcardio + - java.sql + - java.sql.rowset + - java.transaction.xa + - java.xml.crypto + - jdk.charsets + - jdk.crypto.cryptoki + - jdk.crypto.ec + - jdk.dynalink + - jdk.httpserver + - jdk.jsobject + - jdk.localedata + - jdk.naming.dns + - jdk.security.auth + - jdk.security.jgss + - jdk.xml.dom + - jdk.zipfs + - java.compiler + - jdk.internal.vm.compiler + - jdk.internal.vm.compiler.management + - jdk.jdwp.agent + +parts: + dependencies: + plugin: nil + stage-packages: + - base-passwd_data + - base-files_base + - libc6_libs + - libgcc-s1_libs + - libstdc++6_libs + - zlib1g_libs + - libpcsclite1_libs + - libnss3_libs + override-build: | + craftctl default + groupadd --root ${CRAFT_PART_INSTALL} app -g 10001 + useradd -d /home/app -s /bin/bash --root ${CRAFT_PART_INSTALL} -g app -m -u 10001 app + + runtime: + plugin: nil + build-packages: + - openjdk-21-jdk-headless + override-build: | + JAVA_HOME=usr/lib/jvm/java-21-openjdk-${CRAFT_ARCH_BUILD_FOR} + rm -rf ${CRAFT_PART_INSTALL}/${JAVA_HOME} + jlink --add-modules java.base,java.instrument,\ + java.logging,java.management,java.management.rmi,\ + java.naming,java.prefs,java.rmi,java.security.sasl,\ + java.xml,jdk.internal.vm.ci,\ + jdk.jfr,jdk.management,jdk.management.jfr,jdk.management.agent,\ + jdk.net,jdk.nio.mapmode,jdk.sctp,jdk.unsupported,jdk.naming.rmi,\ + java.se,java.net.http,java.scripting,java.security.jgss,\ + java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,\ + java.xml.crypto,jdk.charsets,jdk.crypto.cryptoki,\ + jdk.crypto.ec,jdk.dynalink,jdk.httpserver,jdk.jsobject,jdk.localedata,\ + jdk.naming.dns,jdk.security.auth,jdk.security.jgss,jdk.xml.dom,\ + jdk.zipfs,java.compiler,jdk.internal.vm.compiler,jdk.internal.vm.compiler.management,\ + jdk.jdwp.agent --no-man-pages -G \ + --output ${CRAFT_PART_INSTALL}/${JAVA_HOME} + + cd ${CRAFT_PART_INSTALL} + mkdir -p usr/bin + ln -s --relative ${JAVA_HOME}/bin/java usr/bin/ diff --git a/tests/acmeair/runtest b/tests/acmeair/runtest index 086761dc..185ae1a6 100755 --- a/tests/acmeair/runtest +++ b/tests/acmeair/runtest @@ -21,8 +21,7 @@ TAG=chiselled-demo-17 ACMEAIR_REPO=https://github.com/vpa1977/${PROJECT} DOCKER_OPTS="--rm \ - --tmpfs /tmp:exec \ - -u app \ + -u $(id -u ${USER}):$(id -g ${USER}) \ -v ${M2_CACHE}:${M2_CACHE} \ -v ${TEST_DIR}:${TEST_DIR} \ -w ${TEST_DIR}/${PROJECT} " @@ -36,4 +35,5 @@ docker run \ ${DOCKER_OPTS} \ ${MAVEN_IMAGE} \ -X -e -Dmaven.repo.local="${M2_CACHE}" \ + -Duser.home=${TEST_DIR} \ test diff --git a/tests/app_hello-world/runtest b/tests/app_hello-world/runtest index d56867f6..417e030d 100755 --- a/tests/app_hello-world/runtest +++ b/tests/app_hello-world/runtest @@ -5,4 +5,4 @@ echo "Running test for Java Hello World app" compile src/HelloWorld.java "-d ." -run_container $BASE_IMAGE HelloWorld +run_container $BASE_IMAGE exec java -cp /app HelloWorld diff --git a/tests/build-test-images.sh b/tests/build-test-images.sh new file mode 100755 index 00000000..b6181ce0 --- /dev/null +++ b/tests/build-test-images.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -e + +(cd jre/ubuntu-24.04-headless && \ + rockcraft pack --build-for amd64 && \ + rockcraft.skopeo copy oci-archive:jre_21-edge_amd64.rock docker-daemon:ubuntu/jre:test) + +docker build \ + -t ubuntu/jre:test-builder \ + --build-arg UID=$(id -u ${USER}) \ + --build-arg GID=$(id -g ${USER}) \ + -f tests/containers/builder/Dockerfile.24.04 \ + tests/containers/builder + +docker build \ + -t ubuntu/jre:test-maven \ + --build-arg ARCH=amd64 \ + --build-arg UID=$(id -u ${USER}) \ + --build-arg GID=$(id -g ${USER}) \ + --build-arg BASE_IMAGE=ubuntu/jre:test \ + --build-arg MAVEN_IMAGE=maven:3.9.9-eclipse-temurin-21 \ + -f tests/containers/maven/Dockerfile.24.04 \ + tests/containers/maven diff --git a/tests/containers/builder/Dockerfile.22.04 b/tests/containers/builder/Dockerfile.24.04 similarity index 86% rename from tests/containers/builder/Dockerfile.22.04 rename to tests/containers/builder/Dockerfile.24.04 index 82aa8d92..843eca07 100644 --- a/tests/containers/builder/Dockerfile.22.04 +++ b/tests/containers/builder/Dockerfile.24.04 @@ -1,4 +1,4 @@ -ARG BUILD_IMAGE=eclipse-temurin:17.0.13_11-jdk-jammy +ARG BUILD_IMAGE=eclipse-temurin:21.0.5_11-jdk-noble ARG USER=app ARG UID=101 ARG GROUP=app diff --git a/tests/containers/maven/Dockerfile.22.04 b/tests/containers/maven/Dockerfile.22.04 deleted file mode 100644 index 51079101..00000000 --- a/tests/containers/maven/Dockerfile.22.04 +++ /dev/null @@ -1,47 +0,0 @@ -ARG UBUNTU_RELEASE=22.04 -ARG BASE_IMAGE=ubuntu/jre:17_edge -ARG CHISEL_VERSION=1.0.0 -ARG TARGETARCH=amd64 - -FROM public.ecr.aws/ubuntu/ubuntu:$UBUNTU_RELEASE@sha256:1582c29f34a48752e406f1a261fe9545fad895da3f6bb4be55bc82485557564e AS jdk - -ARG CHISEL_VERSION -ARG TARGETARCH - -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates \ - ca-certificates-java \ - binutils \ - openjdk-17-jdk \ - maven \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* - - RUN jlink --no-header-files --no-man-pages --strip-debug \ - --add-modules ALL-MODULE-PATH --output /opt/java - -SHELL ["/bin/bash", "-oeux", "pipefail", "-c"] -ADD https://github.com/canonical/chisel/releases/download/v${CHISEL_VERSION}/chisel_v${CHISEL_VERSION}_linux_${TARGETARCH}.tar.gz chisel.tar.gz -RUN tar -xvf chisel.tar.gz -C /usr/bin/ -RUN mkdir -p /rootfs \ - && chisel cut --root /rootfs coreutils_bins dash_bins - -FROM $BASE_IMAGE - -COPY --from=jdk /rootfs / -COPY --from=jdk /etc/maven /etc/maven -COPY --from=jdk /usr/share/java /usr/share/java -COPY --from=jdk /usr/share/maven /usr/share/maven - -ENV JAVA_HOME=/opt/java - -# Add javac compiler for maven (it always recompiles package-info.java) -COPY --from=jdk /opt/java/bin/javac /opt/java/bin/ -# compatibility signatures -COPY --from=jdk /opt/java/lib/ct.sym /opt/java/lib/ -# additional jars -COPY --from=jdk /opt/java/lib/*.jar /opt/java/lib/ -# copy modules -COPY --from=jdk /opt/java/lib/modules /opt/java/lib/ - -ENTRYPOINT [ "/usr/share/maven/bin/mvn" ] diff --git a/tests/containers/maven/Dockerfile.24.04 b/tests/containers/maven/Dockerfile.24.04 new file mode 100644 index 00000000..5329ddc2 --- /dev/null +++ b/tests/containers/maven/Dockerfile.24.04 @@ -0,0 +1,41 @@ +ARG UBUNTU_RELEASE=24.04 +ARG BASE_IMAGE=ubuntu/jre:21_edge +ARG MAVEN_IMAGE=maven:3.9.9-eclipse-temurin-21 +ARG ARCH=amd64 +FROM $MAVEN_IMAGE AS builder +FROM public.ecr.aws/ubuntu/ubuntu:$UBUNTU_RELEASE@sha256:da20fb875cfefd317c49e7aaf3998d3e5ad42c5b20f34a0eec6dca2fe4fbb8f4 AS jdk + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates \ + ca-certificates-java \ + binutils \ + openjdk-21-jdk \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +RUN jlink --no-header-files --no-man-pages --strip-debug \ + --add-modules ALL-MODULE-PATH --output /opt/java + +FROM $BASE_IMAGE +ARG ARCH + +COPY --from=builder /bin/sh /bin/sh +COPY --from=builder /usr/bin/chmod /usr/bin/chmod +COPY --from=builder /usr/bin/uname /usr/bin/uname +COPY --from=builder /usr/bin/dirname /usr/bin/dirname +# note, Temurin base does not install into /etc/maven and /usr/share/java +# other base might require copying those folders +COPY --from=builder /usr/share/maven /usr/share/maven + +ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk-$ARCH + +# Add javac compiler for maven (it always recompiles package-info.java) +COPY --from=jdk /opt/java/bin/javac /usr/lib/jvm/java-21-openjdk-$ARCH/bin +# compatibility signatures +COPY --from=jdk /opt/java/lib/ct.sym /usr/lib/jvm/java-21-openjdk-$ARCH/lib +# additional jars +COPY --from=jdk /opt/java/lib/*.jar /usr/lib/jvm/java-21-openjdk-$ARCH/lib +# copy modules +COPY --from=jdk /opt/java/lib/modules /usr/lib/jvm/java-21-openjdk-$ARCH/lib + +ENTRYPOINT [ "/usr/share/maven/bin/mvn" ] diff --git a/tests/https-test/runtest b/tests/https-test/runtest index 60854a8b..fee53a14 100755 --- a/tests/https-test/runtest +++ b/tests/https-test/runtest @@ -6,5 +6,5 @@ echo "Running test for HTTPS connection app" compile src/Main.java "-d ." # run the test and if it fails, retry with the full network diagnostics -run_container $BASE_IMAGE Main || \ - run_container $BASE_IMAGE "-Djavax.net.debug=all Main" +run_container $BASE_IMAGE exec java -cp /app Main || \ + run_container $BASE_IMAGE exec java -cp /app -Djavax.net.debug=all Main diff --git a/tests/pdfbox/Dockerfile b/tests/pdfbox/Dockerfile deleted file mode 100644 index c4fe93ce..00000000 --- a/tests/pdfbox/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -ARG MAVEN_IMAGE -ARG UBUNTU_RELEASE=22.04 -ARG USER=app -ARG UID=101 -ARG GROUP=app -ARG GID=101 -ARG CHISEL_VERSION=1.0.0 -ARG TARGETARCH=amd64 - -FROM public.ecr.aws/ubuntu/ubuntu:$UBUNTU_RELEASE@sha256:1582c29f34a48752e406f1a261fe9545fad895da3f6bb4be55bc82485557564e AS builder -ARG CHISEL_VERSION -ARG TARGETARCH -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* - -SHELL ["/bin/bash", "-oeux", "pipefail", "-c"] -ADD https://github.com/canonical/chisel/releases/download/v${CHISEL_VERSION}/chisel_v${CHISEL_VERSION}_linux_${TARGETARCH}.tar.gz chisel.tar.gz -RUN tar -xvf chisel.tar.gz -C /usr/bin/ -RUN mkdir -p /rootfs \ - && chisel cut --root /rootfs \ - liblcms2-2_libs \ - libfontconfig1_libs \ - libfreetype6_libs \ - libjpeg-turbo8_libs - -FROM $MAVEN_IMAGE -COPY --from=builder /rootfs / diff --git a/tests/pdfbox/runtest b/tests/pdfbox/runtest deleted file mode 100755 index 2d49a210..00000000 --- a/tests/pdfbox/runtest +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -set -ex - -# This tests downloads PDFBox, patches out flaky test, copies javac in the -# container and then builds and runs PDFBox tests -echo "Running Apache PDFBox self-tests" - -if [ -z $MAVEN_IMAGE ]; then - echo 'Please define $MAVEN_IMAGE' - exit 1 -fi - -if [ -z $M2_CACHE ]; then - echo 'Please define $M2_CACHE' - exit 1 -fi - -PDFBOX_REPO=https://github.com/vpa1977/pdfbox -VERSION=3.0.3 -APP=pdfbox -TEST_DIR=`pwd` - -docker build -t ${APP} --build-arg MAVEN_IMAGE=${MAVEN_IMAGE} . - -DOCKER_OPTS="--rm \ - --tmpfs /tmp:exec \ - -u app \ - -v ${M2_CACHE}:${M2_CACHE} \ - -v ${TEST_DIR}:${TEST_DIR} \ - -w ${TEST_DIR}/${APP} " - -git clone --branch ${VERSION} ${PDFBOX_REPO} || \ - (cd ${APP} && \ - git checkout ${VERSION} && - git reset --hard) - -# build and tests with chiselled jre -docker run \ - ${DOCKER_OPTS} \ - ${APP} \ - -Dmaven.repo.local="${M2_CACHE}" \ - test diff --git a/tests/petclinic-test/.config/jgit/config b/tests/petclinic-test/.config/jgit/config new file mode 100644 index 00000000..f2eda3ef --- /dev/null +++ b/tests/petclinic-test/.config/jgit/config @@ -0,0 +1,3 @@ +[filesystem "Ubuntu|21.0.5|/dev/mapper/vgubuntu-root"] + timestampResolution = 2590 nanoseconds + minRacyThreshold = 1420 microseconds diff --git a/tests/petclinic-test/runtest b/tests/petclinic-test/runtest index fc8bc172..05f46c59 100755 --- a/tests/petclinic-test/runtest +++ b/tests/petclinic-test/runtest @@ -30,8 +30,7 @@ git clone --branch ${PETCLINIC_TAG} ${PETCLINIC_REPO} || \ # We should replace Temurin with our dev container DOCKER_OPTS="--rm \ - --tmpfs /tmp:exec \ - -u app \ + -u $(id -u ${USER}):$(id -g ${USER}) \ -v ${M2_CACHE}:${M2_CACHE} \ -v ${TEST_DIR}:${TEST_DIR} \ -w ${TEST_DIR}/${PROJECT} " @@ -40,5 +39,6 @@ DOCKER_OPTS="--rm \ docker run \ ${DOCKER_OPTS} \ ${MAVEN_IMAGE} \ - -Dmaven.repo.local="${M2_CACHE}" \ + -Dmaven.repo.local=${M2_CACHE} \ + -Duser.home=${TEST_DIR} \ test diff --git a/tests/run-all-tests b/tests/run-all-tests index dd554d40..f8c1b90a 100755 --- a/tests/run-all-tests +++ b/tests/run-all-tests @@ -5,15 +5,15 @@ echo "Running tests..." export BASE_IMAGE=${1:-"ubuntu/jre:test"} export BUILD_IMAGE=${2:-"ubuntu/jre:test-builder"} -export M2_CACHE=${3:-"/tmp/.m2"} +export M2_CACHE=${3:-"$(pwd)/.m2"} export MAVEN_IMAGE=${4:-"ubuntu/jre:test-maven"} compile() { - javac -source 17 -target 17 $1 $2 + javac -source 21 -target 21 $1 $2 } run_container() { - docker run --rm -v $PWD:/app:ro -w /app $3 $1 $2 + docker run --rm -v $PWD:/app:ro -w /app $* } export -f compile