spring-attic / spring-native

Spring Native is now superseded by Spring Boot 3 official native support
https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html
Apache License 2.0
2.74k stars 355 forks source link

Unable to start spring native application compiled with graal version 22.1, java 11 #1665

Closed Losishche closed 2 years ago

Losishche commented 2 years ago

I have started using spring native and graal several month ago. I have succesfully compiled and worked application, wich had been compiling with Graal compiler, version 22.0.2 (java version - 11), spring boot 2.6.6, spring native experimental 0.11.4. However after switching to new version of compiler - 22.1.0, java version - 11, application is unable to start anymore after compiling.

There are errors when starting compiled application

2022-07-07 14:29:52,761 251381 [           main] WARN  o.s.b.w.s.c.ServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'projectingArgumentResolverBeanPostProcessor': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Class org.springframework.core.annotation.TypeMappedAnnotation[] is instantiated reflectively but was never registered.Register the class by adding "unsafeAllocated" for the class in reflect-config.json.
2022-07-07 14:29:52,762 251381 [           main] ERROR o.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'projectingArgumentResolverBeanPostProcessor': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Class org.springframework.core.annotation.TypeMappedAnnotation[] is instantiated reflectively but was never registered.Register the class by adding "unsafeAllocated" for the class in reflect-config.json.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:270)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:762)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:567)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
    at com.a1s.discovery.DiscoveryApplication.main(DiscoveryApplication.java:12)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Class org.springframework.core.annotation.TypeMappedAnnotation[] is instantiated reflectively but was never registered.Register the class by adding "unsafeAllocated" for the class in reflect-config.json.
    at org.springframework.aot.beans.factory.InjectedConstructionResolver.resolve(InjectedConstructionResolver.java:88)
    at org.springframework.aot.beans.factory.InjectedElementResolver.resolve(InjectedElementResolver.java:35)
    at org.springframework.aot.beans.factory.InjectedElementResolver.create(InjectedElementResolver.java:66)
    at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$BeanInstanceContext.create(BeanDefinitionRegistrar.java:211)
    at org.springframework.aot.ContextBootstrapInitializer.lambda$initialize$93(ContextBootstrapInitializer.java:574)
    at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$ThrowableFunction.apply(BeanDefinitionRegistrar.java:294)
    at org.springframework.aot.beans.factory.BeanDefinitionRegistrar.lambda$instanceSupplier$0(BeanDefinitionRegistrar.java:115)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
    at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:91)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:111)
    at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:92)
    at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:101)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:255)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1160)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1135)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531)
    ... 14 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Class org.springframework.core.annotation.TypeMappedAnnotation[] is instantiated reflectively but was never registered.Register the class by adding "unsafeAllocated" for the class in reflect-config.json.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:233)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1282)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1243)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    at org.springframework.aot.ContextBootstrapInitializer.lambda$initialize$95(ContextBootstrapInitializer.java:576)
    at org.springframework.aot.beans.factory.BeanDefinitionRegistrar$ThrowableSupplier.get(BeanDefinitionRegistrar.java:317)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
    at org.springframework.aot.beans.factory.InjectedConstructionResolver.lambda$resolve$0(InjectedConstructionResolver.java:83)
    at org.springframework.aot.beans.factory.InjectedConstructionResolver.resolveDependency(InjectedConstructionResolver.java:97)
    at org.springframework.aot.beans.factory.InjectedConstructionResolver.resolve(InjectedConstructionResolver.java:83)
    ... 36 common frames omitted
Caused by: java.lang.IllegalArgumentException: Class org.springframework.core.annotation.TypeMappedAnnotation[] is instantiated reflectively but was never registered.Register the class by adding "unsafeAllocated" for the class in reflect-config.json.
    at com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.arrayHubErrorStub(SubstrateAllocationSnippets.java:252)
    at org.springframework.core.type.classreading.MergedAnnotationReadingVisitor$ArrayVisitor.visitEnd(MergedAnnotationReadingVisitor.java:180)
    at org.springframework.asm.ClassReader.readElementValues(ClassReader.java:3009)
    at org.springframework.asm.ClassReader.readElementValue(ClassReader.java:3179)
    at org.springframework.asm.ClassReader.readElementValues(ClassReader.java:2999)
    at org.springframework.asm.ClassReader.accept(ClassReader.java:609)
    at org.springframework.asm.ClassReader.accept(ClassReader.java:425)
    at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49)
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
    at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:132)
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
    at org.springframework.aot.context.annotation.ImportAwareBeanPostProcessor.setAnnotationMetadata(ImportAwareBeanPostProcessor.java:60)
    at org.springframework.aot.context.annotation.ImportAwareBeanPostProcessor.postProcessBeforeInitialization(ImportAwareBeanPostProcessor.java:49)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    ... 62 common frames omitted

But i have tried to add those classes to reflect-config and it didn't help. I tried also to switch version of spring boot (and native image as well) to 2.6.7 and to 2.7.0 and it also didnt help for me. Please investigate the reasons why it's impossible to build working application with graal 22.1.0 , java 11. Thanks in advance!

Losishche commented 2 years ago

https://github.com/spring-projects-experimental/spring-native/issues/1528

This issue seems connected with my because of the similar error, but you haven't investigated it unfourtunately...

mhalbritter commented 2 years ago

If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.

operrin commented 2 years ago

Hi,

you could find the same issue in the comments of #1626. The repo to reproduce is here: https://github.com/operrin/native-bug/

Best, Olivier

Losishche commented 2 years ago

Hello, team! I'm unable to see direct connections between my case and https://github.com/spring-projects-experimental/spring-native/issues/1626. Apart from it has started to happening after upgrading compiler. Still, I tried to add native hint as explained and in didn't work unfortunately. The same error appeared. At the same time, there were several comments at that issue /1626 where people tell that it doesn't work to them as well. As i understood, there are some unexplained distinctions between compiler version that affects assemlby by spring-native-experimental. Please, make some investigation about it.

Thanks in advance!

operrin commented 2 years ago

See the last comment and exception report. The problem of the native hint fixed the initial problem, but the new error shows a similar problem (Unsatisfied dependency expressed through constructor parameter 0).

Losishche commented 2 years ago

No the initial reason is not similar as I understood. As You can see, the underlying problem is

Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Class org.springframework.core.annotation.TypeMappedAnnotation[] is instantiated reflectively but was never registered.Register the class by adding "unsafeAllocated" for the class in reflect-config.json. at org.springframework.aot.beans.factory.InjectedConstructionResolver.resolve(InjectedConstructionResolver.java:88)

So the reason why constructor parameter is 0 is that ProxyTransactionManagementConfiguration cant be instantiated. There was said that there is lack of config at the reflect.config, but i put config for class ProxyTransactionManagementConfiguration to that file - still the same error. As i said, issue https://github.com/spring-projects-experimental/spring-native/issues/1528 looks similar(but in that case errors told that there was lack of proxy-config. configuration, but it wasn't investigated unfortunately).

I even have version without R2dbc dependency and experience the same error. The question is - what is the difference between compiler versions, which affects functioning so dramaticly? Have it been tested against graal 21.1 with lots of dependencies? I'm able to make working app under this version of compiler only if i have demo application without dependencies... Thanks in advance!

mhalbritter commented 2 years ago

Hello @Losishche, please provide a minimal sample how to reproduce that problem. The project given by @operrin is not related to this one, as far as I can see.

Losishche commented 2 years ago

https://dropmefiles.com/3MmAA

Here is a zip archive with small sample of project which You can compile with graal 22.1 and reproduce the issue. Pass to the zip archive is: 123. There is also docker-compose to start postgres database for project.

mhalbritter commented 2 years ago

I guess these problems are caused by your code which sets up all those databases / entity manager factories / transaction managers by hand. This is not really supported by Spring Native.

I had to clean up your project quite a bit, but it's running now:

I've uploaded it here.

Losishche commented 2 years ago

Thanks for quick answer! That useless hints were there from real big project, which i unfortunately unable to send cause it's not open source. But for our project we investigated that without those hints it just doesn't work I want to find out several things. 1) Do You mean that it's impossible to set up database by hand? 2) If that, is that mean than it is impossible to use 2 database under spring native (because its impossible in spring boot to configure 2 separate database's only by autoconfiguration)? (we use it in our real project).

3) As I said I still have whole my big project which works under graal 21.0.2. and spring boot 2.6.6 (and 2.6.7). If You switch versions at my sample project to it, You will be able to compile and start successfully. It's seems really strange that there are such differencies in behavior beetween that versions...

mhalbritter commented 2 years ago
  1. It could be - i've seen several problems caused by manually wiring datasources
  2. So your usecase is to have two datasources?
  3. I'm quite surprised that this is the case. GraalVM versions can make a difference, but it's usually not that big like it seems in your project.

@sdeleuze What do you think of this?

Losishche commented 2 years ago

2- yes, we have two databases at real project (this was the inicial where i got this sample to Your investigating). That is the main reason, why it was set up by hand. More than that - second database is not supported officially, but we were able to compile and start it with the help of hints and reflect configs under spring boot 2.6.6 and graal 22.0.2...

mhalbritter commented 2 years ago

Where do the files in src/main/resources/META-INF/native-image come from? I guess from a run with the agent?

Even if spring-native doesn't support your usecase, you can always run the JAR file in AOT mode with the GraalVM agent attached (https://www.graalvm.org/22.1/reference-manual/native-image/Agent/) and then copy the JSON files to src/main/resources/META-INF/native-image. Most of the time, just starting up the application is fine, but if you have a test suite you can run against the agent-attached JAR or do some explorative testing that would be even better.

Losishche commented 2 years ago

As for as files in src/main/resources/META-INF/native-image - we made it mostly by ourself. Either from investigations made by testing assembly or assembly-start-and-see what king of beens application unable to reach/instantiate, either from similar cases, described in global network.