Hi Eric,

Maybe not quite your situation, but see #1 in http://lagod.id.au/blog/?p=266.  
Spring configured aspects pretty much blow a hole in the encapsulation of 
Spring contexts that the Spring test framework relies on.  


I don’t know if I'd call this a bug on either side. More a leaky abstraction.  
Spring test makes some promises about encapsulation that it can't really keep, 
but then OTOH any time you bring in byte code manipulation all bets are off - 
after all, that's what byte code manipulation is for.


HTH

Jaime






From: Eric B
Sent: ‎Sunday‎, ‎8‎ ‎November‎ ‎2015 ‎12‎:‎00‎ ‎PM
To: aspectj-users@eclipse.org






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
_______________________________________________
aspectj-users mailing list
aspectj-users@eclipse.org
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to