You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2020/09/16 14:28:55 UTC

[lucene-solr] branch reference_impl_dev updated: @834 Lifecycle.

This is an automated email from the ASF dual-hosted git repository.

markrmiller pushed a commit to branch reference_impl_dev
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/reference_impl_dev by this push:
     new 6b57846  @834 Lifecycle.
6b57846 is described below

commit 6b57846561128ed3348c404ed049e5013bec74fc
Author: markrmiller@gmail.com <ma...@gmail.com>
AuthorDate: Wed Sep 16 09:28:30 2020 -0500

    @834 Lifecycle.
---
 .../scraper/SolrStandaloneScraperTest.java         |   1 -
 .../org/apache/solr/update/PeerSyncWithLeader.java |   9 +-
 .../embedded/TestEmbeddedSolrServerSchemaAPI.java  |   4 -
 .../test/org/apache/solr/core/TestLazyCores.java   |  30 ++--
 .../search/facet/TestCloudJSONFacetJoinDomain.java |   4 -
 .../org/apache/solr/common/util/CloseTracker.java  |   8 +-
 .../solr/client/solrj/SolrExampleTestsBase.java    | 189 ++++++++++-----------
 .../solrj/io/stream/StreamDecoratorTest.java       |   3 +-
 .../src/java/org/apache/solr/SolrTestCase.java     |  29 ++--
 .../src/java/org/apache/solr/SolrTestCaseJ4.java   |  60 ++++---
 .../src/java/org/apache/solr/util/TestHarness.java |   8 +-
 11 files changed, 176 insertions(+), 169 deletions(-)

