• Bug
  • Status: Open
  • 2 Major
  • Resolution:
  • teck
  • Reporter: teck
  • October 17, 2012
  • 0
  • Watchers: 6
  • April 16, 2015

Description

There are places in ehcache where we use ClassLoaderUtil to dynamically locate internal components. That is well and good but I don’t think we should use the policy of preferring the TCCL for loading these classes.

Additionally it is very odd that we allow the TCCL load the desired class but we .class literals to load the argument types.

Examples of this include the enterprise features manager or the TC clustered instance factory.

It seems at least for classes that are internal to the ehcache impl we should always only explicitly use the defining loader of ehcache for these loads (ie. never TCCL)

Comments

d d 2013-09-20

Hi,

We run into this issue with Liferay portal 6.2: Both the portal and a portlet plugin ship with Ehcache 2.7.1, and because of TCCL priority we keep jumping from the portal classloader to the plugin classloader.

So i modified net.sf.ehcache.util.ClassLoaderUtil to give priority to ClassLoaderUtil.class.getClassLoader(), and it solved all troubles. Is it planned to do a such update in a future ehcache version?

Thanks!

Aliabbas Surti 2014-02-18

Hi Tim,

We are facing the same issue in Liferay version 6.2. I have tried the solution that donino has mentioned in the above post but that did not work for us.

I tried using the latest version ehcache 2.8.0 but that did not help too.

Is there any timeline on when this bug is scheduled to be fixed? It would be great if you could please provide us that.

Many thanks.

Tim Eck 2014-03-20

There are _some_ changes around this but only planned for ehcache 2.9.0 at the moment

Aliabbas –> Can you share anymore information? In particular I’d like to see what exception you’re getting (presumably a ClassCastException) and the stack trace involved. Simply hacking the order of order lookups in ClassLoaderUtil is not the right thing to do.

Aliabbas Surti 2014-03-23

Hi Tim,

Here is the stack trace,

