When using @DataJpaTest in a native image, the build aborts with:

Error: Classes that should be initialized at run time got initialized during image building:
------------------------------------------------------------------------------------------------------------------------
 org.springframework.boot.jdbc.EmbeddedDatabaseConnection was unintentionally initialized at build time. To see why org.springframework.boot.jdbc.EmbeddedDatabaseConnection got initialized use --trace-class-initialization=org.springframework.boot.jdbc.EmbeddedDatabaseConnection
To see how the classes got initialized, use --trace-class-initialization=org.springframework.boot.jdbc.EmbeddedDatabaseConnection

See the reproducer here.

Comment From: mhalbritter

The same happens with @DataJdbcTest, as seen here.

Comment From: mhalbritter

And with @JdbcTest, as seen here.

Comment From: mhalbritter

I ran it with trace class initialization, and got this:

Error: Classes that should be initialized at run time got initialized during image building:
 org.springframework.boot.jdbc.EmbeddedDatabaseConnection was unintentionally initialized at build time. org.springframework.boot.jdbc.EmbeddedDatabaseConnection caused initialization of this class with the following trace: 
        at org.springframework.boot.jdbc.EmbeddedDatabaseConnection.<clinit>(EmbeddedDatabaseConnection.java:50)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Unknown Source)
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:568)
        at java.lang.Class.getEnumConstantsShared(Class.java:3837)
        at java.lang.Class.enumConstantDirectory(Class.java:3859)
        at java.lang.Enum.valueOf(Enum.java:267)
        at sun.reflect.annotation.AnnotationParser.parseEnumValue(AnnotationParser.java:479)
        at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:344)
        at java.lang.reflect.Method.getDefaultValue(Method.java:717)
        at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:133)
        at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:85)
        at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:262)
        at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:121)
        at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:73)
        at java.lang.Class.createAnnotationData(Class.java:4068)
        at java.lang.Class.annotationData(Class.java:4057)
        at java.lang.Class.getDeclaredAnnotation(Class.java:3996)
        at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:150)
        at org.junit.platform.commons.util.AnnotationUtils.findMetaAnnotation(AnnotationUtils.java:198)
        at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:156)
        at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:137)
        at org.junit.jupiter.engine.descriptor.DisplayNameUtils.determineDisplayName(DisplayNameUtils.java:73)
        at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.<init>(JupiterTestDescriptor.java:69)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.<init>(ClassBasedTestDescriptor.java:100)
        at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.<init>(ClassTestDescriptor.java:51)
        at org.junit.jupiter.engine.discovery.ClassSelectorResolver.newClassTestDescriptor(ClassSelectorResolver.java:119)
        at org.junit.jupiter.engine.discovery.ClassSelectorResolver.lambda$resolve$5(ClassSelectorResolver.java:98)
        at org.junit.jupiter.engine.discovery.ClassSelectorResolver$$Lambda$700/0x000000010180db60.apply(Unknown Source)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$DefaultContext.createAndAdd(EngineDiscoveryRequestResolution.java:250)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$DefaultContext.addToParent(EngineDiscoveryRequestResolution.java:213)
        at org.junit.jupiter.engine.discovery.ClassSelectorResolver.lambda$resolve$6(ClassSelectorResolver.java:98)
        at org.junit.jupiter.engine.discovery.ClassSelectorResolver$$Lambda$699/0x000000010180d918.apply(Unknown Source)
        at java.util.Optional.map(Optional.java:260)
        at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:96)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolveUniqueId$3(EngineDiscoveryRequestResolution.java:176)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$$Lambda$685/0x000000010180e248.apply(Unknown Source)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
        at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
        at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveUniqueId(EngineDiscoveryRequestResolution.java:176)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:124)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.access$100(EngineDiscoveryRequestResolution.java:58)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$DefaultContext.resolve(EngineDiscoveryRequestResolution.java:228)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$DefaultContext.addToParent(EngineDiscoveryRequestResolution.java:222)
        at org.junit.jupiter.engine.discovery.MethodSelectorResolver$MethodType.resolveUniqueIdIntoTestDescriptor(MethodSelectorResolver.java:224)
        at org.junit.jupiter.engine.discovery.MethodSelectorResolver$MethodType.access$200(MethodSelectorResolver.java:164)
        at org.junit.jupiter.engine.discovery.MethodSelectorResolver.lambda$resolve$4(MethodSelectorResolver.java:117)
        at org.junit.jupiter.engine.discovery.MethodSelectorResolver$$Lambda$687/0x000000010180e6e0.apply(Unknown Source)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:1002)
        at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
        at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
        at org.junit.jupiter.engine.discovery.MethodSelectorResolver.resolve(MethodSelectorResolver.java:133)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolveUniqueId$3(EngineDiscoveryRequestResolution.java:176)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution$$Lambda$685/0x000000010180e248.apply(Unknown Source)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
        at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
        at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveUniqueId(EngineDiscoveryRequestResolution.java:176)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:124)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
        at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
        at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:46)
        at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:69)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
        at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
        at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:110)
        at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:78)
        at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.discover(DefaultLauncherSession.java:81)
        at org.junit.platform.launcher.core.SessionPerRequestLauncher.discover(SessionPerRequestLauncher.java:46)
        at org.graalvm.junit.platform.JUnitPlatformFeature.discoverTestsAndRegisterTestClassesForReflection(JUnitPlatformFeature.java:135)
        at org.graalvm.junit.platform.JUnitPlatformFeature.beforeAnalysis(JUnitPlatformFeature.java:94)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$9(NativeImageGenerator.java:736)
        at com.oracle.svm.hosted.NativeImageGenerator$$Lambda$500/0x000000010179ed48.accept(Unknown Source)
        at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:85)
        at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:736)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:578)
        at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:535)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:580)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)

It looks like AutoConfigureTestDatabase#connection is the culprit.

Comment From: mhalbritter

There are two issues in GraalVM which trigger this bug: https://github.com/oracle/graal/issues/5300 and https://github.com/oracle/graal/issues/5301.

We can workaround the lambda one.

Another workaround for the whole issue would be

--initialize-at-build-time=org.springframework.boot.jdbc.EmbeddedDatabaseConnection

as native image args, but we don't want to rely on build time init.

Comment From: mhalbritter

I've found a way to workaround both GraalVM problems. They only appear if the ctor of the enum is used. when we use a switch inside the enums method, the problem goes away. See https://github.com/mhalbritter/spring-boot/commit/ee5aaaaa7a7b6dc726d7060953f66b07ee45f634 for details.