Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ run the CLI automatically renames a pre-existing global `~/.camel-jbang-user.pro
`~/.camel-cli.properties` and a pre-existing local `./camel-jbang-user.properties` to
`./camel-cli.properties`; an existing new file is never overwritten.

==== Camel CLI launcher Java runtime discovery

The self-contained Camel CLI launcher scripts (`bin/camel.sh` and `bin/camel.bat` in the
`camel-launcher` distribution) now share a single Java runtime discovery contract. Candidates
are evaluated in this fixed order, and the first one that exists, is executable, and reports a
Java major version of at least 17 is used:

1. `JAVACMD` (explicit override, unchanged).
2. `$JAVA_HOME/bin/java` (`%JAVA_HOME%\bin\java.exe` on Windows). This is also how the SDKMAN
`java` candidate is honored, since SDKMAN exports `JAVA_HOME`.
3. The first `java` (`java.exe`) found on `PATH`.
4. `CAMEL_FALLBACK_JAVA`, a new variable set by package-manager installs when the JDK location
is deterministic.

Candidates older than Java 17, missing, non-executable, or with unparseable version output are
skipped. If none qualify, the launcher now exits nonzero with a diagnostic listing the checked
sources instead of attempting to run an unsuitable Java.

The obsolete macOS `JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/...` default was
removed from `camel.sh`; set `JAVA_HOME` or `JAVACMD`, or ensure a Java 17+ `java` is on `PATH`.
Comment thread
davsclaus marked this conversation as resolved.
The Gentoo `java-config` auto-detection and the IBM AIX `$JAVA_HOME/jre/sh/java` probe were also
removed; set `JAVA_HOME` or `JAVACMD` explicitly on those platforms.
`JAVA_OPTS` handling is unchanged: when unset, the default `-Xmx512m` heap is applied.

=== camel-langchain4j-agent

The `Agent.chat()` method return type has changed from `String` to `Result<String>` (from `dev.langchain4j.service.Result`).
Expand Down
121 changes: 91 additions & 30 deletions dsl/camel-jbang/camel-launcher/src/main/resources/bin/camel.bat
Original file line number Diff line number Diff line change
Expand Up @@ -28,45 +28,106 @@ set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set BASEDIR=%DIRNAME%

@REM Java command to use
if "%JAVA_HOME%" == "" goto noJavaHome
set JAVACMD=%JAVA_HOME%\bin\java.exe
goto checkJavaCmd
@REM --- Shared Java 17+ discovery contract ---
@REM Candidates in order: JAVACMD, %JAVA_HOME%\bin\java.exe, java.exe on PATH, CAMEL_FALLBACK_JAVA.
set CAMEL_MIN_JAVA=17

:noJavaHome
set JAVACMD=java.exe
set "CAMEL_JAVACMD="
call :tryJava "%JAVACMD%"
if defined CAMEL_JAVACMD goto haveJava
if defined JAVA_HOME call :tryJava "%JAVA_HOME%\bin\java.exe"
if defined CAMEL_JAVACMD goto haveJava
for %%p in (java.exe) do call :tryJava "%%~$PATH:p"
if defined CAMEL_JAVACMD goto haveJava
call :tryJava "%CAMEL_FALLBACK_JAVA%"
if defined CAMEL_JAVACMD goto haveJava
goto noJava

:checkJavaCmd
if exist "%JAVACMD%" goto init
:haveJava
set "JAVACMD=%CAMEL_JAVACMD%"

echo.
echo Error: JAVA_HOME is not defined correctly. >&2
echo Cannot execute "%JAVACMD%" >&2
echo.
goto error

:init
@REM Set JVM options if specified
if "%JAVA_OPTS%" == "" set JAVA_OPTS=-Xmx512m

@REM Find the JAR file
dir /b "%BASEDIR%\camel-launcher-*.jar" > nul 2>&1
if not errorlevel 1 (
for /f "tokens=*" %%j in ('dir /b "%BASEDIR%\camel-launcher-*.jar"') do set LAUNCHER_JAR=%BASEDIR%\%%j
) else (
for %%i in ("%BASEDIR%\camel-launcher-*.jar") do set LAUNCHER_JAR=%%i
)
@REM Find the launcher JAR
set "LAUNCHER_JAR="
for %%i in ("%BASEDIR%\camel-launcher-*.jar") do set "LAUNCHER_JAR=%%i"

@REM Execute Camel CLI
"%JAVACMD%" %JAVA_OPTS% -jar "%LAUNCHER_JAR%" %*
if ERRORLEVEL 1 goto error
goto end
@REM Execute Camel CLI, preserving arguments and the child exit code
for %%e in ("%JAVACMD%") do set "_JAVACMD_EXT=%%~xe"
if /i "%_JAVACMD_EXT%"==".bat" goto executeJavaBatch
if /i "%_JAVACMD_EXT%"==".cmd" goto executeJavaBatch
goto executeJavaNative

:error
set ERROR_CODE=1
:executeJavaBatch
call "%JAVACMD%" %JAVA_OPTS% -jar "%LAUNCHER_JAR%" %*
set ERROR_CODE=%ERRORLEVEL%
goto javaExecuted

:end
:executeJavaNative
"%JAVACMD%" %JAVA_OPTS% -jar "%LAUNCHER_JAR%" %*
set ERROR_CODE=%ERRORLEVEL%

:javaExecuted
@REM End local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" endlocal & set ERROR_CODE=%ERROR_CODE%
exit /B %ERROR_CODE%

:noJava
echo. 1>&2
echo Error: no suitable Java runtime found. Camel CLI requires Java %CAMEL_MIN_JAVA% or newer. 1>&2
echo Checked: JAVACMD, %%JAVA_HOME%%\bin\java.exe, java.exe on PATH, CAMEL_FALLBACK_JAVA. 1>&2
echo Install a Java %CAMEL_MIN_JAVA%+ runtime and set JAVA_HOME or JAVACMD, or add java.exe to PATH. 1>&2
if "%OS%"=="Windows_NT" endlocal
exit /B 1

exit /B %ERROR_CODE%
:tryJava
@REM %1 = candidate path (quoted). On success sets CAMEL_JAVACMD.
set "_CAND=%~1"
if "%_CAND%"=="" exit /b 1
if not exist "%_CAND%" exit /b 1
for %%e in ("%_CAND%") do set "_CAND_EXT=%%~xe"
set "_PROBE_DIR="
if defined TEMP set "_PROBE_DIR=%TEMP%"
if not defined _PROBE_DIR if defined TMP set "_PROBE_DIR=%TMP%"
if not defined _PROBE_DIR set "_PROBE_DIR=%BASEDIR%"

:tryJavaProbePath
set "_PROBE=%_PROBE_DIR%\camel-java-probe-%RANDOM%-%RANDOM%.tmp"
if exist "%_PROBE%" goto tryJavaProbePath
if /i "%_CAND_EXT%"==".bat" goto tryJavaProbeBatch
if /i "%_CAND_EXT%"==".cmd" goto tryJavaProbeBatch
goto tryJavaProbeNative

:tryJavaProbeBatch
call "%_CAND%" -version <NUL >"%_PROBE%" 2>&1
set "_PROBE_RC=%ERRORLEVEL%"
goto tryJavaProbeComplete

:tryJavaProbeNative
"%_CAND%" -version <NUL >"%_PROBE%" 2>&1
set "_PROBE_RC=%ERRORLEVEL%"

:tryJavaProbeComplete
if "%_PROBE_RC%"=="0" goto tryJavaParseProbe
del /q "%_PROBE%" >NUL 2>&1
set "_PROBE="
exit /b 1

:tryJavaParseProbe
set "_RAW="
for /f "tokens=3" %%v in ('findstr /b /l /i /c:"java version " /c:"openjdk version " "%_PROBE%"') do if not defined _RAW set "_RAW=%%v"
del /q "%_PROBE%" >NUL 2>&1
set "_PROBE="
if not defined _RAW exit /b 1
set "_RAW=%_RAW:"=%"
set "_MAJOR="
for /f "tokens=1,2 delims=." %%a in ("%_RAW%") do (
if "%%a"=="1" (set "_MAJOR=%%b") else (set "_MAJOR=%%a")
)
if not defined _MAJOR exit /b 1
@REM Reject non-numeric majors (e.g. early-access "17-ea") so the numeric compare below is safe.
for /f "delims=0123456789" %%z in ("%_MAJOR%") do exit /b 1
if %_MAJOR% LSS %CAMEL_MIN_JAVA% exit /b 1
set "CAMEL_JAVACMD=%_CAND%"
exit /b 0
79 changes: 45 additions & 34 deletions dsl/camel-jbang/camel-launcher/src/main/resources/bin/camel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,50 +37,61 @@ REPO=

# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
case "`uname`" in
CYGWIN*) cygwin=true ;;
Darwin*) darwin=true
if [ -z "$JAVA_VERSION" ] ; then
JAVA_VERSION="CurrentJDK"
else
echo "Using Java version: $JAVA_VERSION"
fi
if [ -z "$JAVA_HOME" ] ; then
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
fi
;;
esac

if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
# For Cygwin, ensure JAVA_HOME is in UNIX format before it is probed.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# If a specific java binary isn't specified search for the standard 'java' binary
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD=`which java`
fi
fi
# --- Shared Java 17+ discovery contract ---
# Candidates are tried in order: JAVACMD, $JAVA_HOME/bin/java, java on PATH, CAMEL_FALLBACK_JAVA.
# ($JAVA_HOME is also how SDKMAN's java candidate exposes its runtime.)
# Each must exist, be executable, and report a Java major version >= CAMEL_MIN_JAVA.
# Probe output is captured and never printed during a normal invocation.
CAMEL_MIN_JAVA=17

# Echo the Java major version of the launcher in $1, or nothing if it cannot be determined.
camel_java_major() {
_cjm_out=`"$1" -version </dev/null 2>&1` || return 1
_cjm_ver=`echo "$_cjm_out" | sed -n 's/.*version "\([0-9][0-9.]*\).*/\1/p' | head -n 1`
[ -n "$_cjm_ver" ] || return 1
case "$_cjm_ver" in
1.*) echo "$_cjm_ver" | cut -d. -f2 ;;
*) echo "$_cjm_ver" | cut -d. -f1 ;;
esac
}

# Return 0 and set JAVACMD when $1 is an existing, executable, Java >= CAMEL_MIN_JAVA launcher.
camel_try_java() {
[ -n "$1" ] || return 1
[ -x "$1" ] || return 1
_ctj_major=`camel_java_major "$1"` || return 1
[ -n "$_ctj_major" ] || return 1
{ [ "$_ctj_major" -ge "$CAMEL_MIN_JAVA" ]; } 2>/dev/null || return 1
JAVACMD="$1"
return 0
}

if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." 1>&2
echo " We cannot execute $JAVACMD" 1>&2
if camel_try_java "$JAVACMD"; then
:
elif [ -n "$JAVA_HOME" ] && camel_try_java "$JAVA_HOME/bin/java"; then
:
elif _camel_path_java=`command -v java 2>/dev/null` && camel_try_java "$_camel_path_java"; then
:
elif camel_try_java "$CAMEL_FALLBACK_JAVA"; then
:
else
echo "Error: no suitable Java runtime found. Camel CLI requires Java $CAMEL_MIN_JAVA or newer." 1>&2
echo "Checked the following sources (in order):" 1>&2
echo " 1. JAVACMD = ${JAVACMD:-<unset>}" 1>&2
echo " 2. JAVA_HOME/bin/java = ${JAVA_HOME:+$JAVA_HOME/bin/java}" 1>&2
echo " 3. java on PATH = ${_camel_path_java:-<not found>}" 1>&2
echo " 4. CAMEL_FALLBACK_JAVA = ${CAMEL_FALLBACK_JAVA:-<unset>}" 1>&2
echo "Install a Java $CAMEL_MIN_JAVA+ runtime and either add it to PATH, set JAVA_HOME, or set JAVACMD." 1>&2
exit 1
fi

Expand Down
Loading