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

Soft reference-based cache causes confusing exception message from AnnotationTypeMapping resolveAliasTarget #23010

Closed
wilkinsona opened this issue May 21, 2019 · 2 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@wilkinsona
Copy link
Member

Method mirror = resolveAliasTarget(target, targetAliasFor, false);
if (mirror != attribute) {
throw new AnnotationConfigurationException(String.format(
"%s must be declared as an @AliasFor '%s', not '%s'.",
StringUtils.capitalize(AttributeMethods.describe(target)),
attribute.getName(), mirror.getName()));
}

I have a situation where mirror and attribute are different instances of the name attribute on @Bean. The use of != then results in the following exception:

Caused by: org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.context.annotation.Bean] must be declared as an @AliasFor 'name', not 'name'.
	at org.springframework.core.annotation.AnnotationTypeMapping.resolveAliasTarget(AnnotationTypeMapping.java:186) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMapping.resolveAliasTarget(AnnotationTypeMapping.java:130) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMapping.resolveAliasedForTargets(AnnotationTypeMapping.java:122) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMapping.<init>(AnnotationTypeMapping.java:99) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.addIfPossible(AnnotationTypeMappings.java:107) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.addAllMappings(AnnotationTypeMappings.java:68) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.<init>(AnnotationTypeMappings.java:61) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.<init>(AnnotationTypeMappings.java:46) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings$Cache.createMappings(AnnotationTypeMappings.java:215) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324) ~[na:1.8.0_181]
	at org.springframework.core.annotation.AnnotationTypeMappings$Cache.get(AnnotationTypeMappings.java:211) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.forAnnotationType(AnnotationTypeMappings.java:179) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder.process(TypeMappedAnnotations.java:417) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder.doWithAnnotations(TypeMappedAnnotations.java:400) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder.doWithAnnotations(TypeMappedAnnotations.java:366) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.processMethodAnnotations(AnnotationsScanner.java:382) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.processMethodInheritedAnnotations(AnnotationsScanner.java:248) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.processMethod(AnnotationsScanner.java:231) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.process(AnnotationsScanner.java:109) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.scan(AnnotationsScanner.java:96) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.scan(AnnotationsScanner.java:77) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations.scan(TypeMappedAnnotations.java:244) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations.get(TypeMappedAnnotations.java:151) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations.get(TypeMappedAnnotations.java:133) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiredAnnotation(AutowiredAnnotationBeanPostProcessor.java:508) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.lambda$buildAutowiringMetadata$2(AutowiredAnnotationBeanPostProcessor.java:476) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:320) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.buildAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:471) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:438) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:233) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1081) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:567) ~[spring-beans-5.2.0.M2.jar:5.2.0.M2]
	... 15 common frames omitted

The problem occurs when running a Spring Boot application with a very tightly constrained max heap. I suspect it's due to eviction from the soft reference cache used by AnnotationTypeMappings. It's not limited to @Bean as I have also seen it with @RequestMapping:

Caused by: org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.web.bind.annotation.RequestMapping] must be declared as an @AliasFor 'path', not 'path'.
	at org.springframework.core.annotation.AnnotationTypeMapping.resolveAliasTarget(AnnotationTypeMapping.java:186) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMapping.resolveAliasTarget(AnnotationTypeMapping.java:130) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMapping.resolveAliasedForTargets(AnnotationTypeMapping.java:122) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMapping.<init>(AnnotationTypeMapping.java:99) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.addIfPossible(AnnotationTypeMappings.java:107) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.addAllMappings(AnnotationTypeMappings.java:68) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.<init>(AnnotationTypeMappings.java:61) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.<init>(AnnotationTypeMappings.java:46) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings$Cache.createMappings(AnnotationTypeMappings.java:215) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324) ~[na:1.8.0_181]
	at org.springframework.core.annotation.AnnotationTypeMappings$Cache.get(AnnotationTypeMappings.java:211) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationTypeMappings.forAnnotationType(AnnotationTypeMappings.java:179) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder.process(TypeMappedAnnotations.java:417) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder.doWithAnnotations(TypeMappedAnnotations.java:400) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder.doWithAnnotations(TypeMappedAnnotations.java:366) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.processMethodAnnotations(AnnotationsScanner.java:382) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.processMethodHierarchy(AnnotationsScanner.java:266) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.processMethod(AnnotationsScanner.java:236) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.process(AnnotationsScanner.java:109) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.scan(AnnotationsScanner.java:96) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotationsScanner.scan(AnnotationsScanner.java:77) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations.scan(TypeMappedAnnotations.java:244) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.TypeMappedAnnotations.get(TypeMappedAnnotations.java:151) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation(AnnotatedElementUtils.java:633) ~[spring-core-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.createRequestMappingInfo(RequestMappingHandlerMapping.java:262) ~[spring-webmvc-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getMappingForMethod(RequestMappingHandlerMapping.java:225) ~[spring-webmvc-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getMappingForMethod(RequestMappingHandlerMapping.java:65) ~[spring-webmvc-5.2.0.M2.jar:5.2.0.M2]
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$0(AbstractHandlerMethodMapping.java:271) ~[spring-webmvc-5.2.0.M2.jar:5.2.0.M2]
	... 26 common frames omitted
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label May 21, 2019
@jhoeller jhoeller added in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug labels May 21, 2019
@jhoeller jhoeller added this to the 5.2 M3 milestone May 21, 2019
@philwebb
Copy link
Member

I unfortunately couldn't easily add a unit test for this. @wilkinsona could you run your sample again with the latest snapshot and confirm things are now OK?

@sbrannen sbrannen removed the status: waiting-for-triage An issue we've not yet triaged or decided on label May 27, 2019
@wilkinsona
Copy link
Member Author

Looks good to me. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants