Currently, using the ehcache TIM requires that you include the jsr107 jar (from http://sourceforge.net/projects/jsr107cache/
) in your classpath. This jar is optional for ehcache and it seems weird to make users include it if they don't use it (as seems certainly possible and maybe likely).
For the book, I have a simple ehcache test program that uses no jsr107 stuff. You can find it at https://svn.terracotta.org/repo/forge/projects/thebook/trunk/chapter_caching/ehcache/src/main/java/org/terracotta/book/caching/ehcache
If you omit the 107 jar with a command like:
dso-java.sh -cp target/classes:/.m2/repository/net/sf/ehcache/ehcache/1.3.0/ehcache-1.3.0.jar:/.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar -Dtc.config=tc-config.xml org.terracotta.book.caching.ehcache.UserEhcacheExample
You'll get something like:
AW::WARNING - could not load class [net/sf/jsr107cache/CacheListener] as a resource in loader [sun.misc.Launcher$AppClassLoader@3c5982]
java.lang.NoClassDefFoundError: net/sf/jsr107cache/CacheListener
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2395)
at java.lang.Class.getDeclaredMethods(Class.java:1763)
at com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo.<init>(JavaClassInfo.java:125)
at com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo.getClassInfo(JavaClassInfo.java:157)
at com.tc.object.TCClassFactoryImpl.getOrCreate(TCClassFactoryImpl.java:58)
at com.tc.object.ClientObjectManagerImpl.getPortableObjects(ClientObjectManagerImpl.java:216)
at com.tc.object.Traverser.addReferencedObjects(Traverser.java:37)
at com.tc.object.Traverser.traverse(Traverser.java:89)
at com.tc.object.ClientObjectManagerImpl.addToManagedFromRoot(ClientObjectManagerImpl.java:895)
at com.tc.object.ClientObjectManagerImpl.create(ClientObjectManagerImpl.java:278)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreateIfNecesary(ClientObjectManagerImpl.java:342)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreate(ClientObjectManagerImpl.java:315)
at com.tc.object.tx.ClientTransactionManagerImpl.fieldChanged(ClientTransactionManagerImpl.java:609)
at com.tc.object.TCObjectImpl.objectFieldChanged(TCObjectImpl.java:320)
at net.sf.ehcache.CacheManager.__tc_setdefaultCache(CacheManager.java)
at net.sf.ehcache.CacheManager.configure(CacheManager.java:286)
at net.sf.ehcache.CacheManager.__tc_wrapped_init(CacheManager.java:218)
at net.sf.ehcache.CacheManager.init(CacheManager.java)
at net.sf.ehcache.CacheManager.<init>(CacheManager.java:205)
at org.terracotta.book.caching.ehcache.UserEhcacheExample.<init>(UserEhcacheExample.java:9)
at org.terracotta.book.caching.ehcache.UserEhcacheExample.main(UserEhcacheExample.java:51)
Exception in thread "main" java.lang.NoClassDefFoundError: net/sf/jsr107cache/CacheListener
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2395)
at java.lang.Class.getDeclaredMethods(Class.java:1763)
at com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo.<init>(JavaClassInfo.java:125)
at com.tc.aspectwerkz.reflect.impl.java.JavaClassInfo.getClassInfo(JavaClassInfo.java:157)
at com.tc.object.TCClassFactoryImpl.getOrCreate(TCClassFactoryImpl.java:58)
at com.tc.object.ClientObjectManagerImpl.getPortableObjects(ClientObjectManagerImpl.java:216)
at com.tc.object.Traverser.addReferencedObjects(Traverser.java:37)
at com.tc.object.Traverser.traverse(Traverser.java:89)
at com.tc.object.ClientObjectManagerImpl.addToManagedFromRoot(ClientObjectManagerImpl.java:895)
at com.tc.object.ClientObjectManagerImpl.create(ClientObjectManagerImpl.java:278)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreateIfNecesary(ClientObjectManagerImpl.java:342)
at com.tc.object.ClientObjectManagerImpl.lookupOrCreate(ClientObjectManagerImpl.java:315)
at com.tc.object.tx.ClientTransactionManagerImpl.fieldChanged(ClientTransactionManagerImpl.java:609)
at com.tc.object.TCObjectImpl.objectFieldChanged(TCObjectImpl.java:320)
at net.sf.ehcache.CacheManager.__tc_setdefaultCache(CacheManager.java)
at net.sf.ehcache.CacheManager.configure(CacheManager.java:286)
at net.sf.ehcache.CacheManager.__tc_wrapped_init(CacheManager.java:218)
at net.sf.ehcache.CacheManager.init(CacheManager.java)
at net.sf.ehcache.CacheManager.<init>(CacheManager.java:205)
at org.terracotta.book.caching.ehcache.UserEhcacheExample.<init>(UserEhcacheExample.java:9)
at org.terracotta.book.caching.ehcache.UserEhcacheExample.main(UserEhcacheExample.java:51)
Still happening w/ Terracotta 2.7.2 and tim-ehcache-1.4.1 version 1.2.3-SNAPSHOT.
The dependency comes from net.sf.ehcache.CacheManager - it depends directly on net.sf.ehcache.jcache.JCache, which implements net.sf.jsr107cache.Cache.
With normal classloading (without TC) it's possible to load the CacheManager class without loading the JCache class, as long as the JCache class is present in the classpath. Hence the JSR 107 jar is optional under normal conditions.
With Terracotta, though, as the CacheManager instance is instantiated and added to the clustered CacheManager.ALL_CACHE_MANAGERS Collection field, this triggers a bunch of stuff (see attached debug stack trace, taken from Eclipse debugging). Ultimately, TCClassFactoryImpl attempts to construct a new JavaClassInfo object using the CacheManager Class object. JavaClassInfo attempts to retrieve, using reflection, all of the Methods for that Class, and that causes JCache to try to be loaded, which results in the NoClassDefFoundError for net.sf.jsr107cache.Cache.
So the problem seems to be in what JavaClassInfo.getClassInfo() does when attempting to create a JavaClassInfo for a loaded Class. In this case CacheManager is an example of a class that could be loaded normally, but can't be fully examined with reflection since it's dependencies are not all loadable.
(The AW::warning is printed out from AsmClassInfo.createClassInfoFromStream() method, by the way.)
I'm also attaching a shell script, book.sh, which I've been using to run Alex's example.