Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ubuntu/Linux: Java 17, Unrecognized VM option 'MaxPermSize=256m' #85

Open
thedailycommute opened this issue Aug 2, 2024 · 1 comment

Comments

@thedailycommute
Copy link

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:

  1. 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
}
  1. 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
    )
  1. 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 :-)

sbt-launch-lib.bash.txt

@mkurz
Copy link
Member

mkurz commented Aug 2, 2024

To be honest this play-java-angular-seed repo is pretty much unmaintained. It was moved to the playframework organization with some other seed project's which someone else maintains.
If you want to provide pull requests to update this repo, feel free to do so.
IMHO all this sbt launcher scriptes in this repo should just be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants