title: EnableLoadTimeWeaving Spring Boot Embedded Tomcat
body: <p>Caching Aspects are not having any effects at runtime with Spring Boot and Embedded tomcat with LoadTimeWeaving enabled,but we are seeing the weaving is happening fine in the logs. </p>
  
  <p>Below is the configuration, the LoadTimeWeaving is enabled along with the mode as AspectJ for Caching </p>
  
  <pre><code>    @Configuration
      @EnableConfigurationProperties
      @EnableSpringConfigured
      @EnableAspectJAutoProxy(proxyTargetClass = true)
      @EnableLoadTimeWeaving
      @EnableTransactionManagement
      @EnableAsync
      @EnableCaching(mode = AdviceMode.ASPECTJ)
      public class AppConfig {
      }
  </code></pre>
  
  <p><strong>Spring Agent</strong>
  -javaagent:../../../spring-instrument-4.3.3.RELEASE.jar</p>
  
  <p><strong>Logs</strong></p>
  
  <pre><code>[RestartClassLoader@2aaae670] debug weaving 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway'
  [RestartClassLoader@2aaae670] weaveinfo Join point 'method-execution(java.util.List uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway.getHierarchyLevelDefns())' in Type 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway' (RestReferenceDataGateway.java:118) advised by around advice from 'org.springframework.cache.aspectj.AnnotationCacheAspect' (AbstractCacheAspect.aj:64)
  [RestartClassLoader@2aaae670] weaveinfo Join point 'method-execution(java.util.Map uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway.getHierarchyLevelDefinitionMap())' in Type 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway' (RestReferenceDataGateway.java:129) advised by around advice from '**org.springframework.cache.aspectj.AnnotationCacheAspect**' (AbstractCacheAspect.aj:64)
  [RestartClassLoader@2aaae670] **debug generating class** 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway$AjcClosure1'
  [RestartClassLoader@2aaae670] debug generating class 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway$AjcClosure3'
  </code></pre>
  
  <p>there are whole bunch of discussions around this. The weaving is happening on the RestartClassLoader, not sure is it something to do with the class loader. Have also tried adding the below,</p>
  
  <pre><code>@Bean
        public LoadTimeWeaver loadTimeWeaver() throws Throwable {
            InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
            return loadTimeWeaver;
        }
  </code></pre>
  
  <p>Please provide your suggestions.</p>
  
  <p><strong>Edit</strong>
  We need Aspectj mode as we are using caching on private methods. I removed the EnableAspectJAutoProxy but still that does not help. </p>
  
  <p>On further analysis on the load time weaving, I noticed the below behaviour.
  I profile the application and investigated on the class loaders to see the weaving is done correct for the caching annotation to work(classes are trasformed). I noticed for some classes in the classloader ,we have a class with suffix($AjcClosure and those are transformed classes after weaving is done). So, if cachinng annotations is part of those weaved classes, then it works fine. 
  Then I closely looked in to the classes why some classes are weaved correctly and some are not. Then I noticed that if classes are loaded already to the class-loader before weaving happens, then that is where the weaving is not happening.</p>
  
  <pre><code>   @Bean
      public IAService aService(){
         return new AServiceImpl();
      }
  </code></pre>
  
  <p>In the above case, the class is AServiceImpl is loaded to the class loader only when this instance is needed (after load time weaving and caching works perfectly). 
  But if the same class is being initialised using @Component then it is not getting weaved.</p>
  
  <pre><code>@Service
  public class AServiceImpl{
  }
  </code></pre>
  
  <p>I think, in the above case, the class AServiceImpl is loaded to the class loader while the spring container initialises and load time weaving is trying to weave after that). </p>
  
  <p>I verified this behavior again in class loader as well. So, is it an issue if aspectj tries to weave a class that was already loaded. the same problem was raised in the Spring Jira as well in the below link.</p>
  
  <p><a href="https://jira.spring.io/browse/SPR-13786" rel="nofollow noreferrer">https://jira.spring.io/browse/SPR-13786</a></p>
  
  <p>As mentioned in the above link, if I pass the aspectj weaver as java agent like the below, then all the classes are being weaved correctly. So, is it required to have two agents or do we have any other option for this.</p>
  
  <pre><code>-javaagent:../../../aspectjweaver-1.6.1.jar 
  -javaagent:../../../spring-instrument-4.3.3.RELEASE.jar 
  </code></pre>