Skip to content

Commit

Permalink
Updated java options manage. Fixes infinispan#229
Browse files Browse the repository at this point in the history
  • Loading branch information
rigazilla committed May 30, 2024
1 parent 6b1617d commit bc84206
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 97 deletions.
217 changes: 121 additions & 96 deletions modules/org/infinispan/distribution/jvm/added/bin/java-opts.sh
Original file line number Diff line number Diff line change
@@ -1,136 +1,161 @@
#!/bin/sh
# ===================================================================================
# Generic startup script for running arbitrary Java applications with
# being optimized for running in containers
#
# Modified version of https://github.com/fabric8io-images/run-java-sh/blob/master/fish-pepper/run-java-sh/fp-files/run-java.sh
# ===================================================================================

## Generic startup script for running arbitrary Java applications with
## being optimized for running in containers
##
## Modified version of https://github.com/jboss-container-images/openjdk/blob/ubi9/modules/run/artifacts/opt/jboss/container/java/run/run-java.sh
## ===================================================================================
if [ -n "${DEBUG:-}" ]; then
set -x
set -x
fi

# ksh is different for defining local vars
if [ -n "${KSH_VERSION:-}" ]; then
alias local=typeset
fi

# Generic formula evaluation based on awk
calc() {
local formula="$1"
shift
echo "$@" | awk '
function ceil(x) {
return x % 1 ? int(x) + 1 : x
}
function log2(x) {
return log(x)/log(2)
}
function max2(x, y) {
return x > y ? x : y
}
function round(x) {
return int(x + 0.5)
}
{print '"int(${formula})"'}
'
}
export JBOSS_CONTAINER_UTIL_LOGGING_MODULE="${JBOSS_CONTAINER_UTIL_LOGGING_MODULE-/opt/jboss/container/util/logging}"
export JBOSS_CONTAINER_JAVA_RUN_MODULE="${JBOSS_CONTAINER_JAVA_RUN_MODULE-/opt/jboss/container/java/run}"

