I'm adding Spring Cache on an existing spring project using annotations. I'm using Couchbase as cache provider. I want to use load time weaving using AspectJ to allow private method calls and case class method calls to be cached as well.
It's been three days I'm stuck over this problem and I've read dozens of articles, documentations and examples but this thing just doesn't work.
This is what I've done -
@Configuration
@EnableSpringConfigured
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@EnableTransactionManagement
@EnableRetry
@PropertySource(
value = {"classpath:application.properties", "classpath:${spring.profiles.active}.properties"},
ignoreResourceNotFound = true)
public class BeanConfig implements LoadTimeWeavingConfigurer {
... various beans here ...
@Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new TomcatLoadTimeWeaver();// because I'm using Tomcat 7
}
@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
return new InstrumentationLoadTimeWeaver();
}
}
@Configuration
@EnableSpringConfigured
@EnableCaching(mode = AdviceMode.ASPECTJ)
@ComponentScan(basePackages = "com.foo.bar.dao.cache.couchbase")
public class CacheConfigurer extends CachingConfigurerSupport {
@Bean
@Override
public CacheManager cacheManager() {
... cachemanager configuration here ...
}
}
Then I have @Chacheable
on a DAO method on class, not on interface.
Finally, in my Tomcat 7's $CATALINA_HOME/conf/context.xml I have -
<Context>
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
I have added following dependencies in pom.xml (its a maven project) -
- couchbase-spring-cache
- spring-aspects
- aspectjweaver
- aspectjrt
- spring-instrument
- spring-instrument-tomcat
If I do not use LTW caching works fine for methods calls arriving through interfaces (as it should). But after I enable LTW caching doesn't works at all - no caching for any method call, no errors either.
Has anyone tried using LTW for Spring cache with couchbase? What am I missing or doing wrong here?
I'm on Spring 4.3.5.Release.
Update -
Here is my bare-minimal code replicating the situation - https://github.com/harshilsharma63/spring-boilerplate-with-cache
Forget classloader based load-time weaving, especially with Tomcat < 8.0. You'll have a lot of problems related to classloading order, with some classes being loaded before spring would install his weaving classloader, and you're gonna end-up with hard-to debug problems some of your classes not being weaved, etc. Instead, use a java agent.
Here's how to fix your config with Tomcat 7 by switching to java agent based weaving:
@EnableLoadTimeWeaving
annotations.<Loader loaderClass...
fromcontext.xml
.-javaagent:/path/to/aspectjweaver.jar
to your JVM startup arguments.If you're willing to move to Tomcat 8, here are the steps needed:
@EnableLoadTimeWeaving(aspectjWeaving=ENABLED)
to a separate configuration class, let's name itWeavingConfig
.WebInitializer
class so that for thegetRootConfigClasses()
you return onlyWeavingConfig.class
.getServletConfigClasses()
.<Loader loaderClass...
fromcontext.xml
,@EnableAspectJAutoProxy
.Of course, the best would still be to just use compile time weaving.