-
-
Notifications
You must be signed in to change notification settings - Fork 44
Description
A few days ago I downloaded a zipped version of the play-java-angular-seed to use as guidance for an (eventual) upgrade/rewrite of a legacy Angular 2/Play 2.5 application.
However, when I tried to run the version of sbt included in the distribution, I was immediately presented with the following error:
thedailycommute:~/pling/play-java-angular-seed-main$ ./sbt -v
[process_args] java_version = '17.0.12'
# Executing command line:
java
-Xms1024m
-Xmx1024m
-XX:ReservedCodeCacheSize=128m
-XX:MaxPermSize=256m
-jar
/home/thedailycommute/pling/play-java-angular-seed-main/sbt-dist/bin/sbt-launch.jar
Unrecognized VM option 'MaxPermSize=256m'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
I tracked the error to the file sbt-launch-lib.bash, specifically to the get_mem_opts() function, line 92, which reads:
local class_metadata_opt=$([[ "$java_version" < "1.8" ]] && echo "MaxPermSize" || echo "MaxMetaspaceSize")
The problem occurs because Bash is performing a lexicographical comparison of the version strings, and (incorrectly in this case) returns "true", leading to the VM error because MaxPermSize was removed in versions of Java >= 1.8.
I humbly suggest the following changes:
- Add a new function, version_compare(), to allow version strings to be correctly compared.
# Function to compare two version numbers
# Returns:
# -1 if version1 < version2
# 0 if version1 == version2
# 1 if version1 > version2
version_compare() {
# Convert versions to arrays of numbers
IFS=. read -r -a version1 <<< "$1"
IFS=. read -r -a version2 <<< "$2"
# Compare each segment of the versions
for ((i = 0; i < ${#version1[@]} || i < ${#version2[@]}; i++)); do
v1=${version1[i]:-0}
v2=${version2[i]:-0}
if ((v1 > v2)); then
return 1 # version1 is greater
elif ((v1 < v2)); then
return -1 # version1 is less
fi
done
# If we reached here, versions are equal
return 0
}
- Replace the single comparison line in get_mem_opts() with:
# Define class metadata option based on Java version
local class_metadata_opt=$(
version_compare "$java_version" "1.8"
case $? in
-1) echo "MaxPermSize" ;; # Less than 1.8
0|1) echo "MaxMetaspaceSize" ;; # 1.8 or greater
esac
)
- Replace the checkJava() function with:
# Detect that we have java installed.
checkJava() {
local required_version="$1"
# Check if Java is installed
if [[ -z "$java_version" ]]; then
echo
echo "No Java installation was detected."
echo "Please go to http://www.java.com/getjava/ and download"
echo
exit 1
fi
# Compare the installed version with the required version
version_compare "$java_version" "$required_version"
case $? in
-1)
echo
echo "The Java installation you have is not up to date."
echo "$script_name requires at least version $required_version+, you have"
echo "version $java_version."
echo
echo "Please go to http://www.java.com/getjava/ and download"
echo "a valid Java Runtime and install before running $script_name."
echo
exit 1
;;
0|1)
# Version is sufficient
return 0
;;
esac
}
I have attached a fully updated version (with a .txt extension uploading purposes) to simplify validation.
I should also add that the changes were developed with the aid of ChatGPT (because it's been several decades since I last edited a bash script :-)