[jboss-cvs] JBossCache/tests/functional/org/jboss/cache/pojo/memory ...
Ben Wang
bwang at jboss.com
Sat Jan 13 10:55:09 EST 2007
User: bwang
Date: 07/01/13 10:55:09
Added: tests/functional/org/jboss/cache/pojo/memory
SelectedClassnameClassLoader.java
ReplicatedTest.java
Log:
JBCACHE-922 Merged src-50 and tests-50 into src and tests, respectively.
Revision Changes Path
1.1 date: 2007/01/13 15:55:09; author: bwang; state: Exp;JBossCache/tests/functional/org/jboss/cache/pojo/memory/SelectedClassnameClassLoader.java
Index: SelectedClassnameClassLoader.java
===================================================================
package org.jboss.cache.pojo.memory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
/**
* A ClassLoader that loads classes whose classname begins with one of a
* given set of strings, without attempting first to delegate to its
* parent loader.
* <p/>
* This class is intended to allow emulation of 2 different types of common J2EE
* classloading situations.
* <ul>
* <li>Servlet-style child-first classloading, where this class is the
* child loader.</li>
* <li>Parent-first classloading where the parent does not have access to
* certain classes</li>
* </ul>
* </p>
* <p/>
* This class can also be configured to raise a ClassNotFoundException if
* asked to load certain classes, thus allowing classes on the classpath
* to be hidden from a test environment.
* </p>
*
* @author Brian Stansberry
*/
public class SelectedClassnameClassLoader extends ClassLoader
{
private String[] includedClasses = null;
private String[] excludedClasses = null;
private String[] notFoundClasses = null;
private Log log = LogFactory.getLog(SelectedClassnameClassLoader.class);
private Map classes = new java.util.HashMap();
/**
* Creates a new classloader that loads the given classes.
*
* @param includedClasses array of class or package names that should be
* directly loaded by this loader. Classes
* whose name starts with any of the strings
* in this array will be loaded by this class,
* unless their name appears in
* <code>excludedClasses</code>.
* Can be <code>null</code>
* @param excludedClasses array of class or package names that should NOT
* be directly loaded by this loader. Loading of
* classes whose name starts with any of the
* strings in this array will be delegated to
* <code>parent</code>, even if the classes
* package or classname appears in
* <code>includedClasses</code>. Typically this
* parameter is used to exclude loading one or
* more classes in a package whose other classes
* are loaded by this object.
* @param parent ClassLoader to which loading of classes should
* be delegated if necessary
*/
public SelectedClassnameClassLoader(String[] includedClasses,
String[] excludedClasses,
ClassLoader parent)
{
super(parent);
this.includedClasses = includedClasses;
this.excludedClasses = excludedClasses;
}
/**
* Creates a new classloader that loads the given classes.
*
* @param includedClasses array of class or package names that should be
* directly loaded by this loader. Classes
* whose name starts with any of the strings
* in this array will be loaded by this class,
* unless their name appears in
* <code>excludedClasses</code>.
* Can be <code>null</code>
* @param excludedClasses array of class or package names that should NOT
* be directly loaded by this loader. Loading of
* classes whose name starts with any of the
* strings in this array will be delegated to
* <code>parent</code>, even if the classes
* package or classname appears in
* <code>includedClasses</code>. Typically this
* parameter is used to exclude loading one or
* more classes in a package whose other classes
* are loaded by this object.
* @param notFoundClasses array of class or package names for which this
* should raise a ClassNotFoundException
* @param parent ClassLoader to which loading of classes should
* be delegated if necessary
*/
public SelectedClassnameClassLoader(String[] includedClasses,
String[] excludedClasses,
String[] notFoundClasses,
ClassLoader parent)
{
super(parent);
this.includedClasses = includedClasses;
this.excludedClasses = excludedClasses;
this.notFoundClasses = notFoundClasses;
}
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
log.info("In SelectedClassnameClassLoader.loadClass(" + name + "," + resolve + ")");
if (isIncluded(name) && (isExcluded(name) == false))
{
Class c = findClass(name);
if (resolve)
{
resolveClass(c);
}
return c;
} else
{
return super.loadClass(name, resolve);
}
}
protected Class findClass(String name) throws ClassNotFoundException
{
log.info("In SelectedClassnameClassLoader.findClass()");
Class result = (Class) classes.get(name);
if (result != null)
{
return result;
}
if (isIncluded(name) && (isExcluded(name) == false))
{
try
{
InputStream is = getResourceAsStream(name.replace('.', '/').concat(".class"));
byte[] bytes = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
int read;
while ((read = is.read(bytes)) > -1)
{
baos.write(bytes, 0, read);
}
bytes = baos.toByteArray();
result = this.defineClass(name, bytes, 0, bytes.length);
} catch (FileNotFoundException e)
{
throw new ClassNotFoundException("cannot find " + name, e);
} catch (IOException e)
{
throw new ClassNotFoundException("cannot read " + name, e);
}
} else if (isNotFound(name))
{
throw new ClassNotFoundException(name + " is discarded");
} else
{
result = super.findClass(name);
}
classes.put(name, result);
return result;
}
private boolean isIncluded(String className)
{
if (includedClasses != null)
{
for (int i = 0; i < includedClasses.length; i++)
{
if (className.startsWith(includedClasses[i]))
{
return true;
}
}
}
return false;
}
private boolean isExcluded(String className)
{
if (excludedClasses != null)
{
for (int i = 0; i < excludedClasses.length; i++)
{
if (className.startsWith(excludedClasses[i]))
{
return true;
}
}
}
return false;
}
private boolean isNotFound(String className)
{
if (notFoundClasses != null)
{
for (int i = 0; i < notFoundClasses.length; i++)
{
if (className.startsWith(notFoundClasses[i]))
{
return true;
}
}
}
return false;
}
}
1.1 date: 2007/01/13 15:55:09; author: bwang; state: Exp;JBossCache/tests/functional/org/jboss/cache/pojo/memory/ReplicatedTest.java
Index: ReplicatedTest.java
===================================================================
/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.pojo.memory;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.factories.UnitTestCacheFactory;
import org.jboss.cache.pojo.PojoCache;
import org.jboss.cache.pojo.PojoCacheFactory;
import org.jboss.cache.pojo.TestingUtil;
import org.jboss.cache.pojo.test.Address;
import org.jboss.cache.pojo.test.Person;
import org.jboss.cache.pojo.test.SerializedAddress;
import org.jboss.cache.Fqn;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
* @author Ben Wang
*/
public class ReplicatedTest extends TestCase
{
Log log_ = LogFactory.getLog(ReplicatedTest.class);
PojoCache cache_;
PojoCache cache1_;
public ReplicatedTest(String name)
{
super(name);
}
protected void setUp() throws Exception
{
super.setUp();
boolean toStart = false;
cache_ = PojoCacheFactory.createCache(UnitTestCacheFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
cache_.start();
cache1_ = PojoCacheFactory.createCache(UnitTestCacheFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
cache1_.start();
}
protected void tearDown() throws Exception
{
super.tearDown();
cache_.stop();
cache1_.stop();
}
// public void testDummy() {}
/**
* Test replication with classloaders.
*
* @throws Exception
*/
public void testCLLeakageBasic() throws Exception
{
SerializedAddress add = new SerializedAddress();
add.setCity("Taipei");
ClassLoader cla = getClassLoader();
WeakReference refa = new WeakReference(cla);
cache_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(cla);
ClassLoader clb = getClassLoader();
WeakReference refb = new WeakReference(clb);
cache_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(clb);
Fqn fqn = new Fqn("/aop");
cache_.getCache().put(new Fqn("/aop"), "add", add);
TestingUtil.sleepThread(100);
try
{
Object ben = cache1_.getCache().get(fqn, "add");
assertEquals(add.toString(), ben.toString());
ben = null;
} catch (Exception ex)
{
fail("Test fails with exception " + ex);
}
cache_.getCache().remove(fqn, "add");
ClassLoader clc = getClassLoader();
cla = null;
clb = null;
cache_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(clc);
cache1_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(clc);
System.gc(); // force gc
Thread.sleep(1000);
assertNull("Classloader should be gced ", refa.get());
assertNull("Classloader should be gced ", refb.get());
}
private static void forceOutOfMemoryError() throws Exception
{
ArrayList list = new ArrayList();
try
{
long i = 0;
while (true)
{
list.add("BigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBigBig" + (i++));
}
}
catch (Throwable ignored)
{
}
list.clear();
list = null;
System.gc();
Thread.sleep(1000);
}
/**
* Test replication with classloaders.
*
* @throws Exception
*/
public void testCLLeakage() throws Exception
{
Person p = new Person();
p.setName("Ben");
Address add = new Address();
add.setCity("Taipei");
ClassLoader cla = getClassLoader();
WeakReference refa = new WeakReference(cla);
cache_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(cla);
ClassLoader clb = getClassLoader();
cache1_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(clb);
WeakReference refb = new WeakReference(clb);
cache_.attach("/aop", p);
TestingUtil.sleepThread(100);
try
{
Object ben = cache1_.find("/aop");
assertEquals(p.toString(), ben.toString());
ben = null;
} catch (Exception ex)
{
fail("Test fails with exception " + ex);
}
cache_.detach("/aop");
ClassLoader clc = getClassLoader();
cache_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(clc);
cache1_.getCache().getRegion(new Fqn("/aop"), true).registerContextClassLoader(clc);
cla = null;
clb = null;
forceOutOfMemoryError();
assertNull("Classloader should be gced ", refa.get());
assertNull("Classloader should be gced ", refb.get());
}
protected ClassLoader getClassLoader() throws Exception
{
String[] includesClasses = {"org.jboss.cache.aop.test.Person",
"org.jboss.cache.aop.test.Address"};
String [] excludesClasses = {};
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return new SelectedClassnameClassLoader(includesClasses, excludesClasses, cl);
}
public static Test suite() throws Exception
{
return new TestSuite(ReplicatedTest.class);
}
public static void main(String[] args) throws Exception
{
junit.textui.TestRunner.run(ReplicatedTest.suite());
}
}
More information about the jboss-cvs-commits
mailing list