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

Regression: @Inherited annotations declared in superclass are not recognized anymore #24077

Closed
amrynsky opened this issue Nov 13, 2019 · 8 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Milestone

Comments

@amrynsky
Copy link

amrynsky commented Nov 13, 2019

Overview

After migration to spring boot 2.2 we noticed that behavior of the annotations scan has been changed. In our case we define @SpringBootApplication in the base abstract class

@SpringBootApplication
public abstract class BaseApplication {

    protected abstract BaseApplication getApp();

    public void start(String[] args) {
        SpringApplication.run(getApp().getClass(), args);
    }
}

and then multiple concrete applications extend this class

public class DemoApplication extends BaseApplication {
	public static void main(String[] args) {
		new DemoApplication().start(args);
	}

	@Override
	protected BaseApplication getApp() {
		return this;
	}
}

It works fine in the v 2.1.x, but in 2.2 attempt to run the app causes the error:"

java.lang.IllegalArgumentException: No auto-configuration attributes found. Is com.xxx.Application annotated with EnableAutoConfiguration

2019-11-13 09:52:58.571 ERROR 97155 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalArgumentException: No auto-configuration attributes found. Is com.example.demo.DemoApplication annotated with EnableAutoConfiguration?
	at org.springframework.util.Assert.notNull(Assert.java:215) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAttributes(AutoConfigurationImportSelector.java:148) ~[spring-boot-autoconfigure-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry(AutoConfigurationImportSelector.java:115) ~[spring-boot-autoconfigure-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.process(AutoConfigurationImportSelector.java:396) ~[spring-boot-autoconfigure-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:874) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:801) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:771) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:188) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:325) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:242) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at com.example.demo.BaseApplication.start(BaseApplication.java:12) ~[classes/:na]
	at com.example.demo.DemoApplication.main(DemoApplication.java:8) ~[classes/:na]

Steps to reproduce

  • use attached demo project to reproduce the issue
    demo.zip
  • change spring-boot version to 2.1.8.RELEASE and run app again - everything works as expected
@amrynsky
Copy link
Author

It looks like spring-boot v2.2 uses deprecated way to discover annotations org.springframework.core.type.StandardAnnotationMetadata with nestedAnnotationsAsMap set to true. With nestedAnnotationsAsMap = false everything works as expected.

@mbhave
Copy link
Contributor

mbhave commented Nov 20, 2019

@philwebb This seems like a bug in Spring Framework. Could you move it there if you agree?

@snicoll snicoll transferred this issue from spring-projects/spring-boot Nov 25, 2019
@snicoll snicoll changed the title Spring boot 2.2 doesn't recognize annotations defined in the base class Annotations defined in the base class are not recognized anymore Nov 25, 2019
@snicoll snicoll added the type: regression A bug that is also a regression label Nov 25, 2019
@snicoll snicoll added this to the 5.2.2 milestone Nov 25, 2019
@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Nov 25, 2019
@jhoeller
Copy link
Contributor

@sbrannen Could you look at this one tomorrow? Otherwise I can pick it up on Friday.

@sbrannen
Copy link
Member

@sbrannen Could you look at this one tomorrow? Otherwise I can pick it up on Friday.

Sure, I'll take a look and report back to you.

@sbrannen
Copy link
Member

Some preliminary debugging reveals the following.

Spring Framework 2.1.8

The StandardAnnotationMetadata.annotations field contains:

  • @SpringBootApplication(scanBasePackageClasses=[], exclude=[], excludeName=[], scanBasePackages=[])
  • @EnableConfigurationProperties(value=[class com.example.demo.ApplicationConfig])

Spring Framework 5.2.x (master)

The StandardAnnotationMetadata.annotationTypes field contains:

  • org.springframework.boot.context.properties.EnableConfigurationProperties

So, it appears that @Inherited annotations are no longer taken into account in StandardAnnotationMetadata, since the @Inherited @SpringBootApplication annotation is not visible.

sbrannen added a commit that referenced this issue Nov 28, 2019
This commit introduces failing assertions that are currently disabled
via a boolean reproduceGh24077 flag.

Setting that flag to true demonstrates the regression for
StandardAnnotationMetadata and inconsistencies for SimpleAnnotationMetadata.

See gh-24077
@sbrannen sbrannen changed the title Annotations defined in the base class are not recognized anymore @Inherited annotations declared in superclass are not recognized anymore Nov 28, 2019
@sbrannen
Copy link
Member

@amrynsky, I tested your app locally with the changes I pushed to master, and your app no longer fails to start.

If you'd like to test it on your own, you can test against the latest snapshot builds -- for example, by specifying the following in the <properties> section of your pom.xml:

<spring-framework.version>5.2.2.BUILD-SNAPSHOT</spring-framework.version>

You'll also need to configure the snapshot repo for Maven as follows.

<repository>
    <id>repository.spring.snapshot</id>
    <name>Spring Snapshot Repository</name>
    <url>https://repo.spring.io/snapshot</url>
</repository>

Let us know if you run into any issues.

@sbrannen sbrannen changed the title @Inherited annotations declared in superclass are not recognized anymore Regression: @Inherited annotations declared in superclass are not recognized anymore Nov 29, 2019
@amrynsky
Copy link
Author

amrynsky commented Dec 2, 2019

Just tested in several scenarios including our project and everything works as expected.

@sbrannen
Copy link
Member

sbrannen commented Dec 3, 2019

Great! Thanks for letting us know.

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: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

5 participants