max_memory() {
# High number which is the max limit until which memory is supposed to be
# unbounded.
local mem_file="/sys/fs/cgroup/memory.max"
if [ ! -r "${mem_file}" ]; then
mem_file="/sys/fs/cgroup/memory/memory.limit_in_bytes"
fi
if [ -r "${mem_file}" ]; then
local max_mem_cgroup="$(cat ${mem_file})"
local max_mem_meminfo_kb="$(cat /proc/meminfo | awk '/MemTotal/ {print $2}')"
local max_mem_meminfo="$(expr $max_mem_meminfo_kb \* 1024)"
if [ ${max_mem_cgroup:-0} != -1 ] && [ ${max_mem_cgroup:-0} -lt ${max_mem_meminfo:-0} ]
then
echo "${max_mem_cgroup}"
fi
# Default the application dir to the S2I deployment dir
if [ -z "$JAVA_APP_DIR" ]
then JAVA_APP_DIR=/deployments
fi

source "$JBOSS_CONTAINER_UTIL_LOGGING_MODULE/logging.sh"

# ==========================================================
# Generic run script for running arbitrary Java applications
#
# This has forked (and diverged) from:
# at https://github.com/fabric8io/run-java-sh
#
# ==========================================================

# Error is indicated with a prefix in the return value
check_error() {
local msg=$1
if echo ${msg} | grep -q "^ERROR:"; then
log_error ${msg}
exit 1
fi
}

init_limit_env_vars() {
# Read in container limits and export the as environment variables
local mem_limit="$(max_memory)"
if [ -n "${mem_limit}" ]; then
export CONTAINER_MAX_MEMORY="${mem_limit}"
# 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
}

# ==========================================================================
# Check for memory options and set max heap size if needed
calc_max_memory() {
# Check whether -Xmx is already given in JAVA_OPTIONS
if echo "${JAVA_OPTIONS:-}" | grep -q -- "-Xmx"; then
return
fi
# Try hard to find a sane default jar-file
auto_detect_jar_file() {
local dir=$1

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

# Check for the 'real memory size' and calculate Xmx from the ratio
if [ -n "${JAVA_MAX_MEM_RATIO:-}" ]; then
if [ "${JAVA_MAX_MEM_RATIO}" -eq 0 ]; then
# Explicitely switched off
if quarkus="$(is_quarkus_fast_jar)"; then
echo "$quarkus"
return
fi
calc_mem_opt "${CONTAINER_MAX_MEMORY}" "${JAVA_MAX_MEM_RATIO}" "mx"

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
# When JAVA_MAX_MEM_RATIO not set and JVM >= 10 no max_memory
}

# Check for memory options and set initial heap size if requested
calc_init_memory() {
# Check whether -Xms is already given in JAVA_OPTIONS.
if echo "${JAVA_OPTIONS:-}" | grep -q -- "-Xms"; then
return
# 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"

# Check if value set
if [ -z "${JAVA_INIT_MEM_RATIO:-}" ] || [ -z "${CONTAINER_MAX_MEMORY:-}" ] || [ "${JAVA_INIT_MEM_RATIO}" -eq 0 ]; then
return
# 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

# Calculate Xms from the ratio given
calc_mem_opt "${CONTAINER_MAX_MEMORY}" "${JAVA_INIT_MEM_RATIO}" "ms"
}
# Check also $JAVA_APP_DIR. Overrides other defaults
# It's valid to set the app dir in the default script
if [ -f "${JAVA_APP_DIR}/${run_env_sh}" ]; then
source "${JAVA_APP_DIR}/${run_env_sh}"
fi

calc_mem_opt() {
local max_mem="$1"
local fraction="$2"
local mem_opt="$3"
export JAVA_APP_DIR

local val=$(calc 'round($1*$2/100/1048576)' "${max_mem}" "${fraction}")
echo "-X${mem_opt}${val}m"
}
# 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

# Switch on diagnostics except when switched off
diagnostics_options() {
if [ -n "${JAVA_DIAGNOSTICS:-}" ]; then
echo "-XX:NativeMemoryTracking=summary -Xlog:gc*:stdout:time -XX:+UnlockDiagnosticVMOptions"
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
fi
}

gc_options() {
local gc_options="-XX:+ExitOnOutOfMemoryError"
if [ -n "${JAVA_GC_METASPACE_SIZE:-}" ] || [ "${JAVA_GC_METASPACE_SIZE//[!0-9]/}" -gt 0 ]; then
gc_options="${gc_options} -XX:MetaspaceSize=${JAVA_GC_METASPACE_SIZE}"
# Combine all java options
get_java_options() {
local jvm_opts
local debug_opts
local proxy_opts
local opts
if [ -f "${JBOSS_CONTAINER_JAVA_JVM_MODULE}/java-default-options" ]; then
jvm_opts=$(${JBOSS_CONTAINER_JAVA_JVM_MODULE}/java-default-options)
fi

if [ -n "${JAVA_GC_MAX_METASPACE_SIZE:-}" ] || [ "${JAVA_GC_MAX_METASPACE_SIZE//[!0-9]/}" -gt 0 ]; then
gc_options="${gc_options} -XX:MaxMetaspaceSize=${JAVA_GC_MAX_METASPACE_SIZE}"
if [ -f "${JBOSS_CONTAINER_JAVA_JVM_MODULE}/debug-options" ]; then
debug_opts=$(${JBOSS_CONTAINER_JAVA_JVM_MODULE}/debug-options)
fi
if [ -f "${JBOSS_CONTAINER_JAVA_PROXY_MODULE}/proxy-options" ]; then
source "${JBOSS_CONTAINER_JAVA_PROXY_MODULE}/proxy-options"
proxy_opts="$(proxy_options)"
fi
echo ${gc_options}

opts=${JAVA_OPTS-${debug_opts} ${proxy_opts} ${jvm_opts} ${JAVA_OPTS_APPEND}}
# Normalize spaces with awk (i.e. trim and eliminate double spaces)
echo "${opts}" | awk '$1=$1'
}

java_opts() {
init_limit_env_vars
# Echo options, trimming trailing and multiple spaces
echo "${JAVA_OPTIONS:-} $(calc_init_memory) $(calc_max_memory) $(diagnostics_options) $(gc_options)" | awk '$1=$1'
get_java_options
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Set jvm args reflecting container limits and configured env vars
. $ISPN_HOME/bin/java-opts.sh
JAVA_OPTS="$(java_opts)"

set +eo pipefail

# Append JAVA_OPTIONS and the end so user can override defaults
JAVA_OPTS="$(java_opts) $JAVA_OPTIONS"

# Add java options required by Infinispan
export JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true"
Expand Down

0 comments on commit bc84206

Please sign in to comment.