apache / felix-atomos

Apache Felix Atomos
https://felix.apache.org/
Apache License 2.0
38 stars 19 forks source link

UnsupportedClassVersionError on startup with multi-release jars that contain higher JVM version #77

Open bosschaert opened 11 months ago

bosschaert commented 11 months ago

When Atomos starts up it loads all the classes by introspecting Jars.

However it also loads classes from multi-release jars that are for a version that's higher than the currently running JVM.

An exception that shows this:

Caused by: java.lang.UnsupportedClassVersionError: META-INF/versions/19/com/fasterxml/jackson/core/io/doubleparser/FastDoubleSwar has been compiled by a more recent version of the Java Runtime (class file version 63.0), this version of the Java Runtime only recognizes class file versions up to 61.0
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
    at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
    at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
    at java.base/java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:872)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    at org.apache.felix.atomos.utils.core.LauncherImpl.lambda$loadClasses$5(LauncherImpl.java:82)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.zip.ZipFile$EntrySpliterator.tryAdvance(ZipFile.java:567)
    at java.base/java.util.Spliterator.forEachRemaining(Spliterator.java:332)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at org.apache.felix.atomos.utils.core.LauncherImpl.loadClasses(LauncherImpl.java:89)
    at org.apache.felix.atomos.utils.core.LauncherImpl.execute(LauncherImpl.java:193)
    at org.apache.felix.atomos.utils.core.LauncherImpl.execute(LauncherImpl.java:152)
...

A naive fix for this can be seen here, where the META-INF version are being ignored: https://github.com/bosschaert/felix-atomos/commit/4a5683253e0ad7831c67821dbbbde636042eaa38#diff-8c0eef3cf462bc384fa77905eb1bf7fef2cca2177f046e5f6a0ad00e61d236fe

However, a real fix should be more sophisticated, probably taking the current JVM version and then walking back to pick the highest META-INF/versions directory that would still apply, but not trying to load classes from higher JVM versions.

tjwatson commented 11 months ago

Can you describe the scenario where this happens. I think it has to do with the atomos plugin for building, but want to make sure we understand where this is failing. I ask because the report makes it sound like it is the Atomos runtime doing this which I don't believe is the case.