spring-projects / spring-projects/spring-framework

IllegalAccessError for some auto-configured beans when enabling AspectJ load time weaving

Open
#31,300 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: core status: feedback-provided status: waiting-for-triage
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Created this issue as suggested here.

To enable AspectJ load time weaving in a Spring application, one would use the @EnableLoadTimeWeaving annotation as outlined in the Spring reference documention. Due to issue 29609 this is not working and a workaround proposed involves registering AspectJWeavingEnabler and DefaultContextLoadTimeWeaver upfront when instantiating the application context. For a spring boot application, this looks as follows:

SpringApplication.run(new Class[] { Config.class, AspectJWeavingEnabler.class, MyLoadTimeWeaver.class }, args);

With MyLoadTimeWeaver extending DefaultContextLoadTimeWeaver and annotated with @Component("loadTimeWeaver") because the name of the LoadTimeWeaver bean "loadTimeWeaver" is expected by the framework.

When running the application, some auto-configured beans cannot be accessed anymore. E.g. for the spring.boot.ltw module in this repository, the following stacktrace is produced:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: failed to access class org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails from class org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor (org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails is in unnamed module of loader 'app'; org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor is in unnamed module of loader org.springframework.context.support.ContextTypeMatchClassLoader$ContextOverridingClassLoader @159e366)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:550) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1155) ~[spring-context-6.0.11.jar:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-6.0.11.jar:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.0.11.jar:6.0.11]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-3.1.2.jar:3.1.2]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) ~[spring-boot-3.1.2.jar:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-3.1.2.jar:3.1.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-3.1.2.jar:3.1.2]
        at be.pdn.training.aspectj.spring.boot.ltw.Main.main(Main.java:9) ~[classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: failed to access class org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails from class org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor (org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails is in unnamed module of loader 'app'; org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor is in unnamed module of loader org.springframework.context.support.ContextTypeMatchClassLoader$ContextOverridingClassLoader @159e366)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:605) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.0.11.jar:6.0.11]
        ... 19 common frames omitted
Caused by: java.lang.IllegalAccessError: failed to access class org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails from class org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor (org.springframework.boot.autoconfigure.jdbc.PropertiesJdbcConnectionDetails is in unnamed module of loader 'app'; org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor is in unnamed module of loader org.springframework.context.support.ContextTypeMatchClassLoader$ContextOverridingClassLoader @159e366)
        at org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetailsBeanPostProcessor.postProcessBeforeInitialization(JdbcConnectionDetailsBeanPostProcessor.java:54) ~[spring-boot-autoconfigure-3.1.2.jar:3.1.2]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:419) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762) ~[spring-beans-6.0.11.jar:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.11.jar:6.0.11]
        ... 29 common frames omitted

To reproduce yourself:

  • Clone this repository
  • Checkout branch spring_boot_issue
  • Execute mvn compile -pl spring.boot.ltw
  • Make sure JAVA_HOME points to a Java 21 JDK
  • Execute mvn dependency:properties exec:exec -pl spring.boot.ltw

It is possible to workaround this issue by defining manually the beans for which an IllegalAccessError occurs. E.g. for the sample project, uncomment the @Bean annotation for the JdbcConnectionDetails bean in Config.java and it will work.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure by cloning the linked repository, checking out spring_boot_issue, setting JAVA_HOME to Java 21, and running the two Maven commands for spring.boot.ltw. Start with JdbcConnectionDetailsBeanPostProcessor.java:54 and the Config.java workaround, then trace the related auto-configuration classes named in the stack trace. Done means the sample starts without IllegalAccessError for auto-configured beans.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.