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

TraceAsyncCustomAutoConfiguration configures a BeanPostProcessor that changes the type of AsyncConfigurer beans and breaks dependency resolution #2100

Closed
wilkinsona opened this issue Jan 19, 2022 · 10 comments
Milestone

Comments

@wilkinsona
Copy link
Contributor

Describe the bug

Please see spring-projects/spring-boot#29151 for details.

Sample

This zipped Maven project will reproduce the problem using Sleuth 3.0.5 without really involving Boot. Running the main method will fail:

12:12:49.395 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2401f4c3
12:12:49.414 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
12:12:49.536 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
12:12:49.538 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
12:12:49.539 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
12:12:49.540 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
12:12:49.543 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'asyncBeanPostProcessor'
12:12:49.559 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'gh29151Application'
12:12:49.560 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'exampleConfigurer'
12:12:49.606 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2401f4c3, started on Wed Jan 19 12:12:49 GMT 2022
Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'exampleConfigurer' is expected to be of type 'com.example.demo.Gh29151Application$Example' but was actually of type 'org.springframework.cloud.sleuth.instrument.async.LazyTraceAsyncCustomizer'
	at org.springframework.beans.factory.support.AbstractBeanFactory.adaptBeanInstance(AbstractBeanFactory.java:417)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:398)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1160)
	at com.example.demo.Gh29151Application.main(Gh29151Application.java:14)

The failure does not occur without the TraceAsyncCustomAutoConfiguration bean post-processor.

@Saljack
Copy link

Saljack commented Feb 11, 2022

Here is a workaround if you do not want to disable Sleuth for async (spring.sleuth.async.enabled=false). You have to exclude autoconfiguration TraceAsyncCustomAutoConfiguration and wrap your executor with LazyTraceExecutor:

spring:
  autoconfigure:
    exclude:
      - org.springframework.cloud.sleuth.autoconfig.instrument.async.TraceAsyncCustomAutoConfiguration
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

  private final BeanFactory beanFactory;

  public AsyncConfig(BeanFactory beanFactory) {
    this.beanFactory = beanFactory;
  }

  @Override
  public Executor getAsyncExecutor() {
    Executor executor = new ThreadPoolTaskExecutor(); // create or configure your executor
    return new LazyTraceExecutor(beanFactory, executor);
  }
}

@marcingrzejszczak
Copy link
Contributor

This is blocked by spring-projects/spring-framework#27953

@spencergibb spencergibb removed this from To do in 2021.0.3 May 27, 2022
@spencergibb spencergibb added this to To do in 2021.0.4 via automation May 27, 2022
@lette1394
Copy link

Another workaround you can do without modifying any other settings is this.

before

@Configuration
@EnableAsync
class AsyncConfiguration : AsyncConfigurer {
    override fun getAsyncExecutor(): Executor {
        val executor = ThreadPoolTaskExecutor()
        executor.initialize()
        return executor
    }

    override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler {
        return YourCustomAsyncUncaughtExceptionHandler()
    }
}

after

@Configuration
@EnableAsync
class AsyncConfiguration {

    @Bean
    fun asyncConfigurer(): AsyncConfigurer {
        return object : AsyncConfigurer {
            override fun getAsyncExecutor(): Executor {
                val executor = ThreadPoolTaskExecutor()
                executor.initialize()
                return executor
            }

            override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler {
                return YourCustomAsyncUncaughtExceptionHandler()
            }
        }
    }
}

@ryanjbaxter ryanjbaxter removed this from To do in 2021.0.4 Sep 7, 2022
@Arunanandam123
Copy link

Do we have an fix for this issue. We are still seeing the error with Spring boot 2.6.8 and 3.1.0 version of sleuth.

@jxfruit
Copy link

jxfruit commented Jun 29, 2023

May I ask for any progresses or any better solutions?

@jxfruit
Copy link

jxfruit commented Jun 30, 2023

Adding the following configuration into the application.properties and keeping the @bean annotation above the override method getAsyncExecutor() can be a solution.
spring.sleuth.async.enabled=false

My spring version is spring-boot:2.6.7 and spirng-cloud:3.1.x

@Abhishek-Khelge
Copy link

keeping the @bean annotation above the override method getAsyncExecutor() can be a solution.
spring.sleuth.async.enabled=false

this is not working for me

@maradanasai
Copy link

@Saljack @lette1394 The following solutions mentioned are not working for me. Here is the sample reproducible code https://github.com/maradanasai/otel-async-exper.git . Using spring boot 2.7.14 and spring cloud 2021.0.8 version with jdk 17. It is blocking migrating to latest versions.

@marcingrzejszczak
Copy link
Contributor

There's a PR open in Framework that should be fixing this (spring-projects/spring-framework#27953) you can write a comment there that you're being blocked because of this

@marcingrzejszczak
Copy link
Contributor

marcingrzejszczak commented Aug 22, 2023

Since Spring Framework won't merge this PR. The only thing we can do is to document that in cases of exceptions you must

  • disable sleuth async
  • manually instrument the executors using their trace representations

example:

spring.sleuth.async.enabled=false

and configuration example

@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {

	private final BeanFactory beanFactory;

	public AsyncConfiguration(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

	@Override
    @Bean("AsyncTaskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.initialize();
        return new LazyTraceThreadPoolTaskExecutor(beanFactory, executor);
    }
}

I will update the documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

9 participants