[jbosscache-commits] JBoss Cache SVN: r5323 - in core/trunk/src: main/java/org/jboss/cache/marshall and 1 other directories.
jbosscache-commits at lists.jboss.org
jbosscache-commits at lists.jboss.org
Thu Feb 7 10:03:42 EST 2008
Author: manik.surtani at jboss.com
Date: 2008-02-07 10:03:42 -0500 (Thu, 07 Feb 2008)
New Revision: 5323
Added:
core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingJDBCTest.java
Modified:
core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderConfig.java
core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java
Log:
JBCACHE-1287 - CacheLoader load operations cannot deserialize types not visible to cache
Modified: core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java 2008-02-07 14:14:03 UTC (rev 5322)
+++ core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java 2008-02-07 15:03:42 UTC (rev 5323)
@@ -12,6 +12,7 @@
import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.Modification;
+import org.jboss.cache.Region;
import org.jboss.cache.RegionManager;
import org.jboss.cache.buddyreplication.BuddyManager;
import org.jboss.cache.marshall.Marshaller;
@@ -173,6 +174,69 @@
this.regionManager = regionManager;
}
+ protected void regionAwareMarshall(Fqn fqn, Object toMarshall) throws Exception
+ {
+ Region r = regionManager == null ? null : regionManager.getRegion(fqn, Region.Type.MARSHALLING, false);
+ ClassLoader originalClassLoader = null;
+ boolean needToResetLoader = false;
+ Thread current = null;
+
+ if (r != null)
+ {
+ // set the region's class loader as the thread's context classloader
+ needToResetLoader = true;
+ current = Thread.currentThread();
+ originalClassLoader = current.getContextClassLoader();
+ current.setContextClassLoader(r.getClassLoader());
+ }
+
+ try
+ {
+ doMarshall(fqn, toMarshall);
+ }
+ finally
+ {
+ if (needToResetLoader) current.setContextClassLoader(originalClassLoader);
+ }
+ }
+
+ protected Object regionAwareUnmarshall(Fqn fqn, Object toUnmarshall) throws Exception
+ {
+ Region r = regionManager == null ? null : regionManager.getRegion(fqn, Region.Type.MARSHALLING, false);
+ ClassLoader originalClassLoader = null;
+ boolean needToResetLoader = false;
+ Thread current = null;
+
+ if (r != null)
+ {
+ // set the region's class loader as the thread's context classloader
+ needToResetLoader = true;
+ current = Thread.currentThread();
+ originalClassLoader = current.getContextClassLoader();
+ current.setContextClassLoader(r.getClassLoader());
+ }
+
+ try
+ {
+ return doUnmarshall(fqn, toUnmarshall);
+ }
+ finally
+ {
+ if (needToResetLoader) current.setContextClassLoader(originalClassLoader);
+ }
+ }
+
+ protected void doMarshall(Fqn fqn, Object toMarshall) throws Exception
+ {
+ throw new RuntimeException("Should be overridden");
+ }
+
+ protected Object doUnmarshall(Fqn fqn, Object toUnmarshall) throws Exception
+ {
+ throw new RuntimeException("Should be overridden");
+ }
+
+
/**
* Do a preorder traversal: visit the node first, then the node's children
*
Modified: core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java 2008-02-07 14:14:03 UTC (rev 5322)
+++ core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java 2008-02-07 15:03:42 UTC (rev 5323)
@@ -422,7 +422,8 @@
Map m = null;
try
{
- m = (Map) unmarshall(child);
+ //m = (Map) unmarshall(child);
+ m = (Map) regionAwareUnmarshall(fqn, child);
}
catch (FileNotFoundException fnfe)
{
@@ -434,6 +435,13 @@
protected void storeAttributes(Fqn fqn, Map attrs) throws Exception
{
+ regionAwareMarshall(fqn, attrs);
+ }
+
+ @Override
+ protected void doMarshall(Fqn fqn, Object toMarshall) throws Exception
+ {
+ Map attrs = (Map) toMarshall;
File f = getDirectory(fqn, true);
File child = new File(f, DATA);
if (!child.exists())
@@ -451,10 +459,23 @@
throw new IOException("Unable to create file: " + child);
}
}
+ FileOutputStream fileOut = new FileOutputStream(child);
+ ObjectOutputStream output = new ObjectOutputStream(fileOut);
+ getMarshaller().objectToObjectStream(attrs, output);
+ output.close();
+ }
- marshall(attrs, child);
+ @Override
+ protected Object doUnmarshall(Fqn fqn, Object fromFile) throws Exception
+ {
+ FileInputStream fileIn = new FileInputStream((File) fromFile);
+ ObjectInputStream input = new MarshalledValueInputStream(fileIn);
+ Object unmarshalledObj = getMarshaller().objectFromObjectStream(input);
+ input.close();
+ return unmarshalledObj;
}
+
protected boolean isCharacterPortableLocation(String fileAbsolutePath)
{
Matcher matcher = PATH_PATTERN.matcher(fileAbsolutePath);
@@ -498,21 +519,4 @@
return true;
}
-
- protected Object unmarshall(File from) throws Exception
- {
- FileInputStream fileIn = new FileInputStream(from);
- ObjectInputStream input = new MarshalledValueInputStream(fileIn);
- Object unmarshalledObj = getMarshaller().objectFromObjectStream(input);
- input.close();
- return unmarshalledObj;
- }
-
- protected void marshall(Object obj, File to) throws Exception
- {
- FileOutputStream fileOut = new FileOutputStream(to);
- ObjectOutputStream output = new ObjectOutputStream(fileOut);
- getMarshaller().objectToObjectStream(obj, output);
- output.close();
- }
}
Modified: core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderConfig.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderConfig.java 2008-02-07 14:14:03 UTC (rev 5322)
+++ core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderConfig.java 2008-02-07 15:03:42 UTC (rev 5323)
@@ -15,60 +15,65 @@
public class JDBCCacheLoaderConfig extends AdjListJDBCCacheLoaderConfig
{
- private static final long serialVersionUID = -8371846151643130271L;
+ private static final long serialVersionUID = -8371846151643130271L;
- private static final Log log = LogFactory.getLog(JDBCCacheLoaderConfig.class);
+ private static final Log log = LogFactory.getLog(JDBCCacheLoaderConfig.class);
- private String deleteNode;
- private String recursiveChildren;
- private String nodeCountSql;
+ private String deleteNode;
+ private String recursiveChildren;
+ private String nodeCountSql;
- public JDBCCacheLoaderConfig(IndividualCacheLoaderConfig base)
- {
+ public JDBCCacheLoaderConfig(IndividualCacheLoaderConfig base)
+ {
super(base);
setClassName(JDBCCacheLoader.class.getName());
- }
+ }
+ public JDBCCacheLoaderConfig()
+ {
+ setClassName(JDBCCacheLoader.class.getName());
+ }
- public void setProperties(Properties props)
- {
- super.setProperties(props);
- String sqlConcat = props.getProperty("cache.jdbc.sql-concat");
- if (sqlConcat == null) {
- log.info("Missiing JDBCCacheLoader config 'cache.jdbc.sql-concat', using default value:'concat(1,2)'");
- sqlConcat = "concat(1,2)";
- }
- String startingWith = sqlConcat.replace('1', '?').replace("2", "'%'"); //concat(?, '%')
- String appendSepparator = sqlConcat.replace("1", fqnColumn).replace("2", "'/'"); //concat(fqnColumn, '/')
- deleteNode = "delete from " + table + " where " + appendSepparator + " like " + startingWith;
- recursiveChildren = "select " + fqnColumn + "," + nodeColumn + " from " + table + " where " + appendSepparator + " like " + startingWith;
- nodeCountSql = "select count(*) from " + table;
- }
+ public void setProperties(Properties props)
+ {
+ super.setProperties(props);
+ String sqlConcat = props.getProperty("cache.jdbc.sql-concat");
+ if (sqlConcat == null)
+ {
+ log.info("Missiing JDBCCacheLoader config 'cache.jdbc.sql-concat', using default value:'concat(1,2)'");
+ sqlConcat = "concat(1,2)";
+ }
+ String startingWith = sqlConcat.replace('1', '?').replace("2", "'%'"); //concat(?, '%')
+ String appendSepparator = sqlConcat.replace("1", fqnColumn).replace("2", "'/'"); //concat(fqnColumn, '/')
+ deleteNode = "delete from " + table + " where " + appendSepparator + " like " + startingWith;
+ recursiveChildren = "select " + fqnColumn + "," + nodeColumn + " from " + table + " where " + appendSepparator + " like " + startingWith;
+ nodeCountSql = "select count(*) from " + table;
+ }
- /**
- * Returns the sql string for removing a node and all its children.
- */
- public String getDeleteNodeSql()
- {
- return deleteNode;
- }
+ /**
+ * Returns the sql string for removing a node and all its children.
+ */
+ public String getDeleteNodeSql()
+ {
+ return deleteNode;
+ }
- /**
- * Returns an sql that will return a node and all its children.
- */
- public String getRecursiveChildrenSql()
- {
- return recursiveChildren;
- }
+ /**
+ * Returns an sql that will return a node and all its children.
+ */
+ public String getRecursiveChildrenSql()
+ {
+ return recursiveChildren;
+ }
- /**
- * Returns an sql that will count all the persisted node.
- */
- public String getNodeCountSql()
- {
- return nodeCountSql;
- }
+ /**
+ * Returns an sql that will count all the persisted node.
+ */
+ public String getNodeCountSql()
+ {
+ return nodeCountSql;
+ }
}
Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java 2008-02-07 14:14:03 UTC (rev 5322)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java 2008-02-07 15:03:42 UTC (rev 5323)
@@ -529,12 +529,13 @@
ClassLoader old = currentThread.getContextClassLoader();
try
{
- currentThread.setContextClassLoader(loader);
+ // only do this if we haven't already set a context class loader elsewhere.
+ if (old == null) currentThread.setContextClassLoader(loader);
return unmarshallObject(in, refMap);
}
finally
{
- currentThread.setContextClassLoader(old);
+ if (old == null) currentThread.setContextClassLoader(null);
}
}
}
Copied: core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingJDBCTest.java (from rev 5322, core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingJDBCTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingJDBCTest.java 2008-02-07 15:03:42 UTC (rev 5323)
@@ -0,0 +1,153 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Region;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.jboss.cache.eviction.LRUConfiguration;
+import org.jboss.cache.eviction.LRUPolicy;
+import org.jboss.cache.loader.JDBCCacheLoaderConfig;
+import org.jboss.cache.misc.TestingUtil;
+import static org.testng.AssertJUnit.assertEquals;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Tests marshalling/unmarshalling during cache loader operations involving types
+ * not visible to the cache's default classloader.
+ *
+ * @author <a href="mailto:brian.stansberry at jboss.org">Brian Stansberry</a>
+ * @since 2.1.0
+ */
+ at Test(groups = "functional")
+public class CacheLoaderMarshallingJDBCTest extends RegionBasedMarshallingTestBase
+{
+ private static final String className = "org.jboss.cache.marshall.MyUUID";
+
+ private Cache<Object, Object> cache;
+ private Fqn fqn = Fqn.fromString("/a");
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp() throws Exception
+ {
+ originalClassLoader = Thread.currentThread().getContextClassLoader();
+ }
+
+ @AfterMethod(alwaysRun = true)
+ protected void tearDown()
+ {
+ resetContextClassLoader();
+ TestingUtil.killCaches(cache);
+ }
+
+ @Override
+ protected ClassLoader getClassLoader()
+ {
+ String[] includesClasses = {className};
+ String[] excludesClasses = {};
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ return new SelectedClassnameClassLoader(includesClasses, excludesClasses, cl);
+ }
+
+ public void testCacheLoaderMarshalling() throws Exception
+ {
+ cacheLoaderMarshallingTest(false);
+ }
+
+ public void testCacheLoaderRegionBasedMarshalling() throws Exception
+ {
+ cacheLoaderMarshallingTest(true);
+ }
+
+ private void cacheLoaderMarshallingTest(boolean useRegionBased) throws Exception
+ {
+ cache = createCache(useRegionBased);
+ cache.start();
+
+ FooClassLoader loader = new FooClassLoader(originalClassLoader);
+
+ if (useRegionBased)
+ {
+ Region r = cache.getRegion(Fqn.ROOT, true);
+ r.registerContextClassLoader(loader);
+ r.activate();
+ }
+
+ Class clazz = loader.loadFoo();
+ Object obj = clazz.newInstance();
+
+ Thread.currentThread().setContextClassLoader(loader);
+ cache.put(fqn, "key", obj);
+
+ this.resetContextClassLoader();
+ cache.evict(fqn);
+
+ Thread.currentThread().setContextClassLoader(loader);
+ assertEquals(obj, cache.get(fqn, "key"));
+ }
+
+ private Cache createCache(boolean useRegionBased) throws Exception
+ {
+ Properties prop = getProperties();
+
+ // ensure cleanup after each test
+ prop.setProperty("cache.jdbc.table.drop", "true");
+
+ Cache cache = new DefaultCacheFactory<Object, Object>().createCache(false);
+ Configuration config = cache.getConfiguration();
+ config.setUseRegionBasedMarshalling(useRegionBased);
+ config.setInactiveOnStartup(useRegionBased);
+
+ EvictionConfig ec = new EvictionConfig();
+ ec.setDefaultEvictionPolicyClass(LRUPolicy.class.getName());
+ ec.setWakeupIntervalSeconds(1000); // a long time; really disabled
+ EvictionRegionConfig erc = new EvictionRegionConfig();
+ erc.setRegionFqn(Fqn.ROOT);
+ erc.setRegionName("_default_");
+ LRUConfiguration epc = new LRUConfiguration();
+ epc.setMaxNodes(1000);
+ epc.setTimeToLiveSeconds(1000);
+ erc.setEvictionPolicyConfig(epc);
+ List<EvictionRegionConfig> ercs = new ArrayList<EvictionRegionConfig>();
+ ercs.add(erc);
+ ec.setEvictionRegionConfigs(ercs);
+ config.setEvictionConfig(ec);
+
+ CacheLoaderConfig clc = new CacheLoaderConfig();
+ clc.setPassivation(true);
+ clc.setShared(false);
+ JDBCCacheLoaderConfig jdbc_clc = new JDBCCacheLoaderConfig();
+ jdbc_clc.setProperties(prop);
+
+ clc.setIndividualCacheLoaderConfigs(Collections.<IndividualCacheLoaderConfig>singletonList(jdbc_clc));
+ config.setCacheLoaderConfig(clc);
+
+ return cache;
+ }
+
+ private Properties getProperties() throws Exception
+ {
+ Properties properties = new Properties();
+ try
+ {
+ properties.load(this.getClass().getClassLoader().getResourceAsStream("cache-jdbc.properties"));
+ return properties;
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Error loading jdbc properties ", e);
+ }
+ }
+
+}
\ No newline at end of file
Modified: core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java 2008-02-07 14:14:03 UTC (rev 5322)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CacheLoaderMarshallingTest.java 2008-02-07 15:03:42 UTC (rev 5323)
@@ -1,50 +1,49 @@
package org.jboss.cache.marshall;
-import static org.testng.AssertJUnit.assertEquals;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
import org.jboss.cache.Cache;
-import org.jboss.cache.CacheSPI;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Region;
import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.EvictionConfig;
import org.jboss.cache.config.EvictionRegionConfig;
-import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
import org.jboss.cache.eviction.LRUConfiguration;
import org.jboss.cache.eviction.LRUPolicy;
import org.jboss.cache.loader.FileCacheLoaderConfig;
import org.jboss.cache.misc.TestingUtil;
+import static org.testng.AssertJUnit.assertEquals;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
/**
- * Tests marshalling/unmarshalling during cache loader operations involving types
+ * Tests marshalling/unmarshalling during cache loader operations involving types
* not visible to the cache's default classloader.
*
* @author <a href="mailto:brian.stansberry at jboss.org">Brian Stansberry</a>
* @since 2.1.0
*/
- at Test(groups = {"functional", "jgroups"})
+ at Test(groups = "functional")
public class CacheLoaderMarshallingTest extends RegionBasedMarshallingTestBase
{
private static final String tmpDir = System.getProperty("java.io.tmpdir") + File.separatorChar + "CacheLoaderMarshallingTest";
-
+
private static final String className = "org.jboss.cache.marshall.MyUUID";
-
+
private Cache<Object, Object> cache;
private Fqn fqn = Fqn.fromString("/a");
@BeforeMethod(alwaysRun = true)
protected void setUp() throws Exception
{
- originalClassLoader = Thread.currentThread().getContextClassLoader();
+ originalClassLoader = Thread.currentThread().getContextClassLoader();
}
@AfterMethod(alwaysRun = true)
@@ -52,7 +51,7 @@
{
resetContextClassLoader();
TestingUtil.killCaches(cache);
-
+
File f = new File(tmpDir);
if (f.exists())
if (!f.delete())
@@ -67,51 +66,51 @@
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return new SelectedClassnameClassLoader(includesClasses, excludesClasses, cl);
}
-
+
public void testCacheLoaderMarshalling() throws Exception
{
cacheLoaderMarshallingTest(false);
}
-
+
public void testCacheLoaderRegionBasedMarshalling() throws Exception
{
cacheLoaderMarshallingTest(true);
}
-
+
private void cacheLoaderMarshallingTest(boolean useRegionBased) throws Exception
{
cache = createCache(useRegionBased);
cache.start();
-
+
FooClassLoader loader = new FooClassLoader(originalClassLoader);
-
+
if (useRegionBased)
{
Region r = cache.getRegion(Fqn.ROOT, true);
r.registerContextClassLoader(loader);
r.activate();
}
-
+
Class clazz = loader.loadFoo();
Object obj = clazz.newInstance();
-
+
Thread.currentThread().setContextClassLoader(loader);
cache.put(fqn, "key", obj);
-
+
this.resetContextClassLoader();
cache.evict(fqn);
-
+
Thread.currentThread().setContextClassLoader(loader);
assertEquals(obj, cache.get(fqn, "key"));
}
-
+
private Cache createCache(boolean useRegionBased)
{
- Cache cache = (CacheSPI<Object, Object>) new DefaultCacheFactory().createCache(false);
+ Cache cache = new DefaultCacheFactory<Object, Object>().createCache(false);
Configuration config = cache.getConfiguration();
config.setUseRegionBasedMarshalling(useRegionBased);
config.setInactiveOnStartup(useRegionBased);
-
+
EvictionConfig ec = new EvictionConfig();
ec.setDefaultEvictionPolicyClass(LRUPolicy.class.getName());
ec.setWakeupIntervalSeconds(1000); // a long time; really disabled
@@ -126,17 +125,16 @@
ercs.add(erc);
ec.setEvictionRegionConfigs(ercs);
config.setEvictionConfig(ec);
-
+
CacheLoaderConfig clc = new CacheLoaderConfig();
clc.setPassivation(true);
clc.setShared(false);
FileCacheLoaderConfig fclc = new FileCacheLoaderConfig();
fclc.setLocation(tmpDir);
- List<IndividualCacheLoaderConfig> clcs = new ArrayList<IndividualCacheLoaderConfig>();
- clcs.add(fclc);
- clc.setIndividualCacheLoaderConfigs(clcs);
+
+ clc.setIndividualCacheLoaderConfigs(Collections.<IndividualCacheLoaderConfig>singletonList(fclc));
config.setCacheLoaderConfig(clc);
-
+
return cache;
}
More information about the jbosscache-commits
mailing list