Index: src/test/org/apache/lucene/index/TestNRTReaderWithThreads.java =================================================================== --- src/test/org/apache/lucene/index/TestNRTReaderWithThreads.java (revision 912337) +++ src/test/org/apache/lucene/index/TestNRTReaderWithThreads.java (working copy) @@ -54,13 +54,16 @@ int addCount = 0; for (int x=0; x < indexThreads.length; x++) { indexThreads[x].run = false; - assertTrue(indexThreads[x].ex == null); + assertNull("Exception thrown: "+indexThreads[x].ex, indexThreads[x].ex); addCount += indexThreads[x].addCount; delCount += indexThreads[x].delCount; } for (int x=0; x < indexThreads.length; x++) { indexThreads[x].join(); } + for (int x=0; x < indexThreads.length; x++) { + assertNull("Exception thrown: "+indexThreads[x].ex, indexThreads[x].ex); + } //System.out.println("addCount:"+addCount); //System.out.println("delCount:"+delCount); writer.close(); @@ -69,8 +72,8 @@ public class RunThread extends Thread { IndexWriter writer; - boolean run = true; - Throwable ex; + volatile boolean run = true; + volatile Throwable ex; int delCount = 0; int addCount = 0; int type; Index: src/test/org/apache/lucene/util/LuceneTestCase.java =================================================================== --- src/test/org/apache/lucene/util/LuceneTestCase.java (revision 912337) +++ src/test/org/apache/lucene/util/LuceneTestCase.java (working copy) @@ -21,6 +21,9 @@ import java.util.Arrays; import java.util.Iterator; import java.util.Random; +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; import junit.framework.TestCase; @@ -57,6 +60,19 @@ public static final Version TEST_VERSION_CURRENT = LuceneTestCaseJ4.TEST_VERSION_CURRENT; private int savedBoolMaxClauseCount; + + private volatile Thread.UncaughtExceptionHandler savedUncaughtExceptionHandler = null; + + private static class UncaughtExceptionEntry { + public final Thread thread; + public final Throwable exception; + + public UncaughtExceptionEntry(Thread thread, Throwable exception) { + this.thread = thread; + this.exception = exception; + } + } + private List uncaughtExceptions = Collections.synchronizedList(new ArrayList()); public LuceneTestCase() { super(); @@ -69,6 +85,16 @@ @Override protected void setUp() throws Exception { super.setUp(); + + savedUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + uncaughtExceptions.add(new UncaughtExceptionEntry(t, e)); + if (savedUncaughtExceptionHandler != null) + savedUncaughtExceptionHandler.uncaughtException(t, e); + } + }); + ConcurrentMergeScheduler.setTestMode(); savedBoolMaxClauseCount = BooleanQuery.getMaxClauseCount(); } @@ -111,6 +137,16 @@ purgeFieldCache(FieldCache.DEFAULT); } + Thread.setDefaultUncaughtExceptionHandler(savedUncaughtExceptionHandler); + if (!uncaughtExceptions.isEmpty()) { + System.err.println("The following exceptions were thrown by threads:"); + for (UncaughtExceptionEntry entry : uncaughtExceptions) { + System.err.println("*** Thread: " + entry.thread.getName() + " ***"); + entry.exception.printStackTrace(System.err); + } + fail("Some threads throwed uncaught exceptions!"); + } + super.tearDown(); } Index: src/test/org/apache/lucene/util/LuceneTestCaseJ4.java =================================================================== --- src/test/org/apache/lucene/util/LuceneTestCaseJ4.java (revision 912337) +++ src/test/org/apache/lucene/util/LuceneTestCaseJ4.java (working copy) @@ -31,6 +31,9 @@ import java.util.Arrays; import java.util.Iterator; import java.util.Random; +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -79,6 +82,19 @@ private int savedBoolMaxClauseCount; + private volatile Thread.UncaughtExceptionHandler savedUncaughtExceptionHandler = null; + + private static class UncaughtExceptionEntry { + public final Thread thread; + public final Throwable exception; + + public UncaughtExceptionEntry(Thread thread, Throwable exception) { + this.thread = thread; + this.exception = exception; + } + } + private List uncaughtExceptions = Collections.synchronizedList(new ArrayList()); + // This is how we get control when errors occur. // Think of this as start/end/success/failed // events. @@ -94,6 +110,15 @@ @Before public void setUp() throws Exception { + savedUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + uncaughtExceptions.add(new UncaughtExceptionEntry(t, e)); + if (savedUncaughtExceptionHandler != null) + savedUncaughtExceptionHandler.uncaughtException(t, e); + } + }); + ConcurrentMergeScheduler.setTestMode(); savedBoolMaxClauseCount = BooleanQuery.getMaxClauseCount(); seed = null; @@ -138,6 +163,16 @@ } finally { purgeFieldCache(FieldCache.DEFAULT); } + + Thread.setDefaultUncaughtExceptionHandler(savedUncaughtExceptionHandler); + if (!uncaughtExceptions.isEmpty()) { + System.err.println("The following exceptions were thrown by threads:"); + for (UncaughtExceptionEntry entry : uncaughtExceptions) { + System.err.println("*** Thread: " + entry.thread.getName() + " ***"); + entry.exception.printStackTrace(System.err); + } + fail("Some threads throwed uncaught exceptions!"); + } } /**