1

In my Quarkus 3.1.1.Final application I am using Java 17, which is configured in the POM file.
Normally I use the Quarkus CLI and execute quarkus dev or quarkus test while developing.

After upgrading I noticed that these commands no longer work and give the following error:

Exception in thread "main" java.lang.RuntimeException: java.lang.UnsupportedClassVersionError: org/apache/camel/quarkus/core/devmode/CamelHotReplacementSetup has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
    at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:137)
    at io.quarkus.deployment.dev.DevModeMain.main(DevModeMain.java:62)
Caused by: java.lang.UnsupportedClassVersionError: org/apache/camel/quarkus/core/devmode/CamelHotReplacementSetup has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:506)
    at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:466)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:398)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1210)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1221)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1265)
    at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1300)
    at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1385)
    at io.quarkus.deployment.dev.IsolatedTestModeMain.setupRuntimeCompilation(IsolatedTestModeMain.java:73)
    at io.quarkus.deployment.dev.IsolatedTestModeMain.accept(IsolatedTestModeMain.java:123)
    at io.quarkus.deployment.dev.IsolatedTestModeMain.accept(IsolatedTestModeMain.java:34)
    at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:138)
    at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:93)
    at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:131)

It seems that the Quarkus CLI uses Java 11 (55.0) for its execution, even though I have configured Java 17 (61.0).
I have verified my configuration using mvn clean verify, mvn compile quarkus:dev and mvn compile quarkus:test which all build successfully.
Also in IntelliJ I am able to run all tests or individual tests successfully using Java 17.
The application runs in a Java 17 based Docker container without any problems.
The problem here is that Quarkus CLI seems to choose a different Java version.

What is the reason Quarkus CLI choses Java 11 instead of Java 17?
How can I configure Quarkus CLI to use the same Java version as Maven?
Is there anything to learn about the difference between the Maven commands and Quarkus CLI?

Rick Slinkman
  • 643
  • 10
  • 23

1 Answers1

2

The CLI Homebrew packaging is using the following script to determine the java binary that will be executed:

# 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
              if [ -x "/usr/libexec/java_home" ]; then
                  JAVA_HOME=`/usr/libexec/java_home`
              else
                  JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
              fi
           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
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

If you go through it with your OS in mind and checking the various paths, I think you should have your answer as to why the CLI is using a different JDK than the java from your $PATH than Maven is using.

It's very environment-dependent so it's hard to help more without having the environment at hand.

Guillaume Smet
  • 9,921
  • 22
  • 29
  • Based on this I found that the JAVA_HOME variable is wrongly set. I use `jenv` which apparently was configured incorrectly. I found that there was a plugin to manage it better: https://stackoverflow.com/a/36238219/878523 . This made the JAVA_HOME variable to be configured correctly and the CLI commands are working again. Thanks a lot. – Rick Slinkman Jun 10 '23 at 12:34