05:13:39,643 ERROR [localhost-startStop-2][HotDeployImpl:208] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering plugins for -portlet com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering plugins for -portlet at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.throwHotDeployException(BaseHotDeployListener.java:46) at com.liferay.portal.deploy.hot.PluginPackageHotDeployListener.invokeDeploy(PluginPackageHotDeployListener.java:64) at com.liferay.portal.deploy.hot.HotDeployImpl.doFireDeployEvent(HotDeployImpl.java:205) at com.liferay.portal.deploy.hot.HotDeployImpl.fireDeployEvent(HotDeployImpl.java:96) at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:27) at com.liferay.portal.kernel.servlet.PluginContextListener.fireDeployEvent(PluginContextListener.java:164) at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalInit(PluginContextListener.java:154) at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:44) at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:64) at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:56) at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:54) at com.liferay.portal.kernel.servlet.PluginContextListener.contextInitialized(PluginContextListener.java:116) at com.liferay.portal.kernel.servlet.SecurePluginContextListener.contextInitialized(SecurePluginContextListener.java:151) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1113) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1671) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) Caused by: com.liferay.portal.kernel.exception.SystemException: net.sf.ehcache.CacheException: Unable to load class net.sf.ehcache.store.DefaultElementValueComparator. Initial cause was net.sf.ehcache.store.DefaultElementValueComparator.(net.sf.ehcache.config.CacheConfiguration) at com.liferay.portal.service.impl.ServiceComponentLocalServiceImpl.initServiceComponent(ServiceComponentLocalServiceImpl.java:86) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115) at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62) at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175) at $Proxy91.initServiceComponent(Unknown Source) at com.liferay.portal.service.ServiceComponentLocalServiceUtil.initServiceComponent(ServiceComponentLocalServiceUtil.java:288) at com.liferay.portal.deploy.hot.PluginPackageHotDeployListener.initServiceComponent(PluginPackageHotDeployListener.java:247) at com.liferay.portal.deploy.hot.PluginPackageHotDeployListener.doInvokeDeploy(PluginPackageHotDeployListener.java:132) at com.liferay.portal.deploy.hot.PluginPackageHotDeployListener.invokeDeploy(PluginPackageHotDeployListener.java:61) ... 25 more Caused by: net.sf.ehcache.CacheException: Unable to load class net.sf.ehcache.store.DefaultElementValueComparator. Initial cause was net.sf.ehcache.store.DefaultElementValueComparator.(net.sf.ehcache.config.CacheConfiguration) at net.sf.ehcache.util.ClassLoaderUtil.createNewInstance(ClassLoaderUtil.java:100) at net.sf.ehcache.config.ElementValueComparatorConfiguration.createElementComparatorInstance(ElementValueComparatorConfiguration.java:57) at net.sf.ehcache.Cache.(Cache.java:791) at net.sf.ehcache.Cache.clone(Cache.java:2761) at net.sf.ehcache.Cache.clone(Cache.java:163) at net.sf.ehcache.CacheManager.cloneDefaultCache(CacheManager.java:1945) at net.sf.ehcache.CacheManager.addCache(CacheManager.java:1218) at com.liferay.portal.cache.ehcache.EhcachePortalCacheManager.addCache(EhcachePortalCacheManager.java:241) at com.liferay.portal.cache.ehcache.EhcachePortalCacheManager.getCache(EhcachePortalCacheManager.java:136) at com.liferay.portal.cache.MultiVMPoolImpl.getCache(MultiVMPoolImpl.java:47) at com.liferay.portal.dao.orm.common.FinderCacheImpl.\_getPortalCache(FinderCacheImpl.java:231) at com.liferay.portal.dao.orm.common.FinderCacheImpl.getResult(FinderCacheImpl.java:120) at com.liferay.portal.kernel.dao.orm.FinderCacheUtil.getResult(FinderCacheUtil.java:47) at com.liferay.portal.service.persistence.ClassNamePersistenceImpl.fetchByValue(ClassNamePersistenceImpl.java:154) at com.liferay.portal.service.persistence.ClassNamePersistenceImpl.fetchByValue(ClassNamePersistenceImpl.java:135) at com.liferay.portal.service.impl.ClassNameLocalServiceImpl.addClassName(ClassNameLocalServiceImpl.java:41) at sun.reflect.GeneratedMethodAccessor76.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115) at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62) at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175) at $Proxy16.addClassName(Unknown Source) at com.liferay.portal.service.impl.ClassNameLocalServiceImpl.getClassName(ClassNameLocalServiceImpl.java:134) at sun.reflect.GeneratedMethodAccessor190.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115) at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175) at $Proxy16.getClassName(Unknown Source) at com.liferay.portal.service.ClassNameLocalServiceUtil.getClassName(ClassNameLocalServiceUtil.java:302) at com.liferay.portal.model.ModelHintsImpl.read(ModelHintsImpl.java:338) at com.liferay.portal.model.ModelHintsImpl.read(ModelHintsImpl.java:285) at com.liferay.portal.model.ModelHintsUtil.read(ModelHintsUtil.java:96) at com.liferay.portal.service.impl.ServiceComponentLocalServiceImpl.initServiceComponent(ServiceComponentLocalServiceImpl.java:82) ... 39 more Caused by: java.lang.NoSuchMethodException: net.sf.ehcache.store.DefaultElementValueComparator.(net.sf.ehcache.config.CacheConfiguration) at java.lang.Class.getConstructor0(Class.java:2706) at java.lang.Class.getConstructor(Class.java:1657) at net.sf.ehcache.util.ClassLoaderUtil.createNewInstance(ClassLoaderUtil.java:91) ... 93 more

Tim Eck 2014-03-24

Thanks for the stack trace. That certainly looks like the kind of issue that can arise from the problem I describe in this ticket.

The changes I’ve made in ehcache trunk (slated to become ehcache 2.9.0) I think you would at least give you a different result here, but hopefully just “work”

I don’t understand why flipping the order of classloaders in ClassLoaderUtil wouldn’t work for you, that doesn’t add up me for me. Again I don’t reccommend hacking on that class to make things work, but it suspicious that it wouldn’t at least change the problem.

All this said, I think I can assert that there is more than version of ehcache floating around in your system somehow. The thread in the stack trace above has it’s thread context class loader set to something that can load ehcache classes. That loader also differs from the classloader which defined the instance of CacheManager that com.liferay.portal.cache.ehcache.EhcachePortalCacheManager calls upon.

As a data point you could try setting the TCCL explicitly to see what happens:

ClassLoader prev = Thread.currentThread().getContextClassLoader();
try {
   Thread.currentThread().setContextClassLoader(cacheManager.getClass().getClassLoader());
   cacheManager.addCache(...);
finally {
   Thread.currentThread().setContextClassLoader(prev);
}

Sampsa Sohlman 2015-04-16

Hey Tim Eck,

Could you point out the correct fix location?

Sampsa Sohlman 2015-04-16

To be more precise:

“The changes I’ve made in ehcache trunk (slated to become ehcache 2.9.0) I think you would at least give you a different result here, but hopefully just “work””

It seems that ehcache 2.9.0 is solving the problems with Liferay, so I’m looking the correct changes.