Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: 2 Major 2 Major
  • Resolution: Won't Fix
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: tim-ehcache
  • Labels:
    None

Description

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)

  1. book.sh
    19/Dec/08 08:45 AM
    0.5 kB
    Scott Bale
  2. book.sh
    18/Dec/08 03:23 PM
    0.3 kB
    Scott Bale
  3. FORGE-191debugstack.txt
    18/Dec/08 03:23 PM
    4 kB
    Scott Bale

Activity

Hide
Scott Bale added a comment - - 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.

Show
Scott Bale added a comment - - 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.
Hide
Hung Huynh added a comment -

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.

Show
Hung Huynh added a comment - 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.
Hide
Alex Miller added a comment -

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.

Show
Alex Miller added a comment - 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.
Hide
Alex Miller added a comment -

Given that Ehcache code has a compile-time (and possible run-time dependency), I no longer think this is a big deal.

Show
Alex Miller added a comment - Given that Ehcache code has a compile-time (and possible run-time dependency), I no longer think this is a big deal.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: