Skip to content

Commit bc22c01

Browse files
Add oieserver launcher script
This script is the main launcher for the Open Integration Engine (OIE) server. It prepares the Java environment and executes the server launcher JAR file. The script automatically finds a compatible Java runtime (version 17+ by default) by searching for a valid executable in the following priority order: 1. The OIE_JAVA_PATH environment variable. 2. The -java-cmd directive in the oieserver.vmoptions file or included .vmoptions files. Must specify the path to the 'java' executable. This is the preferred way to declare the desired version for running the server and can be overridden by OIE_JAVA_PATH. Can be a relative path from the location of this script. 3. The JAVA_HOME environment variable. 4. The 'java' command available in the system's PATH. It also parses the 'oieserver.vmoptions' file to configure JVM options, system properties (-D...), and classpath modifications. Signed-off-by: Tony Germano <tony@germano.name> Co-authored-by: Mitch Gaffigan <mitch.gaffigan@comcast.net> Issue: #2
1 parent 8e6a11e commit bc22c01

File tree

2 files changed

+231
-1
lines changed

2 files changed

+231
-1
lines changed

server/basedir-includes/oieserver

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
#!/usr/bin/env bash
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
# SPDX-FileCopyrightText: 2025 Tony Germano and Mitch Gaffigan
5+
#
6+
7+
# =============================================================================
8+
# Open Integration Engine Server Launcher Script
9+
#
10+
# Description:
11+
# This script is the main launcher for the Open Integration Engine (OIE)
12+
# server. It prepares the Java environment and executes the server launcher
13+
# JAR file.
14+
#
15+
# The script automatically finds a compatible Java runtime (version 17+ by
16+
# default) by searching for a valid executable in the following priority order:
17+
# 1. The OIE_JAVA_PATH environment variable.
18+
# 2. The -java-cmd directive in the oieserver.vmoptions file or included
19+
# .vmoptions files. Must specify the path to the 'java' executable.
20+
# This is the preferred way to declare the desired version for running
21+
# the server and can be overridden by OIE_JAVA_PATH. Can be a relative
22+
# path from the location of this script.
23+
# 3. The JAVA_HOME environment variable.
24+
# 4. The 'java' command available in the system's PATH.
25+
#
26+
# It also parses the 'oieserver.vmoptions' file to configure JVM options,
27+
# system properties (-D...), and classpath modifications.
28+
#
29+
# Usage:
30+
# ./oieserver.sh [app-arguments]
31+
#
32+
# All [app-arguments] are passed directly to the underlying Java application
33+
# (com.mirth.connect.server.launcher.MirthLauncher).
34+
#
35+
# Configuration via Environment Variables:
36+
# OIE_JAVA_PATH - (Highest priority) Set the full path to the 'java'
37+
# executable to be used. Can be a relative path from the
38+
# location of this script or a tilde path
39+
# (e.g., ~/path/to/java).
40+
# JAVA_HOME - Set the path to the root of a Java installation. The
41+
# script will look for 'bin/java' within this path.
42+
# =============================================================================
43+
44+
APP_ARGS=("$@")
45+
MIN_JAVA_VERSION=17
46+
47+
# Set OIE_HOME to the script directory
48+
OIE_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
49+
CLASSPATH="$OIE_HOME/mirth-server-launcher.jar"
50+
VMOPTIONS=()
51+
# This will hold the validated path to the Java executable. It is intentionally left empty for now.
52+
FINAL_JAVA_CMD=""
53+
# This will temporarily hold the result from parsing the vmoptions file.
54+
VMOPTIONS_JAVA_CMD=""
55+
56+
57+
# --- Function to resolve a path to a canonical absolute path ---
58+
# Resolves a given path, handling tilde, relative, and '..' components.
59+
# @param $1: The path to resolve.
60+
# @echo: The resolved, canonical absolute path.
61+
resolve_absolute_path() {
62+
local path_to_resolve="$1"
63+
64+
# Explicitly handle tilde expansion first
65+
if [[ "$path_to_resolve" =~ ^~ ]]; then
66+
# Use eval to expand the tilde to the user's home directory.
67+
# This correctly handles "~", "~/path", and "~username/path".
68+
path_to_resolve=$(eval echo "$path_to_resolve")
69+
fi
70+
71+
# If the path is not absolute, assume it's relative to OIE_HOME
72+
if [[ ! "$path_to_resolve" =~ ^/ ]]; then
73+
path_to_resolve="$OIE_HOME/$path_to_resolve"
74+
fi
75+
76+
# Use cd and pwd to resolve '..' and '.' components for a canonical path.
77+
if [[ -d "$(dirname "$path_to_resolve")" ]]; then
78+
echo "$(cd "$(dirname "$path_to_resolve")" && pwd)/$(basename "$path_to_resolve")"
79+
else
80+
# If the directory doesn't exist, we can't resolve '..'. Return the concatenated path.
81+
# Subsequent checks in is_valid_java_version will then fail it gracefully.
82+
echo "$path_to_resolve"
83+
fi
84+
}
85+
86+
# --- Function to validate Java version ---
87+
# Checks if a given command points to a Java executable of the required minimum version.
88+
# @param $1: The java command or path to check (e.g., "java", "/opt/jdk-17/bin/java")
89+
# @return: 0 on success (is valid), 1 on failure.
90+
is_valid_java_version() {
91+
local java_cmd="$1"
92+
local error_message="Warning: '$java_cmd' is specified by $2, which is not a valid Java executable of at least version $MIN_JAVA_VERSION. Ignoring."
93+
94+
# Check if the command is found and is executable
95+
if ! command -v "$java_cmd" &> /dev/null || ! [[ -x "$(command -v "$java_cmd")" ]]; then
96+
echo "$error_message" >&2
97+
return 1
98+
fi
99+
100+
# Execute 'java -version' and capture the output from stderr
101+
# Example output: openjdk version "17.0.2" 2022-07-19
102+
local version_output
103+
version_output=$("$java_cmd" -version 2>&1)
104+
105+
# Check if the version command succeeded
106+
if [[ $? -ne 0 ]]; then
107+
echo "$error_message" >&2
108+
return 1
109+
fi
110+
111+
# Extract the major version number. This works for formats like "1.8.0" and "17.0.2".
112+
local major_version
113+
major_version=$(echo "$version_output" | head -n 1 | cut -d '"' -f 2 | cut -d '.' -f 1)
114+
115+
# Check if the extracted version is a number and meets the minimum requirement
116+
if [[ "$major_version" =~ ^[0-9]+$ ]] && [[ "$major_version" -ge "$MIN_JAVA_VERSION" ]]; then
117+
echo "Info: Found suitable java version specified by $2"
118+
return 0 # Success
119+
else
120+
echo "$error_message" >&2
121+
return 1 # Failure
122+
fi
123+
}
124+
125+
# Set Java options by parsing the vmoptions file
126+
parse_vmoptions() {
127+
local file="$1"
128+
129+
if [[ ! -f "$file" ]]; then
130+
echo "Warning: VM options file not found: $file" >&2
131+
return 1
132+
fi
133+
134+
# Read the file line by line
135+
while IFS= read -r line; do
136+
# Trim leading/trailing whitespace
137+
line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
138+
139+
# Skip empty lines and comments
140+
if [[ -z "$line" || "$line" =~ ^# ]]; then
141+
continue
142+
fi
143+
144+
# Evaluate environment variables to be their actual values
145+
# NOTE: This eval also handles tilde expansion for vmoptions lines.
146+
line=$(eval echo "$line")
147+
148+
# Check for -include-options directive
149+
if [[ "$line" =~ ^-include-options[[:space:]]+(.+) ]]; then
150+
local included_file="${BASH_REMATCH[1]}"
151+
# Resolve relative paths
152+
if [[ ! "$included_file" =~ ^/ ]]; then # Not an absolute path
153+
included_file="$(dirname "$file")/$included_file"
154+
fi
155+
# Recursively call parse_vmoptions for the included file
156+
parse_vmoptions "$included_file"
157+
elif [[ "$line" =~ ^-classpath[[:space:]]+(.+) ]]; then
158+
# Handle -classpath directive
159+
CLASSPATH="${BASH_REMATCH[1]}"
160+
elif [[ "$line" =~ ^-classpath/a[[:space:]]+(.+) ]]; then
161+
# Handle -classpath/a directive (append to existing classpath)
162+
CLASSPATH="${CLASSPATH}:${BASH_REMATCH[1]}"
163+
elif [[ "$line" =~ ^-classpath/p[[:space:]]+(.+) ]]; then
164+
# Handle -classpath/p directive (prepend to existing classpath)
165+
CLASSPATH="${BASH_REMATCH[1]}:${CLASSPATH}"
166+
elif [[ "$line" =~ ^-java-cmd[[:space:]]+(.+) ]]; then
167+
# Handle -java-cmd directive
168+
local candidate_java_cmd="${BASH_REMATCH[1]}"
169+
# Resolve path to an absolute one before validation
170+
local resolved_candidate_cmd
171+
resolved_candidate_cmd=$(resolve_absolute_path "$candidate_java_cmd")
172+
173+
if [[ -z "$FINAL_JAVA_CMD" ]] && is_valid_java_version "$resolved_candidate_cmd" "the -java-cmd directive in '$file'"; then
174+
VMOPTIONS_JAVA_CMD="$resolved_candidate_cmd"
175+
fi
176+
else
177+
# Add the option to the accumulated string
178+
VMOPTIONS+=("$line")
179+
fi
180+
done < "$file"
181+
return 0
182+
}
183+
184+
# The OIE_JAVA_PATH has highest priority for specifying the Java executable.
185+
# If a valid version is found, the '-java-cmd' directive will be ignored when parsing the VM options file.
186+
if [[ -n "$OIE_JAVA_PATH" ]]; then
187+
# Resolve path to an absolute one before validation
188+
resolved_oie_java_path=$(resolve_absolute_path "$OIE_JAVA_PATH")
189+
190+
if is_valid_java_version "$resolved_oie_java_path" "the OIE_JAVA_PATH environment variable"; then
191+
FINAL_JAVA_CMD="$resolved_oie_java_path"
192+
fi
193+
fi
194+
195+
# Recursively parse the VM options file
196+
parse_vmoptions "$OIE_HOME/oieserver.vmoptions"
197+
198+
# Find the Java executable if not already set by '$OIE_JAVA_PATH'
199+
if [[ -z "$FINAL_JAVA_CMD" ]]; then
200+
# Check for the result from parsing the vmoptions file.
201+
# Validation is done during parsing.
202+
if [[ -n "$VMOPTIONS_JAVA_CMD" ]]; then
203+
FINAL_JAVA_CMD="$VMOPTIONS_JAVA_CMD"
204+
# If not found, check JAVA_HOME
205+
elif [[ -n "$JAVA_HOME" ]] && [[ -f "$JAVA_HOME/bin/java" ]] && is_valid_java_version "$JAVA_HOME/bin/java" "the JAVA_HOME environment variable"; then
206+
FINAL_JAVA_CMD="$JAVA_HOME/bin/java"
207+
# If still not found, check for 'java' in the system PATH
208+
elif is_valid_java_version "java" "the system PATH"; then
209+
FINAL_JAVA_CMD="java"
210+
fi
211+
fi
212+
213+
# Final check for a valid Java path before execution.
214+
if [[ -z "$FINAL_JAVA_CMD" ]]; then
215+
echo "Error: Could not find a Java ${MIN_JAVA_VERSION}+ installation." >&2
216+
echo "Please configure -java-cmd in conf/custom.vmoptions, set JAVA_HOME, set OIE_JAVA_PATH, or ensure 'java' in your PATH is version ${MIN_JAVA_VERSION} or higher." >&2
217+
exit 1
218+
fi
219+
220+
JAVA_OPTS=("${VMOPTIONS[@]}"
221+
"-cp" "$CLASSPATH"
222+
"com.mirth.connect.server.launcher.MirthLauncher"
223+
"${APP_ARGS[@]}")
224+
225+
# Launch Open Integration Engine (as this PID with exec)
226+
echo "Starting Open Integration Engine..."
227+
echo "Using Java from: $FINAL_JAVA_CMD"
228+
echo "$FINAL_JAVA_CMD ${JAVA_OPTS[*]}"
229+
exec "$FINAL_JAVA_CMD" "${JAVA_OPTS[@]}"

server/conf/custom.vmoptions

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
# : append <path> to classpath.
1414
#
1515
# -java-cmd <path to java command>
16-
# : use the java binary specified to launch the engine.
16+
# : use the java binary specified to launch the engine. Relative paths are relative to
17+
# : the engine home directory.
1718
#
1819
# Additionally, the form ${ENV_VAR} can be used anywhere in the file to substitute the value
1920
# from an environment variable.

0 commit comments

Comments
 (0)