micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.01k stars 1.04k forks source link

Issue after upgrading from 4.3.8 to 4.4.0 #10768

Open auke- opened 2 months ago

auke- commented 2 months ago

Expected Behavior

No response

Actual Behaviour

When trying to upgrade one of our major applications from Micronaut 4.3.8 to 4.4.0 (which includes the update from micronaut-core 4.3.14 to 4.4.3) we encounter the following exception when invoking a @MicronautTest:

@MicronautTest
class ApplicationTest {

  @Inject EmbeddedApplication<?> application;

  @Test
  void testItWorks() {
    Assertions.assertTrue(application.isRunning());
  }
}
java.lang.Error: java.lang.Error: Circular loading of installed providers detected
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:562)
    at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:591)
    at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:672)
    at io.micronaut.core.io.service.ServiceScanner$DefaultServiceCollector.collect(ServiceScanner.java:245)
    at io.micronaut.core.io.service.SoftServiceLoader.collectDynamicServices(SoftServiceLoader.java:201)
    at io.micronaut.core.io.service.SoftServiceLoader.collectAll(SoftServiceLoader.java:176)
    at io.micronaut.context.DefaultBeanContext.resolveBeanDefinitionReferences(DefaultBeanContext.java:1867)
    at io.micronaut.context.DefaultApplicationContext.isBootstrapPropertySourceLocatorPresent(DefaultApplicationContext.java:165)
    at java.base/java.util.Objects.requireNonNullElseGet(Objects.java:310)
    at io.micronaut.context.DefaultApplicationContext.isBootstrapEnabled(DefaultApplicationContext.java:161)
    at io.micronaut.context.DefaultApplicationContext.createEnvironment(DefaultApplicationContext.java:149)
    at io.micronaut.context.DefaultApplicationContext.getEnvironment(DefaultApplicationContext.java:183)
    at io.micronaut.context.DefaultApplicationContextBuilder.build(DefaultApplicationContextBuilder.java:324)
    at io.micronaut.test.extensions.AbstractMicronautExtension.beforeClass(AbstractMicronautExtension.java:345)
    at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.beforeAll(MicronautJunit5Extension.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.Error: Circular loading of installed providers detected
    at java.base/java.nio.file.spi.FileSystemProvider.installedProviders(FileSystemProvider.java:198)
    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:526)
    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:400)
    at io.micronaut.core.io.IOUtils.loadNestedJarUri(IOUtils.java:188)
    at io.micronaut.core.io.IOUtils.resolvePath(IOUtils.java:165)
    at io.micronaut.core.io.IOUtils.eachFile(IOUtils.java:98)
    at io.micronaut.core.io.service.ServiceScanner.computeMicronautServiceTypeNames(ServiceScanner.java:106)
    at io.micronaut.core.io.service.ServiceScanner$MicronautMetaServicesLoader.compute(ServiceScanner.java:296)
    at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
    at java.base/java.util.concurrent.ForkJoinTask.doExec$$$capture(ForkJoinTask.java:373)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

It looks like Micronaut is loading META-INF/micronaut/io.micronaut.inject.BeanDefinitionReference from various .jar files and somehow initializes FileSystemProviders from different threads.

What could be the cause for this error?

Steps To Reproduce

No response

Environment Information

Example Application

No response

Version

4.4.0

graemerocher commented 2 months ago

hmm nothing seems to have changed with service loading in 4.4.x

auke- commented 2 months ago

It looks like it is caused by the GraalVM version bump (org.graalvm.nativeimage:svm from 23.1.2 to 24.0.1):

java.lang.UnsupportedClassVersionError: com/oracle/svm/core/jdk/resources/NativeImageResourceFileSystemProvider has been compiled by a more recent version of the Java Runtime (class file version 65.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:1017)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:467)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1217)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
    at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
    at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
    at java.base/java.nio.file.spi.FileSystemProvider.loadInstalledProviders(FileSystemProvider.java:156)
    at java.base/java.nio.file.spi.FileSystemProvider$1.run(FileSystemProvider.java:207)
    at java.base/java.nio.file.spi.FileSystemProvider$1.run(FileSystemProvider.java:204)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
    at java.base/java.nio.file.spi.FileSystemProvider.installedProviders(FileSystemProvider.java:204)
    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:526)
    at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:400)
    at io.micronaut.core.io.IOUtils.loadNestedJarUri(IOUtils.java:188)
    at io.micronaut.core.io.IOUtils.resolvePath(IOUtils.java:165)
    at io.micronaut.core.io.IOUtils.eachFile(IOUtils.java:98)
    at io.micronaut.core.io.service.ServiceScanner.computeMicronautServiceTypeNames(ServiceScanner.java:106)
    at io.micronaut.core.io.service.ServiceScanner$MicronautMetaServicesLoader.compute(ServiceScanner.java:296)
    at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
    at java.base/java.util.concurrent.ForkJoinTask.doExec$$$capture(ForkJoinTask.java:373)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java)

This exception is swallowed, probably in IOUtils.eachFile().

When I downgrade org.graalvm.nativeimage:svm back to 23.1.2 it works again. It looks like the 24.x branch is compiled for Java 21. The latest 23.x version, 23.1.3 does also works. I can't find any relevant information about this in the GraalVM changelogs.

Since Micronaut 4.x targets both Java 17 and Java 21 I suppose the 23.x version of the GraalVM components should be used.

Furthermore it would be nice if the exception in IOUtils.eachFile() isn't swallowed as it makes finding the cause for this issue very hard.