Author |
Message |
07/12/2011 06:54:39
|
olafos
neo
Joined: 07/12/2011 06:46:47
Messages: 4
Offline
|
Hello,
I'm using Ehcache (2.4.2) clustered with Terracota (3.5.1). I'm using express installation (no DSO). Ocassionally I'm receiving the following exception when reading value from cache:
Code:
net.sf.ehcache.CacheException: java.lang.ClassNotFoundException: boolean
at org.terracotta.modules.ehcache.store.ValueModeHandlerSerialization.getRealKeyObject(ValueModeHandlerSerialization.java:128)
at org.terracotta.modules.ehcache.store.ValueModeHandlerSoftLockAwareSerialization.getRealKeyObject(ValueModeHandlerSoftLockAwareSerialization.java:68)
at org.terracotta.modules.ehcache.store.ClusteredStoreBackendImpl$TDCWithEvents.onExpiry(ClusteredStoreBackendImpl.java:217)
at org.terracotta.cache.TerracottaDistributedCache.expire(TerracottaDistributedCache.java:427)
at org.terracotta.cache.TerracottaDistributedCache.getNonExpiredEntry(TerracottaDistributedCache.java:240)
at org.terracotta.cache.TerracottaDistributedCache.getNonExpiredEntryCoherent(TerracottaDistributedCache.java:152)
at org.terracotta.cache.TerracottaDistributedCache.getTimestampedValueQuiet(TerracottaDistributedCache.java:198)
at org.terracotta.modules.ehcache.store.ClusteredStoreBackendImpl.getTimestampedValueQuiet(ClusteredStoreBackendImpl.java:70)
at org.terracotta.modules.ehcache.store.backend.StrictBackend.get(StrictBackend.java:48)
at org.terracotta.modules.ehcache.store.ClusteredStore.doGet(ClusteredStore.java:360)
at org.terracotta.modules.ehcache.store.ClusteredStore.getQuiet(ClusteredStore.java:351)
at net.sf.ehcache.Cache.searchInStoreWithoutStats(Cache.java:1925)
at net.sf.ehcache.Cache.getQuiet(Cache.java:1788)
at net.sf.ehcache.constructs.blocking.BlockingCache.get(BlockingCache.java:160)
at net.sf.ehcache.constructs.blocking.SelfPopulatingCache.get(SelfPopulatingCache.java:68)
at pl.sns.cache.ehcache.CacheUtils.get(CacheUtils.java:23)
at pl.sns.cache.ehcache.CacheUtils.get(CacheUtils.java:16)
at pl.sns.pap.service.ParameterSourceImpl.getParameter(ParameterSourceImpl.java:143)
at $ParameterSource_1311e90c6ec.getParameter($ParameterSource_1311e90c6ec.java)
at pl.sns.pap.client.components.RewardsEnabled.test(RewardsEnabled.java:17)
at org.apache.tapestry5.corelib.base.AbstractConditional.beginRender(AbstractConditional.java:59)
at org.apache.tapestry5.corelib.base.AbstractConditional$MethodAccess_beginRender_1311e90c7c1.invoke(AbstractConditional$MethodAccess_beginRender_1311e90c7c1.java)
at org.apache.tapestry5.internal.transform.RenderPhaseMethodWorker$Invoker.invoke(RenderPhaseMethodWorker.java:117)
at org.apache.tapestry5.internal.transform.RenderPhaseMethodWorker$RenderPhaseMethodAdvice.advise(RenderPhaseMethodWorker.java:86)
at org.apache.tapestry5.internal.services.AbstractComponentMethodInvocation.proceed(AbstractComponentMethodInvocation.java:86)
at org.apache.tapestry5.corelib.base.AbstractConditional.beginRender(AbstractConditional.java)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$BeginRenderPhase.invokeComponent(ComponentPageElementImpl.java:239)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$AbstractPhase.invoke(ComponentPageElementImpl.java:176)
... 122 more
Caused by: java.lang.ClassNotFoundException: boolean
at java.lang.ClassLoader.findClass(ClassLoader.java:358)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.terracotta.modules.ehcache.store.ThreadContextAwareClassLoader.loadClass(ThreadContextAwareClassLoader.java:34)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.terracotta.cache.serialization.DsoSerializationStrategy$OIS.resolveClass(DsoSerializationStrategy.java:111)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readClass(ObjectInputStream.java:1461)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1311)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at org.terracotta.cache.serialization.DsoSerializationStrategy2.deserializeStringKey(DsoSerializationStrategy2.java:73)
at org.terracotta.modules.ehcache.store.ValueModeHandlerSerialization.getRealKeyObject(ValueModeHandlerSerialization.java:126)
... 149 more
Here's a configuration for the cache that causes problems:
Code:
<cache
name="parameters"
eternal="false"
maxElementsInMemory="100"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
statistics="true">
<terracotta>
<nonstop
enabled="false">
</nonstop>
</terracotta>
</cache>
And here's my terracotta config
Code:
<con:tc-config xmlns:con="http://www.terracotta.org/config">
<system xmlns:tc="http://www.terracotta.org/config">
<configuration-model>development</configuration-model>
</system>
<clients xmlns:tc="http://www.terracotta.org/config">
<logs>%(user.home)/terracotta/client-logs</logs>
</clients>
<servers xmlns:tc="http://www.terracotta.org/config">
<server bind="0.0.0.0" host="192.168.0.22" name="192.168.0.22:9510">
<data>/home/otomczak/terracotta/server-data</data>
<logs>/home/otomczak/terracotta/server-logs</logs>
<statistics>/home/otomczak/terracotta/server-statistics</statistics>
<dso-port bind="0.0.0.0">9510</dso-port>
<jmx-port bind="0.0.0.0">9520</jmx-port>
<l2-group-port bind="0.0.0.0">9530</l2-group-port>
<data-backup>
/home/otomczak/tools/terracotta-3.5.1/bin/data-backup
</data-backup>
<index>/home/otomczak/terracotta/server-data/index</index>
<dso>
<client-reconnect-window>120</client-reconnect-window>
<persistence>
<mode>temporary-swap-only</mode>
</persistence>
<garbage-collection>
<enabled>true</enabled>
<verbose>false</verbose>
<interval>3600</interval>
</garbage-collection>
</dso>
</server>
<mirror-groups>
<mirror-group>
<ha>
<mode>networked-active-passive</mode>
<networked-active-passive>
<election-time>5</election-time>
</networked-active-passive>
</ha>
<members>
<member>192.168.0.22:9510</member>
</members>
</mirror-group>
</mirror-groups>
<ha>
<mode>networked-active-passive</mode>
<networked-active-passive>
<election-time>5</election-time>
</networked-active-passive>
</ha>
<update-check>
<enabled>true</enabled>
<period-days>7</period-days>
</update-check>
</servers>
<application xmlns:tc="http://www.terracotta.org/config">
<dso>
<dso-reflection-enabled>true</dso-reflection-enabled>
</dso>
</application>
</con:tc-config>
Any ideas or pointers what might be wrong with my configuration?
Thanks, Olaf
|
|
|
07/12/2011 10:55:55
|
teck
seraphim
Joined: 05/24/2006 15:03:25
Messages: 1128
Offline
|
Unfortunately that looks like a bug. Is there any chance you are using a instance of boolean.class or java.lang.Boolean.TYPE as a key in this cache? That should work but unfortunately there is a bug with that in the current release and there isn't a workaround short of not using the primitive Class objects as direct cache keys
|
Tim Eck (terracotta engineer)
|
|
|
07/12/2011 13:44:29
|
olafos
neo
Joined: 07/12/2011 06:46:47
Messages: 4
Offline
|
teck,
Thanks for the reply. I'm not using boolean as a cache key, I do however have a key class that contains final boolean field. Should I change it to java.lang.Boolean to make it work? Also does this problem apply to all primitive types?
Thanks, Olaf
|
|
|
07/12/2011 14:00:14
|
olafos
neo
Joined: 07/12/2011 06:46:47
Messages: 4
Offline
|
Ok sorry Tim I misunderstood you.. You're talking about having boolean class object as a cache key and not a boolean. My key class looks like this:
Code:
public static class Key implements Serializable {
private static final long serialVersionUID = 1329312650381461450L;
private final String name;
private final Class<?> klass;
private final boolean collection;
public Key(final String name, final Class<?> klass) {
this(name, klass, false);
}
public Key(final String name, final Class<?> klass, final boolean collection) {
super();
this.name = name;
this.klass = klass;
this.collection = collection;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof Key)) {
return false;
}
final Key rhs = (Key) obj;
return new EqualsBuilder().append(this.name, rhs.name).append(this.klass, rhs.klass).append(this.collection, rhs.collection).isEquals();
}
public Class<?> getKlass() {
return this.klass;
}
public String getName() {
return this.name;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(this.name).append(this.klass).append(this.collection).toHashCode();
}
public boolean isCollection() {
return this.collection;
}
}
so I guess the problem occurs when we put boolean.class in 'klass' field. If this is a known bug then I'll just make sure to put Boolean.class there instead of boolean.class as a workaround.
Thanks, Olaf
|
|
|
07/12/2011 14:53:25
|
teck
seraphim
Joined: 05/24/2006 15:03:25
Messages: 1128
Offline
|
Well I actually didn't ask the question correctly. What I really mean to ask is whether you had an instance of "boolean.class" and/or java.lang.Boolean.TYPE in the object graph of your cache key. From the example Key class posted it looks like that is at least a possibility. Avoiding the java.lang.Class instances that represent the java primitives (ie. Boolean.TYPE, Integer.TYPE, etc) should avoid this bug.
I don't know if swapping java.lang.Boolean.TYPE for java.lang.Boolean.class is a valid thing to do in your particular application. It will avoid the bug though
hope this helps
|
Tim Eck (terracotta engineer)
|
|
|
07/12/2011 15:08:05
|
teck
seraphim
Joined: 05/24/2006 15:03:25
Messages: 1128
Offline
|
I entered this a bug for good measure
https://jira.terracotta.org/jira/browse/CDV-1589
|
Tim Eck (terracotta engineer)
|
|
|
07/13/2011 01:59:16
|
olafos
neo
Joined: 07/12/2011 06:46:47
Messages: 4
Offline
|
Tim,
Indeed switching from boolean.class to Boolean.class when creating cache keys fixed the problem.
Thank you for your help,
Olaf
|
|
|
|