Uploaded image for project: 'Red Hat Fuse'
  1. Red Hat Fuse
  2. ENTESB-10917

ehcache bundle requires dynamic-import to avoid ClassNotFoundException when persistence cache is initialized.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Not a Bug
    • Major
    • None
    • fuse-7.3
    • Fuse Distribution, Karaf
    • None
    • % %
    • Hide
      • Attached is the reproducer, unzip it and build it using command 'mvn clean install'.
      • Deploy it in Red Hat Fuse 7.x with command
        feature:install camel-ehcache
        osgi:install -s mvn:com.mycompany/cache-test/1.0.0
        
      • Application starts well. Now restart Red Hat Fuse.
      • In star up logs we will identify following exception
        Caused by: java.lang.IllegalStateException: Persisted value type class not found
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.recoverBackingMap(OffHeapDiskStore.java:195) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.getBackingMap(OffHeapDiskStore.java:159) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.access$600(OffHeapDiskStore.java:93) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.init(OffHeapDiskStore.java:446) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.initStore(OffHeapDiskStore.java:442) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.initAuthoritativeTier(OffHeapDiskStore.java:494) ~[?:?]
        	at org.ehcache.impl.internal.store.tiering.TieredStore$Provider.initStore(TieredStore.java:445) ~[?:?]
        	at org.ehcache.core.EhcacheManager$8.init(EhcacheManager.java:511) ~[?:?]
        	at org.ehcache.core.StatusTransitioner.runInitHooks(StatusTransitioner.java:135) ~[?:?]
        	at org.ehcache.core.StatusTransitioner.access$000(StatusTransitioner.java:33) ~[?:?]
        	at org.ehcache.core.StatusTransitioner$Transition.succeeded(StatusTransitioner.java:194) ~[?:?]
        	at org.ehcache.core.EhcacheBase.init(EhcacheBase.java:572) ~[?:?]
        	at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:266) ~[?:?]
        	at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:243) ~[?:?]
        	at com.mycompany.ehcache.MySimpleCacheManager.createCache(MySimpleCacheManager.java:101) ~[?:?]
        ----
        ---
        	... 28 more
        Caused by: java.lang.ClassNotFoundException: com.mycompany.ehcache.domain.User not found by org.ehcache.ehcache [228]
        	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1639) ~[?:?]
        	at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80) ~[?:?]
        	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053) ~[?:?]
        	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:?]
        	at org.ehcache.core.internal.util.ClassLoading$DefaultClassLoader.loadClass(ClassLoading.java:57) ~[?:?]
        	at java.lang.Class.forName0(Native Method) ~[?:?]
        	at java.lang.Class.forName(Class.java:348) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.recoverBackingMap(OffHeapDiskStore.java:190) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.getBackingMap(OffHeapDiskStore.java:159) ~[?:?]
        	at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.access$600(OffHeapDiskStore.java:93) ~[?:?]
        
        
      • Now if stop fuse and we delete the folder/files created at permanent CACHE_PATH configured at class MySimpleCacheManager.
        [cpandey@cpandey esb-cache]$ pwd
        /tmp/esb-cache
        [cpandey@cpandey esb-cache]$ tree
        .
        └── mySimpleCache
            └── file
                └── USER_CACHE_1271916c53257f36f0a0b7d732ce5f3c68871d28
                    ├── offheap-disk-store
                    │   ├── ehcache-disk-store.data
                    │   ├── ehcache-disk-store.index
                    │   └── ehcache-disk-store.meta
                    └── value-serializer
                        └── holder-0-CompactJavaSerializer-ObjectStreamClassIndex.bin
        
        5 directories, 4 files
        [cpandey@cpandey esb-cache]$ rm -rf *
        
      • After deleting cache and than restarting Red Hat Fuse, we don't observe this issue again.
      • Nice workaround to this problem is that enable dynamic-import on ehcache bundle.
        karaf@root()> list|grep ehcache
        227 │ Active  │  50 │ 2.21.0.fuse-731003-redhat-00003 │ camel-ehcache
        228 │ Active  │  50 │ 3.5.0                           │ ehcache 3
        karaf@root()> dynamic-import 228
        Enabling dynamic imports on bundle org.ehcache.ehcache [228]
        karaf@root()> 
        
      • Dynamic Import is helpful but enabling dynamic-import is considered to be an anti-pattern. We should have dependencies resolved with Import-Package Manifest header.
      • Problem is this ehcache bundle is not a custom bundle it is being shipped with Red Hat Fuse. Also why this ehcache bundle is failing with classnotfound exception for custom/user-defined class ?
      Show
      Attached is the reproducer, unzip it and build it using command 'mvn clean install'. Deploy it in Red Hat Fuse 7.x with command feature:install camel-ehcache osgi:install -s mvn:com.mycompany/cache-test/1.0.0 Application starts well. Now restart Red Hat Fuse. In star up logs we will identify following exception Caused by: java.lang.IllegalStateException: Persisted value type class not found at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.recoverBackingMap(OffHeapDiskStore.java:195) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.getBackingMap(OffHeapDiskStore.java:159) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.access$600(OffHeapDiskStore.java:93) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.init(OffHeapDiskStore.java:446) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.initStore(OffHeapDiskStore.java:442) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.initAuthoritativeTier(OffHeapDiskStore.java:494) ~[?:?] at org.ehcache.impl.internal.store.tiering.TieredStore$Provider.initStore(TieredStore.java:445) ~[?:?] at org.ehcache.core.EhcacheManager$8.init(EhcacheManager.java:511) ~[?:?] at org.ehcache.core.StatusTransitioner.runInitHooks(StatusTransitioner.java:135) ~[?:?] at org.ehcache.core.StatusTransitioner.access$000(StatusTransitioner.java:33) ~[?:?] at org.ehcache.core.StatusTransitioner$Transition.succeeded(StatusTransitioner.java:194) ~[?:?] at org.ehcache.core.EhcacheBase.init(EhcacheBase.java:572) ~[?:?] at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:266) ~[?:?] at org.ehcache.core.EhcacheManager.createCache(EhcacheManager.java:243) ~[?:?] at com.mycompany.ehcache.MySimpleCacheManager.createCache(MySimpleCacheManager.java:101) ~[?:?] ---- --- ... 28 more Caused by: java.lang.ClassNotFoundException: com.mycompany.ehcache.domain.User not found by org.ehcache.ehcache [228] at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1639) ~[?:?] at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80) ~[?:?] at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053) ~[?:?] at java.lang. ClassLoader .loadClass( ClassLoader .java:357) ~[?:?] at org.ehcache.core.internal.util.ClassLoading$DefaultClassLoader.loadClass(ClassLoading.java:57) ~[?:?] at java.lang. Class .forName0(Native Method) ~[?:?] at java.lang. Class .forName( Class .java:348) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.recoverBackingMap(OffHeapDiskStore.java:190) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.getBackingMap(OffHeapDiskStore.java:159) ~[?:?] at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.access$600(OffHeapDiskStore.java:93) ~[?:?] Now if stop fuse and we delete the folder/files created at permanent CACHE_PATH configured at class MySimpleCacheManager. [cpandey@cpandey esb-cache]$ pwd /tmp/esb-cache [cpandey@cpandey esb-cache]$ tree . └── mySimpleCache └── file └── USER_CACHE_1271916c53257f36f0a0b7d732ce5f3c68871d28 ├── offheap-disk-store │   ├── ehcache-disk-store.data │   ├── ehcache-disk-store.index │   └── ehcache-disk-store.meta └── value-serializer └── holder-0-CompactJavaSerializer-ObjectStreamClassIndex.bin 5 directories, 4 files [cpandey@cpandey esb-cache]$ rm -rf * After deleting cache and than restarting Red Hat Fuse, we don't observe this issue again. Nice workaround to this problem is that enable dynamic-import on ehcache bundle. karaf@root()> list|grep ehcache 227 │ Active │ 50 │ 2.21.0.fuse-731003-redhat-00003 │ camel-ehcache 228 │ Active │ 50 │ 3.5.0 │ ehcache 3 karaf@root()> dynamic- import 228 Enabling dynamic imports on bundle org.ehcache.ehcache [228] karaf@root()> Dynamic Import is helpful but enabling dynamic-import is considered to be an anti-pattern. We should have dependencies resolved with Import-Package Manifest header. Problem is this ehcache bundle is not a custom bundle it is being shipped with Red Hat Fuse. Also why this ehcache bundle is failing with classnotfound exception for custom/user-defined class ? With fix https://issues.apache.org/jira/browse/SMX4-1303 (ancient fix) it appears that dynamic-import should have been a part of ehcache manifest file.

    Attachments

      Activity

        People

          yfang@redhat.com Freeman(Yue) Fang
          rhn-support-cpandey Chandra Shekhar Pandey (Inactive)
          Votes:
          0 Vote for this issue
          Watchers:
          4 Start watching this issue

          Dates

            Created:
            Updated:
            Resolved: