Skip to content

Illegal reflective access on shutdown of ExecutorService #22939

@Clank84

Description

@Clank84

Affects: spring-core-5.1.6.RELEASE

I'm migrating an application to Open JDK 11.0.2, and updated its Spring Boot from v1.5 to v2.1.4, that in turn updates SpringFramework to v5.1.6. My application runs several threads, and I implemented an EventListener for the situation when an administrator shuts down the application and the Context is stopped or closed the application tries to gracefully shutdown the child threads managed by an ExecutorService.

@Component
public class AppController {

  @Autowired
  private ExecutorService runner1;

  public void run(ApplicationArguments theArgs) throws Exception {

    Runnable myRunnable = new Consumer();

    runner1.execute(myRunnable);

    //Do Business Logic, until Thread Interrupted

    runner1.shutdown();
    if (!runner1.awaitTermination(5, TimeUnit.SECONDS)) {
      runner1.shutdownNow();
    }
    System.exit(2);
  }
}

Good news is that everything shuts down. But I do get the following warning with JDK 11:

Illegal reflective access by org.springframework.util.ReflectionUtils (file:spring-core-5.1.6.RELEASE.jar) 
to method java.util.concurrent.Executors$DelegatedExecutorService.shutdown()

My problem appears similar to Issues #22791 and #22242. I've attached a sample project to recreate the error when you use JDK 11, just run the included JUnit class and use the VM arg --illegal-access=debug to see the stacktrace.

WARNING: Illegal reflective access by org.springframework.util.ReflectionUtils (file:spring-core-5.1.6.RELEASE.jar) to method java.util.concurrent.Executors$DelegatedExecutorService.shutdown()
        at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:602)
        at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:336)
        at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:271)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:571)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:543)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1055)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:504)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1062)
        at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1057)
        at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1026)
        at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:945)

reflective-access-threads.zip

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions