Skip to content

Use of same @Configuration class across multiple ApplicationContexts is not threadsafe [SPR-10936] #15564

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 Sep 25, 2013 · 1 comment
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 25, 2013

Eric Sirianni opened SPR-10936 and commented

In our application, we instantiate multiple Spring ApplicationContext scoped to a particular tenant, each using the same @Configuration class. The expectation is that singleton @Beans produced by the @Configuration will be scoped to each individual (per-tenant) ApplicationContext instance. However, we are observing situations where singletons instantiated from the @Configuration are incorrectly shared across ApplicationContext instances.

I've narrowed it down to situations where the ApplicationContexts are instantiated concurrently. This JUnit test exhibits the issue (testSequential passes, testConcurrent fails):

public class ConcurrentConfigurationInitializationTest {

    private static AtomicInteger COUNTER = new AtomicInteger(0);

    @Configuration
    public static class TestConfig {
        @Bean
        public Integer foo() {
            return Integer.valueOf(COUNTER.incrementAndGet());
        }
    }

    @Test
    public void testSequential() throws InterruptedException {
        test(10, 1);
    }

    @Test
    public void testConcurrent() throws InterruptedException {
        test(10, 10);
    }

    private void test(int numContexts, int numThreads) throws InterruptedException {
        final Set<Integer> uniqueBeans = new HashSet<Integer>();
        ExecutorService executor = Executors.newFixedThreadPool(numThreads);

        for (int i = 0; i < numContexts; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    ApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class);
                    Integer bean = (Integer) context.getBean("foo");
                    uniqueBeans.add(bean);
                }
            });
        }
        executor.shutdown();
        executor.awaitTermination(60, TimeUnit.SECONDS);

        assertThat(uniqueBeans).hasSize(numContexts);
    }

}

I would guess that Spring is properly creating a CGLIB-enhanced @Configuration class per ApplicationContext and that the issue is that CGLIB itself is not behaving properly in a multithreaded scenario. Perhaps CGLIB callbacks are getting intermingled between proxies. #14439 seems somewhat relevant in this regard.


Affects: 3.2.4

Attachments:

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Nov 5, 2013

Juergen Hoeller commented

This looks like a duplicate of #14941 and should therefore be fixed in the 4.0 line already. Please give 4.0 RC1 a try and let me know whether anything is still missing...

Juergen

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: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants