Skip to content

Commit

Permalink
Merge pull request #401 from Josh-Matsuoka/ubi9-jlink
Browse files Browse the repository at this point in the history
Integrate the JLink workflow and scripts into the Ubi9 container sources
  • Loading branch information
jmtd authored Dec 13, 2023
2 parents 4bc78f0 + 9433d1a commit 249397b
Show file tree
Hide file tree
Showing 16 changed files with 308 additions and 87 deletions.
1 change: 1 addition & 0 deletions modules/jdk/11/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ envs:
packages:
install:
- java-11-openjdk-devel
- java-11-openjdk-jmods
- tzdata-java

modules:
Expand Down
1 change: 1 addition & 0 deletions modules/jdk/17/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ envs:
packages:
install:
- java-17-openjdk-devel
- java-17-openjdk-jmods

modules:
install:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

function generatejdkdeps() {
echo "Generating JDK deps"
$JAVA_HOME/bin/java --list-modules > java-modules.txt
< java-modules.txt sed "s/\\@.*//" > modules.txt
grep -Fx -f stripped-deps.txt modules.txt | tr '\n' ',' | tr -d "[:space:]" > module-deps.txt
echo "jdk.zipfs" >> module-deps.txt
}
35 changes: 35 additions & 0 deletions modules/jlink/artifacts/opt/jboss/container/java/jlink/mkdeps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash
set -euo pipefail
shopt -s globstar

