You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by tc...@apache.org on 2005/08/11 01:33:48 UTC
svn commit: r231354 - in /jakarta/commons/sandbox/jci/trunk/src:
java/org/apache/commons/jci/ReloadingClassLoader.java
java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
test/org/apache/commons/jci/CompilingClassLoaderTestCase.java
Author: tcurdt
Date: Wed Aug 10 16:33:40 2005
New Revision: 231354
URL: http://svn.apache.org/viewcvs?rev=231354&view=rev
Log:
make the reloading classloader stoppable,
properly test the compiling classloader
Modified:
jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/ReloadingClassLoader.java
jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
jakarta/commons/sandbox/jci/trunk/src/test/org/apache/commons/jci/CompilingClassLoaderTestCase.java
Modified: jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/ReloadingClassLoader.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/ReloadingClassLoader.java?rev=231354&r1=231353&r2=231354&view=diff
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/ReloadingClassLoader.java (original)
+++ jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/ReloadingClassLoader.java Wed Aug 10 16:33:40 2005
@@ -45,8 +45,8 @@
private final ClassLoader parent;
private final ResourceStore store;
private final FilesystemAlterationMonitor fam;
- private final Thread thread;
private final Collection reloadingListeners = new HashSet();
+ private Thread thread;
private ClassLoader delegate;
protected final ResourceReader reader;
@@ -68,16 +68,23 @@
fam = new FilesystemAlterationMonitor();
fam.addListener(createListener(repository), repository);
- thread = new Thread(fam);
-
delegate = new ResourceStoreClassLoader(parent, store);
}
public void start() {
+ thread = new Thread(fam);
thread.start();
reload();
}
+ public void stop() {
+ fam.stop();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ ;
+ }
+ }
protected FilesystemAlterationListener createListener(final File pRepository) {
return new FilesystemAlterationListener() {
Modified: jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java?rev=231354&r1=231353&r2=231354&view=diff
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java (original)
+++ jakarta/commons/sandbox/jci/trunk/src/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java Wed Aug 10 16:33:40 2005
@@ -53,7 +53,8 @@
public boolean hasChanged() {
- return file.lastModified() != lastModified;
+ final long modified = file.lastModified();
+ return modified != lastModified;
}
@@ -143,16 +144,19 @@
private Map directories = new MultiHashMap();
private Map entries = new HashMap();
- private final Object mutex = new Object();
+ private final Object mutexListeners = new Object();
+ private final Object mutexRunning = new Object();
private long delay = 3000;
- private volatile boolean running = true;
+ private boolean running = true;
public FilesystemAlterationMonitor() {
}
public void stop() {
- running = false;
+ synchronized(mutexRunning) {
+ running = false;
+ }
}
public void setInterval( final long pDelay ) {
@@ -161,7 +165,7 @@
public void addListener( final FilesystemAlterationListener listener, final File directory ) {
- synchronized (mutex) {
+ synchronized (mutexListeners) {
// listerner -> dir1, dir2, dir3
final MultiHashMap newListeners = new MultiHashMap(listeners);
@@ -177,7 +181,7 @@
public void removeListener( final FilesystemAlterationListener listener ) {
- synchronized (mutex) {
+ synchronized (mutexListeners) {
// listerner -> dir1, dir2, dir3
final MultiHashMap newListeners = new MultiHashMap(listeners);
Collection d = (Collection) newListeners.remove(listener);
@@ -199,7 +203,7 @@
log.debug("start checking " + root);
Map directories;
- synchronized(mutex) {
+ synchronized(mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
@@ -216,7 +220,7 @@
log.debug("stop checking " + root);
Map directories;
- synchronized(mutex) {
+ synchronized(mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
@@ -234,7 +238,7 @@
log.debug("created " + ((entry.isDirectory())?"dir ":"file ") + entry);
Map directories;
- synchronized(mutex) {
+ synchronized(mutexListeners) {
directories = this.directories;
}
@@ -262,7 +266,7 @@
log.debug("changed " + ((entry.isDirectory())?"dir ":"file ") + entry);
Map directories;
- synchronized(mutex) {
+ synchronized(mutexListeners) {
directories = this.directories;
}
@@ -290,7 +294,7 @@
log.debug("deleted " + ((entry.isDirectory())?"dir ":"file ") + entry);
Map directories;
- synchronized(mutex) {
+ synchronized(mutexListeners) {
directories = this.directories;
}
@@ -314,6 +318,8 @@
private void check( final File root, final Entry entry, final boolean create ) {
+ log.debug("checking " + entry);
+
if (entry.isDirectory()) {
final Entry[] currentChilds = entry.getChilds();
if (entry.hasChanged() || create) {
@@ -362,10 +368,18 @@
public void run() {
log.info("fam running");
- while (running) {
+
+ while (true) {
+
+ synchronized(mutexRunning) {
+ if (!running) {
+ break;
+ }
+ }
+
Map directories;
- synchronized (mutex) {
+ synchronized (mutexListeners) {
directories = this.directories;
}
@@ -375,7 +389,7 @@
onStart(directory);
Entry root;
- synchronized (mutex) {
+ synchronized (mutexListeners) {
root = (Entry)entries.get(directory);
if (root == null) {
root = new Entry(directory, directory);
@@ -393,6 +407,7 @@
} catch (InterruptedException e) {
}
}
+
log.info("fam exiting");
}
}
Modified: jakarta/commons/sandbox/jci/trunk/src/test/org/apache/commons/jci/CompilingClassLoaderTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/jci/trunk/src/test/org/apache/commons/jci/CompilingClassLoaderTestCase.java?rev=231354&r1=231353&r2=231354&view=diff
==============================================================================
--- jakarta/commons/sandbox/jci/trunk/src/test/org/apache/commons/jci/CompilingClassLoaderTestCase.java (original)
+++ jakarta/commons/sandbox/jci/trunk/src/test/org/apache/commons/jci/CompilingClassLoaderTestCase.java Wed Aug 10 16:33:40 2005
@@ -3,66 +3,94 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import junit.framework.TestCase;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import junit.framework.TestCase;
public final class CompilingClassLoaderTestCase extends TestCase {
private final static Log log = LogFactory.getLog(CompilingClassLoaderTestCase.class);
+ private final Object signal = new Object();
+
private CompilingClassLoader cl;
private ReloadingListener listener;
private File repository;
- private boolean reloaded; //FIXME
- protected void setUp() throws Exception {
+ private boolean reloaded;
+ private void waitForReload() {
+ log.debug("waiting for reload signal");
+ int i = 0;
+ while(true) {
+ synchronized(signal) {
+ if (!reloaded) {
+ try {
+ signal.wait(1000);
+ } catch (InterruptedException e) {
+ ;
+ }
+ if (++i > 7) {
+ fail("timeout");
+ }
+ } else {
+ reloaded = false;
+ break;
+ }
+ }
+ }
- repository = createTempDirectory();
+ log.debug("caught reload signal");
+ }
+
+ protected void setUp() throws Exception {
+ repository = createTempDirectory();
assertTrue(repository.exists());
assertTrue(repository.isDirectory());
listener = new ReloadingListener() {
public void reload() {
- log.debug("notifying about the reload");
- reloaded = true; //FIXME
+ synchronized(signal) {
+ reloaded = true;
+ signal.notify();
+ }
}
};
cl = new CompilingClassLoader(this.getClass().getClassLoader(), repository);
cl.addListener(listener);
cl.start();
-
- Thread.sleep(1000);
-
- reloaded = false;
}
-
- public void testCreateCompilation() throws Exception {
- log.debug("creating java files");
-
+ private void initialCompile() throws Exception {
+
+ waitForReload();
+
writeFile(new File(repository, "jci/Simple.java"),
- "package jci;\n"
+ "package jci;\n"
+ "public class Simple { \n"
+ " public String toString() { \n"
+ " return \"Simple\"; \n"
+ " } \n"
+ "} \n"
- );
-
+ );
+
writeFile(new File(repository, "jci/Extended.java"),
"package jci;\n"
- + "public class Extended extends Simple { \n"
- + " public String toString() { \n"
- + " return \"Extended:\" + super.toString(); \n"
- + " } \n"
- + "} \n"
- );
+ + "public class Extended extends Simple { \n"
+ + " public String toString() { \n"
+ + " return \"Extended:\" + super.toString(); \n"
+ + " } \n"
+ + "} \n"
+ );
- Thread.sleep(4000);
+ waitForReload();
+ }
+
+
+ public void testCreate() throws Exception {
+ initialCompile();
Object o;
@@ -73,14 +101,88 @@
assertTrue("Extended:Simple".equals(o.toString()));
}
- public void testChangeCompilation() {
+ public void testChange() throws Exception {
+ initialCompile();
+
+ Object o;
+
+ o = cl.loadClass("jci.Simple").newInstance();
+ assertTrue("Simple".equals(o.toString()));
+
+ o = cl.loadClass("jci.Extended").newInstance();
+ assertTrue("Extended:Simple".equals(o.toString()));
+
+ writeFile(new File(repository, "jci/Simple.java"),
+ "package jci;\n"
+ + "public class Simple { \n"
+ + " public String toString() { \n"
+ + " return \"SIMPLE\"; \n"
+ + " } \n"
+ + "} \n"
+ );
+
+ waitForReload();
+
+ o = cl.loadClass("jci.Simple").newInstance();
+ assertTrue("SIMPLE".equals(o.toString()));
+
+ o = cl.loadClass("jci.Extended").newInstance();
+ assertTrue("Extended:SIMPLE".equals(o.toString()));
}
- public void testDeleteCompilation() {
+ public void testDelete() throws Exception {
+ initialCompile();
+
+ Object o;
+
+ o = cl.loadClass("jci.Simple").newInstance();
+ assertTrue("Simple".equals(o.toString()));
+
+ o = cl.loadClass("jci.Extended").newInstance();
+ assertTrue("Extended:Simple".equals(o.toString()));
+
+ assertTrue(new File(repository, "jci/Extended.java").delete());
+
+ waitForReload();
+
+ o = cl.loadClass("jci.Simple").newInstance();
+ assertTrue("Simple".equals(o.toString()));
+
+ try {
+ o = cl.loadClass("jci.Extended").newInstance();
+ fail();
+ } catch(final ClassNotFoundException e) {
+ assertTrue("jci.Extended".equals(e.getMessage()));
+ }
+
}
+ public void testDeleteDependency() throws Exception {
+ initialCompile();
+
+ Object o;
+
+ o = cl.loadClass("jci.Simple").newInstance();
+ assertTrue("Simple".equals(o.toString()));
+
+ o = cl.loadClass("jci.Extended").newInstance();
+ assertTrue("Extended:Simple".equals(o.toString()));
+
+ assertTrue(new File(repository, "jci/Simple.java").delete());
+
+ waitForReload();
+
+ try {
+ o = cl.loadClass("jci.Extended").newInstance();
+ fail();
+ } catch(final NoClassDefFoundError e) {
+ assertTrue("jci/Simple".equals(e.getMessage()));
+ }
+
+ }
protected void tearDown() throws Exception {
+ cl.stop();
FileUtils.deleteDirectory(repository);
}
@@ -91,10 +193,13 @@
if (!parent.mkdirs()) {
throw new IOException("could not create" + parent);
}
+ log.debug("created directory " + parent.getAbsolutePath());
}
final FileWriter writer = new FileWriter(pFile);
writer.write(pText);
writer.close();
+
+ assertTrue(pFile.exists());
}
private static File createTempDirectory() throws IOException {
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org