You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mu...@apache.org on 2019/08/03 07:59:20 UTC

[lucene-solr] branch branch_8x updated: SOLR-12555: use expectThrows() to verify the ex thrown in tests

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

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


The following commit(s) were added to refs/heads/branch_8x by this push:
     new 488c75f  SOLR-12555: use expectThrows() to verify the ex thrown in tests
488c75f is described below

commit 488c75fb555cdf704cf93b66cc0fdafe2896d159
Author: Munendra S N <mu...@apache.org>
AuthorDate: Sat Aug 3 13:00:49 2019 +0530

    SOLR-12555: use expectThrows() to verify the ex thrown in tests
---
 .../handler/dataimport/TestJdbcDataSource.java     |  37 +-
 .../dataimport/TestSimplePropertiesWriter.java     |  32 +-
 .../TestSolrEntityProcessorEndToEnd.java           |  34 +-
 .../extraction/ExtractingRequestHandlerTest.java   |  74 ++--
 .../apache/solr/ltr/feature/TestValueFeature.java  |  21 +-
 .../org/apache/solr/ltr/model/TestLinearModel.java | 135 +++----
 .../ltr/model/TestMultipleAdditiveTreesModel.java  | 129 +++---
 .../solr/ltr/model/TestNeuralNetworkModel.java     |  66 ++--
 .../apache/solr/ltr/model/TestWrapperModel.java    |  52 +--
 .../apache/solr/ltr/norm/TestMinMaxNormalizer.java |  20 +-
 .../solr/ltr/norm/TestStandardNormalizer.java      |  46 +--
 .../ltr/store/rest/TestManagedFeatureStore.java    |  17 +-
 .../solr/velocity/VelocityResponseWriterTest.java  |  15 +-
 .../embedded/TestEmbeddedSolrServerSchemaAPI.java  |  14 +-
 .../test/org/apache/solr/core/PluginInfoTest.java  |   7 +-
 .../handler/FieldAnalysisRequestHandlerTest.java   |  12 +-
 .../org/apache/solr/handler/JsonLoaderTest.java    |  60 ++-
 .../solr/handler/PingRequestHandlerTest.java       |   9 +-
 .../solr/handler/TestReplicationHandler.java       |   6 +-
 .../org/apache/solr/handler/TestRestoreCore.java   |   2 -
 .../solr/handler/TestSQLHandlerNonCloud.java       |   8 +-
 .../apache/solr/handler/V2ApiIntegrationTest.java  |  10 +-
 .../handler/admin/CoreAdminCreateDiscoverTest.java |  13 +-
 .../solr/handler/admin/CoreAdminHandlerTest.java   |  70 ++--
 .../solr/handler/admin/CoreAdminOperationTest.java | 440 ++++++---------------
 .../admin/CoreMergeIndexesAdminHandlerTest.java    |  19 +-
 .../apache/solr/handler/admin/InfoHandlerTest.java |  20 +-
 .../handler/admin/ShowFileRequestHandlerTest.java  |  44 +--
 .../solr/handler/admin/TestCollectionAPIs.java     |  19 +-
 .../component/DistributedDebugComponentTest.java   |  35 +-
 .../component/DistributedFacetExistsSmallTest.java |  20 +-
 .../handler/component/SpellCheckComponentTest.java |  40 +-
 .../solr/handler/component/StatsComponentTest.java | 109 ++---
 .../SuggestComponentContextFilterQueryTest.java    |  23 +-
 .../component/TestHttpShardHandlerFactory.java     |  72 ++--
 .../org/apache/solr/highlight/HighlighterTest.java |  12 +-
 .../highlight/TestPostingsSolrHighlighter.java     |   9 +-
 .../solr/highlight/TestUnifiedSolrHighlighter.java |  17 +-
 .../solr/index/WrapperMergePolicyFactoryTest.java  |   8 +-
 .../apache/solr/internal/csv/CharBufferTest.java   |   9 +-
 .../apache/solr/metrics/SolrMetricManagerTest.java |   7 +-
 .../org/apache/solr/request/SimpleFacetsTest.java  |  26 +-
 .../apache/solr/request/TestIntervalFaceting.java  |  10 +-
 .../apache/solr/request/TestRemoteStreaming.java   |  28 +-
 .../org/apache/solr/request/TestStreamBody.java    |  10 +-
 .../apache/solr/schema/ChangedSchemaMergeTest.java |  15 +-
 .../test/org/apache/solr/schema/CopyFieldTest.java |  69 ++--
 .../apache/solr/schema/CurrencyFieldTypeTest.java  |   8 +-
 .../apache/solr/schema/PreAnalyzedFieldTest.java   |  19 +-
 .../solr/schema/SpatialRPTFieldTypeTest.java       |  16 +-
 .../apache/solr/schema/TestCloudSchemaless.java    |  41 +-
 .../solr/security/BasicAuthIntegrationTest.java    |  33 +-
 .../solr/security/TestAuthorizationFramework.java  |   5 +-
 .../hadoop/TestDelegationWithHadoopAuth.java       |  20 +-
 .../hadoop/TestImpersonationWithHadoopAuth.java    |  51 +--
 .../solr/servlet/DirectSolrConnectionTest.java     |  11 +-
 .../apache/solr/servlet/SolrRequestParserTest.java |  68 ++--
 .../spelling/ConjunctionSolrSpellCheckerTest.java  |   7 +-
 .../apache/solr/store/hdfs/HdfsDirectoryTest.java  |   6 +-
 .../org/apache/solr/update/AddBlockUpdateTest.java |   8 +-
 .../solr/update/AnalysisErrorHandlingTest.java     |  13 +-
 .../apache/solr/update/DocumentBuilderTest.java    |  46 +--
 .../solr/update/TestAtomicUpdateErrorCases.java    |  52 +--
 .../test/org/apache/solr/update/TestUpdate.java    |  62 ++-
 .../IgnoreLargeDocumentProcessorFactoryTest.java   |  14 +-
 .../StatelessScriptUpdateProcessorFactoryTest.java |  49 +--
 .../processor/TestDocBasedVersionConstraints.java  | 157 ++++----
 .../processor/TolerantUpdateProcessorTest.java     | 129 +++---
 .../org/apache/solr/util/DateMathParserTest.java   |  11 +-
 .../org/apache/solr/util/TestTestInjection.java    |  26 +-
 .../BigEndianAscendingWordDeserializerTest.java    |  24 +-
 .../hll/BigEndianAscendingWordSerializerTest.java  |  42 +-
 .../apache/solr/client/solrj/SolrExampleTests.java | 120 ++----
 .../client/solrj/cloud/autoscaling/TestPolicy.java |   9 +-
 .../solrj/embedded/SolrExampleJettyTest.java       |  18 +-
 .../client/solrj/embedded/TestSolrProperties.java  |  20 +-
 .../client/solrj/impl/BasicHttpSolrClientTest.java | 154 +++-----
 .../client/solrj/impl/CloudSolrClientTest.java     |  33 +-
 .../solrj/impl/SolrPortAwareCookieSpecTest.java    |  66 +---
 .../solrj/impl/TestCloudSolrClientConnections.java |  17 +-
 .../solr/client/solrj/request/SchemaTest.java      |  15 +-
 .../solrj/request/TestConfigSetAdminRequest.java   |  11 +-
 .../solr/client/solrj/request/TestCoreAdmin.java   |  41 +-
 .../response/TestDelegationTokenResponse.java      |  28 +-
 .../solr/common/TestToleratedUpdateError.java      |  26 +-
 .../apache/solr/common/util/JsonValidatorTest.java |  27 +-
 .../org/apache/solr/common/util/NamedListTest.java |  11 +-
 .../solr/common/util/TestValidatingJsonMap.java    |   7 +-
 .../solr/cloud/MiniSolrCloudClusterTest.java       |  14 +-
 89 files changed, 1216 insertions(+), 2269 deletions(-)

diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java
index e091888..158bbc6 100644
--- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java
+++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestJdbcDataSource.java
@@ -16,6 +16,7 @@
  */
 package org.apache.solr.handler.dataimport;
 
+import javax.sql.DataSource;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
@@ -33,17 +34,21 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
-import javax.sql.DataSource;
-
 import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.handler.dataimport.JdbcDataSource.ResultSetIterator;
-import static org.mockito.Mockito.*;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 /**
  * <p>
  * Test for JdbcDataSource
@@ -205,11 +210,9 @@ public class TestJdbcDataSource extends AbstractDataImportHandlerTestCase {
     SQLException sqlException = new SQLException("fake");
     when(dataSource.getConnection()).thenThrow(sqlException);
 
-    try {
-      jdbcDataSource.createConnectionFactory(context, props).call();
-    } catch (SQLException ex) {
-      assertSame(sqlException, ex);
-    }
+    SQLException ex = expectThrows(SQLException.class,
+        () -> jdbcDataSource.createConnectionFactory(context, props).call());
+    assertSame(sqlException, ex);
 
     verify(dataSource).getConnection();
   }
@@ -224,11 +227,10 @@ public class TestJdbcDataSource extends AbstractDataImportHandlerTestCase {
     when(dataSource.getConnection()).thenReturn(connection);
     doThrow(sqlException).when(connection).setAutoCommit(false);
 
-    try {
-      jdbcDataSource.createConnectionFactory(context, props).call();
-    } catch (DataImportHandlerException ex) {
-      assertSame(sqlException, ex.getCause());
-    }
+    DataImportHandlerException ex = expectThrows(DataImportHandlerException.class,
+        () -> jdbcDataSource.createConnectionFactory(context, props).call());
+    assertSame(sqlException, ex.getCause());
+
     verify(dataSource).getConnection();
     verify(connection).setAutoCommit(false);
     verify(connection).close();
@@ -249,12 +251,9 @@ public class TestJdbcDataSource extends AbstractDataImportHandlerTestCase {
         .thenReturn(statement);
     when(statement.execute("query")).thenThrow(sqlException);
 
-    try {
-      jdbcDataSource.getData("query");
-      fail("exception expected");
-    } catch (DataImportHandlerException ex) {
-      assertSame(sqlException, ex.getCause());
-    }
+    DataImportHandlerException ex = expectThrows(DataImportHandlerException.class,
+        () -> jdbcDataSource.getData("query"));
+    assertSame(sqlException, ex.getCause());
 
     verify(dataSource).getConnection();
     verify(connection).setAutoCommit(false);
diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java
index 93a26c3..74e04c9 100644
--- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java
+++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSimplePropertiesWriter.java
@@ -19,7 +19,6 @@ package org.apache.solr.handler.dataimport;
 import java.lang.invoke.MethodHandles;
 import java.sql.Connection;
 import java.sql.ResultSet;
-import java.sql.SQLException;
 import java.sql.Statement;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -28,7 +27,6 @@ import java.util.Locale;
 import java.util.Map;
 
 import org.apache.solr.common.util.SuppressForbidden;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -91,36 +89,22 @@ public class TestSimplePropertiesWriter extends AbstractDIHJdbcTestCase {
       Date docDate= df.parse((String) props.get("last_index_time"));
       int year = currentYearFromDatabase();
       
-      Assert.assertTrue("This date: " + errMsgFormat.format(oneSecondAgo) + " should be prior to the document date: " + errMsgFormat.format(docDate), docDate.getTime() - oneSecondAgo.getTime() > 0);
-      Assert.assertTrue("This date: " + errMsgFormat.format(oneSecondAgo) + " should be prior to the entity date: " + errMsgFormat.format(entityDate), entityDate.getTime() - oneSecondAgo.getTime() > 0);   
+      assertTrue("This date: " + errMsgFormat.format(oneSecondAgo) + " should be prior to the document date: " + errMsgFormat.format(docDate), docDate.getTime() - oneSecondAgo.getTime() > 0);
+      assertTrue("This date: " + errMsgFormat.format(oneSecondAgo) + " should be prior to the entity date: " + errMsgFormat.format(entityDate), entityDate.getTime() - oneSecondAgo.getTime() > 0);
       assertQ(req("*:*"), "//*[@numFound='1']", "//doc/str[@name=\"ayear_s\"]=\"" + year + "\"");    
     }
   }
   
   private int currentYearFromDatabase() throws Exception {
-    Connection conn = null;
-    Statement s = null;
-    ResultSet rs = null;
-    try {
-      conn = newConnection();
-      s = conn.createStatement();
-      rs = s.executeQuery("select year(current_timestamp) from sysibm.sysdummy1");
+    try (
+        Connection conn = newConnection();
+        Statement s = conn.createStatement();
+        ResultSet rs = s.executeQuery("select year(current_timestamp) from sysibm.sysdummy1");
+    ){
       if (rs.next()) {
         return rs.getInt(1);
       }
-      Assert.fail("We should have gotten a row from the db.");
-    } catch (SQLException e) {
-      throw e;
-    } finally {
-      try {
-        rs.close();
-      } catch (Exception ex) {}
-      try {
-        s.close();
-      } catch (Exception ex) {}
-      try {
-        conn.close();
-      } catch (Exception ex) {}
+      fail("We should have gotten a row from the db.");
     }
     return 0;
   }
diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java
index 0529ec3..0bf9cc2 100644
--- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java
+++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java
@@ -16,19 +16,6 @@
  */
 package org.apache.solr.handler.dataimport;
 
-import org.apache.commons.io.FileUtils;
-import org.apache.lucene.util.IOUtils;
-import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.embedded.JettySolrRunner;
-import org.apache.solr.client.solrj.impl.HttpSolrClient;
-import org.apache.solr.common.SolrInputDocument;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.File;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -42,6 +29,19 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
 
+import org.apache.commons.io.FileUtils;
+import org.apache.lucene.util.IOUtils;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.common.SolrInputDocument;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * End-to-end test of SolrEntityProcessor. "Real" test using embedded Solr
  */
@@ -196,13 +196,7 @@ public class TestSolrEntityProcessorEndToEnd extends AbstractDataImportHandlerTe
     
     assertQ(req("*:*"), "//result[@numFound='7']");
     assertQ(req("id:1"), "//result[@numFound='1']");
-    try {
-      assertQ(req("id:1"), "//result/doc/arr[@name='desc']");
-      fail("The document has a field with name desc");
-    } catch(Exception e) {
-      
-    }
-    
+    assertQ(req("id:1"), "count(//result/doc/arr[@name='desc'])=0");
   }
   
   /**
diff --git a/solr/contrib/extraction/src/test/org/apache/solr/handler/extraction/ExtractingRequestHandlerTest.java b/solr/contrib/extraction/src/test/org/apache/solr/handler/extraction/ExtractingRequestHandlerTest.java
index 00b7bf9..14de842 100644
--- a/solr/contrib/extraction/src/test/org/apache/solr/handler/extraction/ExtractingRequestHandlerTest.java
+++ b/solr/contrib/extraction/src/test/org/apache/solr/handler/extraction/ExtractingRequestHandlerTest.java
@@ -227,20 +227,20 @@ public class ExtractingRequestHandlerTest extends SolrTestCaseJ4 {
   @Test
   public void testDefaultField() throws Exception {
     ExtractingRequestHandler handler = (ExtractingRequestHandler) h.getCore().getRequestHandler("/update/extract");
-    assertTrue("handler is null and it shouldn't be", handler != null);
+    assertNotNull("handler is null and it shouldn't be", handler);
+
     try {
       ignoreException("unknown field 'a'");
       ignoreException("unknown field 'meta'");  // TODO: should this exception be happening?
-      loadLocal("extraction/simple.html",
-      "literal.id","simple2",
-      "lowernames", "true",
-        "captureAttr", "true",
-        //"fmap.content_type", "abcxyz",
-        "commit", "true"  // test immediate commit
-      );
-      fail("Should throw SolrException");
-    } catch (SolrException e) {
-      //do nothing
+      expectThrows(SolrException.class, () -> {
+        loadLocal("extraction/simple.html",
+            "literal.id", "simple2",
+            "lowernames", "true",
+            "captureAttr", "true",
+            //"fmap.content_type", "abcxyz",
+            "commit", "true"  // test immediate commit
+        );
+      });
     } finally {
       resetExceptionIgnores();
     }
@@ -296,16 +296,17 @@ public class ExtractingRequestHandlerTest extends SolrTestCaseJ4 {
     assertQ(req("extractionLiteralMV:two"), "//*[@numFound='1']");
 
     try {
+      // TODO: original author did not specify why an exception should be thrown... how to fix?
       loadLocal("extraction/version_control.xml", "fmap.created", "extractedDate", "fmap.producer", "extractedProducer",
-              "fmap.creator", "extractedCreator", "fmap.Keywords", "extractedKeywords",
-              "fmap.Author", "extractedAuthor",
-              "fmap.content", "extractedContent",
-              "literal.id", "two",
-              "fmap.language", "extractedLanguage",
-              "literal.extractionLiteral", "one",
-              "literal.extractionLiteral", "two",
-              "fmap.X-Parsed-By", "ignored_parser",
-              "fmap.Last-Modified", "extractedDate"
+          "fmap.creator", "extractedCreator", "fmap.Keywords", "extractedKeywords",
+          "fmap.Author", "extractedAuthor",
+          "fmap.content", "extractedContent",
+          "literal.id", "two",
+          "fmap.language", "extractedLanguage",
+          "literal.extractionLiteral", "one",
+          "literal.extractionLiteral", "two",
+          "fmap.X-Parsed-By", "ignored_parser",
+          "fmap.Last-Modified", "extractedDate"
       );
       // TODO: original author did not specify why an exception should be thrown... how to fix?
       // assertTrue("Exception should have been thrown", false);
@@ -549,12 +550,9 @@ public class ExtractingRequestHandlerTest extends SolrTestCaseJ4 {
       h.getCore().getRequestHandler("/update/extract");
     assertTrue("handler is null and it shouldn't be", handler != null);
 
-    try{
-      loadLocal("extraction/password-is-solrcell.docx",
-          "literal.id", "one");
-      fail("TikaException is expected because of trying to extract text from password protected word file without supplying a password.");
-    }
-    catch(Exception expected){}
+    expectThrows(Exception.class, () -> {
+      loadLocal("extraction/password-is-solrcell.docx", "literal.id", "one");
+    });
     assertU(commit());
     assertQ(req("*:*"), "//result[@numFound=0]");
 
@@ -581,25 +579,21 @@ public class ExtractingRequestHandlerTest extends SolrTestCaseJ4 {
     ExtractingRequestHandler handler = (ExtractingRequestHandler) h.getCore().getRequestHandler("/update/extract");
     assertTrue("handler is null and it shouldn't be", handler != null);
 
-    try{
+    expectThrows(Exception.class, () -> {
       // Load plain text specifying another mime type, should fail
-      loadLocal("extraction/version_control.txt", 
-              "literal.id", "one",
-              ExtractingParams.STREAM_TYPE, "application/pdf"
+      loadLocal("extraction/version_control.txt",
+          "literal.id", "one",
+          ExtractingParams.STREAM_TYPE, "application/pdf"
       );
-      fail("SolrException is expected because wrong parser specified for the file type");
-    }
-    catch(Exception expected){}
+    });
 
-    try{
+    expectThrows(Exception.class, () -> {
       // Load plain text specifying non existing mimetype, should fail
-      loadLocal("extraction/version_control.txt", 
-              "literal.id", "one",
-              ExtractingParams.STREAM_TYPE, "foo/bar"
+      loadLocal("extraction/version_control.txt",
+          "literal.id", "one",
+          ExtractingParams.STREAM_TYPE, "foo/bar"
       );
-      fail("SolrException is expected because nonexsisting parser specified");
-    }
-    catch(Exception expected){}
+    });
   }
 
   public void testLiteralsOverride() throws Exception {
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java
index 2b22bfe..56f9efb 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/feature/TestValueFeature.java
@@ -51,25 +51,20 @@ public class TestValueFeature extends TestRerankBase {
   public void testValueFeatureWithEmptyValue() throws Exception {
     final RuntimeException expectedException =
         new RuntimeException("mismatch: '0'!='500' @ responseHeader/status");
-    try {
-        loadFeature("c2", ValueFeature.class.getName(), "{\"value\":\"\"}");
-        fail("testValueFeatureWithEmptyValue failed to throw exception: "+expectedException);
-    } catch (RuntimeException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    RuntimeException e = expectThrows(RuntimeException.class, () -> {
+      loadFeature("c2", ValueFeature.class.getName(), "{\"value\":\"\"}");
+    });
+    assertEquals(expectedException.toString(), e.toString());
   }
 
   @Test
   public void testValueFeatureWithWhitespaceValue() throws Exception {
     final RuntimeException expectedException =
         new RuntimeException("mismatch: '0'!='500' @ responseHeader/status");
-    try {
-        loadFeature("c2", ValueFeature.class.getName(),
-              "{\"value\":\" \"}");
-        fail("testValueFeatureWithWhitespaceValue failed to throw exception: "+expectedException);
-    } catch (RuntimeException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    RuntimeException e = expectThrows(RuntimeException.class, () -> {
+      loadFeature("c2", ValueFeature.class.getName(), "{\"value\":\" \"}");
+    });
+    assertEquals(expectedException.toString(), e.toString());
   }
 
   @Test
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
index 6620441..0abba91 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
@@ -93,18 +93,16 @@ public class TestLinearModel extends TestRerankBase {
   public void nullFeatureWeightsTest() {
     final ModelException expectedException =
         new ModelException("Model test2 doesn't contain any weights");
-    try {
-      final List<Feature> features = getFeatures(new String[]
-          {"constant1", "constant5"});
-      final List<Normalizer> norms =
-        new ArrayList<Normalizer>(
-            Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+
+    final List<Feature> features = getFeatures(new String[]
+        {"constant1", "constant5"});
+    final List<Normalizer> norms =
+        new ArrayList<>(Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+    ModelException ex = expectThrows(ModelException.class, () -> {
       createLinearModel("test2",
           features, norms, "test", fstore.getFeatures(), null);
-      fail("unexpectedly got here instead of catching "+expectedException);
-    } catch (ModelException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    });
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
@@ -112,55 +110,48 @@ public class TestLinearModel extends TestRerankBase {
     final SolrException expectedException =
         new SolrException(SolrException.ErrorCode.BAD_REQUEST,
             ModelException.class.getName()+": model 'test3' already exists. Please use a different name");
-    try {
-      final List<Feature> features = getFeatures(new String[]
-          {"constant1", "constant5"});
-      final List<Normalizer> norms =
-        new ArrayList<Normalizer>(
-            Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
-      final Map<String,Object> weights = new HashMap<>();
-      weights.put("constant1", 1d);
-      weights.put("constant5", 1d);
 
-      Map<String,Object> params = new HashMap<String,Object>();
-      params.put("weights", weights);
+    final List<Feature> features = getFeatures(new String[]
+        {"constant1", "constant5"});
+    final List<Normalizer> norms =
+        new ArrayList<>(Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+    final Map<String,Object> weights = new HashMap<>();
+    weights.put("constant1", 1d);
+    weights.put("constant5", 1d);
+
+    Map<String,Object> params = new HashMap<>();
+    params.put("weights", weights);
+    SolrException ex = expectThrows(SolrException.class, () -> {
       final LTRScoringModel ltrScoringModel = createLinearModel("test3",
-          features, norms, "test", fstore.getFeatures(),
-              params);
+          features, norms, "test", fstore.getFeatures(), params);
       store.addModel(ltrScoringModel);
       final LTRScoringModel m = store.getModel("test3");
       assertEquals(ltrScoringModel, m);
       store.addModel(ltrScoringModel);
-      fail("unexpectedly got here instead of catching "+expectedException);
-    } catch (SolrException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    });
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
   public void duplicateFeatureTest() {
     final ModelException expectedException =
         new ModelException("duplicated feature constant1 in model test4");
-    try {
-      final List<Feature> features = getFeatures(new String[]
-          {"constant1", "constant1"});
-      final List<Normalizer> norms =
-        new ArrayList<Normalizer>(
-            Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
-      final Map<String,Object> weights = new HashMap<>();
-      weights.put("constant1", 1d);
-      weights.put("constant5", 1d);
+    final List<Feature> features = getFeatures(new String[]
+        {"constant1", "constant1"});
+    final List<Normalizer> norms =
+        new ArrayList<>(Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+    final Map<String,Object> weights = new HashMap<>();
+    weights.put("constant1", 1d);
+    weights.put("constant5", 1d);
 
-      Map<String,Object> params = new HashMap<String,Object>();
-      params.put("weights", weights);
+    Map<String,Object> params = new HashMap<>();
+    params.put("weights", weights);
+    ModelException ex = expectThrows(ModelException.class, () -> {
       final LTRScoringModel ltrScoringModel = createLinearModel("test4",
-          features, norms, "test", fstore.getFeatures(),
-              params);
+          features, norms, "test", fstore.getFeatures(), params);
       store.addModel(ltrScoringModel);
-      fail("unexpectedly got here instead of catching "+expectedException);
-    } catch (ModelException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    });
+    assertEquals(expectedException.toString(), ex.toString());
 
   }
 
@@ -168,50 +159,44 @@ public class TestLinearModel extends TestRerankBase {
   public void missingFeatureWeightTest() {
     final ModelException expectedException =
         new ModelException("Model test5 lacks weight(s) for [constant5]");
-    try {
-      final List<Feature> features = getFeatures(new String[]
-          {"constant1", "constant5"});
-      final List<Normalizer> norms =
-        new ArrayList<Normalizer>(
-            Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
-      final Map<String,Object> weights = new HashMap<>();
-      weights.put("constant1", 1d);
-      weights.put("constant5missing", 1d);
+    final List<Feature> features = getFeatures(new String[]
+        {"constant1", "constant5"});
+    final List<Normalizer> norms =
+        new ArrayList<>(Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+
+    final Map<String,Object> weights = new HashMap<>();
+    weights.put("constant1", 1d);
+    weights.put("constant5missing", 1d);
 
-      Map<String,Object> params = new HashMap<String,Object>();
-      params.put("weights", weights);
+    Map<String,Object> params = new HashMap<>();
+    params.put("weights", weights);
+    ModelException ex = expectThrows(ModelException.class, () -> {
       createLinearModel("test5",
-          features, norms, "test", fstore.getFeatures(),
-              params);
-      fail("unexpectedly got here instead of catching "+expectedException);
-    } catch (ModelException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+          features, norms, "test", fstore.getFeatures(), params);
+    });
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
   public void emptyFeaturesTest() {
     final ModelException expectedException =
         new ModelException("no features declared for model test6");
-    try {
-      final List<Feature> features = getFeatures(new String[] {});
-      final List<Normalizer> norms =
-        new ArrayList<Normalizer>(
-            Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
-      final Map<String,Object> weights = new HashMap<>();
-      weights.put("constant1", 1d);
-      weights.put("constant5missing", 1d);
+    final List<Feature> features = getFeatures(new String[] {});
+    final List<Normalizer> norms =
+        new ArrayList<>(Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+    final Map<String,Object> weights = new HashMap<>();
+    weights.put("constant1", 1d);
+    weights.put("constant5missing", 1d);
 
-      Map<String,Object> params = new HashMap<String,Object>();
-      params.put("weights", weights);
+    Map<String,Object> params = new HashMap<>();
+    params.put("weights", weights);
+    ModelException ex = expectThrows(ModelException.class, () -> {
       final LTRScoringModel ltrScoringModel = createLinearModel("test6",
           features, norms, "test", fstore.getFeatures(),
           params);
       store.addModel(ltrScoringModel);
-      fail("unexpectedly got here instead of catching "+expectedException);
-    } catch (ModelException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    });
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
 }
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
index e7c920f..d57d2f3 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
@@ -16,14 +16,14 @@
  */
 package org.apache.solr.ltr.model;
 