diff --git a/solr/contrib/prometheus-exporter/src/test/org/apache/solr/prometheus/scraper/SolrStandaloneScraperTest.java b/solr/contrib/prometheus-exporter/src/test/org/apache/solr/prometheus/scraper/SolrStandaloneScraperTest.java
index 39a23fa..6cb952a 100644
--- a/solr/contrib/prometheus-exporter/src/test/org/apache/solr/prometheus/scraper/SolrStandaloneScraperTest.java
+++ b/solr/contrib/prometheus-exporter/src/test/org/apache/solr/prometheus/scraper/SolrStandaloneScraperTest.java
@@ -84,7 +84,6 @@ public class SolrStandaloneScraperTest extends RestTestBase {
   @AfterClass
   public static void cleanUp() throws Exception {
     IOUtils.closeQuietly(solrScraper);
-    IOUtils.closeQuietly(solrClient);
     if (null != executor) {
       executor = null;
     }
diff --git a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
index e849e49..b9d2988 100644
--- a/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
+++ b/solr/core/src/java/org/apache/solr/update/PeerSyncWithLeader.java
@@ -33,7 +33,6 @@ import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.ModifiableSolrParams;
-import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrInfoBean;
@@ -81,7 +80,7 @@ public class PeerSyncWithLeader implements SolrMetricProducer {
     this.ulog = uhandler.getUpdateLog();
     Http2SolrClient httpClient = core
         .getCoreContainer().getUpdateShardHandler().getTheSharedHttpClient();
-    this.clientToLeader = new Http2SolrClient.Builder(leaderUrl).withHttpClient(httpClient).markInternalRequest().build();
+    this.clientToLeader = core.getCoreContainer().getUpdateShardHandler().getTheSharedHttpClient();
 
     this.updater = new PeerSync.Updater(msg(), core);
 
@@ -115,7 +114,7 @@ public class PeerSyncWithLeader implements SolrMetricProducer {
   }
 
   public void close() {
-    IOUtils.closeQuietly(clientToLeader);
+
   }
 
   /**
@@ -333,7 +332,9 @@ public class PeerSyncWithLeader implements SolrMetricProducer {
 
   private NamedList<Object> request(ModifiableSolrParams params, String onFail) {
     try {
-      QueryResponse rsp = new QueryRequest(params, SolrRequest.METHOD.POST).process(clientToLeader);
+      QueryRequest qr = new QueryRequest(params, SolrRequest.METHOD.POST);
+      qr.setBasePath(leaderUrl);
+      QueryResponse rsp = qr.process(clientToLeader);
       Exception exception = rsp.getException();
       if (exception != null) {
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, onFail, exception);
diff --git a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java
index 1c6b700..5fb0185 100644
--- a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java
+++ b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java
@@ -63,10 +63,6 @@ public class TestEmbeddedSolrServerSchemaAPI extends SolrTestCaseJ4 {
 
   @AfterClass
   public static void destroyClass() throws IOException {
-    if (null != server) {
-      server.close(); 
-      server = null;
-    }
     System.clearProperty("managed.schema.mutable");
   }
 
diff --git a/solr/core/src/test/org/apache/solr/core/TestLazyCores.java b/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
index c7c57fb..fcf0f18 100644
--- a/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
+++ b/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
@@ -180,28 +180,22 @@ public class TestLazyCores extends SolrTestCaseJ4 {
   @Test
   public void testLazySearch() throws Exception {
     CoreContainer cc = init();
-    try {
-      // Make sure Lazy4 isn't loaded. Should be loaded on the get
-      checkNotInCores(cc, Arrays.asList("collection4"));
-      SolrCore core4 = cc.getCore("collection4");
 
-      checkSearch(core4);
+    // Make sure Lazy4 isn't loaded. Should be loaded on the get
+    checkNotInCores(cc, Arrays.asList("collection4"));
+    SolrCore core4 = cc.getCore("collection4");
 
-      // Now just insure that the normal searching on "collection1" finds _0_ on the same query that found _2_ above.
-      // Use of makeReq above and req below is tricky, very tricky.
-      SolrCore collection1 = cc.getCore("collection1");
-      assertQ("test raw query",
-          makeReq(collection1, "q", "{!raw f=v_t}hello", "wt", "xml")
-          , "//result[@numFound='0']"
-      );
+    checkSearch(core4);
 
-      checkInCores(cc, "collection1", "collection2", "collection4", "collection5");
+    // Now just insure that the normal searching on "collection1" finds _0_ on the same query that found _2_ above.
+    // Use of makeReq above and req below is tricky, very tricky.
+    SolrCore collection1 = cc.getCore("collection1");
+    assertQ("test raw query", makeReq(collection1, "q", "{!raw f=v_t}hello", "wt", "xml"), "//result[@numFound='0']");
 
-      core4.close();
-      collection1.close();
-    } finally {
-      cc.shutdown();
-    }
+    checkInCores(cc, "collection1", "collection2", "collection4", "collection5");
+
+    core4.close();
+    collection1.close();
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/search/facet/TestCloudJSONFacetJoinDomain.java b/solr/core/src/test/org/apache/solr/search/facet/TestCloudJSONFacetJoinDomain.java
index 66a46fc..43f9153 100644
--- a/solr/core/src/test/org/apache/solr/search/facet/TestCloudJSONFacetJoinDomain.java
+++ b/solr/core/src/test/org/apache/solr/search/facet/TestCloudJSONFacetJoinDomain.java
@@ -195,10 +195,6 @@ public class TestCloudJSONFacetJoinDomain extends SolrCloudTestCase {
   
   @AfterClass
   private static void afterClass() throws Exception {
-    if (null != CLOUD_CLIENT) {
-      CLOUD_CLIENT.close();
-      CLOUD_CLIENT = null;
-    }
     for (Http2SolrClient client : CLIENTS) {
       client.close();
     }
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/CloseTracker.java b/solr/solrj/src/java/org/apache/solr/common/util/CloseTracker.java
index 99fc908..472fbd4 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/CloseTracker.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/CloseTracker.java
@@ -7,6 +7,9 @@ import java.io.Closeable;
 import java.io.PrintWriter;
 
 public class CloseTracker implements Closeable {
+
+    public static  volatile AlreadyClosedException lastAlreadyClosedEx;
+
     private volatile boolean closed = false;
     private volatile String closeStack = "";
     private volatile boolean closeLock;
@@ -21,7 +24,10 @@ public class CloseTracker implements Closeable {
             PrintWriter pw = new PrintWriter(sw);
             new ObjectReleaseTracker.ObjectTrackerException(this.getClass().getName()).printStackTrace(pw);
             String fcloseStack = sw.toString();
-            throw new AlreadyClosedException(fcloseStack + "\nalready closed by:\n");
+            AlreadyClosedException ex = new AlreadyClosedException(fcloseStack + "\nalready closed by:\n" + closeStack);
+            lastAlreadyClosedEx = ex;
+            throw ex;
+
         }
 
         StringBuilderWriter sw = new StringBuilderWriter(4096);
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestsBase.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestsBase.java
index 82b2c2c..fb21a78 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestsBase.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTestsBase.java
@@ -53,71 +53,70 @@ abstract public class SolrExampleTestsBase extends SolrJettyTestBase {
   @Test
   public void testCommitWithinOnAdd() throws Exception {
     // make sure it is empty...
-    try (SolrClient client = getSolrClient(jetty)) {
-      client.deleteByQuery("*:*");// delete everything!
-      client.commit();
-      QueryResponse rsp = client.query(new SolrQuery("*:*"));
-      Assert.assertEquals(0, rsp.getResults().getNumFound());
-
-      // Now try a timed commit...
-      SolrInputDocument doc3 = new SolrInputDocument();
-      doc3.addField("id", "id3");
-      doc3.addField("name", "doc3");
-      doc3.addField("price", 10);
-      UpdateRequest up = new UpdateRequest();
-      up.add(doc3);
-      up.setCommitWithin(10);
-      up.process(client);
-
-      // terrible, flakey way to test and we test commitWithin like this a lot already
-      //    rsp = client.query(new SolrQuery("*:*"));
-      //    Assert.assertEquals(0, rsp.getResults().getNumFound());
-
-      // now check that it comes out...
-      rsp = client.query(new SolrQuery("id:id3"));
-
-      int cnt = 0;
-      while (rsp.getResults().getNumFound() == 0) {
-        // wait and try again for slower/busier machines
-        // and/or parallel test effects.
-
-        if (cnt++ == 20) {
-          break;
-        }
-
-        Thread.sleep(10);
-
-        rsp = client.query(new SolrQuery("id:id3"));
+    SolrClient client = getSolrClient(jetty);
+    client.deleteByQuery("*:*");// delete everything!
+    client.commit();
+    QueryResponse rsp = client.query(new SolrQuery("*:*"));
+    Assert.assertEquals(0, rsp.getResults().getNumFound());
+
+    // Now try a timed commit...
+    SolrInputDocument doc3 = new SolrInputDocument();
+    doc3.addField("id", "id3");
+    doc3.addField("name", "doc3");
+    doc3.addField("price", 10);
+    UpdateRequest up = new UpdateRequest();
+    up.add(doc3);
+    up.setCommitWithin(10);
+    up.process(client);
+
+    // terrible, flakey way to test and we test commitWithin like this a lot already
+    //    rsp = client.query(new SolrQuery("*:*"));
+    //    Assert.assertEquals(0, rsp.getResults().getNumFound());
+
+    // now check that it comes out...
+    rsp = client.query(new SolrQuery("id:id3"));
+
+    int cnt = 0;
+    while (rsp.getResults().getNumFound() == 0) {
+      // wait and try again for slower/busier machines
+      // and/or parallel test effects.
+
+      if (cnt++ == 20) {
+        break;
       }
 
-      Assert.assertEquals(1, rsp.getResults().getNumFound());
+      Thread.sleep(10);
 
-      // Now test the new convenience parameter on the add() for commitWithin
-      SolrInputDocument doc4 = new SolrInputDocument();
-      doc4.addField("id", "id4");
-      doc4.addField("name", "doc4");
-      doc4.addField("price", 10);
-      client.add(doc4, 10);
+      rsp = client.query(new SolrQuery("id:id3"));
+    }
 
-      // now check that it comes out...
-      rsp = client.query(new SolrQuery("id:id4"));
+    Assert.assertEquals(1, rsp.getResults().getNumFound());
 
-      cnt = 0;
-      while (rsp.getResults().getNumFound() == 0) {
-        // wait and try again for slower/busier machines
-        // and/or parallel test effects.
+    // Now test the new convenience parameter on the add() for commitWithin
+    SolrInputDocument doc4 = new SolrInputDocument();
+    doc4.addField("id", "id4");
+    doc4.addField("name", "doc4");
+    doc4.addField("price", 10);
+    client.add(doc4, 10);
 
-        if (cnt++ == 10) {
-          break;
-        }
+    // now check that it comes out...
+    rsp = client.query(new SolrQuery("id:id4"));
 
-        Thread.sleep(10);
+    cnt = 0;
+    while (rsp.getResults().getNumFound() == 0) {
+      // wait and try again for slower/busier machines
+      // and/or parallel test effects.
 
-        rsp = client.query(new SolrQuery("id:id3"));
+      if (cnt++ == 10) {
+        break;
       }
 
-      Assert.assertEquals(1, rsp.getResults().getNumFound());
+      Thread.sleep(10);
+
+      rsp = client.query(new SolrQuery("id:id3"));
     }
+
+    Assert.assertEquals(1, rsp.getResults().getNumFound());
   }
   
   @Test
@@ -219,51 +218,51 @@ abstract public class SolrExampleTestsBase extends SolrJettyTestBase {
   
   @Test
   public void testStreamingRequest() throws Exception {
-    try (SolrClient client = getSolrClient(jetty)) {
-      // Empty the database...
-      client.deleteByQuery("*:*");// delete everything!
-      client.commit();
-      assertNumFound("*:*", 0); // make sure it got in
-
-      // Add some docs to the index
-      UpdateRequest req = new UpdateRequest();
-      for (int i = 0; i < 10; i++) {
-        SolrInputDocument doc = new SolrInputDocument();
-        doc.addField("id", "" + i);
-        doc.addField("cat", "foocat");
-        req.add(doc);
+    SolrClient client = getSolrClient(jetty);
+    // Empty the database...
+    client.deleteByQuery("*:*");// delete everything!
+    client.commit();
+    assertNumFound("*:*", 0); // make sure it got in
+
+    // Add some docs to the index
+    UpdateRequest req = new UpdateRequest();
+    for (int i = 0; i < 10; i++) {
+      SolrInputDocument doc = new SolrInputDocument();
+      doc.addField("id", "" + i);
+      doc.addField("cat", "foocat");
+      req.add(doc);
+    }
+    req.setAction(ACTION.COMMIT, true, true);
+    req.process(client);
+
+    // Make sure it ran OK
+    SolrQuery query = new SolrQuery("*:*");
+    query.set(CommonParams.FL, "id,score,_docid_");
+    QueryResponse response = client.query(query);
+    assertEquals(0, response.getStatus());
+    assertEquals(10, response.getResults().getNumFound());
+
+    // Now make sure each document gets output
+    final AtomicInteger cnt = new AtomicInteger(0);
+    client.queryAndStreamResponse(query, new StreamingResponseCallback() {
+
+      @Override
+      public void streamDocListInfo(long numFound, long start, Float maxScore) {
+        assertEquals(10, numFound);
       }
-      req.setAction(ACTION.COMMIT, true, true);
-      req.process(client);
-
-      // Make sure it ran OK
-      SolrQuery query = new SolrQuery("*:*");
-      query.set(CommonParams.FL, "id,score,_docid_");
-      QueryResponse response = client.query(query);
-      assertEquals(0, response.getStatus());
-      assertEquals(10, response.getResults().getNumFound());
-
-      // Now make sure each document gets output
-      final AtomicInteger cnt = new AtomicInteger(0);
-      client.queryAndStreamResponse(query, new StreamingResponseCallback() {
-
-        @Override
-        public void streamDocListInfo(long numFound, long start, Float maxScore) {
-          assertEquals(10, numFound);
-        }
 
-        @Override
-        public void streamSolrDocument(SolrDocument doc) {
-          cnt.incrementAndGet();
+      @Override
+      public void streamSolrDocument(SolrDocument doc) {
+        cnt.incrementAndGet();
 
-          // Make sure the transformer works for streaming
-          Float score = (Float) doc.get("score");
-          assertEquals("should have score", Float.valueOf(1.0f), score);
-        }
+        // Make sure the transformer works for streaming
+        Float score = (Float) doc.get("score");
+        assertEquals("should have score", Float.valueOf(1.0f), score);
+      }
+
+    });
+    assertEquals(10, cnt.get());
 
-      });
-      assertEquals(10, cnt.get());
-    }
   }
   
   protected QueryResponse assertNumFound(String query, int num)
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
index 3e9d0cc..c19e078 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
@@ -118,8 +118,9 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
   public void closeClientCache() {
     if (solrClientCache != null) {
       solrClientCache.close();
+      solrClientCache = null;
     }
-    if (streamContext != null) IOUtils.closeQuietly(streamContext.getSolrClientCache());
+    streamContext = null;
   }
 
   @Before
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java
index fc0195d..b629e38 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCase.java
@@ -47,12 +47,14 @@ import org.apache.lucene.util.QuickPatchThreadsFilter;
 import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.cloud.autoscaling.ScheduledTriggers;
+import org.apache.solr.common.AlreadyClosedException;
 import org.apache.solr.common.ParWork;
 import org.apache.solr.common.PerThreadExecService;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.TimeTracker;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.CloseTracker;
 import org.apache.solr.common.util.ObjectReleaseTracker;
 import org.apache.solr.common.util.SolrQueuedThreadPool;
 import org.apache.solr.common.util.SysStats;
@@ -439,19 +441,24 @@ public class SolrTestCase extends LuceneTestCase {
       ParWork.closeMyPerThreadExecutor(true);
       ParWork.shutdownRootSharedExec();
 
-      if (!failed && suiteFailureMarker.wasSuccessful() ) {
-        String object = null;
-        // if the tests passed, make sure everything was closed / released
-        if (RandomizedTest.getContext().getTargetClass().isAnnotationPresent(SuppressObjectReleaseTracker.class)) {
-          SuppressObjectReleaseTracker sor = RandomizedTest.getContext().getTargetClass()
-              .getAnnotation(SuppressObjectReleaseTracker.class);
-           object = sor.object();
-        }
+      AlreadyClosedException lastAlreadyClosedExp = CloseTracker.lastAlreadyClosedEx;
+      if (lastAlreadyClosedExp != null) {
+        CloseTracker.lastAlreadyClosedEx = null;
+        throw lastAlreadyClosedExp;
+      }
+
 
-        String orr = ObjectReleaseTracker.checkEmpty(object);
-        ObjectReleaseTracker.clear();
-        assertNull(orr, orr);
+      String object = null;
+      // if the tests passed, make sure everything was closed / released
+      if (RandomizedTest.getContext().getTargetClass().isAnnotationPresent(SuppressObjectReleaseTracker.class)) {
+        SuppressObjectReleaseTracker sor = RandomizedTest.getContext().getTargetClass().getAnnotation(SuppressObjectReleaseTracker.class);
+        object = sor.object();
       }
+
+      String orr = ObjectReleaseTracker.checkEmpty(object);
+      ObjectReleaseTracker.clear();
+      assertNull(orr, orr);
+
     } finally {
       ObjectReleaseTracker.clear();
       TestInjection.reset();
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 0d22378..4f64323 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -511,7 +511,7 @@ public abstract class SolrTestCaseJ4 extends SolrTestCase {
    * For use in test methods as needed.
    * </p>
    */
-  public static TestHarness h;
+  public static volatile TestHarness h;
 
   /**
    * LocalRequestFactory initialized by create[Default]Core[Container] using sensible
@@ -670,38 +670,42 @@ public abstract class SolrTestCaseJ4 extends SolrTestCase {
    * Shuts down the test harness and nulls out the values setup by {@link #initCore}
    */
   public static void deleteCore() {
-    if (h != null) {
-      log.info("###deleteCore" );
-      // If the test case set up Zk, it should still have it as available,
-      // otherwise the core close will just be unnecessarily delayed.
-      CoreContainer cc = h.getCoreContainer();
-      if (! cc.getCores().isEmpty() && cc.isZooKeeperAware()) {
-        try {
-          cc.getZkController().getZkClient().exists("/");
-        } catch (KeeperException e) {
-          log.error("Testing connectivity to ZK by checking for root path failed", e);
-          fail("Trying to tear down a ZK aware core container with ZK not reachable");
-        } catch (InterruptedException ignored) {}
+    try {
+      if (h != null) {
+        log.info("###deleteCore");
+        // If the test case set up Zk, it should still have it as available,
+        // otherwise the core close will just be unnecessarily delayed.
+        CoreContainer cc = h.getCoreContainer();
+        if (!cc.getCores().isEmpty() && cc.isZooKeeperAware()) {
+          try {
+            cc.getZkController().getZkClient().exists("/");
+          } catch (KeeperException e) {
+            log.error("Testing connectivity to ZK by checking for root path failed", e);
+            fail("Trying to tear down a ZK aware core container with ZK not reachable");
+          } catch (InterruptedException ignored) {
+          }
+        }
+
+        h.close();
       }
 
-      h.close();
-    }
+      if (factoryProp == null) {
+        System.clearProperty("solr.directoryFactory");
+      }
 
-    if (factoryProp == null) {
-      System.clearProperty("solr.directoryFactory");
-    }
+      if (System.getProperty(UPDATELOG_SYSPROP) != null) {
+        // clears the updatelog sysprop at the end of the test run
+        System.clearProperty(UPDATELOG_SYSPROP);
+      }
+    } finally {
+      solrConfig = null;
+      h = null;
+      lrf = null;
 
-    if (System.getProperty(UPDATELOG_SYSPROP) != null) {
-      // clears the updatelog sysprop at the end of the test run
-      System.clearProperty(UPDATELOG_SYSPROP);
+      configString = schemaString = null;
+      initCoreDataDir = null;
+      hdfsDataDir = null;
     }
-    
-    solrConfig = null;
-    h = null;
-    lrf = null;
-    configString = schemaString = null;
-    initCoreDataDir = null;
-    hdfsDataDir = null;
   }
 
   /** Validates an update XML String is successful
diff --git a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
index 63e9bd5..9565e28 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
@@ -70,7 +70,7 @@ import org.apache.solr.update.UpdateShardHandlerConfig;
  */
 public class TestHarness extends BaseTestHarness {
   public volatile String coreName;
-  protected final CoreContainer container;
+  protected volatile CoreContainer container;
   public UpdateRequestHandler updater;
  
   /**
@@ -370,7 +370,11 @@ public class TestHarness extends BaseTestHarness {
    */
   public void close() {
     if (container != null) {
-      container.shutdown();
+      try {
+        container.shutdown();
+      } finally {
+        container = null;
+      }
     }
   }