Issue Details (XML | Word | Printable)

Key: FORGE-191
Type: Bug Bug
Status: Resolved Resolved
Resolution: Won't Fix
Priority: 2 Major 2 Major
Assignee: Scott Bale
Reporter: Alex Miller
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Terracotta Forge Projects

ehcache TIM depends on *optional* JSR 107 jar

Created: 09/Mar/08 09:14 PM   Updated: 19/Dec/08 01:23 PM
Component/s: tim-ehcache
Affects Version/s: None
Fix Version/s: None

File Attachments: 1. File book.sh (0.5 kB)
2. File book.sh (0.3 kB)
3. Text File FORGE-191debugstack.txt (4 kB)


Target: 2.7.x
Date of First Response: 19/Mar/08 11:31 AM


 Description  « Hide
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)


 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Scott Bale added a comment - 18/Dec/08 03:21 PM - edited
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.

Hung Huynh added a comment - 18/Dec/08 03:26 PM
If you create a maven project that uses ehcache 1.4.1 (without terracotta), maven will also pull down jsr107cache.jar so I believe it's a real dependency that ehcache uses. It has nothing to do with us.

Alex Miller added a comment - 19/Dec/08 08:16 AM
Hung, you can use Ehcache without the JSR 107 jar, but if you include Terracotta in the mix, it becomes required. Maven may be sucking it down but that's probably just over-zealous dependency definitions in Maven poms, which is certainly common.

That said, I think you're right that this isn't a big deal. I was concerned when I first saw this, but after much more experience with Ehcache, I'd be willing to just accept this as a requirement and not fix.

Alex Miller added a comment - 19/Dec/08 01:23 PM
Given that Ehcache code has a compile-time (and possible run-time dependency), I no longer think this is a big deal.