-import static org.hamcrest.core.StringContains.containsString;
-
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.ltr.TestRerankBase;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.hamcrest.core.StringContains.containsString;
+
 public class TestMultipleAdditiveTreesModel extends TestRerankBase {
 
 
@@ -123,124 +123,107 @@ public class TestMultipleAdditiveTreesModel extends TestRerankBase {
   public void multipleAdditiveTreesTestNoParams() throws Exception {
     final ModelException expectedException =
         new ModelException("no trees declared for model multipleadditivetreesmodel_no_params");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_params.json",
-              "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestNoParams failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
-
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_params.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestEmptyParams() throws Exception {
     final ModelException expectedException =
         new ModelException("no trees declared for model multipleadditivetreesmodel_no_trees");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_trees.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestEmptyParams failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_trees.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestNoWeight() throws Exception {
     final ModelException expectedException =
         new ModelException("MultipleAdditiveTreesModel tree doesn't contain a weight");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_weight.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestNoWeight failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_weight.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestTreesParamDoesNotContatinTree() throws Exception {
     final ModelException expectedException =
         new ModelException("MultipleAdditiveTreesModel tree doesn't contain a tree");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_tree.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestTreesParamDoesNotContatinTree failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_tree.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestNoFeaturesSpecified() throws Exception {
     final ModelException expectedException =
         new ModelException("no features declared for model multipleadditivetreesmodel_no_features");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_features.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestNoFeaturesSpecified failed to throw exception: "+expectedException);
-    } catch (ModelException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_features.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestNoRight() throws Exception {
     final ModelException expectedException =
         new ModelException("MultipleAdditiveTreesModel tree node is missing right");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_right.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestNoRight failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_right.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestNoLeft() throws Exception {
     final ModelException expectedException =
         new ModelException("MultipleAdditiveTreesModel tree node is missing left");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_left.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestNoLeft failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_left.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestNoThreshold() throws Exception {
     final ModelException expectedException =
         new ModelException("MultipleAdditiveTreesModel tree node is missing threshold");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_threshold.json",
-            "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestNoThreshold failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_threshold.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
   public void multipleAdditiveTreesTestMissingTreeFeature() throws Exception {
     final ModelException expectedException =
         new ModelException("MultipleAdditiveTreesModel tree node is leaf with left=-100.0 and right=75.0");
-    try {
-        createModelFromFiles("multipleadditivetreesmodel_no_feature.json",
-              "multipleadditivetreesmodel_features.json");
-        fail("multipleAdditiveTreesTestMissingTreeFeature failed to throw exception: "+expectedException);
-    } catch (ModelException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+
+    ModelException ex = expectThrows(ModelException.class, () -> {
+      createModelFromFiles("multipleadditivetreesmodel_no_feature.json",
+          "multipleadditivetreesmodel_features.json");
+    });
+    assertEquals(expectedException.toString(), ex.toString());
   }
 }
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestNeuralNetworkModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestNeuralNetworkModel.java
index 712249f..9614733 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestNeuralNetworkModel.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestNeuralNetworkModel.java
@@ -205,14 +205,12 @@ public class TestNeuralNetworkModel extends TestRerankBase {
   public void badActivationTest() throws Exception {
     final ModelException expectedException =
             new ModelException("Invalid activation function (\"sig\") in layer 0 of model \"neuralnetworkmodel_bad_activation\".");
-    try {
+    Exception ex = expectThrows(Exception.class, () -> {
       createModelFromFiles("neuralnetworkmodel_bad_activation.json",
-             "neuralnetworkmodel_features.json");
-      fail("badActivationTest failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+          "neuralnetworkmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
@@ -220,14 +218,12 @@ public class TestNeuralNetworkModel extends TestRerankBase {
     final ModelException expectedException =
             new ModelException("Dimension mismatch in model \"neuralnetworkmodel_mismatch_bias\". " +
                                "Layer 0 has 2 bias weights but 3 weight matrix rows.");
-    try {
+    Exception ex = expectThrows(Exception.class, () -> {
       createModelFromFiles("neuralnetworkmodel_mismatch_bias.json",
-             "neuralnetworkmodel_features.json");
-      fail("biasDimensionMismatchTest failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+          "neuralnetworkmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
@@ -235,14 +231,12 @@ public class TestNeuralNetworkModel extends TestRerankBase {
     final ModelException expectedException =
         new ModelException("Dimension mismatch in model \"neuralnetworkmodel_mismatch_input\". The input has " +
                            "4 features, but the weight matrix for layer 0 has 3 columns.");
-    try {
-        createModelFromFiles("neuralnetworkmodel_mismatch_input.json",
-               "neuralnetworkmodel_features.json");
-        fail("inputDimensionMismatchTest failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class,  () -> {
+      createModelFromFiles("neuralnetworkmodel_mismatch_input.json",
+          "neuralnetworkmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
@@ -250,14 +244,12 @@ public class TestNeuralNetworkModel extends TestRerankBase {
     final ModelException expectedException =
         new ModelException("Dimension mismatch in model \"neuralnetworkmodel_mismatch_layers\". The weight matrix " +
                            "for layer 0 has 2 rows, but the weight matrix for layer 1 has 3 columns.");
-    try {
-        createModelFromFiles("neuralnetworkmodel_mismatch_layers.json",
-               "neuralnetworkmodel_features.json");
-        fail("layerDimensionMismatchTest failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("neuralnetworkmodel_mismatch_layers.json",
+          "neuralnetworkmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
   
   @Test
@@ -265,14 +257,12 @@ public class TestNeuralNetworkModel extends TestRerankBase {
     final ModelException expectedException =
         new ModelException("Dimension mismatch in model \"neuralnetworkmodel_too_many_rows\". " +
                            "Layer 1 has 1 bias weights but 2 weight matrix rows.");
-    try {
-        createModelFromFiles("neuralnetworkmodel_too_many_rows.json",
-               "neuralnetworkmodel_features.json");
-        fail("layerDimensionMismatchTest failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      createModelFromFiles("neuralnetworkmodel_too_many_rows.json",
+          "neuralnetworkmodel_features.json");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
   @Test
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestWrapperModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestWrapperModel.java
index 1078393..b31a6ba 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestWrapperModel.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestWrapperModel.java
@@ -63,31 +63,19 @@ public class TestWrapperModel extends TestRerankBase {
   @Test
   public void testValidate() throws Exception {
     WrapperModel wrapperModel = new StubWrapperModel("testModel");
-    try {
-      wrapperModel.validate();
-    } catch (ModelException e) {
-      fail("Validation must succeed if no wrapped model is set");
-    }
+    wrapperModel.validate();
 
     // wrapper model with features
     WrapperModel wrapperModelWithFeatures = new StubWrapperModel("testModel",
         Collections.singletonList(new ValueFeature("val", Collections.emptyMap())), Collections.emptyList());
-    try {
-      wrapperModelWithFeatures.validate();
-      fail("Validation must fail if features of the wrapper model isn't empty");
-    } catch (ModelException e) {
-      assertEquals("features must be empty for the wrapper model testModel", e.getMessage());
-    }
+    ModelException e = expectThrows(ModelException.class, wrapperModelWithFeatures::validate);
+    assertEquals("features must be empty for the wrapper model testModel", e.getMessage());
 
     // wrapper model with norms
     WrapperModel wrapperModelWithNorms = new StubWrapperModel("testModel",
         Collections.emptyList(), Collections.singletonList(IdentityNormalizer.INSTANCE));
-    try {
-      wrapperModelWithNorms.validate();
-      fail("Validation must fail if norms of the wrapper model isn't empty");
-    } catch (ModelException e) {
-      assertEquals("norms must be empty for the wrapper model testModel", e.getMessage());
-    }
+    e = expectThrows(ModelException.class, wrapperModelWithNorms::validate);
+    assertEquals("norms must be empty for the wrapper model testModel", e.getMessage());
 
     assumeWorkingMockito();
 
@@ -102,11 +90,7 @@ public class TestWrapperModel extends TestRerankBase {
                   IdentityNormalizer.INSTANCE,
                   IdentityNormalizer.INSTANCE)
               );
-      try {
-        wrapperModel.updateModel(wrappedModel);
-      } catch (ModelException e) {
-        fail("Validation must succeed if the wrapped model is valid");
-      }
+      wrapperModel.updateModel(wrappedModel);
     }
 
     // update invalid model (feature store mismatch)
@@ -120,12 +104,8 @@ public class TestWrapperModel extends TestRerankBase {
                   IdentityNormalizer.INSTANCE,
                   IdentityNormalizer.INSTANCE)
               );
-      try {
-        wrapperModel.updateModel(wrappedModel);
-        fail("Validation must fail if wrapped model feature store differs from wrapper model feature store");
-      } catch (ModelException e) {
-        assertEquals("wrapper feature store name (_DEFAULT_) must match the wrapped feature store name (wrappedFeatureStore)", e.getMessage());
-      }
+      e = expectThrows(ModelException.class, () -> wrapperModel.updateModel(wrappedModel));
+      assertEquals("wrapper feature store name (_DEFAULT_) must match the wrapped feature store name (wrappedFeatureStore)", e.getMessage());
     }
 
     // update invalid model (no features)
@@ -137,12 +117,8 @@ public class TestWrapperModel extends TestRerankBase {
                   IdentityNormalizer.INSTANCE,
                   IdentityNormalizer.INSTANCE)
               );
-      try {
-        wrapperModel.updateModel(wrappedModel);
-        fail("Validation must fail if the wrapped model is invalid");
-      } catch (ModelException e) {
-        assertEquals("no features declared for model testModel", e.getMessage());
-      }
+      e = expectThrows(ModelException.class, () -> wrapperModel.updateModel(wrappedModel));
+      assertEquals("no features declared for model testModel", e.getMessage());
     }
 
     // update invalid model (no norms)
@@ -154,12 +130,8 @@ public class TestWrapperModel extends TestRerankBase {
                   new ValueFeature("v2", Collections.emptyMap())),
               Collections.emptyList()
               );
-      try {
-        wrapperModel.updateModel(wrappedModel);
-        fail("Validation must fail if the wrapped model is invalid");
-      } catch (ModelException e) {
-        assertEquals("counted 2 features and 0 norms in model testModel", e.getMessage());
-      }
+      e = expectThrows(ModelException.class, () -> wrapperModel.updateModel(wrappedModel));
+      assertEquals("counted 2 features and 0 norms in model testModel", e.getMessage());
     }
   }
 
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java
index 5c26107..7627ae9 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestMinMaxNormalizer.java
@@ -16,16 +16,16 @@
  */
 package org.apache.solr.ltr.norm;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.core.SolrResourceLoader;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 public class TestMinMaxNormalizer {
 
   private final SolrResourceLoader solrResourceLoader = new SolrResourceLoader();
@@ -87,14 +87,10 @@ public class TestMinMaxNormalizer {
     final NormalizerException expectedException =
         new NormalizerException("MinMax Normalizer delta must not be zero "
             + "| min = 10.0,max = 10.0,delta = 0.0");
-    try {
-        implTestMinMax(params,
-              10.0f,
-              10.0f);
-        fail("testMinMaxNormalizerMinEqualToMax failed to throw exception: "+expectedException);
-    } catch(NormalizerException actualException) {
-        assertEquals(expectedException.toString(), actualException.toString());
-    }
+    NormalizerException ex = SolrTestCaseJ4.expectThrows(NormalizerException.class,
+        () -> implTestMinMax(params, 10.0f, 10.0f)
+    );
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java
index 6ef5c30..62e415f 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/norm/TestStandardNormalizer.java
@@ -16,16 +16,16 @@
  */
 package org.apache.solr.ltr.norm;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.core.SolrResourceLoader;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 public class TestStandardNormalizer {
 
   private final SolrResourceLoader solrResourceLoader = new SolrResourceLoader();
@@ -58,14 +58,10 @@ public class TestStandardNormalizer {
     final NormalizerException expectedException =
         new NormalizerException("Standard Normalizer standard deviation must be positive "
             + "| avg = 0.0,std = 0.0");
-    try {
-        implTestStandard(params,
-              0.0f,
-              0.0f);
-        fail("testInvalidSTD failed to throw exception: "+expectedException);
-    } catch(NormalizerException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+    NormalizerException ex = SolrTestCaseJ4.expectThrows(NormalizerException.class,
+        () -> implTestStandard(params, 0.0f, 0.0f)
+    );
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
@@ -75,14 +71,11 @@ public class TestStandardNormalizer {
     final NormalizerException expectedException =
         new NormalizerException("Standard Normalizer standard deviation must be positive "
             + "| avg = 0.0,std = -1.0");
-    try {
-        implTestStandard(params,
-              0.0f,
-              -1f);
-        fail("testInvalidSTD2 failed to throw exception: "+expectedException);
-    } catch(NormalizerException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+
+    NormalizerException ex = SolrTestCaseJ4.expectThrows(NormalizerException.class,
+        () -> implTestStandard(params, 0.0f, -1f)
+    );
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
@@ -93,14 +86,11 @@ public class TestStandardNormalizer {
     final NormalizerException expectedException =
         new NormalizerException("Standard Normalizer standard deviation must be positive "
             + "| avg = 1.0,std = 0.0");
-    try {
-        implTestStandard(params,
-              1f,
-              0f);
-        fail("testInvalidSTD3 failed to throw exception: "+expectedException);
-    } catch(NormalizerException actualException) {
-      assertEquals(expectedException.toString(), actualException.toString());
-    }
+
+    NormalizerException ex = SolrTestCaseJ4.expectThrows(NormalizerException.class,
+        () -> implTestStandard(params, 1f, 0f)
+    );
+    assertEquals(expectedException.toString(), ex.toString());
   }
 
   @Test
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java
index 4fe9523..9ee1ad4 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/store/rest/TestManagedFeatureStore.java
@@ -129,20 +129,15 @@ public class TestManagedFeatureStore extends SolrTestCaseJ4 {
   }
 
   @Test
-  public void getInvalidInstanceTest()
-  {
+  public void getInvalidInstanceTest() {
     final String nonExistingClassName = "org.apache.solr.ltr.feature.LOLFeature";
     final ClassNotFoundException expectedException =
         new ClassNotFoundException(nonExistingClassName);
-    try {
-      fstore.addFeature(createMap("test",
-          nonExistingClassName, null),
-          "testFstore2");
-      fail("getInvalidInstanceTest failed to throw exception: "+expectedException);
-    } catch (Exception actualException) {
-      Throwable rootError = getRootCause(actualException);
-      assertEquals(expectedException.toString(), rootError.toString());
-    }
+    Exception ex = expectThrows(Exception.class, () -> {
+      fstore.addFeature(createMap("test", nonExistingClassName, null), "testFstore2");
+    });
+    Throwable rootError = getRootCause(ex);
+    assertEquals(expectedException.toString(), rootError.toString());
   }
 
 }
diff --git a/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java b/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
index 1a8a913..e36624e 100644
--- a/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
+++ b/solr/contrib/velocity/src/test/org/apache/solr/velocity/VelocityResponseWriterTest.java
@@ -16,20 +16,20 @@
  */
 package org.apache.solr.velocity;
 
+import java.io.IOException;
+import java.io.StringWriter;
+
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.QueryResponseWriter;
 import org.apache.solr.response.SolrParamResourceLoader;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.response.VelocityResponseWriter;
-import org.apache.solr.request.SolrQueryRequest;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import java.io.IOException;
-import java.io.StringWriter;
-
 public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
   @BeforeClass
   public static void beforeClass() throws Exception {
@@ -66,12 +66,7 @@ public class VelocityResponseWriterTest extends SolrTestCaseJ4 {
         SolrParamResourceLoader.TEMPLATE_PARAM_PREFIX+"custom","$response.response.response_data");
     SolrQueryResponse rsp = new SolrQueryResponse();
     StringWriter buf = new StringWriter();
-    try {
-      vrw.write(buf, req, rsp);
-      fail("Should have thrown exception due to missing template");
-    } catch (IOException e) {
-      // expected exception
-    }
+    expectThrows(IOException.class, () -> vrw.write(buf, req, rsp));
   }
 
   @Test
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 5a8c915..0edd0ea 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
@@ -24,10 +24,8 @@ import java.util.Map;
 
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.api.ApiBag;
-import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.request.schema.SchemaRequest;
 import org.apache.solr.client.solrj.response.schema.SchemaResponse;
-import org.apache.solr.client.solrj.response.schema.SchemaResponse.FieldResponse;
 import org.apache.solr.common.SolrException;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -73,15 +71,9 @@ public class TestEmbeddedSolrServerSchemaAPI extends SolrTestCaseJ4 {
   }
 
   @Before
-  public void thereIsNoFieldYet() throws SolrServerException, IOException{
-    try{
-      FieldResponse process = new SchemaRequest.Field(fieldName)
-                  .process(server);
-      fail(""+process);
-    }catch(SolrException e){
-      assertTrue(e.getMessage().contains("No")
-           && e.getMessage().contains("VerificationTest"));
-    }
+  public void thereIsNoFieldYet() {
+    SolrException ex = expectThrows(SolrException.class, () -> new SchemaRequest.Field(fieldName).process(server));
+    assertTrue(ex.getMessage().contains("No") && ex.getMessage().contains("VerificationTest"));
   }
   
   @Test
diff --git a/solr/core/src/test/org/apache/solr/core/PluginInfoTest.java b/solr/core/src/test/org/apache/solr/core/PluginInfoTest.java
index a567eb2..77ffc99 100644
--- a/solr/core/src/test/org/apache/solr/core/PluginInfoTest.java
+++ b/solr/core/src/test/org/apache/solr/core/PluginInfoTest.java
@@ -95,6 +95,7 @@ public class PluginInfoTest extends DOMUtilTestBase {
     PluginInfo pi2 = new PluginInfo(nodeWithAClass, "Node with a Class", false, true);
     assertTrue(pi2.className.equals("myName"));
   }
+
   @Test
   public void testIsEnabled() throws Exception {
     Node node = getNode("<plugin enable=\"true\" />", "plugin");
@@ -105,6 +106,7 @@ public class PluginInfoTest extends DOMUtilTestBase {
     assertFalse(pi.isEnabled());
     
   }
+
   @Test
   public void testIsDefault() throws Exception {
     Node node = getNode("<plugin default=\"true\" />", "plugin");
@@ -115,6 +117,7 @@ public class PluginInfoTest extends DOMUtilTestBase {
     assertFalse(pi.isDefault());
     
   }
+
   @Test
   public void testNoChildren() throws Exception{
     Node node = getNode(configWithNoChildren, "/plugin");
@@ -143,9 +146,8 @@ public class PluginInfoTest extends DOMUtilTestBase {
     PluginInfo pi2 = new PluginInfo(node2, "with No Children", false, false);
     PluginInfo noChild = pi2.getChild("long");
     assertNull(noChild);
-    
-    
   }
+
   @Test
   public void testChildren() throws Exception {
     Node node = getNode(configWith2Children, "plugin");
@@ -157,6 +159,7 @@ public class PluginInfoTest extends DOMUtilTestBase {
       assertTrue( childInfo instanceof PluginInfo );
     }
   }
+
   @Test
   public void testInitArgsCount() throws Exception {
     Node node = getNode(configWithNoChildren, "plugin");
diff --git a/solr/core/src/test/org/apache/solr/handler/FieldAnalysisRequestHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/FieldAnalysisRequestHandlerTest.java
index b233d11..e3c9d07 100644
--- a/solr/core/src/test/org/apache/solr/handler/FieldAnalysisRequestHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/FieldAnalysisRequestHandlerTest.java
@@ -156,15 +156,9 @@ public class FieldAnalysisRequestHandlerTest extends AnalysisRequestHandlerTestB
     params.remove(CommonParams.Q);
     params.remove(AnalysisParams.QUERY);
     params.remove(AnalysisParams.FIELD_VALUE);
-    try {
-      request = handler.resolveAnalysisRequest(req);
-      fail("Analysis request must fail if all of q, analysis.query or analysis.value are absent");
-    } catch (SolrException e) {
-      if (e.code() != SolrException.ErrorCode.BAD_REQUEST.code)  {
-        fail("Unexpected exception");
-      }
-    } catch (Exception e) {
-      fail("Unexpected exception");
+    try (SolrQueryRequest solrQueryRequest = new LocalSolrQueryRequest(h.getCore(), params)) {
+      SolrException ex = expectThrows(SolrException.class, () -> handler.resolveAnalysisRequest(solrQueryRequest));
+      assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, ex.code());
     }
 
     req.close();
diff --git a/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java b/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java
index 5c2292c..6c3a23a 100644
--- a/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java
@@ -93,7 +93,7 @@ public class JsonLoaderTest extends SolrTestCaseJ4 {
     // 
     add = p.addCommands.get(1);
     assertEquals("SolrInputDocument(fields: [f1=[v1, v2], f2=null])", add.solrDoc.toString());
-    assertEquals(false, add.overwrite);
+    assertFalse(add.overwrite);
 
     // parse the commit commands
     assertEquals( 2, p.commitCommands.size() );
@@ -112,21 +112,21 @@ public class JsonLoaderTest extends SolrTestCaseJ4 {
     assertEquals( 4, p.deleteCommands.size() );
     DeleteUpdateCommand delete = p.deleteCommands.get( 0 );
     assertEquals( delete.id, "ID" );
-    assertEquals( delete.query, null );
+    assertNull( delete.query );
     assertEquals( delete.commitWithin, -1);
     
     delete = p.deleteCommands.get( 1 );
     assertEquals( delete.id, "ID" );
-    assertEquals( delete.query, null );
+    assertNull( delete.query );
     assertEquals( delete.commitWithin, 500);
     
     delete = p.deleteCommands.get( 2 );
-    assertEquals( delete.id, null );
+    assertNull( delete.id );
     assertEquals( delete.query, "QUERY" );
     assertEquals( delete.commitWithin, -1);
     
     delete = p.deleteCommands.get( 3 );
-    assertEquals( delete.id, null );
+    assertNull( delete.id );
     assertEquals( delete.query, "QUERY" );
     assertEquals( delete.commitWithin, 500);
 
@@ -153,36 +153,31 @@ public class JsonLoaderTest extends SolrTestCaseJ4 {
     SolrInputField f = d.getField( "id" );
     assertEquals("1", f.getValue());
     assertEquals(add.commitWithin, 100);
-    assertEquals(add.overwrite, false);
+    assertFalse(add.overwrite);
 
     add = p.addCommands.get(1);
     d = add.solrDoc;
     f = d.getField( "id" );
     assertEquals("2", f.getValue());
     assertEquals(add.commitWithin, 100);
-    assertEquals(add.overwrite, false);
+    assertFalse(add.overwrite);
 
     req.close();
   }
 
   @Test
-  public void testInvalidJsonProducesBadRequestSolrException() throws Exception
-  {
+  public void testInvalidJsonProducesBadRequestSolrException() throws Exception {
     SolrQueryResponse rsp = new SolrQueryResponse();
     BufferingRequestProcessor p = new BufferingRequestProcessor(null);
     JsonLoader loader = new JsonLoader();
     String invalidJsonString = "}{";
-    
-    try(SolrQueryRequest req = req()) {
-      try {
-        loader.load(req, rsp, new ContentStreamBase.StringStream(invalidJsonString), p);
-        fail("Expected invalid JSON to produce a SolrException.");
-      } catch (SolrException expectedException) {
-        assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, expectedException.code());
-        assertTrue(expectedException.getMessage().contains("Cannot parse"));
-        assertTrue(expectedException.getMessage().contains("JSON"));
-      }
-    }
+
+    SolrException ex = expectThrows(SolrException.class, () -> {
+      loader.load(req(), rsp, new ContentStreamBase.StringStream(invalidJsonString), p);
+    });
+    assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, ex.code());
+    assertTrue(ex.getMessage().contains("Cannot parse"));
+    assertTrue(ex.getMessage().contains("JSON"));
   }
 
   public void testSimpleFormatInAdd() throws Exception
@@ -201,14 +196,14 @@ public class JsonLoaderTest extends SolrTestCaseJ4 {
     SolrInputField f = d.getField( "id" );
     assertEquals("1", f.getValue());
     assertEquals(add.commitWithin, -1);
-    assertEquals(add.overwrite, true);
+    assertTrue(add.overwrite);
 
     add = p.addCommands.get(1);
     d = add.solrDoc;
     f = d.getField( "id" );
     assertEquals("2", f.getValue());
     assertEquals(add.commitWithin, -1);
-    assertEquals(add.overwrite, true);
+    assertTrue(add.overwrite);
 
     req.close();
   }
@@ -636,25 +631,17 @@ public class JsonLoaderTest extends SolrTestCaseJ4 {
 
     ignoreException("big_integer_t");
 
-    try {
+    SolrException ex = expectThrows(SolrException.class, () -> {
       updateJ(json( "[{'id':'1','big_integer_tl':12345678901234567890}]" ), null);
-      fail("A BigInteger value should overflow a long field");
-    } catch (SolrException e) {
-      if ( ! (e.getCause() instanceof NumberFormatException)) {
-        throw e;
-      }
-    }
+    });
+    assertTrue(ex.getCause() instanceof NumberFormatException);
 
     // Adding a BigInteger to an integer field should fail
     // BigInteger.intValue() returns only the low-order 32 bits.
-    try {
+    ex = expectThrows(SolrException.class, () -> {
       updateJ(json( "[{'id':'1','big_integer_ti':12345678901234567890}]" ), null);
-      fail("A BigInteger value should overflow an integer field");
-    } catch (SolrException e) {
-      if ( ! (e.getCause() instanceof NumberFormatException)) {
-        throw e;
-      }
-    }
+    });
+    assertTrue(ex.getCause() instanceof NumberFormatException);
 
     unIgnoreException("big_integer_t");
   }
@@ -1007,5 +994,4 @@ public class JsonLoaderTest extends SolrTestCaseJ4 {
 
   }
 
-
 }
diff --git a/solr/core/src/test/org/apache/solr/handler/PingRequestHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/PingRequestHandlerTest.java
index 166b0b9..3b3edb3 100644
--- a/solr/core/src/test/org/apache/solr/handler/PingRequestHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/PingRequestHandlerTest.java
@@ -162,13 +162,8 @@ public class PingRequestHandlerTest extends SolrTestCaseJ4 {
   }
   
   public void testBadActionRaisesException() throws Exception {
-    
-    try {
-      SolrQueryResponse rsp = makeRequest(handler, req("action", "badaction"));
-      fail("Should have thrown a SolrException for the bad action");
-    } catch (SolrException se){
-      assertEquals(SolrException.ErrorCode.BAD_REQUEST.code,se.code());
-    }
+    SolrException se = expectThrows(SolrException.class, () -> makeRequest(handler, req("action", "badaction")));
+    assertEquals(SolrException.ErrorCode.BAD_REQUEST.code,se.code());
   }
 
  public void testPingInClusterWithNoHealthCheck() throws Exception {
diff --git a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
index 797f0a7..e18d0b8 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
@@ -1512,10 +1512,8 @@ public class TestReplicationHandler extends SolrTestCaseJ4 {
     List<String> params = Arrays.asList(ReplicationHandler.FILE, ReplicationHandler.CONF_FILE_SHORT, ReplicationHandler.TLOG_FILE);
     for (String param : params) {
       for (String filename : illegalFilenames) {
-        try {
-          invokeReplicationCommand(masterJetty.getLocalPort(), "filecontent&" + param + "=" + filename);
-          fail("Should have thrown exception on illegal path for param " + param + " and file name " + filename);
-        } catch (Exception e) {}
+        expectThrows(Exception.class, () ->
+            invokeReplicationCommand(masterJetty.getLocalPort(), "filecontent&" + param + "=" + filename));
       }
     }
   }
diff --git a/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java b/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java
index 8f04f26..ab12439 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java
@@ -139,8 +139,6 @@ public class TestRestoreCore extends SolrJettyTestBase {
       Thread.sleep(1000);
     }
 
-
-
     int numRestoreTests = nDocs > 0 ? TestUtil.nextInt(random(), 1, 5) : 1;
 
     for (int attempts=0; attempts<numRestoreTests; attempts++) {
diff --git a/solr/core/src/test/org/apache/solr/handler/TestSQLHandlerNonCloud.java b/solr/core/src/test/org/apache/solr/handler/TestSQLHandlerNonCloud.java
index 59e1eea..842272a 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestSQLHandlerNonCloud.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestSQLHandlerNonCloud.java
@@ -54,12 +54,8 @@ public class TestSQLHandlerNonCloud extends SolrJettyTestBase {
     String url = jetty.getBaseUrl() + "/" + DEFAULT_TEST_COLLECTION_NAME;
 
     SolrStream solrStream = new SolrStream(url, sParams);
-    try {
-      getTuples(solrStream);
-      fail(SQLHandler.sqlNonCloudErrorMsg);
-    } catch (IOException e) {
-      assertTrue(e.getMessage().contains(SQLHandler.sqlNonCloudErrorMsg));
-    }
+    IOException ex = expectThrows(IOException.class,  () -> getTuples(solrStream));
+    assertTrue(ex.getMessage().contains(SQLHandler.sqlNonCloudErrorMsg));
   }
 
   private List<Tuple> getTuples(TupleStream tupleStream) throws IOException {
diff --git a/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java b/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
index 834a96e..f82c238 100644
--- a/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
@@ -71,13 +71,9 @@ public class V2ApiIntegrationTest extends SolrCloudTestCase {
         .withPayload(payload)
         .build();
     v2Request.setResponseParser(responseParser);
-    try {
-      v2Request.process(cluster.getSolrClient());
-      fail("expected an exception with error code: "+expectedCode);
-    } catch (HttpSolrClient.RemoteExecutionException e) {
-      assertEquals(expectedCode, e.code());
-
-    }
+    HttpSolrClient.RemoteSolrException ex =  expectThrows(HttpSolrClient.RemoteSolrException.class,
+        () -> v2Request.process(cluster.getSolrClient()));
+    assertEquals(expectedCode, ex.code());
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminCreateDiscoverTest.java b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminCreateDiscoverTest.java
index 41807c7..0c12318 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminCreateDiscoverTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminCreateDiscoverTest.java
@@ -164,8 +164,7 @@ public class CoreAdminCreateDiscoverTest extends SolrTestCaseJ4 {
     assertNull("Exception on create", resp.getException());
 
     // Try to create another core with a different name, but the same instance dir
-    SolrQueryResponse resp2 = new SolrQueryResponse();
-    try {
+    SolrException e = expectThrows(SolrException.class, () -> {
       admin.handleRequestBody
           (req(CoreAdminParams.ACTION,
               CoreAdminParams.CoreAdminAction.CREATE.toString(),
@@ -174,13 +173,9 @@ public class CoreAdminCreateDiscoverTest extends SolrTestCaseJ4 {
               CoreAdminParams.CONFIG, "solrconfig_ren.xml",
               CoreAdminParams.SCHEMA, "schema_ren.xml",
               CoreAdminParams.DATA_DIR, data.getAbsolutePath()),
-              resp2);
-      fail("Creating two cores with a shared instance dir should throw an exception");
-    }
-    catch (SolrException e) {
-      assertTrue(e.getMessage().contains("already defined there"));
-    }
-
+              new SolrQueryResponse());
+    });
+    assertTrue(e.getMessage().contains("already defined there"));
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java
index 2c68320..bafd6ca 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminHandlerTest.java
@@ -138,17 +138,16 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
 
     SolrQueryResponse resp = new SolrQueryResponse();
     // Sneaking in a test for using a bad core name
-    try {
+    SolrException se = expectThrows(SolrException.class, () -> {
       admin.handleRequestBody
           (req(CoreAdminParams.ACTION,
               CoreAdminParams.CoreAdminAction.CREATE.toString(),
               CoreAdminParams.INSTANCE_DIR, instPropFile.getAbsolutePath(),
               CoreAdminParams.NAME, "ugly$core=name"),
-              resp);
+              new SolrQueryResponse());
+    });
+    assertTrue("Expected error message for bad core name.", se.toString().contains("Invalid core"));
 
-    } catch (SolrException se) {
-      assertTrue("Expected error message for bad core name.", se.toString().contains("Invalid core"));
-    }
     CoreDescriptor cd = cores.getCoreDescriptor("ugly$core=name");
     assertNull("Should NOT have added this core!", cd);
 
@@ -171,19 +170,17 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
 
     // attempt to create a bogus core and confirm failure
     ignoreException("Could not load config");
-    try {
-      resp = new SolrQueryResponse();
+    se = expectThrows(SolrException.class, () -> {
       admin.handleRequestBody
-        (req(CoreAdminParams.ACTION, 
-             CoreAdminParams.CoreAdminAction.CREATE.toString(),
-             CoreAdminParams.NAME, "bogus_dir_core",
-             CoreAdminParams.INSTANCE_DIR, "dir_does_not_exist_127896"),
-         resp);
-      fail("bogus collection created ok");
-    } catch (SolrException e) {
-      // :NOOP:
-      // :TODO: CoreAdminHandler's exception messages are terrible, otherwise we could assert something useful here
-    }
+          (req(CoreAdminParams.ACTION,
+              CoreAdminParams.CoreAdminAction.CREATE.toString(),
+              CoreAdminParams.NAME, "bogus_dir_core",
+              CoreAdminParams.INSTANCE_DIR, "dir_does_not_exist_127896"),
+              new SolrQueryResponse());
+    });
+    // :NOOP:
+    // :TODO: CoreAdminHandler's exception messages are terrible, otherwise we could assert something useful here
+
     unIgnoreException("Could not load config");
 
     // check specifically for status of the failed core name
@@ -228,16 +225,15 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
     assertNotNull("Core should have been renamed!", cd);
 
     // Rename it something bogus and see if you get an exception, the old core is still there and the bogus one isn't
-    try {
+    se = expectThrows(SolrException.class, () -> {
       admin.handleRequestBody
           (req(CoreAdminParams.ACTION,
               CoreAdminParams.CoreAdminAction.RENAME.toString(),
               CoreAdminParams.CORE, "rename_me",
               CoreAdminParams.OTHER, "bad$name"),
-              resp);
-    } catch (SolrException e) { // why the heck does create return a SolrException (admittedly wrapping an IAE)
-      assertTrue("Expected error message for bad core name.", e.getMessage().contains("Invalid core"));
-    }
+              new SolrQueryResponse());
+    });
+    assertTrue("Expected error message for bad core name.", se.getMessage().contains("Invalid core"));
 
     cd = cores.getCoreDescriptor("bad$name");
     assertNull("Core should NOT exist!", cd);
@@ -245,8 +241,6 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
     cd = cores.getCoreDescriptor("rename_me");
     assertNotNull("Core should have been renamed!", cd);
 
-
-
     // :TODO: because of SOLR-3665 we can't ask for status from all cores
 
   }
@@ -385,11 +379,8 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
     FileUtils.copyFile(new File(top, "bad-error-solrconfig.xml"), new File(subHome, "solrconfig.xml"));
 
     try (HttpSolrClient client = getHttpSolrClient(runner.getBaseUrl().toString(), DEFAULT_CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT)) {
-      try {
-        CoreAdminRequest.reloadCore("corex", client);
-      } catch (Exception e) {
-        // this is expected because we put a bad solrconfig -- ignore
-      }
+      // this is expected because we put a bad solrconfig -- ignore
+      expectThrows(Exception.class, () -> CoreAdminRequest.reloadCore("corex", client));
 
       CoreAdminRequest.Unload req = new CoreAdminRequest.Unload(false);
       req.setDeleteDataDir(true);
@@ -408,31 +399,22 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
     final CoreAdminHandler admin = new CoreAdminHandler(h.getCoreContainer());
     SolrQueryResponse resp = new SolrQueryResponse();
 
-    try {
+    SolrException e = expectThrows(SolrException.class, () -> {
       admin.handleRequestBody(
           req(CoreAdminParams.ACTION,
               CoreAdminParams.CoreAdminAction.RELOAD.toString(),
               CoreAdminParams.CORE, "non-existent-core")
           , resp);
-      fail("Was able to successfully reload non-existent-core");
-    } catch (Exception e) {
-      assertEquals("Expected error message for non-existent core.", "No such core: non-existent-core", e.getMessage());
-    }
+    });
+    assertEquals("Expected error message for non-existent core.", "No such core: non-existent-core", e.getMessage());
 
     // test null core
-    try {
+    e = expectThrows(SolrException.class, () -> {
       admin.handleRequestBody(
           req(CoreAdminParams.ACTION,
               CoreAdminParams.CoreAdminAction.RELOAD.toString())
           , resp);
-      fail("Was able to successfully reload null core");
-    }
-    catch (Exception e) {
-      if (!(e instanceof SolrException)) {
-        fail("Expected SolrException but got " + e);
-      }
-      assertEquals("Expected error message for non-existent core.", "Missing required parameter: core", e.getMessage());
-    }
-
+    });
+    assertEquals("Expected error message for non-existent core.", "Missing required parameter: core", e.getMessage());
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminOperationTest.java b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminOperationTest.java
index 5d1b36c..cf55cc6 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminOperationTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/CoreAdminOperationTest.java
@@ -16,11 +16,9 @@
  */
 package org.apache.solr.handler.admin;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import java.util.Map;
 
+import com.google.common.collect.Maps;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
@@ -31,7 +29,8 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.google.common.collect.Maps;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class CoreAdminOperationTest extends SolrTestCaseJ4 {
   
@@ -61,100 +60,68 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
 
-    try {
-      CoreAdminOperation.STATUS_OP.execute(callInfo);
-      fail("Expected core-status execution to fail with exception");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+    Exception ex = expectThrows(Exception.class, () -> CoreAdminOperation.STATUS_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testUnloadUnexpectedFailuresResultIn500SolrException() throws Exception {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.UNLOAD_OP.execute(callInfo);
-      fail("Expected core-unload execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () -> CoreAdminOperation.UNLOAD_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testUnloadMissingCoreNameResultsIn400SolrException() throws Exception {
     whenCoreAdminOpHasParams(Maps.newHashMap());
-    
-    try {
-      CoreAdminOperation.UNLOAD_OP.execute(callInfo);
-      fail("Expected core-unload execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () -> CoreAdminOperation.UNLOAD_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testReloadUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.RELOAD_OP.execute(callInfo);
-      fail("Expected core-reload execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () -> CoreAdminOperation.RELOAD_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testReloadMissingCoreNameResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
-    
-    try {
-      CoreAdminOperation.RELOAD_OP.execute(callInfo);
-      fail("Expected core-reload execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () -> CoreAdminOperation.RELOAD_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testCreateUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.CREATE_OP.execute(callInfo);
-      fail("Expected core-create execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.CREATE_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testCreateMissingCoreNameResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
-    
-    try {
-      CoreAdminOperation.CREATE_OP.execute(callInfo);
-      fail("Expected core-create execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.CREATE_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testSwapUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.SWAP_OP.execute(callInfo);
-      fail("Expected core-swap execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.SWAP_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -162,13 +129,9 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     final Map<String, String> params = Maps.newHashMap();
     params.put("other", "some-core-name");
     whenCoreAdminOpHasParams(params);
-    
-    try {
-      CoreAdminOperation.SWAP_OP.execute(callInfo);
-      fail("Expected core-swap execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.SWAP_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
@@ -176,26 +139,18 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     final Map<String, String> params = Maps.newHashMap();
     params.put("core", "some-core-name");
     whenCoreAdminOpHasParams(params);
-    
-    try {
-      CoreAdminOperation.SWAP_OP.execute(callInfo);
-      fail("Expected core-swap execution to fail when no 'other' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.SWAP_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testRenameUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.RENAME_OP.execute(callInfo);
-      fail("Expected core-rename execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.RENAME_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -203,13 +158,9 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     final Map<String, String> params = Maps.newHashMap();
     params.put("other", "some-core-name");
     whenCoreAdminOpHasParams(params);
-    
-    try {
-      CoreAdminOperation.RENAME_OP.execute(callInfo);
-      fail("Expected core-rename execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.RENAME_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
@@ -217,26 +168,18 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     final Map<String, String> params = Maps.newHashMap();
     params.put("core", "some-core-name");
     whenCoreAdminOpHasParams(params);
-    
-    try {
-      CoreAdminOperation.RENAME_OP.execute(callInfo);
-      fail("Expected core-rename execution to fail when no 'other' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.RENAME_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testMergeUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.MERGEINDEXES_OP.execute(callInfo);
-      fail("Expected core-merge execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.MERGEINDEXES_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -244,203 +187,138 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     final Map<String, String> params = Maps.newHashMap();
     params.put("indexDir", "some/index/dir");
     whenCoreAdminOpHasParams(params);
-    
-    try {
-      CoreAdminOperation.MERGEINDEXES_OP.execute(callInfo);
-      fail("Expected core-merge execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.MERGEINDEXES_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testSplitUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.SPLIT_OP.execute(callInfo);
-      fail("Expected split execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.SPLIT_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testSplitMissingCoreParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
-    
-    try {
-      CoreAdminOperation.SPLIT_OP.execute(callInfo);
-      fail("Expected split execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.SPLIT_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testPrepRecoveryUnexpectedFailuresResultIn500SolrException() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.PREPRECOVERY_OP.execute(callInfo);
-      fail("Expected preprecovery execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.PREPRECOVERY_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testRequestRecoveryUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.REQUESTRECOVERY_OP.execute(callInfo);
-      fail("Expected request-recovery execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }    
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTRECOVERY_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testRequestRecoveryMissingCoreParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
-    
-    try {
-      CoreAdminOperation.REQUESTRECOVERY_OP.execute(callInfo);
-      fail("Expected request-recovery execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      thrown.printStackTrace();
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }  
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTRECOVERY_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testRequestSyncUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.REQUESTSYNCSHARD_OP.execute(callInfo);
-      fail("Expected request-sync execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTSYNCSHARD_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testRequestSyncMissingCoreParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
-    
-    try {
-      CoreAdminOperation.REQUESTSYNCSHARD_OP.execute(callInfo);
-      fail("Expected request-sync execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }      
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTSYNCSHARD_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testRequestBufferUpdatesUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.REQUESTBUFFERUPDATES_OP.execute(callInfo);
-      fail("Expected request-buffer-updates execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTBUFFERUPDATES_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testRequestBufferUpdatesMissingCoreParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
 
-    try {
-      CoreAdminOperation.REQUESTBUFFERUPDATES_OP.execute(callInfo);
-      fail("Expected request-buffer-updates execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTBUFFERUPDATES_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testRequestApplyUpdatesUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.REQUESTAPPLYUPDATES_OP.execute(callInfo);
-      fail("Expected request-apply-updates execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }    
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTAPPLYUPDATES_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testRequestApplyUpdatesMissingCoreParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
 
-    try {
-      CoreAdminOperation.REQUESTAPPLYUPDATES_OP.execute(callInfo);
-      fail("Expected request-apply-updates execution to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }    
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTAPPLYUPDATES_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
 
   @Test
   public void testOverseerOpUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.OVERSEEROP_OP.execute(callInfo);
-      fail("Expected overseerop execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.SERVER_ERROR.code);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.OVERSEEROP_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.SERVER_ERROR.code);
   }
   
   @Test
   public void testRequestStatusUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.REQUESTSTATUS_OP.execute(callInfo);
-      fail("Expected request-status execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTSTATUS_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testRequestStatusMissingRequestIdParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
 
-    try {
-      CoreAdminOperation.REQUESTSTATUS_OP.execute(callInfo);
-      fail("Expected request-status execution to fail when no 'requestid' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }    
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REQUESTSTATUS_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
 
   @Test
   public void testRejoinLeaderElectionUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.REJOINLEADERELECTION_OP.execute(callInfo);
-      fail("Expected rejoin-leader-election execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.SERVER_ERROR.code);
-    }    
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.REJOINLEADERELECTION_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.SERVER_ERROR.code);
   }
  
 
@@ -448,38 +326,26 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
   public void testInvokeUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.INVOKE_OP.execute(callInfo);
-      fail("Expected invoke execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }    
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.INVOKE_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testInvokeMissingClassParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
 
-    try {
-      CoreAdminOperation.INVOKE_OP.execute(callInfo);
-      fail("Expected invoke to fail when no 'class' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }    
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.INVOKE_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testBackupUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.BACKUPCORE_OP.execute(callInfo);
-      fail("Expected backup-core execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }  
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.BACKUPCORE_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -488,12 +354,8 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("name", "any-name-param");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.BACKUPCORE_OP.execute(callInfo);
-      fail("Expected backup-core to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.BACKUPCORE_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
@@ -502,25 +364,17 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("core", "any-core-param");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.BACKUPCORE_OP.execute(callInfo);
-      fail("Expected backup-core to fail when no 'name' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.BACKUPCORE_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testRestoreUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.RESTORECORE_OP.execute(callInfo);
-      fail("Expected restore-core execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }  
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.RESTORECORE_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -529,12 +383,8 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("name", "any-name-param");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.RESTORECORE_OP.execute(callInfo);
-      fail("Expected restore-core to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.RESTORECORE_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
@@ -543,25 +393,17 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("core", "any-core-param");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.RESTORECORE_OP.execute(callInfo);
-      fail("Expected restore-core to fail when no 'name' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.RESTORECORE_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testCreateSnapshotUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.CREATESNAPSHOT_OP.execute(callInfo);
-      fail("Expected create-snapshot execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }  
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.CREATESNAPSHOT_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -570,12 +412,8 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("commitName", "anyCommitName");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.CREATESNAPSHOT_OP.execute(callInfo);
-      fail("Expected create-snapshot to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.CREATESNAPSHOT_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
@@ -584,25 +422,17 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("core", "any-core-param");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.CREATESNAPSHOT_OP.execute(callInfo);
-      fail("Expected create-snapshot to fail when no 'commitName' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.CREATESNAPSHOT_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testDeleteSnapshotUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.DELETESNAPSHOT_OP.execute(callInfo);
-      fail("Expected delete-snapshot execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }  
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.DELETESNAPSHOT_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
@@ -611,12 +441,8 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("commitName", "anyCommitName");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.DELETESNAPSHOT_OP.execute(callInfo);
-      fail("Expected delete-snapshot to fail when no 'core' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.DELETESNAPSHOT_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
@@ -625,37 +451,25 @@ public class CoreAdminOperationTest extends SolrTestCaseJ4 {
     params.put("core", "any-core-param");
     whenCoreAdminOpHasParams(params);
 
-    try {
-      CoreAdminOperation.DELETESNAPSHOT_OP.execute(callInfo);
-      fail("Expected delete-snapshot to fail when no 'commitName' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }   
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.DELETESNAPSHOT_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   @Test
   public void testListSnapshotUnexpectedFailuresResultIn500Exception() {
     final Throwable cause = new NullPointerException();
     whenUnexpectedErrorOccursDuringCoreAdminOp(cause);
-    
-    try {
-      CoreAdminOperation.LISTSNAPSHOTS_OP.execute(callInfo);
-      fail("Expected list-snapshot execution to fail with exception.");
-    } catch  (Exception thrown) {
-      assertSolrExceptionWithCodeAndCause(thrown, ErrorCode.SERVER_ERROR.code, cause);
-    }  
+
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.LISTSNAPSHOTS_OP.execute(callInfo));
+    assertSolrExceptionWithCodeAndCause(ex, ErrorCode.SERVER_ERROR.code, cause);
   }
   
   @Test
   public void testListSnapshotMissingCoreParamResultsIn400SolrException() {
     whenCoreAdminOpHasParams(Maps.newHashMap());
 
-    try {
-      CoreAdminOperation.LISTSNAPSHOTS_OP.execute(callInfo);
-      fail("Expected list-snapshot to fail when no 'commitName' param present");
-    } catch (Exception thrown) {
-      assertSolrExceptionWithCode(thrown, ErrorCode.BAD_REQUEST.code);
-    }  
+    Exception ex = expectThrows(Exception.class, () ->  CoreAdminOperation.LISTSNAPSHOTS_OP.execute(callInfo));
+    assertSolrExceptionWithCode(ex, ErrorCode.BAD_REQUEST.code);
   }
   
   private void whenUnexpectedErrorOccursDuringCoreAdminOp(Throwable cause) {
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/CoreMergeIndexesAdminHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/CoreMergeIndexesAdminHandlerTest.java
index e444f20..d593b73 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/CoreMergeIndexesAdminHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/CoreMergeIndexesAdminHandlerTest.java
@@ -84,17 +84,14 @@ public class CoreMergeIndexesAdminHandlerTest extends SolrTestCaseJ4 {
       try {
         dirFactory.fail = true;
         ignoreException(WRAPPED_FAILING_MSG);
-
-        SolrQueryResponse resp = new SolrQueryResponse();
-        admin.handleRequestBody
-            (req(CoreAdminParams.ACTION,
-                CoreAdminParams.CoreAdminAction.MERGEINDEXES.toString(),
-                CoreAdminParams.CORE, "collection1",
-                CoreAdminParams.INDEX_DIR, workDir.getAbsolutePath()),
-                resp);
-        fail("exception expected");
-      } catch (SolrException e) {
-        // expected if error handling properly
+        SolrException e = expectThrows(SolrException.class, () -> {
+          admin.handleRequestBody
+              (req(CoreAdminParams.ACTION,
+                  CoreAdminParams.CoreAdminAction.MERGEINDEXES.toString(),
+                  CoreAdminParams.CORE, "collection1",
+                  CoreAdminParams.INDEX_DIR, workDir.getAbsolutePath()),
+                  new SolrQueryResponse());
+        });
         assertEquals(FailingDirectoryFactory.FailingDirectoryFactoryException.class, e.getCause().getClass());
       } finally {
         unIgnoreException(WRAPPED_FAILING_MSG);
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/InfoHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/InfoHandlerTest.java
index d4ae0de..f846145 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/InfoHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/InfoHandlerTest.java
@@ -49,22 +49,12 @@ public class InfoHandlerTest extends SolrTestCaseJ4 {
     rsp = handleRequest(infoHandler, "logging");
     
     assertNotNull(rsp.getValues().get("watcher"));
-    
-    try {
-      rsp = handleRequest(infoHandler, "info");
-      fail("Should have failed with not found");
-    } catch(SolrException e) {
-      assertEquals(404, e.code());
-    }
-    
-    try {
-      rsp = handleRequest(infoHandler, "");
-      fail("Should have failed with not found");
-    } catch(SolrException e) {
-      assertEquals(404, e.code());
-    }
 
-    
+    SolrException e = expectThrows(SolrException.class, () -> handleRequest(infoHandler, "info"));
+    assertEquals(404, e.code());
+
+    e = expectThrows(SolrException.class, () -> handleRequest(infoHandler, ""));
+    assertEquals(404, e.code());
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/ShowFileRequestHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/ShowFileRequestHandlerTest.java
index ad82b2e..ee8695b 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/ShowFileRequestHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/ShowFileRequestHandlerTest.java
@@ -16,6 +16,11 @@
  */
 package org.apache.solr.handler.admin;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import org.apache.solr.SolrJettyTestBase;
 import org.apache.solr.client.solrj.ResponseParser;
 import org.apache.solr.client.solrj.SolrClient;
@@ -28,11 +33,6 @@ import org.apache.solr.core.SolrCore;
 import org.apache.solr.response.SolrQueryResponse;
 import org.junit.BeforeClass;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 /**
  * Extend SolrJettyTestBase because the SOLR-2535 bug only manifested itself when
  * the {@link org.apache.solr.servlet.SolrDispatchFilter} is used, which isn't for embedded Solr use.
@@ -44,17 +44,13 @@ public class ShowFileRequestHandlerTest extends SolrJettyTestBase {
     createAndStartJetty(legacyExampleCollection1SolrHome());
   }
 
-  public void test404ViaHttp() throws SolrServerException, IOException {
+  public void test404ViaHttp() throws Exception {
     SolrClient client = getSolrClient();
     QueryRequest request = new QueryRequest(params("file",
                                                    "does-not-exist-404.txt"));
     request.setPath("/admin/file");
-    try {
-      QueryResponse resp = request.process(client);
-      fail("didn't get 404 exception");
-    } catch (SolrException e) {
-      assertEquals(404, e.code());
-    }
+    SolrException e = expectThrows(SolrException.class, () -> request.process(client));
+    assertEquals(404, e.code());
   }
 
   public void test404Locally() throws Exception {
@@ -62,21 +58,17 @@ public class ShowFileRequestHandlerTest extends SolrJettyTestBase {
     // we need to test that executing the handler directly does not 
     // throw an exception, just sets the exception on the response.
     initCore("solrconfig.xml", "schema.xml");
-    try {
-      // bypass TestHarness since it will throw any exception found in the
-      // response.
-      SolrCore core = h.getCore();
-      SolrQueryResponse rsp = new SolrQueryResponse();
-      core.execute(core.getRequestHandler("/admin/file"),
-                   req("file", "does-not-exist-404.txt"), rsp);
-      assertNotNull("no exception in response", rsp.getException());
-      assertTrue("wrong type of exception: " + rsp.getException().getClass(),
-                 rsp.getException() instanceof SolrException);
-      assertEquals(404, ((SolrException)rsp.getException()).code());
 
-    } catch (Exception e) {
-      assertNull("Should not have caught an exception", e);
-    }
+    // bypass TestHarness since it will throw any exception found in the
+    // response.
+    SolrCore core = h.getCore();
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    core.execute(core.getRequestHandler("/admin/file"),
+        req("file", "does-not-exist-404.txt"), rsp);
+    assertNotNull("no exception in response", rsp.getException());
+    assertTrue("wrong type of exception: " + rsp.getException().getClass(),
+        rsp.getException() instanceof SolrException);
+    assertEquals(404, ((SolrException)rsp.getException()).code());
   }
 
   public void testDirList() throws SolrServerException, IOException {
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
index aa3bac6..e2e0cad 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
@@ -71,13 +71,11 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 {
     assertEquals("X1", x[0]);
     assertEquals("X2", x[1]);
     assertEquals("Y", m.get("y"));
-    try {
-      CollectionsHandler.copy(params.required(), null, "z");
-      fail("Error expected");
-    } catch (SolrException e) {
-      assertEquals(e.code(), SolrException.ErrorCode.BAD_REQUEST.code);
 
-    }
+    SolrException e = expectThrows(SolrException.class, () -> {
+      CollectionsHandler.copy(params.required(), null, "z");
+    });
+    assertEquals(e.code(), SolrException.ErrorCode.BAD_REQUEST.code);
   }
 
   public void testCommands() throws Exception {
@@ -208,12 +206,9 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 {
   
   static void assertErrorContains(final ApiBag apiBag, final String path, final SolrRequest.METHOD method,
       final String payload, final CoreContainer cc, String expectedErrorMsg) throws Exception {
-    try {
-      makeCall(apiBag, path, method, payload, cc);
-      fail("Expected exception");
-    } catch (RuntimeException e) {
-      assertTrue("Expected exception with error message '" + expectedErrorMsg + "' but got: " + e.getMessage(), e.getMessage().contains(expectedErrorMsg));
-    }
+    RuntimeException e = expectThrows(RuntimeException.class, () -> makeCall(apiBag, path, method, payload, cc));
+    assertTrue("Expected exception with error message '" + expectedErrorMsg + "' but got: " + e.getMessage(),
+        e.getMessage().contains(expectedErrorMsg));
   }
 
   public static Pair<SolrQueryRequest, SolrQueryResponse> makeCall(final ApiBag apiBag, String path,
diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java
index 398d463..49b7ece 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedDebugComponentTest.java
@@ -16,6 +16,17 @@
  */
 package org.apache.solr.handler.component;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.solr.SolrJettyTestBase;
 import org.apache.solr.client.solrj.SolrClient;
@@ -33,17 +44,6 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
 public class DistributedDebugComponentTest extends SolrJettyTestBase {
   
   private static SolrClient collection1;
@@ -395,14 +395,11 @@ public class DistributedDebugComponentTest extends SolrJettyTestBase {
     query.set("distrib", "true");
     query.setFields("id", "text");
     query.set("shards", shard1 + "," + shard2 + "," + badShard);
-    try {
-      ignoreException("Server refused connection");
-      // verify that the request would fail if shards.tolerant=false
-      collection1.query(query);
-      fail("Expecting exception");
-    } catch (SolrException e) {
-      //expected
-    }
+
+    // verify that the request would fail if shards.tolerant=false
+    ignoreException("Server refused connection");
+    expectThrows(SolrException.class, () -> collection1.query(query));
+
     query.set(ShardParams.SHARDS_TOLERANT, "true");
     QueryResponse response = collection1.query(query);
     assertTrue((Boolean)response.getResponseHeader().get(SolrQueryResponse.RESPONSE_HEADER_PARTIAL_RESULTS_KEY));
diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetExistsSmallTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetExistsSmallTest.java
index 0c381e9..1116dc9 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetExistsSmallTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetExistsSmallTest.java
@@ -16,8 +16,6 @@
  */
 package org.apache.solr.handler.component;
 
-import static org.hamcrest.CoreMatchers.is;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.Random;
@@ -32,6 +30,8 @@ import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.junit.Before;
 
+import static org.hamcrest.CoreMatchers.is;
+
 public class DistributedFacetExistsSmallTest extends BaseDistributedSearchTestCase {
 
   public static final String FLD = "t_s";
@@ -150,8 +150,8 @@ public class DistributedFacetExistsSmallTest extends BaseDistributedSearchTestCa
     } else {
       params.set("f."+FLD+".facet.mincount",  ""+(2+random().nextInt(100)) );
     }
-    
-    try {
+
+    SolrException e = expectThrows(SolrException.class, () -> {
       if (random().nextBoolean()) {
         setDistributedParams(params);
         queryServer(params);
@@ -159,13 +159,11 @@ public class DistributedFacetExistsSmallTest extends BaseDistributedSearchTestCa
         params.set("distrib", "false");
         controlClient.query(params);
       }
-      fail();
-    } catch(SolrException e) { // check that distr and single index search fail the same
-      assertEquals(e.code(), ErrorCode.BAD_REQUEST.code);
-      assertTrue(e.getMessage().contains("facet.exists"));
-      assertTrue(e.getMessage().contains("facet.mincount"));
-      assertTrue(e.getMessage().contains(FLD));
-    }
+    });
+    assertEquals(e.code(), ErrorCode.BAD_REQUEST.code);
+    assertTrue(e.getMessage().contains("facet.exists"));
+    assertTrue(e.getMessage().contains("facet.mincount"));
+    assertTrue(e.getMessage().contains(FLD));
   }
 
   private void checkBasicRequest() throws Exception {
diff --git a/solr/core/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java
index eebb4e4..3d18b9a 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java
@@ -85,32 +85,28 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 {
         ,"/spellcheck/suggestions/[0]=='brwn'"
         ,"/spellcheck/suggestions/[1]/numFound==1"
      );
-    try {
-      assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","lowerfilt:(this OR brwn)",
-          SpellingParams.SPELLCHECK_COUNT,"5", SpellingParams.SPELLCHECK_EXTENDED_RESULTS,"false", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, "6")
-          ,"/spellcheck/suggestions/[1]/numFound==1"
-       );
-      fail("there should have been no suggestions (6<7)");
-    } catch(Exception e) {
-      //correctly threw exception
-    }
+
+   expectThrows(Exception.class, () -> {
+     assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","lowerfilt:(this OR brwn)",
+         SpellingParams.SPELLCHECK_COUNT,"5", SpellingParams.SPELLCHECK_EXTENDED_RESULTS,"false", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, "6")
+         ,"/spellcheck/suggestions/[1]/numFound==1"
+     );
+   });
+
     assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","lowerfilt:(this OR brwn)",
         "fq", "id:[0 TO 9]", /*returns 10, less selective */ "fq", "lowerfilt:th*", /* returns 8, most selective */
         SpellingParams.SPELLCHECK_COUNT,"5", SpellingParams.SPELLCHECK_EXTENDED_RESULTS,"false", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, ".90")
         ,"/spellcheck/suggestions/[0]=='brwn'"
         ,"/spellcheck/suggestions/[1]/numFound==1"
      );
-    try {
+
+    expectThrows(Exception.class, () -> {
       assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","lowerfilt:(this OR brwn)",
           "fq", "id:[0 TO 9]", /*returns 10, less selective */ "fq", "lowerfilt:th*", /* returns 8, most selective */
           SpellingParams.SPELLCHECK_COUNT,"5", SpellingParams.SPELLCHECK_EXTENDED_RESULTS,"false", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, ".80")
           ,"/spellcheck/suggestions/[1]/numFound==1"
-       );
-      fail("there should have been no suggestions ((.8 * 8)<7)");
-    } catch(Exception e) {
-      //correctly threw exception
-    }
-    
+      );
+    });
     
     assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","lowerfilt:(this OR brwn)",
         "fq", "id:[0 TO 9]", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST_FQ, "id:[0 TO 9]", 
@@ -118,16 +114,14 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 {
         ,"/spellcheck/suggestions/[0]=='brwn'"
         ,"/spellcheck/suggestions/[1]/numFound==1"
      );
-    try {
+
+    expectThrows(Exception.class, () -> {
       assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellingParams.SPELLCHECK_BUILD, "true", "q","lowerfilt:(this OR brwn)",
-          "fq", "id:[0 TO 9]", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST_FQ, "lowerfilt:th*", 
+          "fq", "id:[0 TO 9]", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST_FQ, "lowerfilt:th*",
           SpellingParams.SPELLCHECK_COUNT,"5", SpellingParams.SPELLCHECK_EXTENDED_RESULTS,"false", SpellingParams.SPELLCHECK_MAX_RESULTS_FOR_SUGGEST, ".64")
           ,"/spellcheck/suggestions/[1]/numFound==1"
-       );
-      fail("there should have been no suggestions ((.64 * 10)<7)");
-    } catch(Exception e) {
-      //correctly threw exception
-    }
+      );
+    });
   } 
   
   @Test
diff --git a/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java
index 1049ec1..3fffc30 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java
@@ -279,9 +279,6 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
             );
   }
 
-  
-
-
   public void doTestMVFieldStatisticsResult(String f) throws Exception {
     assertU(adoc("id", "1", f, "-10", f, "-100", "active_s", "true"));
     assertU(adoc("id", "2", f, "-20", f, "200", "active_s", "true"));
@@ -1085,8 +1082,7 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     for (String param : new String[] { 
         "foo_i", "{!func}field(\"foo_i\")", "{!lucene}_val_:\"field(foo_i)\""
       }) {
-      SolrQueryRequest req = req(common);
-      try {
+      try (SolrQueryRequest req = req(common)){
         ResponseBuilder rb = new ResponseBuilder(req, new SolrQueryResponse(), components);
         
         StatsField sf = new StatsField(rb, param);
@@ -1096,8 +1092,6 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
 
         assertEquals("field name of: " + param,
                      "foo_i", sf.getSchemaField().getName());
-      } finally {
-        req.close();
       }
     }
 
@@ -1105,8 +1099,7 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     for (String param : new String[] { 
         "{!lucene}foo_t:cow", "{!func}query($nested)", "{!field f=foo_t}cow", 
       }) {
-      SolrQueryRequest req = req(common);
-      try {
+      try (SolrQueryRequest req = req(common)) {
         ResponseBuilder rb = new ResponseBuilder(req, new SolrQueryResponse(), components);
         
         StatsField sf = new StatsField(rb, param);
@@ -1119,8 +1112,6 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
         assertEquals("query of :" + param,
                      new TermQuery(new Term("foo_t","cow")),
                      qvs.getQuery());
-      } finally {
-        req.close();
       }
     }
   }
@@ -1792,27 +1783,25 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     ignoreException("hllPreHashed");
     for (SchemaField field : new SchemaField[] { foo_s, foo_i }) {
       // whitebox - field
-      try {
+      SolrException ex = expectThrows(SolrException.class, () -> {
         HllOptions.parseHllOptions(params("cardinality","true", "hllPreHashed", "true"), field);
-        fail("hllPreHashed should have failed for " + field.getName());
-      } catch (SolrException e) {
-        assertTrue("MSG: " + e.getMessage(),
-                   e.getMessage().contains("hllPreHashed is only supported with Long"));
-      }
+      });
+      assertTrue("MSG: " + ex.getMessage(),
+          ex.getMessage().contains("hllPreHashed is only supported with Long"));
       // blackbox - field
       assertQEx("hllPreHashed " + field.getName(), "hllPreHashed is only supported with Long",
                 req(params("stats.field","{!cardinality=true hllPreHashed=true}" + field.getName()),
                     baseParams),
                 ErrorCode.BAD_REQUEST);
     }
+
     // whitebox - function
-    try {
+    SolrException ex = expectThrows(SolrException.class, () -> {
       HllOptions.parseHllOptions(params("cardinality","true", "hllPreHashed", "true"), null);
-      fail("hllPreHashed should have failed for function");
-    } catch (SolrException e) {
-      assertTrue("MSG: " + e.getMessage(),
-                 e.getMessage().contains("hllPreHashed is only supported with Long"));
-    }
+    });
+    assertTrue("MSG: " + ex.getMessage(),
+        ex.getMessage().contains("hllPreHashed is only supported with Long"));
+
     // blackbox - function
     assertQEx("hllPreHashed function", "hllPreHashed is only supported with Long",
               req(params("stats.field","{!func cardinality=true hllPreHashed=true}sum(foo_i,foo_l)"),
@@ -1823,13 +1812,10 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     ignoreException("accuracy");
     for (String invalid : new String[] { "-1", "1.1", "100" }) {
       // whitebox
-      try {
-        Object trash = HllOptions.parseHllOptions(params("cardinality",invalid), foo_s);
-        fail("Should have failed: " + invalid);
-      } catch (SolrException e) {
-        assertTrue("MSG: " + e.getMessage(),
-                   e.getMessage().contains("number between 0 and 1"));
-      }
+      ex = expectThrows(SolrException.class, () -> {
+        HllOptions.parseHllOptions(params("cardinality",invalid), foo_s);
+      });
+      assertTrue("MSG: " + ex.getMessage(), ex.getMessage().contains("number between 0 and 1"));
       // blackbox
       assertQEx("cardinality="+invalid, "number between 0 and 1",
                 req(params("stats.field","{!cardinality="+invalid+"}foo_s"),
@@ -1840,14 +1826,11 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     ignoreException("hllLog2m must be");
     for (int invalid : new int[] { HLL.MINIMUM_LOG2M_PARAM-1, HLL.MAXIMUM_LOG2M_PARAM+11 }) {
       // whitebox
-      try {
-        Object trash = HllOptions.parseHllOptions(params("cardinality","true",
-                                                         "hllLog2m", ""+invalid), foo_s);
-        fail("Should have failed: " + invalid);
-      } catch (SolrException e) {
-        assertTrue("MSG: " + e.getMessage(),
-                   e.getMessage().contains("hllLog2m must be"));
-      }
+      ex = expectThrows(SolrException.class, () -> {
+        HllOptions.parseHllOptions(params("cardinality","true", "hllLog2m", ""+invalid), foo_s);
+      });
+      assertTrue("MSG: " + ex.getMessage(), ex.getMessage().contains("hllLog2m must be"));
+
       // blackbox
       assertQEx("hllLog2m="+invalid, "hllLog2m must be",
                 req(params("stats.field","{!cardinality=true hllLog2m="+invalid+"}foo_s"),
@@ -1858,14 +1841,13 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     ignoreException("hllRegwidth must be");
     for (int invalid : new int[] { HLL.MINIMUM_REGWIDTH_PARAM-1, HLL.MAXIMUM_REGWIDTH_PARAM+1 }) {
       // whitebox
-      try {
-        Object trash = HllOptions.parseHllOptions(params("cardinality","true",
-                                                         "hllRegwidth", ""+invalid), foo_s);
-        fail("Should have failed: " + invalid);
-      } catch (SolrException e) {
-        assertTrue("MSG: " + e.getMessage(),
-                   e.getMessage().contains("hllRegwidth must be"));
-      }
+      ex = expectThrows(SolrException.class, () -> {
+        HllOptions.parseHllOptions(params("cardinality","true",
+            "hllRegwidth", ""+invalid), foo_s);
+      });
+      assertTrue("MSG: " + ex.getMessage(),
+          ex.getMessage().contains("hllRegwidth must be"));
+
       // blackbox
       assertQEx("hllRegwidth="+invalid, "hllRegwidth must be",
                 req(params("stats.field","{!cardinality=true hllRegwidth="+invalid+"}foo_s"),
@@ -1881,19 +1863,16 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     String percentiles = "10.0,99.9,1.0,2.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,98.0,99.0";
     List <String> percentilesList = StrUtils.splitSmart(percentiles, ',');
     
-    // test empty case 
-    SolrQueryRequest query = req("q", "*:*", "stats", "true",
-                                 "stats.field", "{!percentiles='" + percentiles + "'}stat_f");
-    try {
+    // test empty case
+    try (SolrQueryRequest query = req("q", "*:*", "stats", "true", "stats.field",
+        "{!percentiles='" + percentiles + "'}stat_f")) {
       SolrQueryResponse rsp = h.queryAndResponse(null, query);
       NamedList<Double> pout = extractPercentils(rsp, "stat_f");
       for (int i = 0; i < percentilesList.size(); i++) {
         // ensure exact order, but all values should be null (empty result set)
         assertEquals(percentilesList.get(i), pout.getName(i));
-        assertEquals(null, pout.getVal(i));
+        assertNull(pout.getVal(i));
       }
-    } finally {
-      query.close();
     }
     
     int id = 0;
@@ -1907,9 +1886,8 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
 
     assertU(commit());
 
-    query = req("q", "*:*", "stats", "true", 
-                "stats.field", "{!percentiles='" + percentiles + "'}stat_f");
-    try {
+    try (SolrQueryRequest query = req("q", "*:*", "stats", "true",
+        "stats.field", "{!percentiles='" + percentiles + "'}stat_f")) {
       SolrQueryResponse rsp = h.queryAndResponse(null, query);
       NamedList<Double> pout = extractPercentils(rsp, "stat_f");
       for (int i = 0; i < percentilesList.size(); i++) { 
@@ -1918,19 +1896,14 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
         assertEquals(Double.parseDouble(p), pout.getVal(i), 1.0D);
                      
       }
-    } finally {
-      query.close();
     }
     
     // test request for no percentiles
-    query = req("q", "*:*", "stats", "true", 
-                "stats.field", "{!percentiles=''}stat_f");
-    try {
+    try (SolrQueryRequest query = req("q", "*:*", "stats", "true",
+        "stats.field", "{!percentiles=''}stat_f")) {
       SolrQueryResponse rsp = h.queryAndResponse(null, query);
       NamedList<Double> pout = extractPercentils(rsp, "stat_f");
       assertNull(pout);
-    } finally {
-      query.close();
     }
 
     // non-numeric types don't support percentiles
@@ -1939,16 +1912,12 @@ public class StatsComponentTest extends SolrTestCaseJ4 {
     
     assertU(commit());
 
-    query = req("q", "*:*", "stats", "true", 
-                "stats.field", "{!percentiles='" + percentiles + "'}stat_dt",
-                "stats.field", "{!percentiles='" + percentiles + "'}stat_s");
-
-    try {
+    try (SolrQueryRequest query = req("q", "*:*", "stats", "true",
+        "stats.field", "{!percentiles='" + percentiles + "'}stat_dt",
+        "stats.field", "{!percentiles='" + percentiles + "'}stat_s")) {
       SolrQueryResponse rsp = h.queryAndResponse(null, query);
       assertNull(extractPercentils(rsp, "stat_dt"));
       assertNull(extractPercentils(rsp, "stat_s"));
-    } finally {
-      query.close();
     }
     
   }
diff --git a/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentContextFilterQueryTest.java b/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentContextFilterQueryTest.java
index e22e995..1289392 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentContextFilterQueryTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/SuggestComponentContextFilterQueryTest.java
@@ -78,21 +78,12 @@ public class SuggestComponentContextFilterQueryTest extends SolrTestCaseJ4 {
 
   @Test
   public void testBuildThrowsIllegalArgumentExceptionWhenContextIsConfiguredButNotImplemented() throws Exception {
-    try {
-      assertQ(
-          req("qt", rh,
-              SuggesterParams.SUGGEST_BUILD, "true",
-              SuggesterParams.SUGGEST_DICT, "suggest_context_filtering_not_implemented",
-              SuggesterParams.SUGGEST_Q, "examp")
-          ,
-          ""
-      );
-      fail("Expecting exception because ");
-    } catch (RuntimeException e) {
-      Throwable cause = e.getCause();
-      assertTrue(cause instanceof IllegalArgumentException);
-      assertThat(cause.getMessage(), is("this suggester doesn't support contexts"));
-    }
+    IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> {
+      h.query(req("qt", rh, SuggesterParams.SUGGEST_BUILD, "true",
+          SuggesterParams.SUGGEST_DICT, "suggest_context_filtering_not_implemented",
+          SuggesterParams.SUGGEST_Q, "examp"));
+    });
+    assertThat(ex.getMessage(), is("this suggester doesn't support contexts"));
 
     // When not building, no exception is thrown
     assertQ(req("qt", rh,
@@ -210,7 +201,7 @@ public class SuggestComponentContextFilterQueryTest extends SolrTestCaseJ4 {
             SuggesterParams.SUGGEST_Q, "examp"),
         "//lst[@name='suggest']/lst[@name='suggest_blended_infix_suggester_string']/lst[@name='examp']/int[@name='numFound'][.='0']");
 
-   assertQ(req("qt", rh,
+    assertQ(req("qt", rh,
             SuggesterParams.SUGGEST_BUILD, "true",
             SuggesterParams.SUGGEST_DICT, "suggest_blended_infix_suggester_string",
             SuggesterParams.SUGGEST_CONTEXT_FILTER_QUERY, "ctx4",
diff --git a/solr/core/src/test/org/apache/solr/handler/component/TestHttpShardHandlerFactory.java b/solr/core/src/test/org/apache/solr/handler/component/TestHttpShardHandlerFactory.java
index bde28f9..89d5ba1 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/TestHttpShardHandlerFactory.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/TestHttpShardHandlerFactory.java
@@ -16,12 +16,6 @@
  */
 package org.apache.solr.handler.component;
 
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -30,6 +24,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.impl.LBSolrClient;
 import org.apache.solr.client.solrj.impl.PreferenceRule;
@@ -45,6 +40,12 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+
 /**
  * Tests specifying a custom ShardHandlerFactory
  */
@@ -262,14 +263,12 @@ public class TestHttpShardHandlerFactory extends SolrTestCaseJ4 {
   public void testWhitelistHostCheckerDisabled() throws Exception {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://cde:8983", false);
     checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"abc-1.com:8983/solr"}));
-    
-    try {
-      checker = new WhitelistHostChecker("http://cde:8983", true);
-      checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"http://abc-1.com:8983/solr"}));
-      fail("Expecting exception");
-    } catch (SolrException se) {
-      assertThat(se.code(), is(SolrException.ErrorCode.FORBIDDEN.code));
-    }
+
+    WhitelistHostChecker whitelistHostChecker = new WhitelistHostChecker("http://cde:8983", true);
+    SolrException e = expectThrows(SolrException.class, () -> {
+      whitelistHostChecker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList("http://abc-1.com:8983/solr"));
+    });
+    assertThat(e.code(), is(SolrException.ErrorCode.FORBIDDEN.code));
   }
   
   @Test
@@ -283,67 +282,60 @@ public class TestHttpShardHandlerFactory extends SolrTestCaseJ4 {
   @Test
   public void testWhitelistHostCheckerSingleHost() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983/solr", true);
-    checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"http://abc-1.com:8983/solr"}));
+    checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList("http://abc-1.com:8983/solr"));
   }
   
   @Test
   public void testWhitelistHostCheckerMultipleHost() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"http://abc-1.com:8983/solr"}));
+    checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList("http://abc-1.com:8983/solr"));
   }
   
   @Test
   public void testWhitelistHostCheckerMultipleHost2() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"http://abc-1.com:8983/solr", "http://abc-2.com:8983/solr"}));
+    checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList("http://abc-1.com:8983/solr", "http://abc-2.com:8983/solr"));
   }
   
   @Test
   public void testWhitelistHostCheckerNoProtocolInParameter() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    checker.checkWhitelist("abc-1.com:8983/solr", Arrays.asList(new String[]{"abc-1.com:8983/solr"}));
+    checker.checkWhitelist("abc-1.com:8983/solr", Arrays.asList("abc-1.com:8983/solr"));
   }
   
   @Test
   public void testWhitelistHostCheckerNonWhitelistedHost1() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    try {
-      checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"http://abc-4.com:8983/solr"}));
-      fail("Expected exception");
-    } catch (SolrException e) {
-      assertThat(e.code(), is(SolrException.ErrorCode.FORBIDDEN.code));
-      assertThat(e.getMessage(), containsString("not on the shards whitelist"));
-    }
+    SolrException e = expectThrows(SolrException.class, () -> {
+      checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList("http://abc-4.com:8983/solr"));
+    });
+    assertThat(e.code(), is(SolrException.ErrorCode.FORBIDDEN.code));
+    assertThat(e.getMessage(), containsString("not on the shards whitelist"));
   }
   
   @Test
   public void testWhitelistHostCheckerNonWhitelistedHost2() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    try {
-      checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList(new String[]{"http://abc-1.com:8983/solr", "http://abc-4.com:8983/solr"}));
-      fail("Expected exception");
-    } catch (SolrException e) {
-      assertThat(e.code(), is(SolrException.ErrorCode.FORBIDDEN.code));
-      assertThat(e.getMessage(), containsString("not on the shards whitelist"));
-    }
+    SolrException e = expectThrows(SolrException.class, () -> {
+      checker.checkWhitelist("http://abc-1.com:8983/solr", Arrays.asList("http://abc-1.com:8983/solr", "http://abc-4.com:8983/solr"));
+    });
+    assertThat(e.code(), is(SolrException.ErrorCode.FORBIDDEN.code));
+    assertThat(e.getMessage(), containsString("not on the shards whitelist"));
+
   }
   
   @Test
   public void testWhitelistHostCheckerNonWhitelistedHostHttps() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    checker.checkWhitelist("https://abc-1.com:8983/solr", Arrays.asList(new String[]{"https://abc-1.com:8983/solr"}));
+    checker.checkWhitelist("https://abc-1.com:8983/solr", Arrays.asList("https://abc-1.com:8983/solr"));
   }
   
   @Test
   public void testWhitelistHostCheckerInvalidUrl() {
     WhitelistHostChecker checker = new WhitelistHostChecker("http://abc-1.com:8983, http://abc-2.com:8983, http://abc-3.com:8983", true);
-    try {
-      checker.checkWhitelist("abc_1", Arrays.asList(new String[]{"abc_1"}));
-      fail("Expected exception");
-    } catch (SolrException e) {
-      assertThat(e.code(), is(SolrException.ErrorCode.BAD_REQUEST.code));
-      assertThat(e.getMessage(), containsString("Invalid URL syntax"));
-    }
+    SolrException e = expectThrows(SolrException.class, () -> checker.checkWhitelist("abc_1", Arrays.asList("abc_1")));
+    assertThat(e.code(), is(SolrException.ErrorCode.BAD_REQUEST.code));
+    assertThat(e.getMessage(), containsString("Invalid URL syntax"));
   }
   
   @Test
diff --git a/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java b/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java
index 2d4af64..a77917b 100644
--- a/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java
+++ b/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java
@@ -96,14 +96,10 @@ public class HighlighterTest extends SolrTestCaseJ4 {
         "id", "1"));
     assertU(commit());
 
-    try {
-      assertQ("Tried PostingsSolrHighlighter but failed due to offsets not in postings",
-          req("q", "long", "hl.method", "postings", "df", field, "hl", "true"));
-      fail("Did not encounter exception for no offsets");
-    } catch (Exception e) {
-      assertTrue("Cause should be illegal argument", e.getCause() instanceof IllegalArgumentException);
-      assertTrue("Should warn no offsets", e.getCause().getMessage().contains("indexed without offsets"));
-    }
+    IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
+      h.query(req("q", "long", "hl.method", "postings", "df", field, "hl", "true"));
+    });
+    assertTrue("Should warn no offsets", e.getMessage().contains("indexed without offsets"));
     // note: the default schema.xml has no offsets in postings to test the PostingsHighlighter. Leave that for another
     //  test class.
   }
diff --git a/solr/core/src/test/org/apache/solr/highlight/TestPostingsSolrHighlighter.java b/solr/core/src/test/org/apache/solr/highlight/TestPostingsSolrHighlighter.java
index 3862fa6..4fc402b 100644
--- a/solr/core/src/test/org/apache/solr/highlight/TestPostingsSolrHighlighter.java
+++ b/solr/core/src/test/org/apache/solr/highlight/TestPostingsSolrHighlighter.java
@@ -114,13 +114,8 @@ public class TestPostingsSolrHighlighter extends SolrTestCaseJ4 {
 
   public void testMisconfiguredField() {
     ignoreException("was indexed without offsets");
-    try {
-      assertQ("should fail, has no offsets",
-        req("q", "text2:document", "sort", "id asc", "hl", "true", "hl.fl", "text2"));
-      fail();
-    } catch (Exception expected) {
-      // expected
-    }
+    expectThrows(Exception.class, () ->
+        h.query(req("q", "text2:document", "sort", "id asc", "hl", "true", "hl.fl", "text2")));
     resetExceptionIgnores();
   }
   
diff --git a/solr/core/src/test/org/apache/solr/highlight/TestUnifiedSolrHighlighter.java b/solr/core/src/test/org/apache/solr/highlight/TestUnifiedSolrHighlighter.java
index a009e1f..990262e 100644
--- a/solr/core/src/test/org/apache/solr/highlight/TestUnifiedSolrHighlighter.java
+++ b/solr/core/src/test/org/apache/solr/highlight/TestUnifiedSolrHighlighter.java
@@ -69,17 +69,12 @@ public class TestUnifiedSolrHighlighter extends SolrTestCaseJ4 {
   }
 
   public void testImpossibleOffsetSource() {
-    try {
-      assertQ("impossible offset source",
-          req("q", "text2:document", "hl.offsetSource", "postings", "hl.fl", "text2", "sort", "id asc", "hl", "true"),
-          "count(//lst[@name='highlighting']/*)=2",
-          "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='<em>document</em> one'",
-          "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second <em>document</em>'");
-      fail("Did not encounter exception for no offsets");
-    } catch (Exception e) {
-      assertTrue("Cause should be illegal argument", e.getCause() instanceof IllegalArgumentException);
-      assertTrue("Should warn no offsets", e.getCause().getMessage().contains("indexed without offsets"));
-    }
+    IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
+      h.query(req("q", "text2:document", "hl.offsetSource", "postings",
+          "hl.fl", "text2", "sort", "id asc", "hl", "true"));
+    });
+    assertTrue("Should warn no offsets", e.getMessage().contains("indexed without offsets"));
+
   }
 
   public void testMultipleSnippetsReturned() {
diff --git a/solr/core/src/test/org/apache/solr/index/WrapperMergePolicyFactoryTest.java b/solr/core/src/test/org/apache/solr/index/WrapperMergePolicyFactoryTest.java
index d416e13..16be62c 100644
--- a/solr/core/src/test/org/apache/solr/index/WrapperMergePolicyFactoryTest.java
+++ b/solr/core/src/test/org/apache/solr/index/WrapperMergePolicyFactoryTest.java
@@ -38,12 +38,8 @@ public class WrapperMergePolicyFactoryTest extends SolrTestCaseJ4 {
   public void testFailsIfNoClassSpecifiedForWrappedPolicy() {
     final MergePolicyFactoryArgs args = new MergePolicyFactoryArgs();
     args.add(WrapperMergePolicyFactory.WRAPPED_PREFIX, "foo");
-    try {
-      new DefaultingWrapperMergePolicyFactory(resourceLoader, args, null).getMergePolicy();
-      fail("Should have failed when no 'class' specified for wrapped merge policy");
-    } catch (final IllegalArgumentException e) {
-      // Good!
-    }
+    expectThrows(IllegalArgumentException.class,
+        () -> new DefaultingWrapperMergePolicyFactory(resourceLoader, args, null).getMergePolicy());
   }
 
   public void testProperlyInitializesWrappedMergePolicy() {
diff --git a/solr/core/src/test/org/apache/solr/internal/csv/CharBufferTest.java b/solr/core/src/test/org/apache/solr/internal/csv/CharBufferTest.java
index ebde228..10e58f4 100644
--- a/solr/core/src/test/org/apache/solr/internal/csv/CharBufferTest.java
+++ b/solr/core/src/test/org/apache/solr/internal/csv/CharBufferTest.java
@@ -17,18 +17,13 @@
 package org.apache.solr.internal.csv;
 
 import junit.framework.TestCase;
+import org.apache.solr.SolrTestCaseJ4;
 
 public class CharBufferTest extends TestCase {
     public void testCreate() {
         CharBuffer cb = new CharBuffer();
         assertEquals(0, cb.length());
-        try {
-            cb = new CharBuffer(0);
-            fail("Should not be possible");
-        } catch(IllegalArgumentException e) {
-            // expected
-        }
-        
+        SolrTestCaseJ4.expectThrows(IllegalArgumentException.class, () -> new CharBuffer(0));
         cb = new CharBuffer(128);
         assertEquals(0, cb.length());
     }
diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java b/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java
index e95b73e..95defcc 100644
--- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java
@@ -93,12 +93,7 @@ public class SolrMetricManagerTest extends SolrTestCaseJ4 {
     // this should simply skip existing names
     metricManager.registerAll(registryName, mr, true);
     // this should produce error
-    try {
-      metricManager.registerAll(registryName, mr, false);
-      fail("registerAll with duplicate metric names should fail");
-    } catch (IllegalArgumentException e) {
-      // expected
-    }
+    expectThrows(IllegalArgumentException.class, () -> metricManager.registerAll(registryName, mr, false));
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java b/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java
index ccdd65f..809c68d 100644
--- a/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java
+++ b/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java
@@ -490,22 +490,20 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 {
         "*[count(//lst[@name='airport_s1']/int)=1]",
         "//lst[@name='airport_s1']/int[@name='ams'][.='2']"
     );
-    
-    try {
+
+    SolrException e = expectThrows(SolrException.class, () -> {
       h.query(
-           req(
-               "q", "*:*",
-               "fq", "id_i1:[2000 TO 2004]",
-               "group.facet", "true",
-               "facet", "true",
-               "facet.field", "airport_s1",
-               "facet.prefix", "a"
-           )
+          req(
+              "q", "*:*",
+              "fq", "id_i1:[2000 TO 2004]",
+              "group.facet", "true",
+              "facet", "true",
+              "facet.field", "airport_s1",
+              "facet.prefix", "a"
+          )
       );
-      fail("Exception should have been thrown");
-    } catch (SolrException e) {
-      assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, e.code());
-    }
+    });
+    assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, e.code());
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java b/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java
index 4918bca..7882dc0 100644
--- a/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java
+++ b/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java
@@ -690,13 +690,9 @@ public class TestIntervalFaceting extends SolrTestCaseJ4 {
 
   private void assertBadInterval(String fieldName, String intervalStr, String errorMsg) {
     SchemaField f = h.getCore().getLatestSchema().getField(fieldName);
-    try {
-      new FacetInterval(f, intervalStr, new ModifiableSolrParams());
-      fail("Expecting SyntaxError for interval String: " + intervalStr);
-    } catch (SyntaxError e) {
-      assertTrue("Unexpected error message for interval String: " + intervalStr + ": " +
-          e.getMessage(), e.getMessage().contains(errorMsg));
-    }
+    SyntaxError e = expectThrows(SyntaxError.class,  () -> new FacetInterval(f, intervalStr, new ModifiableSolrParams()));
+    assertTrue("Unexpected error message for interval String: " + intervalStr + ": " +
+        e.getMessage(), e.getMessage().contains(errorMsg));
   }
 
   private void assertInterval(String fieldName, String intervalStr, long[] included, long[] lowerThanStart, long[] graterThanEnd) throws SyntaxError {
diff --git a/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java b/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java
index cf97b1f..20e9a07 100644
--- a/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java
+++ b/solr/core/src/test/org/apache/solr/request/TestRemoteStreaming.java
@@ -16,6 +16,16 @@
  */
 package org.apache.solr.request;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.SolrJettyTestBase;
@@ -33,16 +43,6 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-
 /**
  * See SOLR-2854.
  */
@@ -112,12 +112,8 @@ public class TestRemoteStreaming extends SolrJettyTestBase {
     SolrQuery query = new SolrQuery();
     query.setQuery( "*:*" );//for anything
     query.add("stream.url",makeDeleteAllUrl());
-    try {
-      getSolrClient().query(query);
-      fail();
-    } catch (SolrException se) {
-      assertSame(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode(se.code()));
-    }
+    SolrException se = expectThrows(SolrException.class, () -> getSolrClient().query(query));
+    assertSame(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode(se.code()));
   }
   
   /** Compose a url that if you get it, it will delete all the data. */
diff --git a/solr/core/src/test/org/apache/solr/request/TestStreamBody.java b/solr/core/src/test/org/apache/solr/request/TestStreamBody.java
index 15eb020..ab4648d 100644
--- a/solr/core/src/test/org/apache/solr/request/TestStreamBody.java
+++ b/solr/core/src/test/org/apache/solr/request/TestStreamBody.java
@@ -118,13 +118,9 @@ public class TestStreamBody extends RestTestBase {
       public String getPath() { //don't let superclass substitute qt for the path
         return "/update";
       }
-    };    
-    try {
-      queryRequest.process(getSolrClient());
-      fail();
-    } catch (SolrException se) {
-      assertTrue(se.getMessage(), se.getMessage().contains("Stream Body is disabled"));
-    }
+    };
+    SolrException se = expectThrows(SolrException.class, () -> queryRequest.process(getSolrClient()));
+    assertTrue(se.getMessage(), se.getMessage().contains("Stream Body is disabled"));
     enableStreamBody(true);
     queryRequest.process(getSolrClient());
   }
diff --git a/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java b/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java
index 8ad547a..a26c835 100644
--- a/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java
@@ -22,12 +22,9 @@ import java.lang.invoke.MethodHandles;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.commons.io.FileUtils;
-
-import org.apache.lucene.search.similarities.Similarity;
-
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.LocalSolrQueryRequest;
@@ -106,13 +103,9 @@ public class ChangedSchemaMergeTest extends SolrTestCaseJ4 {
     SchemaSimilarityFactory broken = new SchemaSimilarityFactory();
     broken.init(new ModifiableSolrParams());
     // NO INFORM
-    try {
-      Similarity bogus = broken.getSimilarity();
-      fail("SchemaSimilarityFactory should have thrown IllegalStateException b/c inform not used");
-    } catch (IllegalStateException expected) {
-      assertTrue("GOT: " + expected.getMessage(),
-                 expected.getMessage().contains("SolrCoreAware.inform"));
-    }
+    IllegalStateException e = expectThrows(IllegalStateException.class, broken::getSimilarity);
+    assertTrue("GOT: " + e.getMessage(),
+        e.getMessage().contains("SolrCoreAware.inform"));
   }
   
   @Test
diff --git a/solr/core/src/test/org/apache/solr/schema/CopyFieldTest.java b/solr/core/src/test/org/apache/solr/schema/CopyFieldTest.java
index 86a8aca..6ef47cc 100644
--- a/solr/core/src/test/org/apache/solr/schema/CopyFieldTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/CopyFieldTest.java
@@ -42,56 +42,45 @@ public class CopyFieldTest extends SolrTestCaseJ4 {
 
   @Test
   public void testCopyFieldSchemaFieldSchemaField() {
-    try {
+    IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
       new CopyField(new SchemaField("source", new TextField()), null);
-      fail("CopyField failed with null SchemaField argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
-    }
-    try {
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
+
+    e = expectThrows(IllegalArgumentException.class, () -> {
       new CopyField(null, new SchemaField("destination", new TextField()));
-      fail("CopyField failed with null SchemaField argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
-    }
-    try {
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
+
+    e = expectThrows(IllegalArgumentException.class, () -> {
       new CopyField(null, null);
-      fail("CopyField failed with null SchemaField argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
-    }
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
   }
 
   @Test
   public void testCopyFieldSchemaFieldSchemaFieldInt() {
-    try {
-      new CopyField(null,
-          new SchemaField("destination", new TextField()), 1000);
-      fail("CopyField failed with null SchemaField argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
-    }
-    try {
-      new CopyField(new SchemaField("source", new TextField()), null,
-          1000);
-      fail("CopyField failed with null SchemaField argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
-    }
-    try {
+    IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
+      new CopyField(null, new SchemaField("destination", new TextField()), 1000);
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
+
+    e = expectThrows(IllegalArgumentException.class, () -> {
+      new CopyField(new SchemaField("source", new TextField()), null, 1000);
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
+
+    e = expectThrows(IllegalArgumentException.class, () -> {
       new CopyField(null, null, 1000);
-      fail("CopyField failed with null SchemaField argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
-    }
-    try {
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't be NULL"));
+
+    e = expectThrows(IllegalArgumentException.class, () -> {
       new CopyField(new SchemaField("source", new TextField()),
           new SchemaField("destination", new TextField()), -1000);
-      fail("CopyField failed with negative length argument.");
-    } catch (IllegalArgumentException e) {
-      assertTrue(e.getLocalizedMessage().contains(
-          "can't have a negative value"));
-    }
+    });
+    assertTrue(e.getLocalizedMessage().contains("can't have a negative value"));
+
     new CopyField(new SchemaField("source", new TextField()),
         new SchemaField("destination", new TextField()), CopyField.UNLIMITED);
   }
diff --git a/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTypeTest.java b/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTypeTest.java
index 1959b3b..d717469 100644
--- a/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTypeTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/CurrencyFieldTypeTest.java
@@ -468,13 +468,7 @@ public class CurrencyFieldTypeTest extends SolrTestCaseJ4 {
     assertEquals("3.14,GBP", new CurrencyValue(314, "GBP").strValue());
 
     CurrencyValue currencyValue = new CurrencyValue(314, "XYZ");
-    try {
-      String string = currencyValue.strValue();
-      fail("Expected SolrException");
-    } catch (SolrException exception) {
-    } catch (Throwable throwable) {
-      fail("Expected SolrException");
-    }
+    expectThrows(SolrException.class,  currencyValue::strValue);
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/schema/PreAnalyzedFieldTest.java b/solr/core/src/test/org/apache/solr/schema/PreAnalyzedFieldTest.java
index a494654..ae39ffa 100644
--- a/solr/core/src/test/org/apache/solr/schema/PreAnalyzedFieldTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/PreAnalyzedFieldTest.java
@@ -225,32 +225,27 @@ public class PreAnalyzedFieldTest extends SolrTestCaseJ4 {
       "]}";
   
   @Test
-  public void testParsers() {
+  public void testParsers() throws Exception {
     PreAnalyzedField paf = new PreAnalyzedField();
     // use Simple format
     HashMap<String,String> args = new HashMap<>();
     args.put(PreAnalyzedField.PARSER_IMPL, SimplePreAnalyzedParser.class.getName());
     paf.init(h.getCore().getLatestSchema(), args);
-    try {
+    {
       Field f = (Field)paf.fromString(field, valid[0]);
-    } catch (Exception e) {
-      fail("Should pass: '" + valid[0] + "', exception: " + e);
     }
+
     // use JSON format
     args.put(PreAnalyzedField.PARSER_IMPL, JsonPreAnalyzedParser.class.getName());
     paf.init(h.getCore().getLatestSchema(), args);
-    try {
-      Field f = (Field)paf.fromString(field, valid[0]);
-      fail("Should fail JSON parsing: '" + valid[0] + "'");
-    } catch (Exception e) {
-    }
+    expectThrows(Exception.class, () -> paf.fromString(field, valid[0]));
+
     byte[] deadbeef = new byte[]{(byte)0xd, (byte)0xe, (byte)0xa, (byte)0xd, (byte)0xb, (byte)0xe, (byte)0xe, (byte)0xf};
     PreAnalyzedParser parser = new JsonPreAnalyzedParser();
-    try {
+
+    {
       Field f = (Field)paf.fromString(field, jsonValid);
       assertEquals(jsonValid, parser.toFormattedString(f));
-    } catch (Exception e) {
-      fail("Should pass: '" + jsonValid + "', exception: " + e);
     }
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/schema/SpatialRPTFieldTypeTest.java b/solr/core/src/test/org/apache/solr/schema/SpatialRPTFieldTypeTest.java
index 60e47ca..5524a31 100644
--- a/solr/core/src/test/org/apache/solr/schema/SpatialRPTFieldTypeTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/SpatialRPTFieldTypeTest.java
@@ -110,13 +110,8 @@ public class SpatialRPTFieldTypeTest extends AbstractBadConfigTestBase {
   }
   
   public void testJunkValuesForDistanceUnits() throws Exception {
-    try {
-      setupRPTField("rose", "true");
-      fail("Expected exception for bad value of distanceUnits.");
-    } catch (Exception ex) {
-      if(!ex.getMessage().startsWith("Must specify distanceUnits as one of"))
-        throw ex;
-    }
+    Exception ex = expectThrows(Exception.class, () -> setupRPTField("rose", "true"));
+    assertTrue(ex.getMessage().startsWith("Must specify distanceUnits as one of"));
   }
 
   public void testMaxDistErrConversion() throws Exception {
@@ -217,12 +212,7 @@ public class SpatialRPTFieldTypeTest extends AbstractBadConfigTestBase {
     assertEquals(wkt, out);
 
     //assert fails GeoJSON
-    try {
-      ftype.parseShape("{\"type\":\"Point\",\"coordinates\":[1,2]}");
-      fail("Should not parse GeoJSON if told format is WKT");
-    } catch (SolrException e) {// expected
-      System.out.println(e);
-    }
+    expectThrows(SolrException.class, () -> ftype.parseShape("{\"type\":\"Point\",\"coordinates\":[1,2]}"));
 
   }
 
diff --git a/solr/core/src/test/org/apache/solr/schema/TestCloudSchemaless.java b/solr/core/src/test/org/apache/solr/schema/TestCloudSchemaless.java
index e6a6303..b281e34 100644
--- a/solr/core/src/test/org/apache/solr/schema/TestCloudSchemaless.java
+++ b/solr/core/src/test/org/apache/solr/schema/TestCloudSchemaless.java
@@ -15,6 +15,15 @@
  * limitations under the License.
  */
 package org.apache.solr.schema;
+
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.function.UnaryOperator;
+
 import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
@@ -31,14 +40,6 @@ import org.restlet.ext.servlet.ServerServlet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.lang.invoke.MethodHandles;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.function.UnaryOperator;
-
 /**
  * Tests a schemaless collection configuration with SolrCloud
  */
@@ -139,8 +140,6 @@ public class TestCloudSchemaless extends AbstractFullDistribZkTestBase {
     // Now, let's ensure that writing the same field with two different types fails
     int failTrials = 50;
     for (int i = 0; i < failTrials; ++i) {
-      List<SolrInputDocument> docs = null;
-
       SolrInputDocument intDoc = new SolrInputDocument();
       intDoc.addField("id", Long.toHexString(Double.doubleToLongBits(random().nextDouble())));
       intDoc.addField("longOrDateField" + i, "123");
@@ -150,28 +149,20 @@ public class TestCloudSchemaless extends AbstractFullDistribZkTestBase {
       dateDoc.addField("longOrDateField" + i, "1995-12-31T23:59:59Z");
 
       // randomize the order of the docs
-      if (random().nextBoolean()) {
-        docs = Arrays.asList(intDoc, dateDoc);
-      } else {
-        docs = Arrays.asList(dateDoc, intDoc);
-      }
+      List<SolrInputDocument> docs = random().nextBoolean()? Arrays.asList(intDoc, dateDoc): Arrays.asList(dateDoc, intDoc);
 
-      try {
+      SolrException ex = expectThrows(SolrException.class,  () -> {
         randomClient.add(docs);
         randomClient.commit();
-        fail("Expected Bad Request Exception");
-      } catch (SolrException se) {
-        assertEquals(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode(se.code()));
-      }
+      });
+      assertEquals(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode(ex.code()));
 
-      try {
+      ex = expectThrows(SolrException.class,  () -> {
         CloudSolrClient cloudSolrClient = getCommonCloudSolrClient();
         cloudSolrClient.add(docs);
         cloudSolrClient.commit();
-        fail("Expected Bad Request Exception");
-      } catch (SolrException ex) {
-        assertEquals(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode((ex).code()));
-      }
+      });
+      assertEquals(ErrorCode.BAD_REQUEST, ErrorCode.getErrorCode(ex.code()));
     }
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
index 5f1efc8..7bb1498 100644
--- a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
@@ -201,30 +201,18 @@ public class BasicAuthIntegrationTest extends SolrCloudAuthTestCase {
       CollectionAdminRequest.Reload reload = CollectionAdminRequest.reloadCollection(COLLECTION);
 
       try (HttpSolrClient solrClient = getHttpSolrClient(baseUrl)) {
-        try {
-          rsp = solrClient.request(reload);
-          fail("must have failed");
-        } catch (HttpSolrClient.RemoteSolrException e) {
-
-        }
+        expectThrows(HttpSolrClient.RemoteSolrException.class, () -> solrClient.request(reload));
         reload.setMethod(SolrRequest.METHOD.POST);
-        try {
-          rsp = solrClient.request(reload);
-          fail("must have failed");
-        } catch (HttpSolrClient.RemoteSolrException e) {
-
-        }
+        expectThrows(HttpSolrClient.RemoteSolrException.class, () -> solrClient.request(reload));
       }
       cluster.getSolrClient().request(CollectionAdminRequest.reloadCollection(COLLECTION)
           .setBasicAuthCredentials("harry", "HarryIsUberCool"));
 
-      try {
+      expectThrows(HttpSolrClient.RemoteSolrException.class, () -> {
         cluster.getSolrClient().request(CollectionAdminRequest.reloadCollection(COLLECTION)
             .setBasicAuthCredentials("harry", "Cool12345"));
-        fail("This should not succeed");
-      } catch (HttpSolrClient.RemoteSolrException e) {
-        assertAuthMetricsMinimums(14, 5, 8, 1, 0, 0);
-      }
+      });
+      assertAuthMetricsMinimums(14, 5, 8, 1, 0, 0);
 
       executeCommand(baseUrl + authzPrefix, cl,"{set-permission : { name : update , role : admin}}", "harry", "HarryIsUberCool");
 
@@ -242,10 +230,9 @@ public class BasicAuthIntegrationTest extends SolrCloudAuthTestCase {
       delQuery.setBasicAuthCredentials("harry","HarryIsUberCool");
       delQuery.process(aNewClient, COLLECTION);//this should succeed
       try {
-        delQuery = new UpdateRequest().deleteByQuery("*:*");
-        delQuery.process(aNewClient, COLLECTION);
-        fail("This should not have succeeded without credentials");
-      } catch (HttpSolrClient.RemoteSolrException e) {
+        HttpSolrClient.RemoteSolrException e = expectThrows(HttpSolrClient.RemoteSolrException.class, () -> {
+          new UpdateRequest().deleteByQuery("*:*").process(aNewClient, COLLECTION);
+        });
         assertTrue(e.getMessage().contains("Unauthorized request"));
       } finally {
         aNewClient.close();
@@ -377,9 +364,7 @@ public class BasicAuthIntegrationTest extends SolrCloudAuthTestCase {
     ArrayList<Replica> l = new ArrayList<>();
 
     for (Slice slice : coll.getSlices()) {
-      for (Replica replica : slice.getReplicas()) {
-        l.add(replica);
-      }
+      l.addAll(slice.getReplicas());
     }
     Collections.shuffle(l, random);
     return l.isEmpty() ? null : l.get(0);
diff --git a/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java b/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
index c3d6f60..e2dda3e 100644
--- a/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
+++ b/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
@@ -72,10 +72,7 @@ public class TestAuthorizationFramework extends AbstractFullDistribZkTestBase {
 
       // This user is blacklisted in the mock. The request should return a 403.
       params.add("uname", "user1");
-      try {
-        cloudClient.query(params);
-        fail("This should have failed");
-      } catch (Exception e) {}
+      expectThrows(Exception.class, () -> cloudClient.query(params));
       log.info("Ending test");
     } finally {
       MockAuthorizationPlugin.denyUsers.clear();
diff --git a/solr/core/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java b/solr/core/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
index 07ac0df..b87b854 100644
--- a/solr/core/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
+++ b/solr/core/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
@@ -43,8 +43,6 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import junit.framework.Assert;
-
 public class TestDelegationWithHadoopAuth extends SolrCloudTestCase {
   protected static final int NUM_SERVERS = 2;
   protected static final String USER_1 = "foo";
@@ -381,23 +379,17 @@ public class TestDelegationWithHadoopAuth extends SolrCloudTestCase {
       ss.close();
     }
 
-    ss = new HttpSolrClient.Builder(primarySolrClient.getBaseURL().toString())
-        .withKerberosDelegationToken(token)
-        .withResponseParser(primarySolrClient.getParser())
-        .build();
-    try {
+    try (HttpSolrClient client = new HttpSolrClient.Builder(primarySolrClient.getBaseURL())
+             .withKerberosDelegationToken(token)
+             .withResponseParser(primarySolrClient.getParser())
+             .build()) {
       // test with token via property
-      doSolrRequest(ss, request, HttpStatus.SC_OK);
+      doSolrRequest(client, request, HttpStatus.SC_OK);
 
       // test with param -- should throw an exception
       ModifiableSolrParams tokenParam = new ModifiableSolrParams();
       tokenParam.set("delegation", "invalidToken");
-      try {
-        doSolrRequest(ss, getAdminRequest(tokenParam), ErrorCode.FORBIDDEN.code);
-        Assert.fail("Expected exception");
-      } catch (IllegalArgumentException ex) {}
-    } finally {
-      ss.close();
+      expectThrows(IllegalArgumentException.class, () -> doSolrRequest(client, getAdminRequest(tokenParam), ErrorCode.FORBIDDEN.code));
     }
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java b/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
index ed8397b..5ce7527 100644
--- a/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
+++ b/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
@@ -16,9 +16,6 @@
  */
 package org.apache.solr.security.hadoop;
 
-import static org.apache.solr.security.HttpParamDelegationTokenPlugin.USER_PARAM;
-import static org.apache.solr.security.hadoop.ImpersonationUtil.*;
-
 import java.net.InetAddress;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
@@ -40,6 +37,11 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.apache.solr.security.HttpParamDelegationTokenPlugin.USER_PARAM;
+import static org.apache.solr.security.hadoop.ImpersonationUtil.getExpectedGroupExMsg;
+import static org.apache.solr.security.hadoop.ImpersonationUtil.getExpectedHostExMsg;
+import static org.apache.solr.security.hadoop.ImpersonationUtil.getProxyRequest;
+
 public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   protected static final int NUM_SERVERS = 2;
   private static final boolean defaultAddRequestHeadersToContext =
@@ -97,10 +99,8 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   @Test
   public void testProxyNoConfigGroups() throws Exception {
     try (SolrClient solrClient = newSolrClient()) {
-      solrClient.request(getProxyRequest("noGroups","bar"));
-      fail("Expected RemoteSolrException");
-    }
-    catch (HttpSolrClient.RemoteSolrException ex) {
+      HttpSolrClient.RemoteSolrException ex = expectThrows(HttpSolrClient.RemoteSolrException.class,
+          () -> solrClient.request(getProxyRequest("noGroups","bar")));
       assertTrue(ex.getLocalizedMessage(), ex.getMessage().contains(getExpectedGroupExMsg("noGroups", "bar")));
     }
   }
@@ -108,10 +108,8 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   @Test
   public void testProxyWrongHost() throws Exception {
     try (SolrClient solrClient = newSolrClient()) {
-      solrClient.request(getProxyRequest("wrongHost","bar"));
-      fail("Expected RemoteSolrException");
-    }
-    catch (HttpSolrClient.RemoteSolrException ex) {
+      HttpSolrClient.RemoteSolrException ex = expectThrows(HttpSolrClient.RemoteSolrException.class,
+          () -> solrClient.request(getProxyRequest("wrongHost","bar")));
       assertTrue(ex.getMessage().contains(getExpectedHostExMsg("wrongHost")));
     }
   }
@@ -119,10 +117,8 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   @Test
   public void testProxyNoConfigHosts() throws Exception {
     try (SolrClient solrClient = newSolrClient()) {
-      solrClient.request(getProxyRequest("noHosts","bar"));
-      fail("Expected RemoteSolrException");
-    }
-    catch (HttpSolrClient.RemoteSolrException ex) {
+      HttpSolrClient.RemoteSolrException ex = expectThrows(HttpSolrClient.RemoteSolrException.class,
+          () -> solrClient.request(getProxyRequest("noHosts","bar")));
       assertTrue(ex.getMessage().contains(getExpectedHostExMsg("noHosts")));
     }
   }
@@ -139,10 +135,8 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   public void testProxyInvalidProxyUser() throws Exception {
     try (SolrClient solrClient = newSolrClient()) {
       // wrong direction, should fail
-      solrClient.request(getProxyRequest("bar","anyHostAnyUser"));
-      fail("Expected RemoteSolrException");
-    }
-    catch (HttpSolrClient.RemoteSolrException ex) {
+      HttpSolrClient.RemoteSolrException ex = expectThrows(HttpSolrClient.RemoteSolrException.class,
+          () -> solrClient.request(getProxyRequest("bar","anyHostAnyUser")));
       assertTrue(ex.getMessage().contains(getExpectedGroupExMsg("bar", "anyHostAnyUser")));
     }
   }
@@ -166,10 +160,8 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   @Test
   public void testProxyInvalidGroup() throws Exception {
     try (SolrClient solrClient = newSolrClient()) {
-      solrClient.request(getProxyRequest("bogusGroup","bar"));
-      fail("Expected RemoteSolrException");
-    }
-    catch (HttpSolrClient.RemoteSolrException ex) {
+      HttpSolrClient.RemoteSolrException ex = expectThrows(HttpSolrClient.RemoteSolrException.class,
+          () -> solrClient.request(getProxyRequest("bogusGroup","bar")));
       assertTrue(ex.getMessage().contains(getExpectedGroupExMsg("bogusGroup", "bar")));
     }
   }
@@ -177,11 +169,7 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
   @Test
   public void testProxyNullProxyUser() throws Exception {
     try (SolrClient solrClient = newSolrClient()) {
-      solrClient.request(getProxyRequest("","bar"));
-      fail("Expected RemoteSolrException");
-    }
-    catch (HttpSolrClient.RemoteSolrException ex) {
-      // this exception is specific to our implementation, don't check a specific message.
+      expectThrows(HttpSolrClient.RemoteSolrException.class, () -> solrClient.request(getProxyRequest("","bar")));
     }
   }
 
@@ -199,15 +187,12 @@ public class TestImpersonationWithHadoopAuth  extends SolrCloudTestCase {
 
     // try a command to each node, one of them must be forwarded
     for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
-      HttpSolrClient client =
-          new HttpSolrClient.Builder(jetty.getBaseUrl().toString() + "/" + collectionName).build();
-      try {
+      try (HttpSolrClient client =
+               new HttpSolrClient.Builder(jetty.getBaseUrl().toString() + "/" + collectionName).build()) {
         ModifiableSolrParams params = new ModifiableSolrParams();
         params.set("q", "*:*");
         params.set(USER_PARAM, "user");
         client.query(params);
-      } finally {
-        client.close();
       }
     }
   }
diff --git a/solr/core/src/test/org/apache/solr/servlet/DirectSolrConnectionTest.java b/solr/core/src/test/org/apache/solr/servlet/DirectSolrConnectionTest.java
index 9b70155..5252d4b 100644
--- a/solr/core/src/test/org/apache/solr/servlet/DirectSolrConnectionTest.java
+++ b/solr/core/src/test/org/apache/solr/servlet/DirectSolrConnectionTest.java
@@ -23,9 +23,7 @@ import org.apache.solr.SolrTestCaseJ4;
 import org.junit.BeforeClass;
 
 
-
-public class DirectSolrConnectionTest extends SolrTestCaseJ4
-{
+public class DirectSolrConnectionTest extends SolrTestCaseJ4 {
 
   
   @BeforeClass
@@ -52,13 +50,8 @@ public class DirectSolrConnectionTest extends SolrTestCaseJ4
     
     assertTrue( got.indexOf( "<str name=\"echoParams\">explicit</str>" ) > 5 );
     
-    
     // It should throw an exception for unknown handler
-    try {
-      direct.request( "/path to nonexistang thingy!!", null );
-      fail( "should throw an exception" );
-    }
-    catch( Exception ex ){}
+    expectThrows(Exception.class, () -> direct.request( "/path to nonexistang thingy!!", null ));
   }
   
 
diff --git a/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java b/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java
index 917b1b4..bc2aa19 100644
--- a/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java
+++ b/solr/core/src/test/org/apache/solr/servlet/SolrRequestParserTest.java
@@ -16,6 +16,9 @@
  */
 package org.apache.solr.servlet;
 
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -31,10 +34,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import javax.servlet.ReadListener;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.solr.SolrTestCaseJ4;
@@ -45,17 +44,20 @@ import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.ContentStream;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.servlet.SolrRequestParsers.MultipartRequestParser;
 import org.apache.solr.servlet.SolrRequestParsers.FormDataRequestParser;
+import org.apache.solr.servlet.SolrRequestParsers.MultipartRequestParser;
 import org.apache.solr.servlet.SolrRequestParsers.RawRequestParser;
 import org.apache.solr.servlet.SolrRequestParsers.StandardRequestParser;
-import static org.mockito.Mockito.*;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 public class SolrRequestParserTest extends SolrTestCaseJ4 {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -208,12 +210,7 @@ public class SolrRequestParserTest extends SolrTestCaseJ4 {
       "=hallo"         // missing key
     };
     for (String s : invalid) {
-      try {
-        SolrRequestParsers.parseQueryString(s);
-        fail("Should throw SolrException");
-      } catch (SolrException se) {
-        // pass
-      }
+      expectThrows(SolrException.class, () -> SolrRequestParsers.parseQueryString(s));
     }
   }
   
@@ -327,15 +324,12 @@ public class SolrRequestParserTest extends SolrTestCaseJ4 {
     when(request.getMethod()).thenReturn("POST");
     when(request.getInputStream()).thenReturn(new ByteServletInputStream(large.toString().getBytes(StandardCharsets.US_ASCII)));
 
-    FormDataRequestParser formdata = new FormDataRequestParser( limitKBytes );    
-    try {
-      formdata.parseParamsAndFillStreams(request, new ArrayList<ContentStream>());
-      fail("should throw SolrException");
-    } catch (SolrException solre) {
-      assertTrue(solre.getMessage().contains("upload limit"));
-      assertEquals(400, solre.code());
-    }
-
+    FormDataRequestParser formdata = new FormDataRequestParser( limitKBytes );
+    SolrException e = expectThrows(SolrException.class, () -> {
+      formdata.parseParamsAndFillStreams(request, new ArrayList<>());
+    });
+    assertTrue(e.getMessage().contains("upload limit"));
+    assertEquals(400, e.code());
     verify(request).getInputStream();
   }
   
@@ -363,14 +357,12 @@ public class SolrRequestParserTest extends SolrTestCaseJ4 {
       }
     });
 
-    FormDataRequestParser formdata = new FormDataRequestParser( 2048 );    
-    try {
-      formdata.parseParamsAndFillStreams(request, new ArrayList<ContentStream>());
-      fail("should throw SolrException");
-    } catch (SolrException solre) {
-      assertTrue(solre.getMessage().startsWith("Solr requires that request parameters"));
-      assertEquals(500, solre.code());
-    }
+    FormDataRequestParser formdata = new FormDataRequestParser( 2048 );
+    SolrException e = expectThrows(SolrException.class, () -> {
+      formdata.parseParamsAndFillStreams(request, new ArrayList<>());
+    });
+    assertTrue(e.getMessage().startsWith("Solr requires that request parameters"));
+    assertEquals(500, e.code());
     verify(request).getInputStream();
   }
   
@@ -382,14 +374,12 @@ public class SolrRequestParserTest extends SolrTestCaseJ4 {
     // we emulate Tomcat that throws IllegalStateException when parameters were parsed before:
     when(request.getInputStream()).thenThrow(new IllegalStateException());
 
-    FormDataRequestParser formdata = new FormDataRequestParser( 2048 );    
-    try {
-      formdata.parseParamsAndFillStreams(request, new ArrayList<ContentStream>());
-      fail("should throw SolrException");
-    } catch (SolrException solre) {
-      assertTrue(solre.getMessage().startsWith("Solr requires that request parameters"));
-      assertEquals(500, solre.code());
-    }
+    FormDataRequestParser formdata = new FormDataRequestParser( 2048 );
+    SolrException e = expectThrows(SolrException.class, () -> {
+      formdata.parseParamsAndFillStreams(request, new ArrayList<>());
+    });
+    assertTrue(e.getMessage().startsWith("Solr requires that request parameters"));
+    assertEquals(500, e.code());
     verify(request).getInputStream();
   }
   
@@ -432,10 +422,6 @@ public class SolrRequestParserTest extends SolrTestCaseJ4 {
     }
   }
 
-
-
-
-
   @Test
   public void testAutoDetect() throws Exception {
     String curl = "curl/7.30.0";
diff --git a/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java b/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java
index 98ec2e7..1b476ea 100644
--- a/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java
+++ b/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java
@@ -60,12 +60,7 @@ public class ConjunctionSolrSpellCheckerTest extends SolrTestCase {
     
     cssc.addChecker(checker1);
     cssc.addChecker(checker2);
-    try {
-      cssc.addChecker(checker3);
-      fail("ConjunctionSolrSpellChecker should have thrown an exception about non-identical StringDistances.");
-    } catch (IllegalArgumentException iae) {
-      // correct behavior
-    }
+    expectThrows(IllegalArgumentException.class, () -> cssc.addChecker(checker3));
   }
 
   static class MockSolrSpellChecker extends SolrSpellChecker {
diff --git a/solr/core/src/test/org/apache/solr/store/hdfs/HdfsDirectoryTest.java b/solr/core/src/test/org/apache/solr/store/hdfs/HdfsDirectoryTest.java
index cf1039a..5e72b52 100644
--- a/solr/core/src/test/org/apache/solr/store/hdfs/HdfsDirectoryTest.java
+++ b/solr/core/src/test/org/apache/solr/store/hdfs/HdfsDirectoryTest.java
@@ -154,11 +154,7 @@ public class HdfsDirectoryTest extends SolrTestCaseJ4 {
   private void testEof(String name, Directory directory, long length) throws IOException {
     IndexInput input = directory.openInput(name, new IOContext());
     input.seek(length);
-    try {
-      input.readByte();
-      fail("should throw eof");
-    } catch (Exception e) {
-    }
+    expectThrows(Exception.class, input::readByte);
   }
 
   @Test
diff --git a/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java b/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java
index 00a6a8d..08a2834 100644
--- a/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java
+++ b/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java
@@ -906,12 +906,7 @@ public class AddBlockUpdateTest extends SolrTestCaseJ4 {
   }
 
   private void assertFailedBlockU(final String msg) {
-    try {
-      assertBlockU(msg, "1");
-      fail("expecting fail");
-    } catch (Exception e) {
-      // gotcha
-    }
+    expectThrows(Exception.class, () -> assertBlockU(msg, "1"));
   }
 
   private void assertBlockU(final String msg, String expected) {
@@ -936,4 +931,3 @@ public class AddBlockUpdateTest extends SolrTestCaseJ4 {
     }
   }
 }
-
diff --git a/solr/core/src/test/org/apache/solr/update/AnalysisErrorHandlingTest.java b/solr/core/src/test/org/apache/solr/update/AnalysisErrorHandlingTest.java
index 2034fa0..535386f 100644
--- a/solr/core/src/test/org/apache/solr/update/AnalysisErrorHandlingTest.java
+++ b/solr/core/src/test/org/apache/solr/update/AnalysisErrorHandlingTest.java
@@ -27,7 +27,6 @@ import org.junit.Test;
  */
 public class AnalysisErrorHandlingTest extends SolrTestCaseJ4 {
 
-
   public String getCoreName() { return "basic"; }
 
   @BeforeClass
@@ -35,16 +34,12 @@ public class AnalysisErrorHandlingTest extends SolrTestCaseJ4 {
     initCore("solrconfig-basic.xml","solr/analysisconfs/analysis-err-schema.xml");
   }
 
-
-
   @Test
   public void testMultipleUpdatesPerAdd() {
     clearIndex();
-    try {
-      h.update("<add><doc><field name=\"id\">1</field><field name=\"text\">Alas Poor Yorik</field></doc></add>");
-      fail("Failed to even throw the exception we are stewing over.");
-    } catch (SolrException se) {
-      assertTrue(se.getMessage().contains("Exception writing document id 1 to the index"));
-    }
+    SolrException se = expectThrows(SolrException.class,
+        () -> h.update("<add><doc><field name=\"id\">1</field><field name=\"text\">Alas Poor Yorik</field></doc></add>")
+    );
+    assertTrue(se.getMessage().contains("Exception writing document id 1 to the index"));
   }
 }
diff --git a/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java b/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
index 857dc65..bf819a0 100644
--- a/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
+++ b/solr/core/src/test/org/apache/solr/update/DocumentBuilderTest.java
@@ -60,25 +60,18 @@ public class DocumentBuilderTest extends SolrTestCaseJ4 {
   }
 
   @Test
-  public void testBuildDocument() throws Exception 
-  {
+  public void testBuildDocument() throws Exception {
     SolrCore core = h.getCore();
-    
     // undefined field
-    try {
-      SolrInputDocument doc = new SolrInputDocument();
-      doc.setField( "unknown field", 12345 );
-      DocumentBuilder.toDocument( doc, core.getLatestSchema() );
-      fail( "should throw an error" );
-    }
-    catch( SolrException ex ) {
-      assertEquals( "should be bad request", 400, ex.code() );
-    }
+    SolrInputDocument doc = new SolrInputDocument();
+    doc.setField( "unknown field", 12345 );
+
+    SolrException ex = expectThrows(SolrException.class, () -> DocumentBuilder.toDocument( doc, core.getLatestSchema() ));
+    assertEquals("should be bad request", 400, ex.code());
   }
 
   @Test
-  public void testNullField() 
-  {
+  public void testNullField() {
     SolrCore core = h.getCore();
     
     // make sure a null value is not indexed
@@ -89,34 +82,23 @@ public class DocumentBuilderTest extends SolrTestCaseJ4 {
   }
 
   @Test
-  public void testExceptions() 
-  {
+  public void testExceptions() {
     SolrCore core = h.getCore();
     
     // make sure a null value is not indexed
     SolrInputDocument doc = new SolrInputDocument();
     doc.addField( "id", "123" );
     doc.addField( "unknown", "something" );
-    try {
-      DocumentBuilder.toDocument( doc, core.getLatestSchema() );
-      fail( "added an unknown field" );
-    }
-    catch( Exception ex ) {
-      assertTrue( "should have document ID", ex.getMessage().indexOf( "doc=123" ) > 0 );
-    }
+    Exception ex = expectThrows(Exception.class, () -> DocumentBuilder.toDocument( doc, core.getLatestSchema() ));
+    assertTrue( "should have document ID", ex.getMessage().indexOf( "doc=123" ) > 0 );
     doc.remove( "unknown" );
     
 
     doc.addField( "weight", "not a number" );
-    try {
-      DocumentBuilder.toDocument( doc, core.getLatestSchema() );
-      fail( "invalid 'float' field value" );
-    }
-    catch( Exception ex ) {
-      assertTrue( "should have document ID", ex.getMessage().indexOf( "doc=123" ) > 0 );
-      assertTrue( "cause is number format", ex.getCause() instanceof NumberFormatException );
-    }
-    
+    ex = expectThrows(Exception.class, () -> DocumentBuilder.toDocument( doc, core.getLatestSchema()));
+    assertTrue( "should have document ID", ex.getMessage().indexOf( "doc=123" ) > 0 );
+    assertTrue( "cause is number format", ex.getCause() instanceof NumberFormatException );
+
     // now make sure it is OK
     doc.setField( "weight", "1.34" );
     DocumentBuilder.toDocument( doc, core.getLatestSchema() );
diff --git a/solr/core/src/test/org/apache/solr/update/TestAtomicUpdateErrorCases.java b/solr/core/src/test/org/apache/solr/update/TestAtomicUpdateErrorCases.java
index 9985130..53842b5 100644
--- a/solr/core/src/test/org/apache/solr/update/TestAtomicUpdateErrorCases.java
+++ b/solr/core/src/test/org/apache/solr/update/TestAtomicUpdateErrorCases.java
@@ -38,23 +38,13 @@ public class TestAtomicUpdateErrorCases extends SolrTestCaseJ4 {
       addAndGetVersion(sdoc("id", "1", "val_i", "42"), null);
       assertU(commit());
 
-      try {
-        ignoreException("updateLog");
-
-        // updating docs should fail
-        addAndGetVersion(sdoc("id", "1", "val_i", map("inc",-666)), null);
-        
-        fail("didn't get error about needing updateLog");
-      } catch (SolrException ex) {
-        assertEquals(400, ex.code());
-        // if the message doesn't match our expectation, wrap & rethrow
-        if (ex.getMessage().indexOf("unless <updateLog/> is configured") < 0) {
-          throw new RuntimeException("exception message is not expected", ex);
-        }
-      } finally {
-        resetExceptionIgnores();
-      }
-
+      // updating docs should fail
+      ignoreException("updateLog");
+      SolrException ex = expectThrows(SolrException.class,
+          () -> addAndGetVersion(sdoc("id", "1", "val_i", map("inc",-666)), null));
+      assertEquals(400, ex.code());
+      assertTrue(ex.getMessage().contains("unless <updateLog/> is configured"));
+      resetExceptionIgnores();
     } finally {
       System.clearProperty("enable.update.log");
       deleteCore();
@@ -68,30 +58,20 @@ public class TestAtomicUpdateErrorCases extends SolrTestCaseJ4 {
       assertNotNull("this test requires an update chain named 'nodistrib'",
                     h.getCore().getUpdateProcessingChain("nodistrib")); 
 
-
       // creating docs should work fine
       addAndGetVersion(sdoc("id", "1", "val_i", "42"), 
                        params("update.chain","nodistrib"));
       assertU(commit());
 
-      try {
-        ignoreException("DistributedUpdateProcessorFactory");
-
-        // updating docs should fail
-        addAndGetVersion(sdoc("id", "1", "val_i", map("inc",-666)), 
-                         params("update.chain","nodistrib"));
-        
-        fail("didn't get error about needing DistributedUpdateProcessorFactory");
-      } catch (SolrException ex) {
-        assertEquals(400, ex.code());
-        // if the message doesn't match our expectation, wrap & rethrow
-        if (ex.getMessage().indexOf("DistributedUpdateProcessorFactory") < 0) {
-          throw new RuntimeException("exception message is not expected", ex);
-        }
-      } finally {
-        resetExceptionIgnores();
-      }
-
+      ignoreException("DistributedUpdateProcessorFactory");
+      // updating docs should fail
+      SolrException ex = expectThrows(SolrException.class, () -> {
+        addAndGetVersion(sdoc("id", "1", "val_i", map("inc",-666)),
+            params("update.chain","nodistrib"));
+      });
+      assertEquals(400, ex.code());
+      assertTrue(ex.getMessage().contains("DistributedUpdateProcessorFactory"));
+      resetExceptionIgnores();
     } finally {
       deleteCore();
     }
diff --git a/solr/core/src/test/org/apache/solr/update/TestUpdate.java b/solr/core/src/test/org/apache/solr/update/TestUpdate.java
index f16c384..f276dc7 100644
--- a/solr/core/src/test/org/apache/solr/update/TestUpdate.java
+++ b/solr/core/src/test/org/apache/solr/update/TestUpdate.java
@@ -16,15 +16,15 @@
  */
 package org.apache.solr.update;
 
+import java.io.IOException;
+import java.util.concurrent.Callable;
+
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import java.io.IOException;
-import java.util.concurrent.Callable;
-
 public class TestUpdate extends SolrTestCaseJ4 {
   @BeforeClass
   public static void beforeClass() throws Exception {
@@ -82,21 +82,14 @@ public class TestUpdate extends SolrTestCaseJ4 {
 
 
     long version2;
-    try {
-      // try bad version added as a field in the doc
-      version2 = addAndGetVersion(sdoc("id","1", "val_is",map("add",-100), "_version_",2), null);
-      fail();
-    } catch (SolrException se) {
-      assertEquals(409, se.code());
-    }
+    SolrException se = expectThrows(SolrException.class,
+        () -> addAndGetVersion(sdoc("id","1", "val_is",map("add",-100), "_version_",2), null));
+    assertEquals(409, se.code());
 
-    try {
-      // try bad version added as a request param
-      version2 = addAndGetVersion(sdoc("id","1", "val_is",map("add",-100)), params("_version_","2"));
-      fail();
-    } catch (SolrException se) {
-      assertEquals(409, se.code());
-    }
+    // try bad version added as a request param
+    se = expectThrows(SolrException.class,
+        () -> addAndGetVersion(sdoc("id","1", "val_is",map("add",-100)), params("_version_","2")));
+    assertEquals(409, se.code());
 
     // try good version added as a field in the doc
     version = addAndGetVersion(sdoc("id","1", "val_is",map("add",-100), "_version_",version), null);
@@ -130,15 +123,10 @@ public class TestUpdate extends SolrTestCaseJ4 {
     version = deleteAndGetVersion("1", null);
     afterUpdate.call();
 
-
-    try {
-      // test that updating a non-existing doc fails if we set _version_=1
-      version2 = addAndGetVersion(sdoc("id","1", "val_is",map("add",-101), "_version_","1"), null);
-      fail();
-    } catch (SolrException se) {
-      assertEquals(409, se.code());
-    }
-
+    // test that updating a non-existing doc fails if we set _version_=1
+    se = expectThrows(SolrException.class,
+        () -> addAndGetVersion(sdoc("id","1", "val_is",map("add",-101), "_version_","1"), null));
+    assertEquals(409, se.code());
 
     // test that by default we can update a non-existing doc
     version = addAndGetVersion(sdoc("id","1", "val_i",102, "val_is",map("add",-102)), null);
@@ -208,20 +196,14 @@ public class TestUpdate extends SolrTestCaseJ4 {
     );
 
     // test that updating a unique id results in failure.
-    try {
-      ignoreException("Invalid update of id field");
-      version = addAndGetVersion(sdoc(
-          "id", map("set","1"),
-          "val_is", map("inc","2000000000")
-      ),
-          null);
-
-      fail();
-    } catch (SolrException se) {
-      resetExceptionIgnores();
-      assertEquals(400, se.code());
-      assertTrue(se.getMessage().indexOf("Invalid update of id field") >= 0);
-    }
+    ignoreException("Invalid update of id field");
+    se = expectThrows(SolrException.class,
+        () -> addAndGetVersion(
+            sdoc("id", map("set","1"), "val_is", map("inc","2000000000")), null)
+    );
+    resetExceptionIgnores();
+    assertEquals(400, se.code());
+    assertTrue(se.getMessage().contains("Invalid update of id field"));
 
     afterUpdate.call();
 
diff --git a/solr/core/src/test/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactoryTest.java b/solr/core/src/test/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactoryTest.java
index c5319ea..89d3314 100644
--- a/solr/core/src/test/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactoryTest.java
+++ b/solr/core/src/test/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactoryTest.java
@@ -43,20 +43,16 @@ public class IgnoreLargeDocumentProcessorFactoryTest extends SolrTestCase {
 
     IgnoreLargeDocumentProcessorFactory factory = new IgnoreLargeDocumentProcessorFactory();
     factory.init(args);
-    try {
-      UpdateRequestProcessor processor = factory.getInstance(null, null, null);
-      processor.processAdd(getUpdate(1024));
-      fail("Expected processor to ignore the update");
-    } catch (SolrException e) {
-      //expected
-    }
+
+    UpdateRequestProcessor processor = factory.getInstance(null, null, null);
+    expectThrows(SolrException.class, () -> processor.processAdd(getUpdate(1024)));
 
     args = new NamedList();
     args.add(IgnoreLargeDocumentProcessorFactory.LIMIT_SIZE_PARAM, 2);
     factory = new IgnoreLargeDocumentProcessorFactory();
     factory.init(args);
-    UpdateRequestProcessor processor = factory.getInstance(null, null, null);
-    processor.processAdd(getUpdate(1024));
+    UpdateRequestProcessor requestProcessor = factory.getInstance(null, null, null);
+    requestProcessor.processAdd(getUpdate(1024));
 
   }
 
diff --git a/solr/core/src/test/org/apache/solr/update/processor/StatelessScriptUpdateProcessorFactoryTest.java b/solr/core/src/test/org/apache/solr/update/processor/StatelessScriptUpdateProcessorFactoryTest.java
index e53bfdc..04c277c 100644
--- a/solr/core/src/test/org/apache/solr/update/processor/StatelessScriptUpdateProcessorFactoryTest.java
+++ b/solr/core/src/test/org/apache/solr/update/processor/StatelessScriptUpdateProcessorFactoryTest.java
@@ -16,20 +16,18 @@
  */
 package org.apache.solr.update.processor;
 
-import org.apache.solr.common.params.ModifiableSolrParams;
-import org.apache.solr.common.SolrException;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.core.SolrCore;
 import org.junit.Assume;
 import org.junit.BeforeClass;
 
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptEngine;
-
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Tests {@link StatelessScriptUpdateProcessorFactory}.
  *
@@ -233,33 +231,22 @@ public class StatelessScriptUpdateProcessorFactoryTest extends UpdateProcessorTe
 
   public void testPropogatedException() throws Exception  {
     final String chain = "error-on-add";
-    try {
-      SolrInputDocument d = processAdd(chain,
-                                       doc(f("id", "5"),
-                                           f("name", " foo "),
-                                           f("subject", "bar")));
-    } catch (SolrException e) {
-      assertTrue("Exception doesn't contain script error string: " + e.getMessage(),
-                 0 < e.getMessage().indexOf("no-soup-fo-you"));
-      return;
-    }
-    fail("Did not get exception from script");
-
+    SolrException e = expectThrows(SolrException.class, () ->
+        processAdd(chain, doc(f("id", "5"), f("name", " foo "),
+            f("subject", "bar")))
+    );
+    assertTrue("Exception doesn't contain script error string: " + e.getMessage(),
+        0 < e.getMessage().indexOf("no-soup-fo-you"));
   }
 
   public void testMissingFunctions() throws Exception  {
     final String chain = "missing-functions";
-    try {
-      SolrInputDocument d = processAdd(chain,
-                                       doc(f("id", "5"),
-                                           f("name", " foo "),
-                                           f("subject", "bar")));
-    } catch (SolrException e) {
-      assertTrue("Exception doesn't contain expected error: " + e.getMessage(),
-                 0 < e.getMessage().indexOf("processAdd"));
-      return;
-    }
-    fail("Did not get exception from script");
+    SolrException e = expectThrows(SolrException.class, () ->
+        processAdd(chain, doc(f("id", "5"),
+            f("name", " foo "), f("subject", "bar")))
+    );
+    assertTrue("Exception doesn't contain expected error: " + e.getMessage(),
+        0 < e.getMessage().indexOf("processAdd"));
   }
 
   public void testJavaScriptCompatibility() throws Exception  {
diff --git a/solr/core/src/test/org/apache/solr/update/processor/TestDocBasedVersionConstraints.java b/solr/core/src/test/org/apache/solr/update/processor/TestDocBasedVersionConstraints.java
index 917afad..7dd1a1c 100644
--- a/solr/core/src/test/org/apache/solr/update/processor/TestDocBasedVersionConstraints.java
+++ b/solr/core/src/test/org/apache/solr/update/processor/TestDocBasedVersionConstraints.java
@@ -16,17 +16,12 @@
  */
 package org.apache.solr.update.processor;
 
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.hasItem;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+
 import org.apache.lucene.util.TestUtil;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
@@ -35,11 +30,16 @@ import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
-import org.apache.solr.update.processor.DocBasedVersionConstraintsProcessorFactory;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.junit.Before;
 import org.junit.BeforeClass;
 
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
 public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
 
   @BeforeClass
@@ -223,23 +223,23 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
     updateJ(jsonAdd(sdoc("id", "aaa", "name", "a1", "my_version_l", "1001")),
             params("update.chain","external-version-failhard"));
     assertU(commit());
-    try {
+
+    SolrException ex = expectThrows(SolrException.class, () -> {
       updateJ(jsonAdd(sdoc("id", "aaa", "name", "XX", "my_version_l", "42")),
-              params("update.chain","external-version-failhard"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+          params("update.chain","external-version-failhard"));
+    });
+    assertEquals(409, ex.code());
+
     assertU(commit());
     assertJQ(req("qt","/get", "id","aaa", "fl","name")
              , "=={'doc':{'name':'a1'}}");
-    try {
-      deleteAndGetVersion("aaa", params("del_version", "7", 
-                                        "update.chain","external-version-failhard"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+
+    ex = expectThrows(SolrException.class, () -> {
+      deleteAndGetVersion("aaa", params("del_version", "7",
+          "update.chain","external-version-failhard"));
+    });
+    assertEquals(409, ex.code());
+
     assertJQ(req("qt","/get", "id","aaa", "fl","name")
              , "=={'doc':{'name':'a1'}}");
     assertU(commit());
@@ -247,13 +247,12 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
     // fail low version delete against uncommitted doc from updateLog
     updateJ(jsonAdd(sdoc("id", "aaa", "name", "a2", "my_version_l", "1002")), 
             params("update.chain","external-version-failhard"));
-    try {
-      deleteAndGetVersion("aaa", params("del_version", "8", 
-                                        "update.chain","external-version-failhard"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+    ex = expectThrows(SolrException.class, () -> {
+      deleteAndGetVersion("aaa", params("del_version", "8",
+          "update.chain","external-version-failhard"));
+    });
+    assertEquals(409, ex.code());
+
     assertJQ(req("qt","/get", "id","aaa", "fl","name")
              , "=={'doc':{'name':'a2'}}");
     assertU(commit());
@@ -265,13 +264,12 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
     // fail low version add against uncommitted "delete" from updateLog
     deleteAndGetVersion("aaa", params("del_version", "1010",
                                       "update.chain","external-version-failhard"));
-    try {
+    ex = expectThrows(SolrException.class, () -> {
       updateJ(jsonAdd(sdoc("id", "aaa", "name", "XX", "my_version_l", "1005")),
-              params("update.chain","external-version-failhard"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+          params("update.chain","external-version-failhard"));
+    });
+    assertEquals(409, ex.code());
+
     assertJQ(req("qt","/get", "id","aaa", "fl","my_version_l")
              , "=={'doc':{'my_version_l':1010}}}");
     assertU(commit());
@@ -282,13 +280,12 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
 
     // fail low version add against committed "delete"
     // (delete was already done & committed above)
-    try {
+    ex = expectThrows(SolrException.class, () -> {
       updateJ(jsonAdd(sdoc("id", "aaa", "name", "XX", "my_version_l", "1009")),
-              params("update.chain","external-version-failhard"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+          params("update.chain","external-version-failhard"));
+    });
+    assertEquals(409, ex.code());
+
     assertJQ(req("qt","/get", "id","aaa", "fl","my_version_l")
              , "=={'doc':{'my_version_l':1010}}}");
     assertU(commit());
@@ -304,28 +301,25 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
       params("update.chain","external-version-failhard-multiple"));
     assertU(commit());
     // All variations of additional versions should fail other than my_version_l greater or my_version_f greater.
-    try {
+    SolrException ex = expectThrows(SolrException.class, () -> {
       updateJ(jsonAdd(sdoc("id", "aaa", "name", "X1", "my_version_l", "1000", "my_version_f", "1.0")),
           params("update.chain","external-version-failhard-multiple"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
-    try {
+    });
+    assertEquals(409, ex.code());
+
+    ex = expectThrows(SolrException.class, () -> {
       updateJ(jsonAdd(sdoc("id", "aaa", "name", "X2", "my_version_l", "1001", "my_version_f", "0.9")),
           params("update.chain","external-version-failhard-multiple"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+    });
+    assertEquals(409, ex.code());
+
     // Also fails on the exact same version
-    try {
+    ex = expectThrows(SolrException.class, () -> {
       updateJ(jsonAdd(sdoc("id", "aaa", "name", "X3", "my_version_l", "1001", "my_version_f", "1.0")),
           params("update.chain","external-version-failhard-multiple"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+    });
+    assertEquals(409, ex.code());
+
     //Verify we are still unchanged
     assertU(commit());
     assertJQ(req("q","+id:aaa +name:a1"), "/response/numFound==1");
@@ -347,30 +341,28 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
     updateJ(jsonAdd(sdoc("id", "aaa", "name", "a1", "my_version_l", "1001", "my_version_f", "1.0")),
         params("update.chain","external-version-failhard-multiple"));
     assertU(commit());
-    try {
+
+    SolrException ex = expectThrows(SolrException.class, () -> {
       deleteAndGetVersion("aaa", params("del_version", "1000", "del_version_2", "1.0",
           "update.chain","external-version-failhard-multiple"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
-    try {
+    });
+    assertEquals(409, ex.code());
+
+    ex = expectThrows(SolrException.class, () -> {
       deleteAndGetVersion("aaa", params("del_version", "1001", "del_version_2", "0.9",
           "update.chain","external-version-failhard-multiple"));
-      fail("no 409");
-    } catch (SolrException ex) {
-      assertEquals(409, ex.code());
-    }
+    });
+    assertEquals(409, ex.code());
+
     // And just verify if we pass version 1, we still error if version 2 isn't found.
-    try {
-      ignoreException("Delete by ID must specify doc version param");
+    ignoreException("Delete by ID must specify doc version param");
+    ex = expectThrows(SolrException.class, () -> {
       deleteAndGetVersion("aaa", params("del_version", "1001",
           "update.chain","external-version-failhard-multiple"));
-      fail("no 400");
-    } catch (SolrException ex) {
-      assertEquals(400, ex.code());
-      unIgnoreException("Delete by ID must specify doc version param");
-    }
+    });
+    assertEquals(400, ex.code());
+    unIgnoreException("Delete by ID must specify doc version param");
+
     //Verify we are still unchanged
     assertU(commit());
     assertJQ(req("q","+id:aaa +name:a1"), "/response/numFound==1");
@@ -505,19 +497,18 @@ public class TestDocBasedVersionConstraints extends SolrTestCaseJ4 {
 
     // Try updating both with a new version and using the enforced version chain, expect id=b to fail bc old
     // doc is missing the version field
-    version = "3";
-    updateJ(json("[{\"id\": \"a\", \"name\": \"a1\", \"my_version_l\": " + version + "}]"),
+    String newVersion = "3";
+    updateJ(json("[{\"id\": \"a\", \"name\": \"a1\", \"my_version_l\": " + newVersion + "}]"),
             params("update.chain", "external-version-constraint"));
-    try {
-      ignoreException("Doc exists in index, but has null versionField: my_version_l");
-      updateJ(json("[{\"id\": \"b\", \"name\": \"b1\", \"my_version_l\": " + version + "}]"),
-              params("update.chain", "external-version-constraint"));
-      fail("Update to id=b should have failed because existing doc is missing version field");
-    } catch (final SolrException ex) {
-      // expected
-      assertEquals("Doc exists in index, but has null versionField: my_version_l", ex.getMessage());
-      unIgnoreException("Doc exists in index, but has null versionField: my_version_l");
-    }
+
+    ignoreException("Doc exists in index, but has null versionField: my_version_l");
+    SolrException ex = expectThrows(SolrException.class, () -> {
+      updateJ(json("[{\"id\": \"b\", \"name\": \"b1\", \"my_version_l\": " + newVersion + "}]"),
+          params("update.chain", "external-version-constraint"));
+    });
+    assertEquals("Doc exists in index, but has null versionField: my_version_l", ex.getMessage());
+    unIgnoreException("Doc exists in index, but has null versionField: my_version_l");
+
     assertU(commit());
     assertJQ(req("q","*:*"), "/response/numFound==2");
     assertJQ(req("qt","/get", "id", "a", "fl", "id,my_version_l"), "=={'doc':{'id':'a', 'my_version_l':3}}"); // version changed to 3
diff --git a/solr/core/src/test/org/apache/solr/update/processor/TolerantUpdateProcessorTest.java b/solr/core/src/test/org/apache/solr/update/processor/TolerantUpdateProcessorTest.java
index 6e7584f..07b3a88 100644
--- a/solr/core/src/test/org/apache/solr/update/processor/TolerantUpdateProcessorTest.java
+++ b/solr/core/src/test/org/apache/solr/update/processor/TolerantUpdateProcessorTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.solr.update.processor;
 
+import javax.xml.xpath.XPathExpressionException;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.lang.reflect.Method;
@@ -26,8 +27,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import javax.xml.xpath.XPathExpressionException;
-
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
@@ -136,81 +135,59 @@ public class TolerantUpdateProcessorTest extends UpdateProcessorTestBase {
   
   @Test
   public void testInvalidAdds() throws IOException {
-    SolrInputDocument invalidDoc = doc(field("text", "the quick brown fox")); //no id
-    try {
-      // This doc should fail without being tolerant
-      add("not-tolerant", null, invalidDoc);
-      fail("Expecting exception");
-    } catch (Exception e) {
-      //expected
-      assertTrue(e.getMessage().contains("Document is missing mandatory uniqueKey field"));
-    }
-    assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", Arrays.asList(new SolrInputDocument[]{invalidDoc}), null, "(unknown)");
+    SolrInputDocument invalidDoc1 = doc(field("text", "the quick brown fox")); //no id
+    // This doc should fail without being tolerant
+    Exception e = expectThrows(Exception.class, () -> add("not-tolerant", null, invalidDoc1));
+    assertTrue(e.getMessage().contains("Document is missing mandatory uniqueKey field"));
+
+    assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", Arrays.asList(new SolrInputDocument[]{invalidDoc1}), null, "(unknown)");
     
     //a valid doc
-    SolrInputDocument validDoc = doc(field("id", "1"), field("text", "the quick brown fox"));
-    
-    try {
-      // This batch should fail without being tolerant
-      add("not-tolerant", null, Arrays.asList(new SolrInputDocument[]{invalidDoc, validDoc}));
-      fail("Expecting exception");
-    } catch (Exception e) {
-      //expected
-      assertTrue(e.getMessage().contains("Document is missing mandatory uniqueKey field"));
-    }
+    SolrInputDocument validDoc1 = doc(field("id", "1"), field("text", "the quick brown fox"));
+
+    // This batch should fail without being tolerant
+    e = expectThrows(Exception.class, () -> add("not-tolerant", null,
+        Arrays.asList(new SolrInputDocument[]{invalidDoc1, validDoc1})));
+    assertTrue(e.getMessage().contains("Document is missing mandatory uniqueKey field"));
     
     assertU(commit());
-    assertQ(req("q","id:1")
-        ,"//result[@numFound='0']");
+    assertQ(req("q","id:1"),"//result[@numFound='0']");
     
     
-    assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", Arrays.asList(new SolrInputDocument[]{invalidDoc, validDoc}), null, "(unknown)");
+    assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", Arrays.asList(new SolrInputDocument[]{invalidDoc1, validDoc1}), null, "(unknown)");
     assertU(commit());
     
     // verify that the good document made it in. 
-    assertQ(req("q","id:1")
-        ,"//result[@numFound='1']");
-    
-    invalidDoc = doc(field("id", "2"), field("weight", "aaa"));
-    validDoc = doc(field("id", "3"), field("weight", "3"));
-    
-    try {
-      // This batch should fail without being tolerant
-      add("not-tolerant", null, Arrays.asList(new SolrInputDocument[]{invalidDoc, validDoc})); //no id
-      fail("Expecting exception");
-    } catch (Exception e) {
-      //expected
-      assertTrue(e.getMessage().contains("Error adding field"));
-    }
+    assertQ(req("q","id:1"),"//result[@numFound='1']");
     
+    SolrInputDocument invalidDoc2 = doc(field("id", "2"), field("weight", "aaa"));
+    SolrInputDocument validDoc2 = doc(field("id", "3"), field("weight", "3"));
+
+    // This batch should fail without being tolerant
+    e = expectThrows(Exception.class, () -> add("not-tolerant", null,
+        Arrays.asList(new SolrInputDocument[]{invalidDoc2, validDoc2})));
+    assertTrue(e.getMessage().contains("Error adding field"));
+
     assertU(commit());
-    assertQ(req("q","id:3")
-        ,"//result[@numFound='0']");
+    assertQ(req("q","id:3"),"//result[@numFound='0']");
     
-    assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", Arrays.asList(new SolrInputDocument[]{invalidDoc, validDoc}), null, "2");
+    assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", Arrays.asList(new SolrInputDocument[]{invalidDoc2, validDoc2}), null, "2");
     assertU(commit());
     
     // The valid document was indexed
-    assertQ(req("q","id:3")
-        ,"//result[@numFound='1']");
+    assertQ(req("q","id:3"),"//result[@numFound='1']");
     
     // The invalid document was NOT indexed
-    assertQ(req("q","id:2")
-        ,"//result[@numFound='0']");
+    assertQ(req("q","id:2"),"//result[@numFound='0']");
     
   }
   
   @Test
   public void testMaxErrorsDefault() throws IOException {
-    try {
-      // by default the TolerantUpdateProcessor accepts all errors, so this batch should succeed with 10 errors.
-      assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, null, badIds);
-    } catch(Exception e) {
-      fail("Shouldn't get an exception for this batch: " + e.getMessage());
-    }
+    // by default the TolerantUpdateProcessor accepts all errors, so this batch should succeed with 10 errors.
+    assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, null, badIds);
     assertU(commit());
-    assertQ(req("q","*:*")
-        ,"//result[@numFound='10']");
+    assertQ(req("q","*:*"),"//result[@numFound='10']");
   }
   
   public void testMaxErrorsSucceed() throws IOException {
@@ -219,40 +196,31 @@ public class TolerantUpdateProcessorTest extends UpdateProcessorTestBase {
     // still OK
     assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, requestParams, badIds);
     assertU(commit());
-    assertQ(req("q","*:*")
-        ,"//result[@numFound='10']");
+    assertQ(req("q","*:*"),"//result[@numFound='10']");
   }
   
   @Test
   public void testMaxErrorsThrowsException() throws IOException {
     ModifiableSolrParams requestParams = new ModifiableSolrParams();
     requestParams.add("maxErrors", "5");
-    try {
-      // should fail
-      assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, requestParams, badIds);
-      fail("Expecting exception");
-    } catch (SolrException e) {
-      assertTrue(e.getMessage(),
-                 e.getMessage().contains("ERROR: [doc=1] Error adding field 'weight'='b' msg=For input string: \"b\""));
-    }
+
+    SolrException e = expectThrows(SolrException.class, () ->
+        assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, requestParams, badIds));
+    assertTrue(e.getMessage(),
+        e.getMessage().contains("ERROR: [doc=1] Error adding field 'weight'='b' msg=For input string: \"b\""));
     //the first good documents made it to the index
     assertU(commit());
-    assertQ(req("q","*:*")
-        ,"//result[@numFound='6']");
+    assertQ(req("q","*:*"),"//result[@numFound='6']");
   }
 
   @Test
   public void testMaxErrorsInfinite() throws IOException {
     ModifiableSolrParams requestParams = new ModifiableSolrParams();
     requestParams.add("maxErrors", "-1");
-    try {
-      assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, null, badIds);
-    } catch(Exception e) {
-      fail("Shouldn't get an exception for this batch: " + e.getMessage());
-    }
+    assertAddsSucceedWithErrors("tolerant-chain-max-errors-not-set", docs, null, badIds);
+
     assertU(commit());
-    assertQ(req("q","*:*")
-            ,"//result[@numFound='10']");
+    assertQ(req("q","*:*"),"//result[@numFound='10']");
   }
   
   @Test
@@ -261,17 +229,14 @@ public class TolerantUpdateProcessorTest extends UpdateProcessorTestBase {
     List<SolrInputDocument> smallBatch = docs.subList(0, 2);
     ModifiableSolrParams requestParams = new ModifiableSolrParams();
     requestParams.add("maxErrors", "0");
-    try {
-      // should fail
-      assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", smallBatch, requestParams, "1");
-      fail("Expecting exception");
-    } catch (SolrException e) {
-      assertTrue(e.getMessage().contains("ERROR: [doc=1] Error adding field 'weight'='b' msg=For input string: \"b\""));
-    }
+
+    SolrException e = expectThrows(SolrException.class, () ->
+        assertAddsSucceedWithErrors("tolerant-chain-max-errors-10", smallBatch, requestParams, "1"));
+    assertTrue(e.getMessage().contains("ERROR: [doc=1] Error adding field 'weight'='b' msg=For input string: \"b\""));
+
     //the first good documents made it to the index
     assertU(commit());
-    assertQ(req("q","*:*")
-        ,"//result[@numFound='1']");
+    assertQ(req("q","*:*"),"//result[@numFound='1']");
   }
   
   @Test
diff --git a/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java b/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java
index f5d3de2..d3ea248 100644
--- a/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java
+++ b/solr/core/src/test/org/apache/solr/util/DateMathParserTest.java
@@ -319,14 +319,9 @@ public class DateMathParserTest extends SolrTestCaseJ4 {
     badCommands.put("?SECONDS", 0);
 
     for (String command : badCommands.keySet()) {
-      try {
-        Date out = p.parseMath(command);
-        fail("Didn't generate SyntaxError for: " + command);
-      } catch (ParseException e) {
-        assertEquals("Wrong pos for: " + command + " => " + e.getMessage(),
-                     badCommands.get(command).intValue(), e.getErrorOffset());
-
-      }
+      ParseException e = expectThrows(ParseException.class, () -> p.parseMath(command));
+      assertEquals("Wrong pos for: " + command + " => " + e.getMessage(),
+          badCommands.get(command).intValue(), e.getErrorOffset());
     }
     
   }
diff --git a/solr/core/src/test/org/apache/solr/util/TestTestInjection.java b/solr/core/src/test/org/apache/solr/util/TestTestInjection.java
index 84282ca..089b671 100644
--- a/solr/core/src/test/org/apache/solr/util/TestTestInjection.java
+++ b/solr/core/src/test/org/apache/solr/util/TestTestInjection.java
@@ -36,18 +36,10 @@ public class TestTestInjection extends SolrTestCase {
   
   public void testBasics() {
     TestInjection.failReplicaRequests = "true:100";
-    
-    try {
-      TestInjection.injectFailReplicaRequests();
-      fail("should fail 100%");
-    } catch (Throwable e) {
-      assertFalse("Should not fail based on bad syntax",
-          e.getMessage().toLowerCase(Locale.ENGLISH).contains("bad syntax"));
 
-      // good
-      
-      // assertTrue("Should fail with * based error: " + e.getClass().getName(), (e instanceof *));
-    }
+    Exception e = expectThrows(Exception.class, TestInjection::injectFailReplicaRequests);
+    assertFalse("Should not fail based on bad syntax",
+        e.getMessage().toLowerCase(Locale.ENGLISH).contains("bad syntax"));
     
     TestInjection.failReplicaRequests = "true:00";
     for (int i = 0; i < 100; i++) {
@@ -78,19 +70,13 @@ public class TestTestInjection extends SolrTestCase {
 
   public void testBadSyntax(String syntax) {
     TestInjection.failReplicaRequests = syntax;
-    
-    try {
-      TestInjection.injectFailReplicaRequests();
-      fail("should fail 100%");
-    } catch (Exception e) {
-      assertTrue(e.getMessage().toLowerCase(Locale.ENGLISH).contains("bad syntax"));
-      // good
-    }
+    Exception e = expectThrows(Exception.class, TestInjection::injectFailReplicaRequests);
+    assertTrue(e.getMessage().toLowerCase(Locale.ENGLISH).contains("bad syntax"));
   }
   
   public void testGoodSyntax(String syntax) {
     TestInjection.failReplicaRequests = syntax;
-    
+
     try {
       TestInjection.injectFailReplicaRequests();
     } catch (Exception e) {
diff --git a/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordDeserializerTest.java b/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordDeserializerTest.java
index 5fdde31..d7a4fed 100644
--- a/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordDeserializerTest.java
+++ b/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordDeserializerTest.java
@@ -34,28 +34,22 @@ public class BigEndianAscendingWordDeserializerTest extends SolrTestCase {
     @Test
     public void constructorErrorTest() {
         // word length too small
-        try {
+        IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
             new BigEndianAscendingWordDeserializer(0/*wordLength, below minimum of 1*/, 0/*bytePadding, arbitrary*/, new byte[1]/*bytes, arbitrary, not used here*/);
-            fail("Should complain about too-short words.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Word length must be"));
-        }
+        });
+        assertTrue(e.getMessage().contains("Word length must be"));
 
         // word length too large
-        try {
+        e = expectThrows(IllegalArgumentException.class, () -> {
             new BigEndianAscendingWordDeserializer(65/*wordLength, above maximum of 64*/, 0/*bytePadding, arbitrary*/, new byte[1]/*bytes, arbitrary, not used here*/);
-            fail("Should complain about too-long words.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Word length must be"));
-        }
+        });
+        assertTrue(e.getMessage().contains("Word length must be"));
 
         // byte padding negative
-        try {
+        e = expectThrows(IllegalArgumentException.class, () -> {
             new BigEndianAscendingWordDeserializer(5/*wordLength, arbitrary*/, -1/*bytePadding, too small*/, new byte[1]/*bytes, arbitrary, not used here*/);
-            fail("Should complain about negative byte padding.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Byte padding must be"));
-        }
+        });
+        assertTrue(e.getMessage().contains("Byte padding must be"));
     }
 
     /**
diff --git a/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordSerializerTest.java b/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordSerializerTest.java
index 81b93fe..285b623 100644
--- a/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordSerializerTest.java
+++ b/solr/core/src/test/org/apache/solr/util/hll/BigEndianAscendingWordSerializerTest.java
@@ -31,36 +31,28 @@ public class BigEndianAscendingWordSerializerTest extends SolrTestCase {
     @Test
     public void constructorErrorTest() {
         // word length too small
-        try {
-            new BigEndianAscendingWordSerializer(0/*wordLength, below minimum of 1*/, 1/*wordCount, arbitrary*/, 0/*bytePadding, arbitrary*/);
-            fail("Should complain about too-short words.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Word length must be"));
-        }
+        IllegalArgumentException e = expectThrows(IllegalArgumentException.class,  () -> {
+            new BigEndianAscendingWordSerializer(0/*wordLength, below minimum of 1*/, 1/*wordCount, arbitrary*/, 0/*bytePadding, arbitrary*/);;
+        });
+        assertTrue(e.getMessage().contains("Word length must be"));
 
         // word length too large
-        try {
+        e = expectThrows(IllegalArgumentException.class,  () -> {
             new BigEndianAscendingWordSerializer(65/*wordLength, above max of 64*/, 1/*wordCount, arbitrary*/, 0/*bytePadding, arbitrary*/);
-            fail("Should complain about too-long words.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Word length must be"));
-        }
+        });
+        assertTrue(e.getMessage().contains("Word length must be"));
 
         // word count negative
-        try {
+        e = expectThrows(IllegalArgumentException.class,  () -> {
             new BigEndianAscendingWordSerializer(5/*wordLength, arbitrary*/, -1/*wordCount, too small*/, 0/*bytePadding, arbitrary*/);
-            fail("Should complain about negative word count.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Word count must be"));
-        }
+        });
+        assertTrue(e.getMessage().contains("Word count must be"));
 
         // byte padding negative
-        try {
+        e = expectThrows(IllegalArgumentException.class,  () -> {
             new BigEndianAscendingWordSerializer(5/*wordLength, arbitrary*/, 1/*wordCount, arbitrary*/, -1/*bytePadding, too small*/);
-            fail("Should complain about negative byte padding.");
-        } catch(final IllegalArgumentException e) {
-            assertTrue(e.getMessage().contains("Byte padding must be"));
-        }
+        });
+        assertTrue(e.getMessage().contains("Byte padding must be"));
     }
 
     /**
@@ -74,12 +66,8 @@ public class BigEndianAscendingWordSerializerTest extends SolrTestCase {
                                                  0/*bytePadding, arbitrary*/);
 
         // getBytes without enough writeWord should throw
-        try {
-            serializer.getBytes();
-            fail("Should throw.");
-        } catch(final RuntimeException e) {
-            assertTrue(e.getMessage().contains("Not all words"));
-        }
+        RuntimeException e = expectThrows(RuntimeException.class, serializer::getBytes);
+        assertTrue(e.getMessage().contains("Not all words"));
     }
 
     /**
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
index 4a0b581..5391b89 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
@@ -17,10 +17,6 @@
 package org.apache.solr.client.solrj;
 
 
-import static org.apache.solr.common.params.UpdateParams.ASSUME_CONTENT_TYPE;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.core.StringContains.containsString;
-
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -38,6 +34,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 
+import com.google.common.collect.Maps;
 import org.apache.lucene.util.TestUtil;
 import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
 import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
@@ -84,7 +81,9 @@ import org.noggit.JSONParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Maps;
+import static org.apache.solr.common.params.UpdateParams.ASSUME_CONTENT_TYPE;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.core.StringContains.containsString;
 
 /**
  * This should include tests against the example solr config
@@ -482,50 +481,25 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
     query.set(CommonParams.QT, "/analysis/field");
     query.set(AnalysisParams.FIELD_TYPE, "pint");
     query.set(AnalysisParams.FIELD_VALUE, "ignore_exception");
-    try {
-      client.query( query );
-      Assert.fail("should have a number format exception");
-    }
-    catch(SolrException ex) {
-      assertEquals(400, ex.code());
-      assertThat(ex.getMessage(), containsString("Invalid Number: ignore_exception"));
-    }
-    catch(Throwable t) {
-      t.printStackTrace();
-      Assert.fail("should have thrown a SolrException! not: "+t);
-    }
-    
-    try {
-      //the df=text here is a kluge for the test to supply a default field in case there is none in schema.xml
-      // alternatively, the resulting assertion could be modified to assert that no default field is specified.
-      client.deleteByQuery( "{!df=text} ??::?? ignore_exception" ); // query syntax error
-      Assert.fail("should have a number format exception");
-    }
-    catch(SolrException ex) {
-      assertEquals(400, ex.code());
-      assertTrue(ex.getMessage().indexOf("??::?? ignore_exception")>0);  // The reason should get passed through
-    }
-    catch(Throwable t) {
-      t.printStackTrace();
-      Assert.fail("should have thrown a SolrException! not: "+t);
+    SolrException ex = expectThrows(SolrException.class, () -> client.query(query));
+    assertEquals(400, ex.code());
+    assertThat(ex.getMessage(), containsString("Invalid Number: ignore_exception"));
+
+    //the df=text here is a kluge for the test to supply a default field in case there is none in schema.xml
+    // alternatively, the resulting assertion could be modified to assert that no default field is specified.
+    ex = expectThrows(SolrException.class, () -> client.deleteByQuery( "{!df=text} ??::?? ignore_exception" ));
+    assertTrue(ex.getMessage().indexOf("??::?? ignore_exception")>0);  // The reason should get passed through
+    assertEquals(400, ex.code());
 
-    }
     SolrInputDocument doc = new SolrInputDocument();
     doc.addField("id", "DOCID");
     doc.addField("id", "DOCID2");
     doc.addField("name", "hello");
 
     if (client instanceof HttpSolrClient) {
-      try {
-        client.add(doc);
-        fail("Should throw exception!");
-      } catch (SolrException ex) {
-        assertEquals(400, ex.code());
-        assertTrue(ex.getMessage().indexOf(
-            "contains multiple values for uniqueKey") > 0); // The reason should get passed through
-      } catch (Throwable t) {
-        Assert.fail("should have thrown a SolrException! not: " + t);
-      }
+      ex = expectThrows(SolrException.class, () -> client.add(doc));
+      assertEquals(400, ex.code());
+      assertTrue(ex.getMessage().indexOf("contains multiple values for uniqueKey") > 0);
     } else if (client instanceof ErrorTrackingConcurrentUpdateSolrClient) {
       //XXX concurrentupdatesolrserver reports errors differently
       ErrorTrackingConcurrentUpdateSolrClient concurrentClient = (ErrorTrackingConcurrentUpdateSolrClient) client;
@@ -1199,47 +1173,35 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
     SolrQuery query = new SolrQuery("*:*");
     query.addFacetPivotField("{!stats=s1}features,manu");
     query.addGetFieldStatistics("{!key=inStock_val tag=s1}inStock");
-    try {
-      client.query(query);
-      fail("SolrException should be thrown on query");
-    } catch (SolrException e) {
-      assertEquals("Pivot facet on boolean is not currently supported, bad request returned", 400, e.code());
-      assertTrue(e.getMessage().contains("is not currently supported"));
-      assertTrue(e.getMessage().contains("boolean"));
-    }
+
+    SolrException e = expectThrows(SolrException.class, () -> client.query(query));
+    assertEquals("Pivot facet on boolean is not currently supported, bad request returned", 400, e.code());
+    assertTrue(e.getMessage().contains("is not currently supported"));
+    assertTrue(e.getMessage().contains("boolean"));
 
     // asking for multiple stat tags -- see SOLR-6663
-    query = new SolrQuery("*:*");
-    query.addFacetPivotField("{!stats=tag1,tag2}features,manu");
-    query.addGetFieldStatistics("{!tag=tag1}price", "{!tag=tag2}popularity");
-    query.setFacetMinCount(0);
-    query.setRows(0);
-    try {
-      client.query(query);
-      fail("SolrException should be thrown on query");
-    } catch (SolrException e) {
-      assertEquals(400, e.code());
-      assertTrue(e.getMessage().contains("stats"));
-      assertTrue(e.getMessage().contains("comma"));
-      assertTrue(e.getMessage().contains("tag"));
-    }
+    SolrQuery query2 = new SolrQuery("*:*");
+    query2.addFacetPivotField("{!stats=tag1,tag2}features,manu");
+    query2.addGetFieldStatistics("{!tag=tag1}price", "{!tag=tag2}popularity");
+    query2.setFacetMinCount(0);
+    query2.setRows(0);
+
+    e = expectThrows(SolrException.class, () -> client.query(query2));
+    assertEquals(400, e.code());
+    assertTrue(e.getMessage().contains("stats"));
+    assertTrue(e.getMessage().contains("comma"));
+    assertTrue(e.getMessage().contains("tag"));
 
     // text field
-    query = new SolrQuery("*:*");
-    query.addFacetPivotField("{!stats=s1}features,manu");
-    query.addGetFieldStatistics("{!tag=s1}features");
-    query.setFacetMinCount(0);
-    query.setRows(0);
-    try {
-      client.query(query);
-      fail("SolrException should be thrown on query");
-    } catch (SolrException e) {
-      assertEquals("Pivot facet on string is not currently supported, bad request returned", 400, e.code());
-      assertTrue(e.getMessage().contains("is not currently supported"));
-      assertTrue(e.getMessage().contains("text_general"));
-    }
-    
-
+    SolrQuery query3 = new SolrQuery("*:*");
+    query3.addFacetPivotField("{!stats=s1}features,manu");
+    query3.addGetFieldStatistics("{!tag=s1}features");
+    query3.setFacetMinCount(0);
+    query3.setRows(0);
+    e = expectThrows(SolrException.class, () -> client.query(query3));
+    assertEquals("Pivot facet on string is not currently supported, bad request returned", 400, e.code());
+    assertTrue(e.getMessage().contains("is not currently supported"));
+    assertTrue(e.getMessage().contains("text_general"));
   }
 
   @Test
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/cloud/autoscaling/TestPolicy.java b/solr/solrj/src/test/org/apache/solr/client/solrj/cloud/autoscaling/TestPolicy.java
index 63e87a2..5535e60 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/cloud/autoscaling/TestPolicy.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/cloud/autoscaling/TestPolicy.java
@@ -898,13 +898,8 @@ public class TestPolicy extends SolrTestCaseJ4 {
   }
 
   private static void expectError(String name, Object val, String msg) {
-    try {
-      Clause.validate(name, val, true);
-      fail("expected exception containing " + msg);
-    } catch (Exception e) {
-      assertTrue("expected exception containing " + msg, e.getMessage().contains(msg));
-    }
-
+    Exception e = expectThrows(Exception.class, () -> Clause.validate(name, val, true));
+    assertTrue("expected exception containing " + msg, e.getMessage().contains(msg));
   }
 
   public void testOperands() {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
index 79f8092..db0bd28 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
@@ -19,9 +19,9 @@ package org.apache.solr.client.solrj.embedded;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
-import java.nio.charset.StandardCharsets;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
@@ -40,7 +40,6 @@ import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.util.NamedList;
-import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -62,17 +61,10 @@ public class SolrExampleJettyTest extends SolrExampleTests {
   }
 
   @Test
-  public void testBadSetup()
-  {
-    try {
-      // setup the server...
-      String url = "http" + (isSSLMode() ? "s" : "") +  "://127.0.0.1/?core=xxx";
-      HttpSolrClient client = getHttpSolrClient(url);
-      Assert.fail("HttpSolrServer should not allow a path with a parameter: " + client.getBaseURL());
-    }
-    catch( Exception ex ) {
-      // expected
-    }
+  public void testBadSetup() {
+    // setup the server...
+    String url = "http" + (isSSLMode() ? "s" : "") +  "://127.0.0.1/?core=xxx";
+    expectThrows(Exception.class, () -> getHttpSolrClient(url));
   }
 
   @Test
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java
index 5f89c87..6972d96 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/TestSolrProperties.java
@@ -16,10 +16,9 @@
  */
 package org.apache.solr.client.solrj.embedded;
 
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
-
 import java.lang.invoke.MethodHandles;
 
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
@@ -77,12 +76,7 @@ public class TestSolrProperties extends AbstractEmbeddedSolrServerTestCase {
     SolrTestCaseJ4.ignoreException("unknown field");
 
     // You can't add it to core1
-    try {
-      up.process(getSolrCore1());
-      fail("Can't add core0 field to core1!");
-    }
-    catch (Exception ex) {
-    }
+    expectThrows(Exception.class, () -> up.process(getSolrCore1()));
 
     // Add to core1
     doc.setField("id", "BBB");
@@ -92,14 +86,8 @@ public class TestSolrProperties extends AbstractEmbeddedSolrServerTestCase {
     up.process(getSolrCore1());
 
     // You can't add it to core1
-    try {
-      SolrTestCaseJ4.ignoreException("core0");
-      up.process(getSolrCore0());
-      fail("Can't add core1 field to core0!");
-    }
-    catch (Exception ex) {
-    }
-    
+    SolrTestCaseJ4.ignoreException("core0");
+    expectThrows(Exception.class, () -> up.process(getSolrCore0()));
     SolrTestCaseJ4.resetExceptionIgnores();
 
     // now Make sure AAA is in 0 and BBB in 1
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
index 5b5566d..4460223 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
@@ -207,12 +207,9 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   
   @Test
   public void testTimeout() throws Exception {
-
     SolrQuery q = new SolrQuery("*:*");
     try(HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/slow/foo", DEFAULT_CONNECTION_TIMEOUT, 2000)) {
-      client.query(q, METHOD.GET);
-      fail("No exception thrown.");
-    } catch (SolrServerException e) {
+      SolrServerException e = expectThrows(SolrServerException.class, () -> client.query(q, METHOD.GET));
       assertTrue(e.getMessage().contains("Timeout"));
     }
 
@@ -230,13 +227,9 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
 
     try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       DebugServlet.setErrorCode(status);
-      try {
-        SolrQuery q = new SolrQuery("foo");
-        client.query(q, METHOD.GET);
-        fail("Didn't get excepted exception from oversided request");
-      } catch (SolrException e) {
-        assertEquals("Unexpected exception status code", status, e.code());
-      }
+      SolrQuery q = new SolrQuery("foo");
+      SolrException e = expectThrows(SolrException.class, () -> client.query(q, METHOD.GET));
+      assertEquals("Unexpected exception status code", status, e.code());
     } finally {
       DebugServlet.clear();
     }
@@ -248,9 +241,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       SolrQuery q = new SolrQuery("foo");
       q.setParam("a", "\u1234");
-      try {
-        client.query(q, METHOD.GET);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.query(q, METHOD.GET));
 
       //default method
       assertEquals("get", DebugServlet.lastMethod);
@@ -274,9 +265,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
 
       //POST
       DebugServlet.clear();
-      try {
-        client.query(q, METHOD.POST);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.query(q, METHOD.POST));
 
       assertEquals("post", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -292,9 +281,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
 
       //PUT
       DebugServlet.clear();
-      try {
-        client.query(q, METHOD.PUT);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.query(q, METHOD.PUT));
 
       assertEquals("put", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -311,9 +298,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       //XML/GET
       client.setParser(new XMLResponseParser());
       DebugServlet.clear();
-      try {
-        client.query(q, METHOD.GET);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.query(q, METHOD.GET));
 
       assertEquals("get", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -329,9 +314,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       //XML/POST
       client.setParser(new XMLResponseParser());
       DebugServlet.clear();
-      try {
-        client.query(q, METHOD.POST);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.query(q, METHOD.POST));
 
       assertEquals("post", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -347,9 +330,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
 
       client.setParser(new XMLResponseParser());
       DebugServlet.clear();
-      try {
-        client.query(q, METHOD.PUT);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.query(q, METHOD.PUT));
 
       assertEquals("put", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -370,9 +351,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   public void testDelete() throws Exception {
     DebugServlet.clear();
     try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
-      try {
-        client.deleteById("id");
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.deleteById("id"));
 
       //default method
       assertEquals("post", DebugServlet.lastMethod);
@@ -391,9 +370,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
 
       //XML
       client.setParser(new XMLResponseParser());
-      try {
-        client.deleteByQuery("*:*");
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.deleteByQuery("*:*"));
 
       assertEquals("post", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -412,21 +389,10 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     DebugServlet.clear();
     try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       Collection<String> ids = Collections.singletonList("a");
-      try {
-        client.getById("a");
-      } catch (ParseException ignored) {}
-
-      try {
-        client.getById(ids, null);
-      } catch (ParseException ignored) {}
-
-      try {
-        client.getById("foo", "a");
-      } catch (ParseException ignored) {}
-
-      try {
-        client.getById("foo", ids, null);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.getById("a"));
+      expectThrows(ParseException.class, () -> client.getById(ids, null));
+      expectThrows(ParseException.class, () -> client.getById("foo", "a"));
+      expectThrows(ParseException.class, () -> client.getById("foo", ids, null));
     }
   }
 
@@ -437,9 +403,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       UpdateRequest req = new UpdateRequest();
       req.add(new SolrInputDocument());
       req.setParam("a", "\u1234");
-      try {
-        client.request(req);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.request(req));
 
       //default method
       assertEquals("post", DebugServlet.lastMethod);
@@ -460,9 +424,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       //XML response and writer
       client.setParser(new XMLResponseParser());
       client.setRequestWriter(new RequestWriter());
-      try {
-        client.request(req);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.request(req));
 
       assertEquals("post", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -478,9 +440,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       client.setParser(new BinaryResponseParser());
       client.setRequestWriter(new BinaryRequestWriter());
       DebugServlet.clear();
-      try {
-        client.request(req);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.request(req));
 
       assertEquals("post", DebugServlet.lastMethod);
       assertEquals("Solr[" + HttpSolrClient.class.getName() + "] 1.0", DebugServlet.headers.get("User-Agent"));
@@ -501,40 +461,30 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     try (HttpSolrClient client = getHttpSolrClient(clientUrl)) {
       SolrQuery q = new SolrQuery("*:*");
       // default = false
-      try {
-        client.query(q);
-        fail("Should have thrown an exception.");
-      } catch (SolrServerException e) {
-        assertTrue(e.getMessage().contains("redirect"));
-      }
+      SolrServerException e = expectThrows(SolrServerException.class, () -> client.query(q));
+      assertTrue(e.getMessage().contains("redirect"));
 
       client.setFollowRedirects(true);
       client.query(q);
 
       //And back again:
       client.setFollowRedirects(false);
-      try {
-        client.query(q);
-        fail("Should have thrown an exception.");
-      } catch (SolrServerException e) {
-        assertTrue(e.getMessage().contains("redirect"));
-      }
+      e = expectThrows(SolrServerException.class, () -> client.query(q));
+      assertTrue(e.getMessage().contains("redirect"));
     }
 
   }
   
   @Test
   public void testCompression() throws Exception {
-    SolrQuery q = new SolrQuery("*:*");
+    final SolrQuery q = new SolrQuery("*:*");
     
     final String clientUrl = jetty.getBaseUrl().toString() + "/debug/foo";
     try (HttpSolrClient client = getHttpSolrClient(clientUrl)) {
       // verify request header gets set
       DebugServlet.clear();
-      try {
-        client.query(q);
-      } catch (ParseException ignored) {}
-      assertNull(DebugServlet.headers.toString(), DebugServlet.headers.get("Accept-Encoding")); 
+      expectThrows(ParseException.class, () -> client.query(q));
+      assertNull(DebugServlet.headers.toString(), DebugServlet.headers.get("Accept-Encoding"));
     }
     
     try (HttpSolrClient client = getHttpSolrClient(clientUrl, null, null, true)) {
@@ -549,7 +499,6 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
         client.query(q);
       } catch (ParseException ignored) {}
     }
-
     assertNull(DebugServlet.headers.get("Accept-Encoding"));
     
     // verify server compresses output
@@ -579,8 +528,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     
     // verify compressed response can be handled
     try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/collection1")) {
-      q = new SolrQuery("foo");
-      QueryResponse response = client.query(q);
+      QueryResponse response = client.query(new SolrQuery("foo"));
       assertEquals(0, response.getStatus());
     }
   }
@@ -685,9 +633,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
 
       SolrQuery q = new SolrQuery("foo");
       q.setParam("a", "\u1234");
-      try {
-        server.query(q, random().nextBoolean()?METHOD.POST:METHOD.GET);
-      } catch (Throwable t) {}
+      expectThrows(Exception.class, () -> server.query(q, random().nextBoolean()?METHOD.POST:METHOD.GET));
 
       // Assert cookies from UseContextCallback 
       assertNotNull(DebugServlet.cookies);
@@ -759,48 +705,40 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       client.setQueryParams(setOf("serverOnly"));
       UpdateRequest req = new UpdateRequest();
       setReqParamsOf(req, "serverOnly", "notServer");
-      try {
-        client.request(req);
-      } catch (ParseException ignored) {}
+      expectThrows(ParseException.class, () -> client.request(req));
       verifyServletState(client, req);
   
       // test without server query params
       DebugServlet.clear();
       client.setQueryParams(setOf());
-      req = new UpdateRequest();
-      req.setQueryParams(setOf("requestOnly"));
-      setReqParamsOf(req, "requestOnly", "notRequest");
-      try {
-        client.request(req);
-      } catch (ParseException ignored) {}
-      verifyServletState(client, req);
+      UpdateRequest req2 = new UpdateRequest();
+      req2.setQueryParams(setOf("requestOnly"));
+      setReqParamsOf(req2, "requestOnly", "notRequest");
+      expectThrows(ParseException.class, () -> client.request(req2));
+      verifyServletState(client, req2);
   
       // test with both request and server query params
       DebugServlet.clear();
-      req = new UpdateRequest();
+      UpdateRequest req3 = new UpdateRequest();
       client.setQueryParams(setOf("serverOnly", "both"));
-      req.setQueryParams(setOf("requestOnly", "both"));
-      setReqParamsOf(req, "serverOnly", "requestOnly", "both", "neither");
-       try {
-        client.request(req);
-       } catch (ParseException ignored) {}
-      verifyServletState(client, req);
+      req3.setQueryParams(setOf("requestOnly", "both"));
+      setReqParamsOf(req3, "serverOnly", "requestOnly", "both", "neither");
+      expectThrows(ParseException.class, () -> client.request(req3));
+      verifyServletState(client, req3);
   
       // test with both request and server query params with single stream
       DebugServlet.clear();
-      req = new UpdateRequest();
-      req.add(new SolrInputDocument());
+      UpdateRequest req4 = new UpdateRequest();
+      req4.add(new SolrInputDocument());
       client.setQueryParams(setOf("serverOnly", "both"));
-      req.setQueryParams(setOf("requestOnly", "both"));
-      setReqParamsOf(req, "serverOnly", "requestOnly", "both", "neither");
-       try {
-        client.request(req);
-       } catch (ParseException ignored) {}
+      req4.setQueryParams(setOf("requestOnly", "both"));
+      setReqParamsOf(req4, "serverOnly", "requestOnly", "both", "neither");
+      expectThrows(ParseException.class, () -> client.request(req4));
       // NOTE: single stream requests send all the params
       // as part of the query string.  So add "neither" to the request
       // so it passes the verification step.
-      req.setQueryParams(setOf("requestOnly", "both", "neither"));
-      verifyServletState(client, req);
+      req4.setQueryParams(setOf("requestOnly", "both", "neither"));
+      verifyServletState(client, req4);
     }
   }
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
index 24f4a4b..1c9ba04 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
@@ -32,6 +32,9 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.TimeoutException;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.lucene.util.LuceneTestCase.Slow;
 import org.apache.lucene.util.TestUtil;
@@ -75,10 +78,6 @@ import org.junit.rules.ExpectedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
 
 /**
  * This test would be faster if we simulated the zk state instead.
@@ -667,10 +666,8 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
   public void testShutdown() throws IOException {
     try (CloudSolrClient client = getCloudSolrClient("[ff01::114]:33332")) {
       client.setZkConnectTimeout(100);
-      client.connect();
-      fail("Expected exception");
-    } catch (SolrException e) {
-      assertTrue(e.getCause() instanceof TimeoutException);
+      SolrException ex = expectThrows(SolrException.class, client::connect);
+      assertTrue(ex.getCause() instanceof TimeoutException);
     }
   }
 
@@ -679,14 +676,10 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
 
   @Test
   public void testWrongZkChrootTest() throws IOException {
-
-    exception.expect(SolrException.class);
-    exception.expectMessage("cluster not found/not ready");
-
     try (CloudSolrClient client = getCloudSolrClient(cluster.getZkServer().getZkAddress() + "/xyz/foo")) {
       client.setZkClientTimeout(1000 * 60);
-      client.connect();
-      fail("Expected exception");
+      SolrException ex = expectThrows(SolrException.class, client::connect);
+      assertTrue(ex.getMessage().contains("cluster not found/not ready"));
     }
   }
 
@@ -765,16 +758,8 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
   public void testCollectionDoesntExist() throws Exception {
     CloudSolrClient client = getRandomClient();
     SolrInputDocument doc = new SolrInputDocument("id", "1", "title_s", "my doc");
-    try {
-      client.add("boguscollectionname", doc);
-      fail();
-    } catch (SolrException ex) {
-      if (ex.getMessage().equals("Collection not found: boguscollectionname")) {
-        // pass
-      } else {
-        throw ex;
-      }
-    }
+    SolrException ex = expectThrows(SolrException.class, () -> client.add("boguscollectionname", doc));
+    assertEquals("Collection not found: boguscollectionname", ex.getMessage());
   }
 
   public void testRetryUpdatesWhenClusterStateIsStale() throws Exception {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SolrPortAwareCookieSpecTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SolrPortAwareCookieSpecTest.java
index b5f08d6..c4c4643 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SolrPortAwareCookieSpecTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SolrPortAwareCookieSpecTest.java
@@ -20,6 +20,7 @@ import org.apache.http.cookie.CookieAttributeHandler;
 import org.apache.http.cookie.CookieOrigin;
 import org.apache.http.cookie.MalformedCookieException;
 import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.solr.SolrTestCaseJ4;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -36,12 +37,7 @@ public class SolrPortAwareCookieSpecTest {
     h.validate(cookie, origin);
 
     cookie.setDomain("somehost:1234");
-    try {
-      h.validate(cookie, origin);
-      Assert.fail("MalformedCookieException should have been thrown");
-    } catch (final MalformedCookieException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(MalformedCookieException.class, () -> h.validate(cookie, origin));
   }
 
   @Test
@@ -51,12 +47,7 @@ public class SolrPortAwareCookieSpecTest {
     final CookieAttributeHandler h = new SolrPortAwareCookieSpecFactory.PortAwareDomainHandler();
 
     cookie.setDomain("myhost");
-    try {
-      h.match(cookie, null);
-      Assert.fail("IllegalArgumentException should have been thrown, since origin is null.");
-    } catch (final IllegalArgumentException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(IllegalArgumentException.class, () -> h.match(cookie, null));
 
     cookie.setDomain(null);
     Assert.assertFalse(h.match(cookie, origin));
@@ -84,12 +75,7 @@ public class SolrPortAwareCookieSpecTest {
     h.validate(cookie, origin);
 
     cookie.setDomain("otherhost");
-    try {
-      h.validate(cookie, origin);
-      Assert.fail("MalformedCookieException should have been thrown");
-    } catch (final MalformedCookieException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(MalformedCookieException.class, () ->  h.validate(cookie, origin));
   }
 
   @Test
@@ -102,19 +88,10 @@ public class SolrPortAwareCookieSpecTest {
     h.validate(cookie, origin);
 
     cookie.setDomain(".otherdomain.com");
-    try {
-      h.validate(cookie, origin);
-      Assert.fail("MalformedCookieException should have been thrown");
-    } catch (final MalformedCookieException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(MalformedCookieException.class, () ->  h.validate(cookie, origin));
+
     cookie.setDomain("www.otherdomain.com");
-    try {
-      h.validate(cookie, origin);
-      Assert.fail("MalformedCookieException should have been thrown");
-    } catch (final MalformedCookieException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(MalformedCookieException.class, () ->  h.validate(cookie, origin));
   }
 
   @Test
@@ -127,12 +104,7 @@ public class SolrPortAwareCookieSpecTest {
     h.validate(cookie, origin);
 
     cookie.setDomain(".com");
-    try {
-      h.validate(cookie, origin);
-      Assert.fail("MalformedCookieException should have been thrown");
-    } catch (final MalformedCookieException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(MalformedCookieException.class, () ->  h.validate(cookie, origin));
   }
 
   @Test
@@ -145,12 +117,7 @@ public class SolrPortAwareCookieSpecTest {
     h.validate(cookie, origin);
 
     cookie.setDomain(".b.c");
-    try {
-      h.validate(cookie, origin);
-      Assert.fail("MalformedCookieException should have been thrown");
-    } catch (final MalformedCookieException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(MalformedCookieException.class, () ->  h.validate(cookie, origin));
   }
 
   @Test
@@ -179,18 +146,9 @@ public class SolrPortAwareCookieSpecTest {
   @Test
   public void testDomainInvalidInput() throws Exception {
     final CookieAttributeHandler h = new SolrPortAwareCookieSpecFactory.PortAwareDomainHandler();
-    try {
-      h.match(null, null);
-      Assert.fail("IllegalArgumentException must have been thrown");
-    } catch (final IllegalArgumentException ex) {
-      // expected
-    }
-    try {
-      h.match(new BasicClientCookie("name", "value"), null);
-      Assert.fail("IllegalArgumentException must have been thrown");
-    } catch (final IllegalArgumentException ex) {
-      // expected
-    }
+    SolrTestCaseJ4.expectThrows(IllegalArgumentException.class, () -> h.match(null, null));
+    SolrTestCaseJ4.expectThrows(IllegalArgumentException.class,
+        () -> h.match(new BasicClientCookie("name", "value"), null));
   }
 
 }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/TestCloudSolrClientConnections.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/TestCloudSolrClientConnections.java
index 8d9193f..4289ebf 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/TestCloudSolrClientConnections.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/TestCloudSolrClientConnections.java
@@ -40,13 +40,8 @@ public class TestCloudSolrClientConnections extends SolrTestCaseJ4 {
       CloudSolrClient client = cluster.getSolrClient();
       CollectionAdminRequest.List listReq = new CollectionAdminRequest.List();
 
-      try {
-        client.request(listReq);
-        fail("Requests to a non-running cluster should throw a SolrException");
-      }
-      catch (SolrException e) {
-        assertTrue("Unexpected message: " + e.getMessage(), e.getMessage().contains("cluster not found/not ready"));
-      }
+      SolrException e = expectThrows(SolrException.class, () -> client.request(listReq));
+      assertTrue("Unexpected message: " + e.getMessage(), e.getMessage().contains("cluster not found/not ready"));
 
       cluster.startJettySolrRunner();
       cluster.waitForAllNodes(30);
@@ -70,12 +65,10 @@ public class TestCloudSolrClientConnections extends SolrTestCaseJ4 {
     MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(0, createTempDir(), buildJettyConfig("/solr"));
     try {
       CloudSolrClient client = cluster.getSolrClient();
-      try {
+      SolrException e = expectThrows(SolrException.class, () -> {
         ((ZkClientClusterStateProvider)client.getClusterStateProvider()).uploadConfig(configPath, "testconfig");
-        fail("Requests to a non-running cluster should throw a SolrException");
-      } catch (SolrException e) {
-        assertTrue("Unexpected message: " + e.getMessage(), e.getMessage().contains("cluster not found/not ready"));
-      }
+      });
+      assertTrue("Unexpected message: " + e.getMessage(), e.getMessage().contains("cluster not found/not ready"));
 
       cluster.startJettySolrRunner();
       cluster.waitForAllNodes(30);
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
index 75301df..76ce4ab 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
@@ -329,12 +329,7 @@ public class SchemaTest extends RestTestBase {
     SchemaResponse.UpdateResponse deleteFieldResponse = deleteFieldRequest.process(getSolrClient());
     assertValidSchemaResponse(deleteFieldResponse);
 
-    try {
-      fieldSchemaRequest.process(getSolrClient());
-      fail(String.format(Locale.ROOT, "after removal, the field %s shouldn't be anymore available over Schema API", fieldName));
-    } catch (SolrException e) {
-      //success
-    }
+    expectThrows(SolrException.class, () -> fieldSchemaRequest.process(getSolrClient()));
   }
 
   @Test
@@ -454,13 +449,7 @@ public class SchemaTest extends RestTestBase {
     SchemaResponse.UpdateResponse deleteDynamicFieldResponse = deleteFieldRequest.process(getSolrClient());
     assertValidSchemaResponse(deleteDynamicFieldResponse);
 
-    try {
-      dynamicFieldSchemaRequest.process(getSolrClient());
-      fail(String.format(Locale.ROOT, "after removal, the dynamic field %s shouldn't be anymore available over Schema API",
-          dynamicFieldName));
-    } catch (SolrException e) {
-      //success
-    }
+    expectThrows(SolrException.class, () -> dynamicFieldSchemaRequest.process(getSolrClient()));
   }
 
   @Test
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestConfigSetAdminRequest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestConfigSetAdminRequest.java
index 50e4f5d..345a165 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestConfigSetAdminRequest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestConfigSetAdminRequest.java
@@ -19,7 +19,6 @@ package org.apache.solr.client.solrj.request;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.response.ConfigSetAdminResponse;
-import org.junit.Assert;
 import org.junit.Test;
 
 /**
@@ -48,13 +47,9 @@ public class TestConfigSetAdminRequest extends SolrTestCaseJ4 {
   }
 
   private void verifyException(ConfigSetAdminRequest request, String errorContains) {
-    try {
-      request.getParams();
-      Assert.fail("Expected exception");
-    } catch (Exception e) {
-      assertTrue("Expected exception message to contain: " + errorContains,
-          e.getMessage().contains(errorContains));
-    }
+    Exception e = expectThrows(Exception.class, request::getParams);
+    assertTrue("Expected exception message to contain: " + errorContains,
+        e.getMessage().contains(errorContains));
   }
 
   private static class MyConfigSetAdminRequest extends ConfigSetAdminRequest<MyConfigSetAdminRequest, ConfigSetAdminResponse> {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
index de7c620..0cf59b7 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
@@ -43,7 +43,6 @@ import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.params.ModifiableSolrParams;
-import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.metrics.SolrCoreMetricManager;
@@ -163,43 +162,27 @@ public class TestCoreAdmin extends AbstractEmbeddedSolrServerTestCase {
     params.set("name", collectionName);
     QueryRequest request = new QueryRequest(params);
     request.setPath("/admin/cores");
-    boolean gotExp = false;
-    NamedList<Object> resp = null;
-    try {
-      resp = getSolrAdmin().request(request);
-    } catch (SolrException e) {
-      gotExp = true;
-    }
-    
-    assertTrue(gotExp);
+    expectThrows(SolrException.class, () -> getSolrAdmin().request(request));
   }
   
   @Test
   public void testInvalidCoreNamesAreRejectedWhenCreatingCore() {
     final Create createRequest = new Create();
-    
-    try {
-      createRequest.setCoreName("invalid$core@name");
-      fail();
-    } catch (SolrException e) {
-      final String exceptionMessage = e.getMessage();
-      assertTrue(exceptionMessage.contains("Invalid core"));
-      assertTrue(exceptionMessage.contains("invalid$core@name"));
-      assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics"));
-    }
+    SolrException e = expectThrows(SolrException.class, () -> createRequest.setCoreName("invalid$core@name"));
+    final String exceptionMessage = e.getMessage();
+    assertTrue(exceptionMessage.contains("Invalid core"));
+    assertTrue(exceptionMessage.contains("invalid$core@name"));
+    assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics"));
   }
   
   @Test
   public void testInvalidCoreNamesAreRejectedWhenRenamingExistingCore() throws Exception {
-    try {
-      CoreAdminRequest.renameCore("validExistingCoreName", "invalid$core@name", null);
-      fail();
-    } catch (SolrException e) {
-      final String exceptionMessage = e.getMessage();
-      assertTrue(e.getMessage(), exceptionMessage.contains("Invalid core"));
-      assertTrue(exceptionMessage.contains("invalid$core@name"));
-      assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics"));
-    }
+    SolrException e = expectThrows(SolrException.class,
+        () -> CoreAdminRequest.renameCore("validExistingCoreName", "invalid$core@name", null));
+    final String exceptionMessage = e.getMessage();
+    assertTrue(e.getMessage(), exceptionMessage.contains("Invalid core"));
+    assertTrue(exceptionMessage.contains("invalid$core@name"));
+    assertTrue(exceptionMessage.contains("must consist entirely of periods, underscores, hyphens, and alphanumerics"));
   }
 
   @Test
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/response/TestDelegationTokenResponse.java b/solr/solrj/src/test/org/apache/solr/client/solrj/response/TestDelegationTokenResponse.java
index d14c0a8..b5508df 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/response/TestDelegationTokenResponse.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/response/TestDelegationTokenResponse.java
@@ -68,12 +68,10 @@ public class TestDelegationTokenResponse extends SolrTestCase {
     DelegationTokenResponse.Get getResponse = new DelegationTokenResponse.Get();
 
     // not a map
-    try {
+    expectThrows(SolrException.class, () -> {
       delegationTokenResponse(getRequest, getResponse, "");
       getResponse.getDelegationToken();
-      fail("Expected SolrException");
-    } catch (SolrException se) {
-    }
+    });
 
     // doesn't have Token outerMap
     final String someToken = "someToken";
@@ -81,12 +79,8 @@ public class TestDelegationTokenResponse extends SolrTestCase {
     assertNull(getResponse.getDelegationToken());
 
     // Token is not a map
-    try {
-      delegationTokenResponse(getRequest, getResponse, getMapJson("Token", someToken));
-      getResponse.getDelegationToken();
-      fail("Expected SolrException");
-    } catch (SolrException se) {
-    }
+    delegationTokenResponse(getRequest, getResponse, getMapJson("Token", someToken));
+    expectThrows(SolrException.class, getResponse::getDelegationToken);
 
     // doesn't have urlString
     delegationTokenResponse(getRequest, getResponse, getNestedMapJson("Token", "notUrlString", someToken));
@@ -104,24 +98,18 @@ public class TestDelegationTokenResponse extends SolrTestCase {
     DelegationTokenResponse.Renew renewResponse = new DelegationTokenResponse.Renew();
 
     // not a map
-    try {
+    expectThrows(SolrException.class, () -> {
       delegationTokenResponse(renewRequest, renewResponse, "");
       renewResponse.getExpirationTime();
-      fail("Expected SolrException");
-    } catch (SolrException se) {
-    }
+    });
 
     // doesn't have long
     delegationTokenResponse(renewRequest, renewResponse, getMapJson("notLong", "123"));
     assertNull(renewResponse.getExpirationTime());
 
     // long isn't valid
-    try {
-      delegationTokenResponse(renewRequest, renewResponse, getMapJson("long", "aaa"));
-      renewResponse.getExpirationTime();
-      fail("Expected SolrException");
-    } catch (SolrException se) {
-    }
+    delegationTokenResponse(renewRequest, renewResponse, getMapJson("long", "aaa"));
+    expectThrows(SolrException.class, renewResponse::getExpirationTime);
 
     // valid
     Long expirationTime = Long.MAX_VALUE;
diff --git a/solr/solrj/src/test/org/apache/solr/common/TestToleratedUpdateError.java b/solr/solrj/src/test/org/apache/solr/common/TestToleratedUpdateError.java
index c5cbb4a..7dd3427 100644
--- a/solr/solrj/src/test/org/apache/solr/common/TestToleratedUpdateError.java
+++ b/solr/solrj/src/test/org/apache/solr/common/TestToleratedUpdateError.java
@@ -53,30 +53,18 @@ public class TestToleratedUpdateError extends SolrTestCase {
   @Test
   // commented out on: 24-Dec-2018   @BadApple(bugUrl="https://issues.apache.org/jira/browse/SOLR-12028") // added 20-Sep-2018
   public void testParseMapErrorChecking() {
-    SimpleOrderedMap<String> bogus = new SimpleOrderedMap<String>();
-    try {
-      ToleratedUpdateError.parseMap(bogus);
-      fail("map should not be parsable");
-    } catch (SolrException e) {
-      assertTrue(e.toString(), e.getMessage().contains("Map does not represent a ToleratedUpdateError") );
-    }
+    SimpleOrderedMap<String> bogus = new SimpleOrderedMap<>();
+    SolrException e = expectThrows(SolrException.class, () -> ToleratedUpdateError.parseMap(bogus));
+    assertTrue(e.toString(), e.getMessage().contains("Map does not represent a ToleratedUpdateError"));
 
     bogus.add("id", "some id");
     bogus.add("message", "some message");
-    try {
-      ToleratedUpdateError.parseMap(bogus);
-      fail("map should still not be parsable");
-    } catch (SolrException e) {
-      assertTrue(e.toString(), e.getMessage().contains("Map does not represent a ToleratedUpdateError") );
-    }
+    e = expectThrows(SolrException.class, () -> ToleratedUpdateError.parseMap(bogus));
+    assertTrue(e.toString(), e.getMessage().contains("Map does not represent a ToleratedUpdateError"));
     
     bogus.add("type", "not a real type");
-    try {
-      ToleratedUpdateError.parseMap(bogus);
-      fail("invalid type should not be parsable");
-    } catch (SolrException e) {
-      assertTrue(e.toString(), e.getMessage().contains("Invalid type")); 
-    }
+    e = expectThrows(SolrException.class, () -> ToleratedUpdateError.parseMap(bogus));
+    assertTrue(e.toString(), e.getMessage().contains("Invalid type"));
   }
   
   public void testParseMap() {
diff --git a/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java b/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
index b39c497..8c06266 100644
--- a/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
@@ -76,19 +76,17 @@ public class JsonValidatorTest extends SolrTestCaseJ4  {
 
     errs = validator.validateJson(Utils.fromJSONString("{name:x, age:'x21', adult:'true'}"));
     assertEquals(1, errs.size());
-    try {
-      validator = new JsonSchemaValidator("{" +
+    Exception e = expectThrows(Exception.class, () -> {
+      new JsonSchemaValidator("{" +
           "  type:object," +
           "  properties: {" +
           "   age : {type: int}," +
           "   adult : {type: Boolean}," +
           "   name: {type: string}}}");
-      fail("should have failed");
-    } catch (Exception e) {
-      assertTrue(e.getMessage().contains("Unknown type"));
-    }
+    });
+    assertTrue(e.getMessage().contains("Unknown type"));
 
-    try {
+    e = expectThrows(Exception.class, () -> {
       new JsonSchemaValidator("{" +
           "  type:object," +
           "   x : y," +
@@ -96,21 +94,18 @@ public class JsonValidatorTest extends SolrTestCaseJ4  {
           "   age : {type: number}," +
           "   adult : {type: boolean}," +
           "   name: {type: string}}}");
-      fail("should have failed");
-    } catch (Exception e) {
-      assertTrue(e.getMessage().contains("Unknown key"));
-    }
-    try {
+    });
+    assertTrue(e.getMessage().contains("Unknown key"));
+
+    e = expectThrows(Exception.class, () -> {
       new JsonSchemaValidator("{" +
           "  type:object," +
           "  propertes: {" +
           "   age : {type: number}," +
           "   adult : {type: boolean}," +
           "   name: {type: string}}}");
-      fail("should have failed");
-    } catch (Exception e) {
-      assertTrue(e.getMessage().contains("Unknown key : propertes"));
-    }
+    });
+    assertTrue(e.getMessage().contains("Unknown key : propertes"));
 
     validator = new JsonSchemaValidator("{" +
         "  type:object," +
diff --git a/solr/solrj/src/test/org/apache/solr/common/util/NamedListTest.java b/solr/solrj/src/test/org/apache/solr/common/util/NamedListTest.java
index af642a0..644257b 100644
--- a/solr/solrj/src/test/org/apache/solr/common/util/NamedListTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/util/NamedListTest.java
@@ -25,6 +25,7 @@ import org.apache.solr.common.SolrException;
 import org.junit.Test;
 
 public class NamedListTest extends SolrTestCase {
+
   public void testRemove() {
     NamedList<String> nl = new NamedList<>();
     nl.add("key1", "value1");
@@ -87,14 +88,8 @@ public class NamedListTest extends SolrTestCase {
     assertEquals("value1-3", values.get(2));
     assertEquals(6, values.size());
     assertEquals(7, nl.size());
-    try {
-      values = (ArrayList<String>) nl.removeConfigArgs("key2");
-      fail();
-    }
-    catch(SolrException e) {
-      // Expected exception.
-      assertTrue(true);
-    }
+
+    expectThrows(SolrException.class, () -> nl.removeConfigArgs("key2"));
     // nl should be unmodified when removeArgs throws an exception.
     assertEquals(7, nl.size());
   }
diff --git a/solr/solrj/src/test/org/apache/solr/common/util/TestValidatingJsonMap.java b/solr/solrj/src/test/org/apache/solr/common/util/TestValidatingJsonMap.java
index 0a12aea..b53488a 100644
--- a/solr/solrj/src/test/org/apache/solr/common/util/TestValidatingJsonMap.java
+++ b/solr/solrj/src/test/org/apache/solr/common/util/TestValidatingJsonMap.java
@@ -28,6 +28,7 @@ import static org.apache.solr.common.util.ValidatingJsonMap.ENUM_OF;
 import static org.apache.solr.common.util.ValidatingJsonMap.NOT_NULL;
 
 public class TestValidatingJsonMap extends SolrTestCaseJ4 {
+
   public void testBasic() throws Exception {
     ValidatingJsonMap m = ValidatingJsonMap.wrap(
         makeMap("a", Boolean.TRUE,
@@ -38,10 +39,8 @@ public class TestValidatingJsonMap extends SolrTestCaseJ4 {
     assertEquals(Boolean.TRUE, m.getBool("a", Boolean.FALSE));
     assertEquals(Boolean.FALSE, m.getBool("b", Boolean.TRUE));
     assertEquals(Integer.valueOf(10), m.getInt("i",0));
-    try {
-      m.getList("l", ENUM_OF, ImmutableSet.of("X", "Z"));
-      fail("Must have failed with unexpected type");
-    } catch (RuntimeException e) { }
+
+    expectThrows(RuntimeException.class, () -> m.getList("l", ENUM_OF, ImmutableSet.of("X", "Z")));
 
     List l = m.getList("l", ENUM_OF, ImmutableSet.of("X", "Y", "Z"));
     assertEquals(2,l.size());
diff --git a/solr/test-framework/src/test/org/apache/solr/cloud/MiniSolrCloudClusterTest.java b/solr/test-framework/src/test/org/apache/solr/cloud/MiniSolrCloudClusterTest.java
index d7dbcc7..2fb4dba 100644
--- a/solr/test-framework/src/test/org/apache/solr/cloud/MiniSolrCloudClusterTest.java
+++ b/solr/test-framework/src/test/org/apache/solr/cloud/MiniSolrCloudClusterTest.java
@@ -82,16 +82,10 @@ public class MiniSolrCloudClusterTest extends SolrTestCase {
       }
     };
 
-    try {
-      cluster.shutdown();
-      fail("Expected an exception to be thrown on MiniSolrCloudCluster shutdown");
-    }
-    catch (Exception e) {
-      assertEquals("Error shutting down MiniSolrCloudCluster", e.getMessage());
-      assertEquals("Expected one suppressed exception", 1, e.getSuppressed().length);
-      assertEquals("Fake IOException on shutdown!", e.getSuppressed()[0].getMessage());
-    }
-
+    Exception ex = expectThrows(Exception.class, cluster::shutdown);
+    assertEquals("Error shutting down MiniSolrCloudCluster", ex.getMessage());
+    assertEquals("Expected one suppressed exception", 1, ex.getSuppressed().length);
+    assertEquals("Fake IOException on shutdown!", ex.getSuppressed()[0].getMessage());
   }
 
   @Test