Skip to content

@AliasFor is needed on all attributes (even if they have the same name as the "parent") [SPR-13554] #18130

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

Closed
spring-projects-issues opened this issue Oct 8, 2015 · 5 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 8, 2015

Dave Syer opened SPR-13554 and commented

From a comment in #18028. "The custom annotation has to use @AliasFor on all its inherited attributes for this to work." (And Sam said: "Are you saying that convention-based attribute overrides do not work? If so, then that's a bug, and please report it.")


Affects: 4.2.1

Issue Links:

Referenced from: commits 6826bdd, 5e1d6e4

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Dave Syer, thanks for raising the issue.

I'll look into it.

If you could provide a small example that reproduces the issue (or at least sketch out the failing scenario), that would be very helpful.

Cheers,

Sam

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

In the interim, without further input, I have done my best to recreate the scenario that (I believe) you are describing.

Specifically, in the following @HalfConventionBasedAndHalfAliasedComposedContextConfig annotation, we have the following attributes:

  1. locations: overrides locations in @ContextConfig following the naming convention-based approach available prior to Spring 4.2.
  2. xmlConfigFiles: overrides locations in @ContextConfig using an explicit alias declared via @AliasFor.
@ContextConfig
@Retention(RetentionPolicy.RUNTIME)
@interface HalfConventionBasedAndHalfAliasedComposedContextConfig {

	String[] locations() default {};

	@AliasFor(annotation = ContextConfig.class, attribute = "locations")
	String[] xmlConfigFiles() default {};
}

Dave Syer, can you please confirm that the test introduced in GitHub commit 5e1d6e4 reflects the scenario you encountered?

Thanks!

Sam

@spring-projects-issues
Copy link
Collaborator Author

Dave Syer commented

Yes, that looks similar at least (you are talking about HalfConventionBasedAndHalfAliasedComposedContextConfigClassV2 in your test?). The original source of this issue was this: https://github.com/spring-cloud/spring-cloud-cli/blob/master/spring-cloud-cli/src/main/java/org/springframework/boot/groovy/cloud/EnableBinding.java (I had to add @AliasFor to the value attribute even though I expected it to be inherited by convention).

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Dave Syer,

The original source of this issue was this: https://github.com/spring-cloud/spring-cloud-cli/blob/master/spring-cloud-cli/src/main/java/org/springframework/boot/groovy/cloud/EnableBinding.java (I had to add @AliasFor to the value attribute even though I expected it to be inherited by convention).

Ahhhh, well... this is not a bug. Rather, this is a known limitation of convention-based attribute overrides: the value attribute is not supported as an attribute override "by convention". value can only be used as an attribute override in conjunction with @AliasFor.

The following snippet from AnnotatedElementUtils displays the logic in question.

// Implicit annotation attribute override based on convention
else if (!AnnotationUtils.VALUE.equals(attributeName) && attributes.containsKey(attributeName)) {
	overrideAttribute(element, annotation, attributes, attributeName, attributeName);
}

One of the primary reasons for this is the fact that component stereotypes (e.g., @Service, @Controller, @MyTransactionalService, etc.) declare the name of the component via the value attribute. This convention has existed since Spring 2.5, so we cannot change this.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

The aforementioned @HalfConventionBasedAndHalfAliasedComposedContextConfig attempts to use a hybrid approach for attribute overrides with one attribute overriding via name-based convention and the other overriding explicitly via @AliasFor.

Since Spring does not support such a hybrid approach for annotation attribute overrides with transitive implicit aliases, I am resolving this issue as Works as Designed.

Rationale: the main problem with convention based overrides is that they are ambiguous: it is unclear for which meta-annotation the override is intended and therefore impossible to know upfront if convention-based attribute overrides should be considered as transitive implicit aliases for other local attributes. These issues can only be reliably addressed by explicit use of @AliasFor.

@spring-projects-issues spring-projects-issues added type: bug A general bug status: declined A suggestion or change that we don't feel we should currently apply in: core Issues in core modules (aop, beans, core, context, expression) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues removed the type: bug A general bug label Jan 12, 2019
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) status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

2 participants