Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing hint issue when defining a custom MongoTemplate. #4763

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

omercelikceng
Copy link

Hello,

I have a Spring Boot service where I save data to different databases at runtime. Additionally, I need to customize some settings based on certain conditions. Therefore, I create custom MongoTemplate beans. My implementation works successfully. So, under normal conditions, I can save my data to different databases and my code works.

However, when I build my project as a native image, it throws an error during startup. For now, I have solved the problem by adding the relevant class as a hint in my project. However, I wanted to contribute by opening a pull request for this issue.

To help you reproduce the issue, I am sharing a POC project. If you follow the steps in the README.md file on the main branch, you will encounter the error. Additionally, you can switch to the solution branch to see if the solution works.

Spring Boot Version : 3.3.2

The branch link where you can reproduce the error : https://github.com/omercelikceng/native-poc-mongodb-error/tree/main
The branch link where the error is resolved : https://github.com/omercelikceng/native-poc-mongodb-error/tree/solution

Error :

2024-08-07T12:48:07.223Z  WARN 1 --- [           main] o.s.c.support.GenericApplicationContext  : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'basicCrudOperation': Unsatisfied dependency expressed through field 'mongoTemplate': Error creating bean with name 'liveMongoTemplate': Type org.springframework.data.mongodb.core.aggregation.AggregationOperation not present
Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'basicCrudOperation': Unsatisfied dependency expressed through field 'mongoTemplate': Error creating bean with name 'liveMongoTemplate': Type org.springframework.data.mongodb.core.aggregation.AggregationOperation not present
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveValue(AutowiredFieldValueResolver.java:194)
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveAndSet(AutowiredFieldValueResolver.java:167)
        at org.example.graalvm.mongodb.BasicCrudOperation__Autowiring.apply(BasicCrudOperation__Autowiring.java:17)
        at org.springframework.beans.factory.support.InstanceSupplier$1.get(InstanceSupplier.java:83)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:949)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1237)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1180)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
        at org.example.graalvm.mongodb.GraalVMMongoErrorApplication.main(GraalVMMongoErrorApplication.java:10)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liveMongoTemplate': Type org.springframework.data.mongodb.core.aggregation.AggregationOperation not present
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveValue(AutowiredFieldValueResolver.java:188)
        ... 21 more
Caused by: java.lang.TypeNotPresentException: Type org.springframework.data.mongodb.core.aggregation.AggregationOperation not present
        at [email protected]/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117)
        at [email protected]/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
        at [email protected]/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
        at [email protected]/sun.reflect.generics.visitor.Reifier.visitArrayTypeSignature(Reifier.java:159)
        at [email protected]/sun.reflect.generics.tree.ArrayTypeSignature.accept(ArrayTypeSignature.java:42)
        at [email protected]/sun.reflect.generics.repository.ConstructorRepository.computeParameterTypes(ConstructorRepository.java:111)
        at [email protected]/sun.reflect.generics.repository.ConstructorRepository.getParameterTypes(ConstructorRepository.java:87)
        at [email protected]/java.lang.reflect.Executable.getGenericParameterTypes(Executable.java:298)
        at [email protected]/java.lang.reflect.Method.getGenericParameterTypes(Method.java:333)
        at org.springframework.core.BridgeMethodResolver.isResolvedTypeMatch(BridgeMethodResolver.java:190)
        at org.springframework.core.BridgeMethodResolver.isBridgeMethodFor(BridgeMethodResolver.java:180)
        at org.springframework.core.BridgeMethodResolver.searchCandidates(BridgeMethodResolver.java:159)
        at org.springframework.core.BridgeMethodResolver.resolveBridgeMethod(BridgeMethodResolver.java:121)
        at org.springframework.core.BridgeMethodResolver.getMostSpecificMethod(BridgeMethodResolver.java:98)
        at org.springframework.aop.support.AopUtils.getMostSpecificMethod(AopUtils.java:209)
        at org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.computeTransactionAttribute(AbstractFallbackTransactionAttributeSource.java:158)
        at org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute(AbstractFallbackTransactionAttributeSource.java:111)
        at org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut.matches(TransactionAttributeSourcePointcut.java:56)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:298)
        at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:330)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:136)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:99)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:80)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:368)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:320)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:438)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1809)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
        ... 30 more
Caused by: java.lang.ClassNotFoundException: org.springframework.data.mongodb.core.aggregation.AggregationOperation
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:123)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:87)
        at [email protected]/java.lang.Class.forName(DynamicHub.java:1324)
        at [email protected]/java.lang.Class.forName(DynamicHub.java:1313)
        at [email protected]/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
        ... 58 more

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 7, 2024
@christophstrobl
Copy link
Member

Thank you for reaching out - this sounds very much like #4637

@omercelikceng
Copy link
Author

omercelikceng commented Aug 9, 2024

Hello @christophstrobl . Yes, I have seen this issue. It was resolved by removing the spring-cloud-starter-openfeign dependency. However, my problem is different and the related issue(#4637) has been closed. Therefore, I have created a new issue.

Normally, when I create a native image and run the application, it works successfully. However, when I define MongoTemplate and TransactionTemplate beans as custom, create a native image, and run it, I get an error. This is because AggregationOperation is not registered in the hint. If you would like to reproduce the error, I have created a POC project(minimal sample).

@christophstrobl
Copy link
Member

@omercelikceng thank you for the reproducer - the underlying issue remains the same as with #4637 being the BridgeMethodResolver trying to read signatures from types that had been removed by GraalVM.

This is not a scenario specific to MongoOperations and MongoTemplate but may occur on any type framework tries to resolve methods on. May it be to detect candidates for transactional proxies or types being proxied for any other reason.
Providing hints for AggregationOperation via data-mongodb would patch this one incarnation of the issue that will for sure surface somewhere else again.

Let me \\cc @sedleuze - maybe we could rethink 4637-comment#1953799740 regarding changes in core fw to cover this scenario.

@christophstrobl christophstrobl added unlikely theme: aot An issue related to Ahead-Of-Time processing and removed status: waiting-for-triage An issue we've not yet triaged labels Aug 20, 2024
@omercelikceng
Copy link
Author

@christophstrobl Thank you very much for your interest. I thought that manually adding this class was the right approach. However, I understood what you meant. Actually, it was discussed that @snicoll would review this situation and provide feedback. However, it seems that the feedback was not provided, or I may have missed it. (#4637 (comment)). However, this issue hasn't been progressed. Also, the username 'sdeleuze' was incorrectly written, so I'm tagging again. @sdeleuze

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: aot An issue related to Ahead-Of-Time processing unlikely
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants