Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Problems with AspectJ woven classes in Junit suites - static data hanging around?

I have originally posted this question on StackOverflow (http://stackoverflow.com/q/33576324/827480) as a Spring question, but the more I investigate the more I feel that it is something due to AspectJ weaving.

I have a bunch of JUnit tests that all function individually. Each one is a true standalone unit test - single class under test. No contexts are required. I can run them all individually or all together either in Eclipse or via maven / surefire-plugin.

I have since added a new Integration test which leverages the Spring Context, etc and uses the SpringJUnit4ClassRunner. As soon as I add this test to my suite, any test cases run after this class fail.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = IntegrationTestConfiguration.class)
@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
@ActiveProfiles("test")
public class ImportServiceIntegrationTest {
   ...
}

I suspect that there is something maintained in the JVM (some static data) after the test class is terminated.

I am using Spring Cache annotations with the following config:

@Configuration
@EnableCaching(mode=AdviceMode.ASPECTJ)
public class CacheConfig extends CachingConfigurerSupport{

    /**
     * EhCache configuration.  Used to minimize calls to Veracode
     * 
     * @return
     */
    @Bean(destroyMethod="shutdown")
    public net.sf.ehcache.CacheManager ehCacheManager() {
        ...
        ...
    }
        ...
}

As soon as my integration test class finishes, my subsequent test throws the following error:

java.lang.IllegalStateException: The workItems Cache is not alive (STATUS_SHUTDOWN)
        at net.sf.ehcache.Cache$CacheStatus.checkAlive(Cache.java:4097)
        at net.sf.ehcache.Cache.checkStatus(Cache.java:2788)
        at net.sf.ehcache.Cache.get(Cache.java:1744)
        at org.springframework.cache.ehcache.EhCacheCache.get(EhCacheCache.java:65)
        at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:68)
        at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:461)
        at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:432)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:333)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:299)
        at org.springframework.cache.aspectj.AbstractCacheAspect.ajc$around$org_springframework_cache_aspectj_AbstractCacheAspect$1$2bc714b5(AbstractCacheAspect.aj:74)
        at com.synchronize.repository.rtc.WorkItemRepositoryImpl.findById(WorkItemRepositoryImpl.java:192)
        at com.synchronize.repository.rtc.WorkItemRepositoryImpl.findById(WorkItemRepositoryImpl.java:192)
        at com.synchronize.repository.rtc.WorkItemRepositoryImpl.getState(WorkItemRepositoryImpl.java:179)
        at com.synchronize.repository.rtc.WorkItemRepositoryImplTest.testGetState(WorkItemRepositoryImplTest.java:178)

So it is fairly clear to me that Spring is not cleaning something up after it is done (my subsequent class doesn't even load the Spring context - it is a plain vanilla Junit test!).

If I look at the compiled Java class, I see that AspectJ has added some static fields.  Ex:

  private static final JoinPoint.StaticPart ajc$tjp_0;
  private static final JoinPoint.StaticPart ajc$tjp_1;
  static
  {
    ajc$preClinit();
  }


I suspect that when the Spring context is initialized that some value(s) are being set in these variables that isn't getting cleared out at the close of the context.  Given that static data is not eliminated between JUnit tests, subsequent tests try to access data  previously configured by Spring but no longer available and consequently the tests fail.

I am not sure if this is an AspectJ Weaving issue, or a Spring issue.  I am leaning more towards it being an AspectJ issue as it is likely due to the way that ajc implements/weaves the advice.

There are workarounds to my issue.  Use separate JVM forks for each test, or put my spring tests in a different test suite, but both workarounds do not necessarily address the issue at hand; why is this happening in the first place?

Is this an ajc issue?  Are there known limitations to the way that AspectJ weaves classes?  Or is this a bug/deficiency in AspectJ?  Is there a way to avoid this problem in the first place?

Thanks,


Eric


Back to the top