I've got a Heroku Java app that makes use of the Spymemcached library, which in my case is included by my use of the hibernate-memcached library (1.3).
I now need to make sure that all requests to my app go over HTTPS. This led me to this post, where the solution pivots on making use of the webapp-runner plugin and some config to get the right headers to my app (you provide the runner a context.xml).
My problem is that the webapp-runner plugin has a dependency (further down the dependency graph) on the Spymemcached library as well, which causes a conflict on start up. Furthermore, I can't downgrade webapp-runner to 7.0.22.1 as suggested by this post, as the support for specifying the context.xml came after the fact.
So I thought it would be a simple matter of excluding Spymemcached from my hibernate-memcached dependency so that only the webapp-runner's Spymemcached source would be included:
<dependency>
<groupId>com.googlecode</groupId>
<artifactId>hibernate-memcached</artifactId>
<version>1.3</version>
<exclusions>
<exclusion>
<artifactId>hibernate</artifactId>
<groupId>org.hibernate</groupId>
</exclusion>
<exclusion>
<groupId>spy</groupId>
<artifactId>spymemcached</artifactId>
</exclusion>
</exclusions>
</dependency>
But for some reason I still get the conflict on start up - on the factory bean that creates my memcachedClient which I specify in my application context:
<bean id="memcachedClient" class="net.spy.memcached.spring.MemcachedClientFactoryBean">...</bean>
Resulting in the infamous java.lang.NoClassDefFoundError:
Error loading class [net.spy.memcached.spring.MemcachedClientFactoryBean] for bean with name 'memcachedClient' defined in file [/home/markus/coding/reader/target/tomcat.8080/work/Tomcat/localhost/_/WEB-INF/classes/META-INF/spring/applicationContext.xml]: problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError: org/springframework/beans/factory/FactoryBean
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)...
When I search for the MemcachedClientFactoryBean in my IDE I can see that it's made available by the webapp-runner and not hibernate-memcached, so the exclusion seemed to have done something right.
Am I missing something obvious here? How do I get rid of this NoClassDefFoundError?
FYI I found out that version 7.0.22 of webapp-runner does indeed have support for providing it a context.xml by running java -jar target/webapp-runner.jar --help
It differs slightly to the later versions where you specify ... --context_xml ...
instead of ... --context-xml ...
Version 7.0.22 of webapp-runner doesn't have Spymemcached as a dependency, which solves the problem.