felix-atomos
felix-atomos copied to clipboard
UnsupportedClassVersionError on startup with multi-release jars that contain higher JVM version
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.