function generate_deps() {
# Create a temporary directory for a module path
# This works around "Module java.xml.bind not found, required by java.ws.rs"
mkdir dependencies

if [[ -v JAVA_LIB_DIR ]]; then
# Serially copy all library JARsinto a flat directory. Serially as we may
# have multiple libs with the same name; in which case, we clobber all but
# one rather than fail the script
find $JAVA_LIB_DIR -type f -name '*.jar' -exec cp -vt dependencies {} \;

echo "Working with: "
echo $JAVA_APP_JAR
echo $JAVA_LIB_DIR
# generate the dependency list
$JAVA_HOME/bin/jdeps --multi-release $JAVA_VERSION -R -s \
--module-path dependencies \
"$JAVA_APP_JAR" \
"$JAVA_LIB_DIR"/**/*.jar \
> deps.txt || {
echo "jdeps failed: return code $?"
exit $?
}
else
$JAVA_HOME/bin/jdeps --multi-release $JAVA_VERSION -R -s \
--module-path dependencies \
"$JAVA_APP_JAR" \
> deps.txt
cat deps.txt
fi
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
# TODO: Still Needed?
set -euo pipefail

depsfile="module-deps.txt"

function generate_jre_image() {
test -f $depsfile
modules="$(cat $depsfile)"

$JAVA_HOME/bin/jlink --output "$S2I_JLINK_OUTPUT_PATH" \
--add-modules "$modules" \
--strip-debug --no-header-files --no-man-pages \
--compress=2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail

function mkstrippeddeps() {
if [ -f "deps.txt" ]; then
echo "deps exists, filtering"
<deps.txt \
grep 'java\|jdk\.' | # mostly removes target/, but also jdk8internals
sed -E "s/Warning: .*//" | #remove extraneous warnings
sed -E "s/.*-> //" | # remove src of src -> dep
sed -E "s/.*\.jar//" | # remove extraneous dependencies
sed "s#/.*##" | # delete anything after a slash. in practice target/..
sort | uniq |
tee stripped-deps.txt
echo "Stripping dependencies complete"
else
echo "deps does not exist"
fi
}
14 changes: 14 additions & 0 deletions modules/jlink/configure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
# Configure module
set -e

SCRIPT_DIR=$(dirname $0)
ARTIFACTS_DIR=${SCRIPT_DIR}/artifacts

chown -R default:root $SCRIPT_DIR
chmod -R ug+rwX $SCRIPT_DIR
chmod ug+x ${ARTIFACTS_DIR}/opt/jboss/container/java/jlink/*

pushd ${ARTIFACTS_DIR}
cp -pr * /
popd
25 changes: 25 additions & 0 deletions modules/jlink/module.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
schema_version: 1

name: "jboss.container.java.jlink"
version: "2.0"
description: ^
"Provides support for building custom JREs with a slimmed
down set of modules by making use of Jdeps and Jlink"

execute:
- script: configure.sh

envs:
- name: JBOSS_CONTAINER_JAVA_JLINK_MODULE
value: /opt/jboss/container/java/jlink
- name: S2I_JLINK_OUTPUT_PATH
value: /tmp/jre

modules:
install:
- name: jboss.container.java.run
- name: jboss.container.util.pathfinder

packages:
install:
- binutils # for objcopy
92 changes: 5 additions & 87 deletions modules/run/artifacts/opt/jboss/container/java/run/run-java.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,101 +22,19 @@ check_error() {
fi
}

# detect Quarkus fast-jar package type (OPENJDK-631)
is_quarkus_fast_jar() {
if test -f quarkus-app/quarkus-run.jar; then
log_info "quarkus fast-jar package type detected"
echo quarkus-app/quarkus-run.jar
return 0
else
return 1
fi
}

# Try hard to find a sane default jar-file
auto_detect_jar_file() {
local dir=$1

# Filter out temporary jars from the shade plugin which start with 'original-'
local old_dir=$(pwd)
cd ${dir}
if [ $? = 0 ]; then

if quarkus="$(is_quarkus_fast_jar)"; then
echo "$quarkus"
return
fi

local nr_jars=`ls *.jar 2>/dev/null | grep -v '^original-' | wc -l | tr -d '[[:space:]]'`
if [ ${nr_jars} = 1 ]; then
ls *.jar | grep -v '^original-'
exit 0
fi

log_error "Neither \$JAVA_MAIN_CLASS nor \$JAVA_APP_JAR is set and ${nr_jars} JARs found in ${dir} (1 expected)"
cd ${old_dir}
else
log_error "No directory ${dir} found for auto detection"
fi
}

# Check directories (arg 2...n) for a jar file (arg 1)
get_jar_file() {
local jar=$1
shift;

if [ "${jar:0:1}" = "/" ]; then
if [ -f "${jar}" ]; then
echo "${jar}"
else
log_error "No such file ${jar}"
fi
else
for dir in $*; do
if [ -f "${dir}/$jar" ]; then
echo "${dir}/$jar"
return
fi
done
log_error "No ${jar} found in $*"
fi
}

load_env() {
# Configuration stuff is read from this file
local run_env_sh="run-env.sh"

# Load default default config
if [ -f "${JBOSS_CONTAINER_JAVA_RUN_MODULE}/${run_env_sh}" ]; then
source "${JBOSS_CONTAINER_JAVA_RUN_MODULE}/${run_env_sh}"
fi

# Check also $JAVA_APP_DIR. Overrides other defaults
# It's valid to set the app dir in the default script
if [ -z "${JAVA_APP_DIR}" ]; then
# XXX: is this correct? This is defaulted above to /deployments. Should we
# define a default to the old /opt/java-run?
JAVA_APP_DIR="${JBOSS_CONTAINER_JAVA_RUN_MODULE}"
else
if [ -f "${JAVA_APP_DIR}/${run_env_sh}" ]; then
source "${JAVA_APP_DIR}/${run_env_sh}"
fi
fi
export JAVA_APP_DIR

# JAVA_LIB_DIR defaults to JAVA_APP_DIR
export JAVA_LIB_DIR="${JAVA_LIB_DIR:-${JAVA_APP_DIR}}"
if [ -z "${JAVA_MAIN_CLASS}" ] && [ -z "${JAVA_APP_JAR}" ]; then
JAVA_APP_JAR="$(auto_detect_jar_file ${JAVA_APP_DIR})"
check_error "${JAVA_APP_JAR}"
fi

if [ "x${JAVA_APP_JAR}" != x ]; then
local jar="$(get_jar_file ${JAVA_APP_JAR} ${JAVA_APP_DIR} ${JAVA_LIB_DIR})"
check_error "${jar}"
export JAVA_APP_JAR=${jar}
else
export JAVA_MAIN_CLASS
# Load JAVA_APP_JAR and JAVA_LIB_DIR
if [ -f "${JBOSS_CONTAINER_UTIL_PATHFINDER_MODULE}/pathfinder.sh" ]; then
source "$JBOSS_CONTAINER_UTIL_PATHFINDER_MODULE/pathfinder.sh"
setup_java_app_and_lib
fi
}

Expand Down
21 changes: 21 additions & 0 deletions modules/s2i/bash/artifacts/usr/local/s2i/assemble
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,24 @@ source "${JBOSS_CONTAINER_JAVA_S2I_MODULE}/maven-s2i-overrides"
# invoke the build
maven_s2i_build

# run the pathfinder scripts to define JAVA_APP_JAR and JAVA_LIB_DIR
source "${JBOSS_CONTAINER_UTIL_PATHFINDER_MODULE}/pathfinder.sh"
echo "Setting up java app and lib variables"
setup_java_app_and_lib

# include our jlink scripts
source "${JBOSS_CONTAINER_JAVA_JLINK_MODULE}/mkdeps.sh"
echo "Invoking mkdeps"
generate_deps

source "${JBOSS_CONTAINER_JAVA_JLINK_MODULE}/mkstrippeddeps.sh"
echo "Stripping dependencies"
mkstrippeddeps

source "${JBOSS_CONTAINER_JAVA_JLINK_MODULE}/generatejdkdeps.sh"
echo "Generating JDK dependencies"
generatejdkdeps

source "${JBOSS_CONTAINER_JAVA_JLINK_MODULE}/mkjreimage.sh"
echo "Linking jre"
generate_jre_image
2 changes: 2 additions & 0 deletions modules/s2i/bash/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ modules:
- name: jboss.container.maven.s2i
- name: jboss.container.java.run
- name: jboss.container.util.logging
- name: jboss.container.java.jlink
- name: jboss.container.util.pathfinder

packages:
install:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function s2i_core_env_init() {
S2I_IMAGE_SOURCE_MOUNTS="${S2I_IMAGE_SOURCE_MOUNTS:-${CUSTOM_INSTALL_DIRECTORIES}}"
S2I_ENABLE_INCREMENTAL_BUILDS="${S2I_ENABLE_INCREMENTAL_BUILDS:-true}"
S2I_DELETE_SOURCE="${S2I_DELETE_SOURCE:-true}"
S2I_ENABLE_JLINK="${S2I_ENABLE_JLINK:-false}"
}

# extensions may override this method to initialize environment variables
Expand Down Expand Up @@ -88,11 +89,13 @@ function s2i_core_copy_deployments() {
if [ ! -d "${S2I_TARGET_DEPLOYMENTS_DIR}" ]; then
log_info "S2I_TARGET_DEPLOYMENTS_DIR does not exist, creating ${S2I_TARGET_DEPLOYMENTS_DIR}"
mkdir -pm 775 "${S2I_TARGET_DEPLOYMENTS_DIR}"
echo "created $S2I_TARGET_DEPLOYMENTS_DIR"
fi
local relative_source=$(realpath --relative-to "${S2I_SOURCE_DIR}" "${1}/${S2I_SOURCE_DEPLOYMENTS_DIR}")
log_info "Copying deployments from $relative_source to ${S2I_TARGET_DEPLOYMENTS_DIR}..."
for filter in ${S2I_SOURCE_DEPLOYMENTS_FILTER:-*}; do
find "${S2I_SOURCE_DIR}/${relative_source}/" -maxdepth 1 -name "${filter}" | xargs -I '{}' -r cp -Lrpv '{}' "${S2I_TARGET_DEPLOYMENTS_DIR}"
echo "Copying $filter to $S2I_TARGET_DEPLOYMENTS_DIR"
done
fi
fi
Expand Down
6 changes: 6 additions & 0 deletions modules/s2i/core/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ envs:
Delete source files at the end of build. Defaults to true.
example: "false"

- name: S2I_ENABLE_JLINK
description: ^
Enables the Jdeps/JLink workflow to minimize JRE size
example: "false"
value: false

run:
cmd:
- "/usr/local/s2i/run"
Expand Down
Loading

0 comments on commit 249397b

Please sign in to comment.