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

dsmiley pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_10x by this push:
     new e5340a954b6 SOLR-17968: HttpSolrClient as new base class (#3829)
e5340a954b6 is described below

commit e5340a954b6700627b8826431a243c2e2759b0f3
Author: David Smiley <[email protected]>
AuthorDate: Sun May 17 23:53:15 2026 -0400

    SOLR-17968: HttpSolrClient as new base class (#3829)
    
    **Summary:** Reintroduce HttpSolrClient by promoting and refactoring 
`HttpSolrClientBase`.  Kept the(test) Apache HttpClient implementation in its 
own package while new Jetty and JDK implementations extend the common base.
    
    **Key Changes:**
    1. **Renamed** `HttpSolrClientBase` → `HttpSolrClient` (new primary base 
class)
    2. **Restructured builders** - converted `HttpSolrClientBuilderBase` into 
an inner class `HttpSolrClient.BuilderBase`
    3. **Added factory method** - static `HttpSolrClient.builder(url)` to 
simplify client creation
    4. **Method rename** - instance method `builder()` → `toBuilder(url)` to 
avoid naming conflicts
---
 changelog/unreleased/SOLR-17968-HttpSolrClient.yml |  10 +
 solr/core/gradle.lockfile                          |  20 +-
 .../java/org/apache/solr/core/CoreContainer.java   |   6 +-
 .../modules/deployment-guide/pages/solrj.adoc      |   9 +-
 .../pages/major-changes-in-solr-10.adoc            |   5 +
 .../jetty/ConcurrentUpdateJettySolrClient.java     |   6 +-
 .../client/solrj/jetty/HttpJettySolrClient.java    |  23 +-
 .../jetty/ConcurrentUpdateJettySolrClientTest.java |   8 +-
 .../solrj/jetty/HttpJettySolrClientProxyTest.java  |   4 +-
 .../solrj/jetty/HttpJettySolrClientTest.java       |   6 +-
 solr/solrj-streaming/build.gradle                  |   1 -
 solr/solrj-streaming/gradle.lockfile               |  20 +-
 .../solr/client/solrj/io/SolrClientCache.java      |  23 +-
 .../client/solrj/io/sql/DatabaseMetaDataImpl.java  |   4 +-
 .../solrj/impl/SolrClientNodeStateProvider.java    |   2 +-
 .../solr/common/cloud/NodesSysPropsCacher.java     |   6 +-
 .../org/apache/solr/client/solrj/SolrRequest.java  |   4 +-
 .../client/solrj/impl/CloudHttp2SolrClient.java    |   8 +-
 .../solr/client/solrj/impl/CloudSolrClient.java    |  59 +---
 .../solrj/impl/ConcurrentUpdateBaseSolrClient.java |  10 +-
 .../solrj/impl/ConcurrentUpdateJdkSolrClient.java  |   6 +-
 .../solrj/impl/HttpClusterStateProvider.java       |   6 +-
 .../solr/client/solrj/impl/HttpJdkSolrClient.java  |   9 +-
 ...HttpSolrClientBase.java => HttpSolrClient.java} | 379 +++++++++++++++++++--
 .../solrj/impl/HttpSolrClientBuilderBase.java      | 281 ---------------
 .../solr/client/solrj/impl/LBAsyncSolrClient.java  |   4 +-
 .../solr/client/solrj/impl/LBSolrClient.java       |   6 +-
 .../solrj/impl/ClusterStateProviderTest.java       |   7 +-
 .../impl/ConcurrentUpdateJdkSolrClientTest.java    |   6 +-
 .../impl/ConcurrentUpdateSolrClientTestBase.java   |   6 +-
 .../client/solrj/impl/HttpJdkSolrClientTest.java   |   4 +-
 .../solrj/impl/HttpSolrClientBadInputTest.java     |   1 -
 .../client/solrj/impl/HttpSolrClientTestBase.java  |  44 +--
 .../src/java/org/apache/solr/SolrBackend.java      |   4 +-
 .../solr/client/solrj/apache/HttpSolrClient.java   |   5 +-
 .../apache/SolrPortAwareCookieSpecFactory.java     |   1 +
 .../solr/client/solrj/apache/package-info.java     |   1 +
 37 files changed, 502 insertions(+), 502 deletions(-)

diff --git a/changelog/unreleased/SOLR-17968-HttpSolrClient.yml 
b/changelog/unreleased/SOLR-17968-HttpSolrClient.yml
new file mode 100644
index 00000000000..8f6d0d59ae4
--- /dev/null
+++ b/changelog/unreleased/SOLR-17968-HttpSolrClient.yml
@@ -0,0 +1,10 @@
+
+title: >
+  Introduce org.apache.solr.client.solrj.HttpSolrClient, implemented by the 
Jetty & JDK HttpClient based SolrClients.
+  It's builder will use Jetty if available, otherwise JDK.
+type: other
+authors:
+  - name: David Smiley
+links:
+  - name: SOLR-17968
+    url: https://issues.apache.org/jira/browse/SOLR-17968
diff --git a/solr/core/gradle.lockfile b/solr/core/gradle.lockfile
index 500a077b541..7267ab45b84 100644
--- a/solr/core/gradle.lockfile
+++ b/solr/core/gradle.lockfile
@@ -133,23 +133,23 @@ 
org.carrot2:morfologik-polish:2.1.9=jarValidation,testRuntimeClasspath
 org.carrot2:morfologik-stemming:2.1.9=jarValidation,testRuntimeClasspath
 
org.codehaus.woodstox:stax2-api:4.2.2=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
 
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-client-transport:12.0.34=apiHelper,jarValidation,runtimeClasspath,runtimeLibs,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-client:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-common:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-hpack:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-client-transport:12.0.34=jarValidation,runtimeClasspath,runtimeLibs,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-client:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-common:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-hpack:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
 
org.eclipse.jetty.http2:jetty-http2-server:12.0.34=jarValidation,testRuntimeClasspath
-org.eclipse.jetty:jetty-alpn-client:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-alpn-java-client:12.0.34=apiHelper,jarValidation,runtimeClasspath,runtimeLibs,testRuntimeClasspath
+org.eclipse.jetty:jetty-alpn-client:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-alpn-java-client:12.0.34=jarValidation,runtimeClasspath,runtimeLibs,testRuntimeClasspath
 
org.eclipse.jetty:jetty-alpn-java-server:12.0.34=jarValidation,testRuntimeClasspath
 org.eclipse.jetty:jetty-alpn-server:12.0.34=jarValidation,testRuntimeClasspath
-org.eclipse.jetty:jetty-client:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-http:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-io:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-client:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-http:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-io:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
 org.eclipse.jetty:jetty-rewrite:12.0.34=jarValidation,testRuntimeClasspath
 
org.eclipse.jetty:jetty-security:12.0.34=jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
 
org.eclipse.jetty:jetty-server:12.0.34=jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
 
org.eclipse.jetty:jetty-session:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-util:12.0.34=apiHelper,compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-util:12.0.34=compileClasspath,jarValidation,runtimeClasspath,runtimeLibs,testCompileClasspath,testRuntimeClasspath
 
org.glassfish.hk2.external:aopalliance-repackaged:3.1.1=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
 org.glassfish.hk2.external:aopalliance-repackaged:4.0.0-M3=runtimeLibs
 
org.glassfish.hk2:hk2-api:3.1.1=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java 
b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 2b6343a6856..d7c67ecf3af 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -69,7 +69,7 @@ import org.apache.solr.api.ClusterPluginsSource;
 import org.apache.solr.api.ContainerPluginsRegistry;
 import org.apache.solr.api.JerseyResource;
 import org.apache.solr.client.solrj.SolrRequest;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.io.SolrClientCache;
 import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
@@ -706,7 +706,7 @@ public class CoreContainer {
    *
    * @see #getDefaultHttpSolrClient()
    * @see ZkController#getSolrClient()
-   * @see HttpSolrClientBase#requestWithBaseUrl(String, SolrRequest, String)
+   * @see HttpSolrClient#requestWithBaseUrl(String, SolrRequest, String)
    * @deprecated likely to simply be moved to the ObjectCache so as to not be 
used
    */
   @Deprecated
@@ -2462,7 +2462,7 @@ public class CoreContainer {
    * <p>The caller does not need to close the client.
    *
    * @return the existing {@link HttpJettySolrClient}
-   * @see HttpSolrClientBase#requestWithBaseUrl(String, SolrRequest, String)
+   * @see HttpSolrClient#requestWithBaseUrl(String, SolrRequest, String)
    */
   public HttpJettySolrClient getDefaultHttpSolrClient() {
     return solrClientProvider.getSolrClient();
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc 
b/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc
index b7792a4bc71..decefc3f36f 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc
@@ -51,7 +51,7 @@ For projects built with Gradle, place the following in your 
`build.gradle`:
 
 [source,groovy,subs="attributes"]
 ----
-compile group: 'org.apache.solr', name: 'solr-solrj', version: 
'{solr-full-version}'
+implementation 'org.apache.solr:solr-solrj:{solr-full-version}'
 ----
 
 ==== Optional Jetty Module
@@ -72,7 +72,7 @@ For Gradle:
 
 [source,groovy,subs="attributes"]
 ----
-compile group: 'org.apache.solr', name: 'solrj-solrj-jetty', version: 
'{solr-full-version}'
+implementation 'org.apache.solr:solr-solrj-jetty:{solr-full-version}'
 ----
 
 Alternatively, you can use `HttpJdkSolrClient` from the base `solr-solrj` 
artifact,
@@ -121,10 +121,11 @@ Requests are sent in the form of 
{solr-javadocs}/solrj/org/apache/solr/client/so
 
 `SolrClient` has a few concrete implementations, each geared towards a 
different usage-pattern or resiliency model:
 
+- 
{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/HttpSolrClient.html[`HttpSolrClient`]
 - a general purpose client whose builder creates a `HttpJettySolrClient` if 
available, or `HttpJdkSolrClient` otherwise.
 - 
{solr-javadocs}/solrj-jetty/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.html[`HttpJettySolrClient`]
 - a general purpose client based on Jetty HttpClient.  Supports HTTP/2 and 
HTTP/1.1, async, non-blocking.  Most used & tested.
 - 
{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.html[`HttpJdkSolrClient`]
 - a general purpose client based on JDK HttpClient.  Supports HTTP/2 and 
HTTP/1.1, async, non-blocking.  Has no dependencies.
 - 
{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/LBSolrClient.html[`LBSolrClient`]
 - an internal client that delegates to other clients pointed at different URLs 
for fail-over/availability.  Adjusts the list of "in-service" nodes based on 
node health.
-- 
{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/CloudSolrClient.html[`CloudSolrClient`]
 - the ideal client for SolrCloud.  Using the "cluster state", it routes 
requests to the optimal nodes, including splitting out the documents in an 
UpdateRequest to different nodes.
+- 
{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/CloudSolrClient.html[`CloudSolrClient`]
 - the ideal client for SolrCloud.  Using the "cluster state", it routes 
requests to the optimal nodes, including splitting out the documents in an 
UpdateRequest to different nodes.  Its builder will create a 
`CloudJettySolrClient` if available, or `CloudJdkSolrClient` otherwise.
 - 
{solr-javadocs}/solrj-jetty/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.html[`ConcurrentUpdateJettySolrClient`]
 - geared towards indexing-centric workloads.
 Buffers documents internally before sending larger batches to Solr.
 - 
{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClient.html[`ConcurrentUpdateJdkSolrClient`]
 - similar to `ConcurrentUpdateJettySolrClient` but delegates to 
`HttpJdkSolrClient` and has no dependencies.
@@ -164,7 +165,7 @@ Users can avoid this pattern by specifying a "default" 
collection when creating
 If specified on a Builder, the created `SolrClient` will use this default for 
making requests whenever a collection or core is needed (and no overriding 
value is specified).
 
 ==== Timeouts
-All `SolrClient` implementations allow users to specify the connection and 
read timeouts for communicating with Solr.
+All `SolrClient` implementations allow users to specify the connection and 
idle timeouts for communicating with Solr.
 These are provided at client creation time, as in the example below:
 
 [source,java,indent=0]
diff --git 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index 9b7764634aa..e9f0a7d2908 100644
--- 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -61,6 +61,11 @@ Solr 10.1 nodes only send and accept the `SolrAuthV2` (v2) 
header for inter-node
 Before performing a rolling upgrade to 10.1, ensure no node in the cluster has 
`solr.pki.sendVersion=v1` set, as those nodes would send the legacy `SolrAuth` 
header that 10.1 nodes will reject.
 The `solr.pki.sendVersion` and `solr.pki.acceptVersions` system properties are 
no longer recognized in 10.1 and can be removed from your configuration.
 
+=== SolrJ
+
+HttpSolrClient returns; this time as a base class for HttpJettySolrClient and 
HttpJdkSolrClient.
+Its builder will dynamically detect if solr-jetty is available and use that, 
otherwise it will use the JDK client.
+
 == Solr 10.0
 
 === Solr Jetty parameters
diff --git 
a/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
 
b/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
index 2275976eefc..7e8686f1a39 100644
--- 
a/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
+++ 
b/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
@@ -27,7 +27,7 @@ import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.common.params.ModifiableSolrParams;
@@ -48,7 +48,7 @@ public class ConcurrentUpdateJettySolrClient extends 
ConcurrentUpdateBaseSolrCli
   public static class Builder extends ConcurrentUpdateBaseSolrClient.Builder {
     /**
      * @see 
org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient.Builder#Builder(String,
-     *     HttpSolrClientBase)
+     *     HttpSolrClient)
      */
     public Builder(String baseUrl, HttpJettySolrClient client) {
       this(baseUrl, client, false);
@@ -56,7 +56,7 @@ public class ConcurrentUpdateJettySolrClient extends 
ConcurrentUpdateBaseSolrCli
 
     /**
      * @see 
org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient.Builder#Builder(String,
-     *     HttpSolrClientBase, boolean)
+     *     HttpSolrClient, boolean)
      */
     public Builder(String baseSolrUrl, HttpJettySolrClient client, boolean 
closeHttpClient) {
       super(baseSolrUrl, client, closeHttpClient);
diff --git 
a/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
 
b/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
index 05491bb8e69..fdd5fa8443b 100644
--- 
a/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
+++ 
b/solr/solrj-jetty/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
@@ -42,8 +42,7 @@ import org.apache.solr.client.api.util.SolrVersion;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBuilderBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.LBSolrClient;
 import org.apache.solr.client.solrj.impl.SolrClientCustomizer;
 import org.apache.solr.client.solrj.impl.SolrHttpConstants;
@@ -95,12 +94,8 @@ import org.slf4j.MDC;
 /**
  * An HTTP {@link SolrClient} using Jetty {@link HttpClient}. This is Solr's 
most mature client for
  * direct HTTP.
- *
- * <p>Despite the name, this client supports HTTP 1.1 and 2 -- toggle with 
{@link
- * HttpSolrClientBuilderBase#useHttp1_1(boolean)}. In retrospect, the name 
should have been {@code
- * HttpJettySolrClient}.
  */
-public class HttpJettySolrClient extends HttpSolrClientBase {
+public class HttpJettySolrClient extends HttpSolrClient {
   // formerly known at Http2SolrClient
 
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -555,8 +550,8 @@ public class HttpJettySolrClient extends HttpSolrClientBase 
{
   }
 
   @Override
-  public HttpSolrClientBuilderBase<?, ?> builder() {
-    return new HttpJettySolrClient.Builder().withHttpClient(this);
+  protected BuilderBase<?, ?> toBuilder(String baseUrl) {
+    return new HttpJettySolrClient.Builder(baseUrl).withHttpClient(this);
   }
 
   // merely exposing for superclass's method visibility to this package
@@ -579,7 +574,7 @@ public class HttpJettySolrClient extends HttpSolrClientBase 
{
 
   // merely exposing for superclass's method visibility to this package
   protected static String basicAuthCredentialsToAuthorizationString(String 
user, String pass) {
-    return HttpSolrClientBase.basicAuthCredentialsToAuthorizationString(user, 
pass);
+    return HttpSolrClient.basicAuthCredentialsToAuthorizationString(user, 
pass);
   }
 
   private NamedList<Object> processErrorsAndResponse(
@@ -941,8 +936,7 @@ public class HttpJettySolrClient extends HttpSolrClientBase 
{
     return asyncTracker.availablePermits();
   }
 
-  public static class Builder
-      extends HttpSolrClientBuilderBase<HttpJettySolrClient.Builder, 
HttpJettySolrClient> {
+  public static class Builder extends BuilderBase<Builder, 
HttpJettySolrClient> {
 
     private HttpClient httpClient;
 
@@ -1004,8 +998,7 @@ public class HttpJettySolrClient extends 
HttpSolrClientBase {
       return this;
     }
 
-    public HttpSolrClientBuilderBase<HttpJettySolrClient.Builder, 
HttpJettySolrClient>
-        withSSLConfig(SSLConfig sslConfig) {
+    public BuilderBase<Builder, HttpJettySolrClient> withSSLConfig(SSLConfig 
sslConfig) {
       this.sslConfig = sslConfig;
       return this;
     }
@@ -1041,7 +1034,7 @@ public class HttpJettySolrClient extends 
HttpSolrClientBase {
       return null;
     }
 
-    protected <B extends HttpSolrClientBase> B build(Class<B> type) {
+    protected <B extends HttpSolrClient> B build(Class<B> type) {
       return type.cast(build());
     }
 
diff --git 
a/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
 
b/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
index aa49a737a50..df28d17f3b0 100644
--- 
a/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
+++ 
b/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
@@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient;
 import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClientTestBase;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 
 public class ConcurrentUpdateJettySolrClientTest extends 
ConcurrentUpdateSolrClientTestBase {
 
@@ -31,7 +31,7 @@ public class ConcurrentUpdateJettySolrClientTest extends 
ConcurrentUpdateSolrCli
       String serverUrl,
       int queueSize,
       int threadCount,
-      HttpSolrClientBase solrClient,
+      HttpSolrClient solrClient,
       AtomicInteger successCounter,
       AtomicInteger failureCounter,
       StringBuilder errors) {
@@ -44,7 +44,7 @@ public class ConcurrentUpdateJettySolrClientTest extends 
ConcurrentUpdateSolrCli
   }
 
   @Override
-  public HttpSolrClientBase solrClient(Integer overrideIdleTimeoutMs) {
+  public HttpSolrClient solrClient(Integer overrideIdleTimeoutMs) {
     var builder = new HttpJettySolrClient.Builder();
     if (overrideIdleTimeoutMs != null) {
       builder.withIdleTimeout(overrideIdleTimeoutMs, TimeUnit.MILLISECONDS);
@@ -54,7 +54,7 @@ public class ConcurrentUpdateJettySolrClientTest extends 
ConcurrentUpdateSolrCli
 
   @Override
   public ConcurrentUpdateBaseSolrClient concurrentClient(
-      HttpSolrClientBase solrClient,
+      HttpSolrClient solrClient,
       String baseUrl,
       String defaultCollection,
       int queueSize,
diff --git 
a/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
 
b/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
index 7b4f85ba7fe..091229b4649 100644
--- 
a/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
+++ 
b/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
@@ -25,7 +25,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.SolrQuery;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.util.EnvUtils;
@@ -109,7 +109,7 @@ public class HttpJettySolrClientProxyTest extends 
SolrTestCaseJ4 {
   }
 
   /** Set up a simple http proxy and verify a request works */
-  public void testProxy(HttpSolrClientBase client) throws Exception {
+  public void testProxy(HttpSolrClient client) throws Exception {
     String id = "1234";
     SolrInputDocument doc = new SolrInputDocument();
     doc.addField("id", id);
diff --git 
a/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
 
b/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
index 7d4ffa9242e..11bf3e3c85a 100644
--- 
a/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
+++ 
b/solr/solrj-jetty/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
@@ -33,7 +33,7 @@ import org.apache.solr.client.solrj.RemoteSolrException;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBuilderBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.HttpSolrClientTestBase;
 import org.apache.solr.client.solrj.request.JavaBinRequestWriter;
 import org.apache.solr.client.solrj.request.QueryRequest;
@@ -65,7 +65,7 @@ public class HttpJettySolrClientTest extends 
HttpSolrClientTestBase {
 
   @Override
   @SuppressWarnings(value = "unchecked")
-  protected <B extends HttpSolrClientBuilderBase<?, ?>> B builder(
+  protected <B extends HttpSolrClient.BuilderBase<?, ?>> B builder(
       String url, int connectionTimeout, int socketTimeout) {
     var b =
         new HttpJettySolrClient.Builder(url)
@@ -333,7 +333,7 @@ public class HttpJettySolrClientTest extends 
HttpSolrClientTestBase {
   public void testAsyncGet() throws Exception {
     String url = solrTestRule.getBaseUrl() + DEBUG_SERVLET_PATH;
     ResponseParser rp = new XMLResponseParser();
-    HttpSolrClientBuilderBase<?, ?> b =
+    HttpSolrClient.BuilderBase<?, ?> b =
         builder(url, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT).withResponseParser(rp);
     super.testQueryAsync(b);
   }
diff --git a/solr/solrj-streaming/build.gradle 
b/solr/solrj-streaming/build.gradle
index 765887f99fe..93bf46f788c 100644
--- a/solr/solrj-streaming/build.gradle
+++ b/solr/solrj-streaming/build.gradle
@@ -21,7 +21,6 @@ description = 'Solrj-Streaming - SolrJ requiring Streaming 
Expressions'
 
 dependencies {
   implementation project(':solr:solrj')
-  implementation project(':solr:solrj-jetty')
 
   // declare dependencies we use even though already declared by solrj-core
   implementation libs.slf4j.api
diff --git a/solr/solrj-streaming/gradle.lockfile 
b/solr/solrj-streaming/gradle.lockfile
index c8054e03603..e0b32df6d92 100644
--- a/solr/solrj-streaming/gradle.lockfile
+++ b/solr/solrj-streaming/gradle.lockfile
@@ -127,23 +127,23 @@ 
org.codehaus.janino:commons-compiler:3.1.11=jarValidation,testRuntimeClasspath
 org.codehaus.janino:janino:3.1.11=jarValidation,testRuntimeClasspath
 org.codehaus.woodstox:stax2-api:4.2.2=jarValidation,testRuntimeClasspath
 
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.34=jarValidation,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-client-transport:12.0.34=jarValidation,runtimeClasspath,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-client:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-common:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty.http2:jetty-http2-hpack:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-client-transport:12.0.34=jarValidation,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-client:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-common:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty.http2:jetty-http2-hpack:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
 
org.eclipse.jetty.http2:jetty-http2-server:12.0.34=jarValidation,testRuntimeClasspath
-org.eclipse.jetty:jetty-alpn-client:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-alpn-java-client:12.0.34=jarValidation,runtimeClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-alpn-client:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-alpn-java-client:12.0.34=jarValidation,testRuntimeClasspath
 
org.eclipse.jetty:jetty-alpn-java-server:12.0.34=jarValidation,testRuntimeClasspath
 org.eclipse.jetty:jetty-alpn-server:12.0.34=jarValidation,testRuntimeClasspath
-org.eclipse.jetty:jetty-client:12.0.34=jarValidation,runtimeClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-http:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.eclipse.jetty:jetty-io:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-client:12.0.34=jarValidation,testRuntimeClasspath
+org.eclipse.jetty:jetty-http:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-io:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
 org.eclipse.jetty:jetty-rewrite:12.0.34=jarValidation,testRuntimeClasspath
 org.eclipse.jetty:jetty-security:12.0.34=jarValidation,testRuntimeClasspath
 org.eclipse.jetty:jetty-server:12.0.34=jarValidation,testRuntimeClasspath
 org.eclipse.jetty:jetty-session:12.0.34=jarValidation,testRuntimeClasspath
-org.eclipse.jetty:jetty-util:12.0.34=compileClasspath,jarValidation,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.eclipse.jetty:jetty-util:12.0.34=jarValidation,testCompileClasspath,testRuntimeClasspath
 
org.glassfish.hk2.external:aopalliance-repackaged:4.0.0-M3=jarValidation,testRuntimeClasspath
 org.glassfish.hk2:hk2-api:4.0.0-M3=jarValidation,testRuntimeClasspath
 org.glassfish.hk2:hk2-locator:4.0.0-M3=jarValidation,testRuntimeClasspath
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
index 1e8fdc9293b..3aa7748bc01 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
@@ -26,10 +26,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBuilderBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.SolrHttpConstants;
-import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.common.AlreadyClosedException;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.URLUtil;
@@ -49,7 +47,7 @@ public class SolrClientCache implements Closeable {
   protected String basicAuthCredentials = null; // Only support with the 
httpJettySolrClient
 
   private final Map<String, SolrClient> solrClients = new HashMap<>();
-  private final HttpSolrClientBase httpSolrClient;
+  private final HttpSolrClient httpSolrClient;
   private final AtomicBoolean isClosed = new AtomicBoolean(false);
   private final AtomicReference<String> defaultZkHost = new 
AtomicReference<>();
 
@@ -57,7 +55,7 @@ public class SolrClientCache implements Closeable {
     this.httpSolrClient = null;
   }
 
-  public SolrClientCache(HttpSolrClientBase httpSolrClient) {
+  public SolrClientCache(HttpSolrClient httpSolrClient) {
     this.httpSolrClient = httpSolrClient;
   }
 
@@ -104,7 +102,7 @@ public class SolrClientCache implements Closeable {
   }
 
   protected CloudSolrClient newCloudSolrClient(
-      String connectionString, HttpSolrClientBase httpSolrClient, boolean 
canUseACLs) {
+      String connectionString, HttpSolrClient httpSolrClient, boolean 
canUseACLs) {
     var builder = new CloudSolrClient.Builder(connectionString);
     builder.canUseZkACLs(canUseACLs);
     // using internal builder to ensure the internal client gets closed
@@ -138,15 +136,18 @@ public class SolrClientCache implements Closeable {
     return client;
   }
 
-  protected HttpSolrClientBuilderBase<?, ?> newHttpSolrClientBuilder(
-      String url, HttpSolrClientBase httpSolrClient) {
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  protected HttpSolrClient.BuilderBase<?, ?> newHttpSolrClientBuilder(
+      String url, HttpSolrClient httpSolrClient) {
     final var builder =
         (url == null || URLUtil.isBaseUrl(url)) // URL may be null here and 
set by caller
-            ? new HttpJettySolrClient.Builder(url)
-            : new HttpJettySolrClient.Builder(URLUtil.extractBaseUrl(url))
+            ? HttpSolrClient.builder(url)
+            : HttpSolrClient.builder(URLUtil.extractBaseUrl(url))
                 .withDefaultCollection(URLUtil.extractCoreFromCoreUrl(url));
     if (httpSolrClient != null) {
-      builder.withHttpClient((HttpJettySolrClient) httpSolrClient); // TODO 
support JDK
+      // this generics hack works around the fact that we can't guarantee that 
the new client and
+      // the existing passed-in client are compatible  Oh well; tough luck, 
best-effort.
+      ((HttpSolrClient.BuilderBase) builder).withHttpClient(httpSolrClient);
       // cannot set connection timeout
     } else {
       builder.withConnectionTimeout(minConnTimeout, TimeUnit.MILLISECONDS);
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
index cde6a04b068..99d85080bf6 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.SystemInfoRequest;
 import org.apache.solr.client.solrj.response.SystemInfoResponse;
 import org.apache.solr.common.cloud.ClusterState;
@@ -121,7 +121,7 @@ class DatabaseMetaDataImpl implements DatabaseMetaData {
     for (String node : liveNodes) {
       try {
         String nodeURL = Utils.getBaseUrlForNodeName(node, urlScheme);
-        solrClient = new HttpJettySolrClient.Builder(nodeURL).build();
+        solrClient = HttpSolrClient.builder(nodeURL).build();
 
         SystemInfoRequest req = new SystemInfoRequest();
         SystemInfoResponse resp = req.process(solrClient);
diff --git 
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
 
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
index f036d294f60..44e4babce6d 100644
--- 
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
+++ 
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
@@ -261,7 +261,7 @@ public class SolrClientNodeStateProvider implements 
NodeStateProvider, MapWriter
           (ZkClientClusterStateProvider) 
cloudSolrClient.getClusterStateProvider();
     }
 
-    protected HttpSolrClientBase httpSolrClient() {
+    protected HttpSolrClient httpSolrClient() {
       return cloudSolrClient.getHttpClient();
     }
 
diff --git 
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
 
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
index 856c6d8a9f9..b9b6894fd9a 100644
--- 
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
+++ 
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
@@ -22,7 +22,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import org.apache.solr.client.solrj.SolrRequest;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.GenericSolrRequest;
 import org.apache.solr.common.NavigableObject;
 import org.apache.solr.common.SolrException;
@@ -34,9 +34,9 @@ public class NodesSysPropsCacher implements NodesSysProps, 
AutoCloseable {
   private volatile boolean isClosed = false;
   private final Map<String, Map<String, Object>> nodeVsTagsCache = new 
ConcurrentHashMap<>();
   private final ZkStateReader zkStateReader;
-  private final HttpSolrClientBase solrClient;
+  private final HttpSolrClient solrClient;
 
-  public NodesSysPropsCacher(HttpSolrClientBase solrClient, ZkStateReader 
zkStateReader) {
+  public NodesSysPropsCacher(HttpSolrClient solrClient, ZkStateReader 
zkStateReader) {
     this.zkStateReader = zkStateReader;
     this.solrClient = solrClient;
     zkStateReader.registerLiveNodesListener(
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrRequest.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrRequest.java
index f33dd5dd0c2..0f2b21b7f85 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrRequest.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrRequest.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.RequestWriter;
 import org.apache.solr.client.solrj.response.ResponseParser;
 import org.apache.solr.client.solrj.response.StreamingResponseCallback;
@@ -321,7 +321,7 @@ public abstract class SolrRequest<T> implements 
Serializable {
    * @throws IOException if there is a communication error
    * @lucene.experimental
    */
-  public final T processWithBaseUrl(HttpSolrClientBase client, String baseUrl, 
String collection)
+  public final T processWithBaseUrl(HttpSolrClient client, String baseUrl, 
String collection)
       throws SolrServerException, IOException {
     // duplicative with process(), except for requestWithBaseUrl
     long startNanos = System.nanoTime();
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
index 72cfd2d042e..0118b680428 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
@@ -21,8 +21,8 @@ import java.util.concurrent.TimeUnit;
 import org.apache.solr.common.util.IOUtils;
 
 /**
- * This {@link CloudSolrClient} is a base implementation using a {@link 
HttpSolrClientBase}. The '2'
- * in the name has no differentiating significance anymore.
+ * This {@link CloudSolrClient} is a base implementation using a {@link 
HttpSolrClient}. The '2' in
+ * the name has no differentiating significance anymore.
  *
  * @since solr 8.0
  * @lucene.internal
@@ -32,7 +32,7 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
 
   private final ClusterStateProvider stateProvider;
   private final LBSolrClient lbClient;
-  private final HttpSolrClientBase myClient;
+  private final HttpSolrClient myClient;
   private final boolean clientIsInternal;
 
   /**
@@ -102,7 +102,7 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
     return stateProvider;
   }
 
-  public HttpSolrClientBase getHttpClient() {
+  public HttpSolrClient getHttpClient() {
     return myClient;
   }
 }
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
index 8eb4733ecac..e701b68b726 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
@@ -21,7 +21,6 @@ import static org.apache.solr.common.params.CommonParams.ID;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Constructor;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
@@ -138,42 +137,16 @@ public abstract class CloudSolrClient extends SolrClient {
    * based {@code HttpClient} if available, or will otherwise use the JDK.
    */
   public static class Builder {
-    private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    // If the Jetty-based HttpJettySolrClient builder is on the classpath, 
this will be its no-arg
-    // constructor; otherwise it will be null and we will fall back to the JDK 
HTTP client.
-    private static final Constructor<? extends HttpSolrClientBuilderBase<?, ?>>
-        HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR;
-
-    static {
-      Constructor<? extends HttpSolrClientBuilderBase<?, ?>> ctor = null;
-      try {
-        @SuppressWarnings("unchecked")
-        Class<? extends HttpSolrClientBuilderBase<?, ?>> builderClass =
-            (Class<? extends HttpSolrClientBuilderBase<?, ?>>)
-                
Class.forName("org.apache.solr.client.solrj.jetty.HttpJettySolrClient$Builder");
-        ctor = builderClass.getDeclaredConstructor();
-        ctor.newInstance(); // perhaps fails because Jetty libs aren't on the 
classpath
-      } catch (Throwable t) {
-        // Class not present or incompatible; leave ctor as null to indicate 
unavailability
-        if (log.isTraceEnabled()) {
-          log.trace(
-              "HttpJettySolrClient$Builder not available on classpath; will 
use HttpJdkSolrClient",
-              t);
-        }
-      }
-      HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR = ctor;
-    }
 
     protected Collection<String> zkHosts = new ArrayList<>();
     protected List<String> solrUrls = new ArrayList<>();
     protected String zkChroot;
-    protected HttpSolrClientBase httpClient;
+    protected HttpSolrClient httpClient;
     protected boolean shardLeadersOnly = true;
     protected boolean directUpdatesToLeadersOnly = false;
     protected boolean parallelUpdates = true;
     protected ClusterStateProvider stateProvider;
-    protected HttpSolrClientBuilderBase<?, ?> internalClientBuilder;
+    protected HttpSolrClient.BuilderBase<?, ?> internalClientBuilder;
     protected RequestWriter requestWriter;
     protected ResponseParser responseParser;
     protected long retryExpiryTimeNano =
@@ -395,7 +368,7 @@ public abstract class CloudSolrClient extends SolrClient {
      *
      * @return this
      */
-    public Builder withHttpClient(HttpSolrClientBase httpSolrClient) {
+    public Builder withHttpClient(HttpSolrClient httpSolrClient) {
       if (this.internalClientBuilder != null) {
         throw new IllegalStateException(
             "The builder can't accept an httpClient AND an 
internalClientBuilder, only one of those can be provided");
@@ -412,7 +385,7 @@ public abstract class CloudSolrClient extends SolrClient {
      * @param internalClientBuilder the builder to use for creating the 
internal http client.
      * @return this
      */
-    public Builder withHttpClientBuilder(HttpSolrClientBuilderBase<?, ?> 
internalClientBuilder) {
+    public Builder withHttpClientBuilder(HttpSolrClient.BuilderBase<?, ?> 
internalClientBuilder) {
       if (this.httpClient != null) {
         throw new IllegalStateException(
             "The builder can't accept an httpClient AND an 
internalClientBuilder, only one of those can be provided");
@@ -423,7 +396,7 @@ public abstract class CloudSolrClient extends SolrClient {
 
     @Deprecated(since = "9.10")
     public Builder withInternalClientBuilder(
-        HttpSolrClientBuilderBase<?, ?> internalClientBuilder) {
+        HttpSolrClient.BuilderBase<?, ?> internalClientBuilder) {
       return withHttpClientBuilder(internalClientBuilder);
     }
 
@@ -467,31 +440,17 @@ public abstract class CloudSolrClient extends SolrClient {
       return new CloudHttp2SolrClient(this);
     }
 
-    protected HttpSolrClientBase createOrGetHttpClient() {
+    protected HttpSolrClient createOrGetHttpClient() {
       if (httpClient != null) {
         return httpClient;
       } else if (internalClientBuilder != null) {
         return internalClientBuilder.build();
-      }
-
-      HttpSolrClientBuilderBase<?, ?> builder;
-      if (HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR != null) {
-        try {
-          log.debug("Using HttpJettySolrClient as the delegate http client");
-          builder = HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR.newInstance();
-        } catch (RuntimeException e) {
-          throw e;
-        } catch (Exception e) {
-          throw new RuntimeException(e);
-        }
       } else {
-        log.debug("Using HttpJdkSolrClient as the delegate http client");
-        builder = new HttpJdkSolrClient.Builder();
+        return HttpSolrClient.builder(null).build();
       }
-      return builder.build();
     }
 
-    protected LBSolrClient createOrGetLbClient(HttpSolrClientBase myClient) {
+    protected LBSolrClient createOrGetLbClient(HttpSolrClient myClient) {
       return myClient.createLBSolrClient();
     }
 
@@ -505,7 +464,7 @@ public abstract class CloudSolrClient extends SolrClient {
       return stateProvider;
     }
 
-    protected ClusterStateProvider 
createHttpClusterStateProvider(HttpSolrClientBase httpClient) {
+    protected ClusterStateProvider 
createHttpClusterStateProvider(HttpSolrClient httpClient) {
       try {
         return new HttpClusterStateProvider<>(solrUrls, httpClient);
       } catch (Exception e) {
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java
index 59513af9481..752e7131509 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java
@@ -54,7 +54,7 @@ public abstract class ConcurrentUpdateBaseSolrClient extends 
SolrClient {
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   private static final Update END_UPDATE = new Update(null, null);
 
-  private HttpSolrClientBase client;
+  private HttpSolrClient client;
   protected final String basePath;
   protected final CustomBlockingQueue<Update> queue;
   private final ExecutorService scheduler;
@@ -618,7 +618,7 @@ public abstract class ConcurrentUpdateBaseSolrClient 
extends SolrClient {
   /** Constructs {@link ConcurrentUpdateBaseSolrClient} instances from 
provided configuration. */
   public abstract static class Builder {
     protected long idleTimeoutMillis;
-    protected HttpSolrClientBase client;
+    protected HttpSolrClient client;
     protected String baseSolrUrl;
     protected String defaultCollection;
     protected int queueSize = 10;
@@ -646,7 +646,7 @@ public abstract class ConcurrentUpdateBaseSolrClient 
extends SolrClient {
      *     internally. Callers are responsible for closing the provided client 
(after closing any
      *     clients created by this builder)
      */
-    public Builder(String baseSolrUrl, HttpSolrClientBase client) {
+    public Builder(String baseSolrUrl, HttpSolrClient client) {
       this(baseSolrUrl, client, false);
     }
 
@@ -670,7 +670,7 @@ public abstract class ConcurrentUpdateBaseSolrClient 
extends SolrClient {
      *     ConcurrentUpdateBaseSolrClient should assume responsibility for 
closing the provided
      *     'client'
      */
-    public Builder(String baseSolrUrl, HttpSolrClientBase client, boolean 
closeHttpClient) {
+    public Builder(String baseSolrUrl, HttpSolrClient client, boolean 
closeHttpClient) {
       this.baseSolrUrl = baseSolrUrl;
       this.client = client;
       this.closeHttpClient = closeHttpClient;
@@ -768,7 +768,7 @@ public abstract class ConcurrentUpdateBaseSolrClient 
extends SolrClient {
      */
     public abstract ConcurrentUpdateBaseSolrClient build();
 
-    public HttpSolrClientBase getClient() {
+    public HttpSolrClient getClient() {
       return client;
     }
   }
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClient.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClient.java
index 87bceda8408..8ebbd64bd80 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClient.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClient.java
@@ -76,7 +76,7 @@ public class ConcurrentUpdateJdkSolrClient extends 
ConcurrentUpdateBaseSolrClien
   public static class Builder extends ConcurrentUpdateBaseSolrClient.Builder {
     /**
      * @see 
org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient.Builder#Builder(String,
-     *     HttpSolrClientBase)
+     *     HttpSolrClient)
      */
     public Builder(String baseUrl, HttpJdkSolrClient client) {
 
@@ -88,9 +88,9 @@ public class ConcurrentUpdateJdkSolrClient extends 
ConcurrentUpdateBaseSolrClien
 
     /**
      * @see 
org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient.Builder#Builder(String,
-     *     HttpSolrClientBase, boolean)
+     *     HttpSolrClient, boolean)
      */
-    public Builder(String baseSolrUrl, HttpSolrClientBase client, boolean 
closeHttpClient) {
+    public Builder(String baseSolrUrl, HttpSolrClient client, boolean 
closeHttpClient) {
       super(baseSolrUrl, client, closeHttpClient);
     }
 
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java
index 17b41e951a0..f6b60dc2543 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.util.List;
 
 /** A CSP that uses Solr HTTP APIs. */
-public class HttpClusterStateProvider<C extends HttpSolrClientBase>
+public class HttpClusterStateProvider<C extends HttpSolrClient>
     extends BaseHttpClusterStateProvider {
   // formerly known as Http2ClusterStateProvider
 
@@ -32,7 +32,7 @@ public class HttpClusterStateProvider<C extends 
HttpSolrClientBase>
    * caller's responsibility to close the client.
    *
    * @param solrUrls root path solr urls
-   * @param httpClient an instance of HttpSolrClientBase
+   * @param httpClient an instance of HttpSolrClient
    * @throws Exception if a problem with initialization occurs
    */
   public HttpClusterStateProvider(List<String> solrUrls, C httpClient) throws 
Exception {
@@ -51,7 +51,7 @@ public class HttpClusterStateProvider<C extends 
HttpSolrClientBase>
   @Override
   @SuppressWarnings("unchecked")
   protected C getSolrClient(String baseUrl) {
-    return (C) httpClient.builder().withBaseSolrUrl(baseUrl).build();
+    return (C) httpClient.toBuilder(baseUrl).build();
   }
 
   public C getHttpClient() {
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java
index 53b538c56f4..502637e026f 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java
@@ -71,7 +71,7 @@ import org.slf4j.LoggerFactory;
  * This client will connect to solr using Http/2 but can seamlessly downgrade 
to Http/1.1 when
  * connecting to Solr hosts running on older versions.
  */
-public class HttpJdkSolrClient extends HttpSolrClientBase {
+public class HttpJdkSolrClient extends HttpSolrClient {
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private static final String USER_AGENT =
@@ -563,8 +563,8 @@ public class HttpJdkSolrClient extends HttpSolrClientBase {
   }
 
   @Override
-  public HttpSolrClientBuilderBase<?, ?> builder() {
-    return new HttpJdkSolrClient.Builder().withHttpClient(this);
+  protected BuilderBase<?, ?> toBuilder(String baseUrl) {
+    return new HttpJdkSolrClient.Builder(baseUrl).withHttpClient(this);
   }
 
   @Override
@@ -572,8 +572,7 @@ public class HttpJdkSolrClient extends HttpSolrClientBase {
     return new LBSolrClient.Builder<>(this).build();
   }
 
-  public static class Builder
-      extends HttpSolrClientBuilderBase<HttpJdkSolrClient.Builder, 
HttpJdkSolrClient> {
+  public static class Builder extends BuilderBase<Builder, HttpJdkSolrClient> {
 
     private SSLContext sslContext;
 
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
similarity index 51%
rename from 
solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java
rename to 
solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
index 4133b824690..93ae9e332f1 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
@@ -20,16 +20,18 @@ package org.apache.solr.client.solrj.impl;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URLDecoder;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
 import java.util.Base64;
 import java.util.Collection;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
 import org.apache.solr.client.solrj.RemoteSolrException;
@@ -47,21 +49,23 @@ import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.ContentStream;
 import org.apache.solr.common.util.NamedList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * Utility/base functionality for direct HTTP client implementations.
+ * A simple/direct {@link SolrClient} using HTTP.
  *
- * @lucene.internal
+ * <p>The protected methods can be considered as internal / unstable APIs.
+ *
+ * @see #builder(String)
+ * @see "org.apache.solr.client.solrj.jetty.HttpJettySolrClient"
+ * @see org.apache.solr.client.solrj.impl.HttpJdkSolrClient
  */
-public abstract class HttpSolrClientBase extends SolrClient {
-
-  protected static final String DEFAULT_PATH = ClientUtils.DEFAULT_PATH;
+public abstract class HttpSolrClient extends SolrClient {
+  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   protected static final Charset FALLBACK_CHARSET = StandardCharsets.UTF_8;
-  private static final List<String> errPath = Arrays.asList("metadata", 
"error-class");
-
-  /** The URL of the Solr server. */
-  protected final String serverBaseUrl;
 
+  protected final String baseUrl;
   protected final long requestTimeoutMillis;
 
   protected final Set<String> urlParamNames;
@@ -75,19 +79,8 @@ public abstract class HttpSolrClientBase extends SolrClient {
 
   protected final String basicAuthAuthorizationStr;
 
-  protected HttpSolrClientBase(String serverBaseUrl, 
HttpSolrClientBuilderBase<?, ?> builder) {
-    if (serverBaseUrl != null) {
-      if (!serverBaseUrl.equals("/") && serverBaseUrl.endsWith("/")) {
-        serverBaseUrl = serverBaseUrl.substring(0, serverBaseUrl.length() - 1);
-      }
-
-      if (serverBaseUrl.startsWith("//")) {
-        serverBaseUrl = serverBaseUrl.substring(1, serverBaseUrl.length());
-      }
-      this.serverBaseUrl = serverBaseUrl;
-    } else {
-      this.serverBaseUrl = null;
-    }
+  protected HttpSolrClient(String serverBaseUrl, BuilderBase<?, ?> builder) {
+    this.baseUrl = extractBaseUrl(serverBaseUrl);
     this.requestTimeoutMillis = builder.getRequestTimeoutMillis();
     this.basicAuthAuthorizationStr = builder.basicAuthAuthorizationStr;
     if (builder.requestWriter != null) {
@@ -104,7 +97,24 @@ public abstract class HttpSolrClientBase extends SolrClient 
{
     }
   }
 
-  public abstract HttpSolrClientBuilderBase<?, ?> builder();
+  private static String extractBaseUrl(String serverBaseUrl) {
+    if (serverBaseUrl == null) {
+      return null;
+    }
+    if (!serverBaseUrl.equals("/") && serverBaseUrl.endsWith("/")) {
+      serverBaseUrl = serverBaseUrl.substring(0, serverBaseUrl.length() - 1);
+    }
+
+    if (serverBaseUrl.startsWith("//")) {
+      serverBaseUrl = serverBaseUrl.substring(1);
+    }
+    return serverBaseUrl;
+  }
+
+  /** Typically looks like {@code http://localhost:8983/solr} (no core or 
collection) */
+  public String getBaseURL() {
+    return baseUrl;
+  }
 
   /**
    * @lucene.internal
@@ -113,7 +123,7 @@ public abstract class HttpSolrClientBase extends SolrClient 
{
 
   protected String getRequestUrl(SolrRequest<?> solrRequest, String collection)
       throws MalformedURLException {
-    return ClientUtils.buildRequestUrl(solrRequest, serverBaseUrl, collection);
+    return ClientUtils.buildRequestUrl(solrRequest, getBaseURL(), collection);
   }
 
   protected ResponseParser responseParser(SolrRequest<?> solrRequest) {
@@ -328,7 +338,7 @@ public abstract class HttpSolrClientBase extends SolrClient 
{
    * @param collection an optional collection or core name used to override 
the client's "default
    *     collection". May be 'null' for any requests that don't require a 
collection or wish to rely
    *     on the client's default
-   * @see SolrRequest#processWithBaseUrl(HttpSolrClientBase, String, String)
+   * @see SolrRequest#processWithBaseUrl(HttpSolrClient, String, String)
    */
   public abstract NamedList<Object> requestWithBaseUrl(
       String baseUrl, SolrRequest<?> solrRequest, String collection)
@@ -360,14 +370,10 @@ public abstract class HttpSolrClientBase extends 
SolrClient {
     return requestAsync(request, null);
   }
 
-  public boolean isV2ApiRequest(final SolrRequest<?> request) {
+  protected boolean isV2ApiRequest(final SolrRequest<?> request) {
     return request.getApiVersion() == SolrRequest.ApiVersion.V2;
   }
 
-  public String getBaseURL() {
-    return serverBaseUrl;
-  }
-
   public ResponseParser getParser() {
     return parser;
   }
@@ -375,4 +381,313 @@ public abstract class HttpSolrClientBase extends 
SolrClient {
   public Set<String> getUrlParamNames() {
     return urlParamNames;
   }
+
+  /**
+   * @lucene.internal
+   */
+  protected abstract BuilderBase<?, ?> toBuilder(String baseUrl);
+
+  // If the Jetty-based HttpJettySolrClient builder is on the classpath, this 
will be its no-arg
+  // constructor; otherwise it will be null and we will fall back to the JDK 
HTTP client.
+  private static final Constructor<? extends BuilderBase<?, ?>> 
HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR;
+
+  static {
+    Constructor<? extends HttpSolrClient.BuilderBase<?, ?>> ctor = null;
+    try {
+      @SuppressWarnings("unchecked")
+      Class<? extends HttpSolrClient.BuilderBase<?, ?>> builderClass =
+          (Class<? extends HttpSolrClient.BuilderBase<?, ?>>)
+              
Class.forName("org.apache.solr.client.solrj.jetty.HttpJettySolrClient$Builder");
+      ctor = builderClass.getDeclaredConstructor();
+      ctor.newInstance(); // perhaps fails because Jetty libs aren't on the 
classpath
+    } catch (Throwable t) {
+      // Class not present or incompatible; leave ctor as null to indicate 
unavailability
+      if (log.isTraceEnabled()) {
+        log.trace(
+            "HttpJettySolrClient$Builder not available on classpath; will use 
HttpJdkSolrClient",
+            t);
+      }
+    }
+    HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR = ctor;
+  }
+
+  /**
+   * Provides a new builder of an {@link HttpSolrClient}. The implementation 
will try to create a
+   * {@code org.apache.solr.client.solrj.jetty.HttpJettySolrClient} if 
available, otherwise will
+   * fall back on {@link HttpJdkSolrClient}.
+   *
+   * @param baseUrl for {@link BuilderBase#withBaseSolrUrl(String)}.
+   */
+  public static BuilderBase<?, ?> builder(String baseUrl) {
+    HttpSolrClient.BuilderBase<?, ?> builder;
+    if (HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR != null) {
+      try {
+        log.debug("Using HttpJettySolrClient as the delegate http client");
+        builder = HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR.newInstance();
+      } catch (RuntimeException e) {
+        throw e;
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    } else {
+      log.debug("Using HttpJdkSolrClient as the delegate http client");
+      builder = new HttpJdkSolrClient.Builder();
+    }
+    return builder.withBaseSolrUrl(baseUrl);
+  }
+
+  public abstract static class BuilderBase<B extends BuilderBase<?, ?>, C 
extends HttpSolrClient> {
+
+    protected Long idleTimeoutMillis;
+    protected Long connectionTimeoutMillis;
+    protected Long requestTimeoutMillis;
+    protected String basicAuthAuthorizationStr;
+    protected Boolean followRedirects;
+    protected String baseSolrUrl;
+    protected RequestWriter requestWriter;
+    protected ResponseParser responseParser;
+    protected String defaultCollection;
+    protected Set<String> urlParamNames;
+    protected Integer maxConnectionsPerHost;
+    protected ExecutorService executor;
+    protected final boolean defaultUseHttp1_1 = 
Boolean.getBoolean("solr.http1");
+    protected Boolean useHttp1_1;
+    protected String proxyHost;
+    protected int proxyPort;
+    protected boolean proxyIsSocks4;
+    protected boolean proxyIsSecure;
+
+    public abstract C build();
+
+    /**
+     * Provide a seed HttpSolrClient for the builder values, values can still 
be overridden by using
+     * builder methods
+     */
+    @SuppressWarnings("unchecked")
+    public B withHttpClient(C httpSolrClient) {
+      if (this.basicAuthAuthorizationStr == null) {
+        this.basicAuthAuthorizationStr = 
httpSolrClient.basicAuthAuthorizationStr;
+      }
+      if (this.requestTimeoutMillis == null) {
+        this.requestTimeoutMillis = httpSolrClient.requestTimeoutMillis;
+      }
+      if (this.requestWriter == null) {
+        this.requestWriter = httpSolrClient.requestWriter;
+      }
+      if (this.responseParser == null) {
+        this.responseParser = httpSolrClient.parser;
+      }
+      if (this.urlParamNames == null) {
+        this.urlParamNames = httpSolrClient.urlParamNames;
+      }
+      return (B) (this);
+    }
+
+    /** Provides the Base Solr Url. */
+    @SuppressWarnings("unchecked")
+    public B withBaseSolrUrl(String baseSolrUrl) {
+      this.baseSolrUrl = baseSolrUrl;
+      return (B) this;
+    }
+
+    /** Provides a {@link RequestWriter} for created clients to use when 
handing requests. */
+    @SuppressWarnings("unchecked")
+    public B withRequestWriter(RequestWriter requestWriter) {
+      this.requestWriter = requestWriter;
+      return (B) this;
+    }
+
+    /** Provides a {@link ResponseParser} for created clients to use when 
handling requests. */
+    @SuppressWarnings("unchecked")
+    public B withResponseParser(ResponseParser responseParser) {
+      this.responseParser = responseParser;
+      return (B) this;
+    }
+
+    /** Sets a default for core or collection based requests. */
+    @SuppressWarnings("unchecked")
+    public B withDefaultCollection(String defaultCoreOrCollection) {
+      this.defaultCollection = defaultCoreOrCollection;
+      return (B) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public B withFollowRedirects(boolean followRedirects) {
+      this.followRedirects = followRedirects;
+      return (B) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public B withExecutor(ExecutorService executor) {
+      this.executor = executor;
+      return (B) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public B withBasicAuthCredentials(String user, String pass) {
+      if (user != null || pass != null) {
+        if (user == null || pass == null) {
+          throw new IllegalStateException(
+              "Invalid Authentication credentials. Either both username and 
password or none must be provided");
+        }
+      }
+      this.basicAuthAuthorizationStr = 
basicAuthCredentialsToAuthorizationString(user, pass);
+      return (B) this;
+    }
+
+    /**
+     * Expert Method
+     *
+     * @param urlParamNames set of param keys that are only sent via the query 
string. Note that the
+     *     param will be sent as a query string if the key is part of this Set 
or the SolrRequest's
+     *     query params.
+     * @see SolrRequest#getQueryParams
+     */
+    @SuppressWarnings("unchecked")
+    public B withTheseParamNamesInTheUrl(Set<String> urlParamNames) {
+      this.urlParamNames = urlParamNames;
+      return (B) this;
+    }
+
+    /**
+     * Set maxConnectionsPerHost for http1 connections, maximum number http2 
connections is limited
+     * to 4
+     */
+    @SuppressWarnings("unchecked")
+    public B withMaxConnectionsPerHost(int max) {
+      this.maxConnectionsPerHost = max;
+      return (B) this;
+    }
+
+    /**
+     * The max time a connection can be idle (that is, without traffic of 
bytes in either
+     * direction). Sometimes called a "socket timeout". Note: not applicable 
to the JDK HttpClient.
+     */
+    @SuppressWarnings("unchecked")
+    public B withIdleTimeout(long idleConnectionTimeout, TimeUnit unit) {
+      this.idleTimeoutMillis = 
TimeUnit.MILLISECONDS.convert(idleConnectionTimeout, unit);
+      return (B) this;
+    }
+
+    public long getIdleTimeoutMillis() {
+      return idleTimeoutMillis != null && idleTimeoutMillis > 0
+          ? idleTimeoutMillis
+          : SolrHttpConstants.DEFAULT_SO_TIMEOUT;
+    }
+
+    /** The max time a connection can take to connect to destinations. */
+    @SuppressWarnings("unchecked")
+    public B withConnectionTimeout(long connectionTimeout, TimeUnit unit) {
+      this.connectionTimeoutMillis = 
TimeUnit.MILLISECONDS.convert(connectionTimeout, unit);
+      return (B) this;
+    }
+
+    public long getConnectionTimeoutMillis() {
+      return connectionTimeoutMillis != null && connectionTimeoutMillis > 0
+          ? connectionTimeoutMillis
+          : SolrHttpConstants.DEFAULT_CONNECT_TIMEOUT;
+    }
+
+    /** Set a timeout for requests to receive a response. */
+    @SuppressWarnings("unchecked")
+    public B withRequestTimeout(long requestTimeout, TimeUnit unit) {
+      this.requestTimeoutMillis = 
TimeUnit.MILLISECONDS.convert(requestTimeout, unit);
+      return (B) this;
+    }
+
+    public long getRequestTimeoutMillis() {
+      return requestTimeoutMillis != null && requestTimeoutMillis > 0
+          ? requestTimeoutMillis
+          : getIdleTimeoutMillis();
+    }
+
+    /**
+     * If true, prefer http1.1 over http2. If not set, the default is 
determined by system property
+     * 'solr.http1'. Otherwise, false.
+     *
+     * @param useHttp1_1 prefer http1.1?
+     * @return this Builder
+     */
+    @SuppressWarnings("unchecked")
+    public B useHttp1_1(boolean useHttp1_1) {
+      this.useHttp1_1 = useHttp1_1;
+      return (B) this;
+    }
+
+    /**
+     * Return whether the HttpSolrClient built will prefer http1.1 over http2.
+     *
+     * @return whether to prefer http1.1
+     */
+    public boolean shouldUseHttp1_1() {
+      return useHttp1_1 != null ? useHttp1_1 : defaultUseHttp1_1;
+    }
+
+    /**
+     * Setup a proxy
+     *
+     * @param host The proxy host
+     * @param port The proxy port
+     * @param isSocks4 If true creates an SOCKS 4 proxy, otherwise creates an 
HTTP proxy
+     * @param isSecure If true enables the secure flag on the proxy
+     * @return this Builder
+     */
+    @SuppressWarnings("unchecked")
+    public B withProxyConfiguration(String host, int port, boolean isSocks4, 
boolean isSecure) {
+      this.proxyHost = host;
+      this.proxyPort = port;
+      this.proxyIsSocks4 = isSocks4;
+      this.proxyIsSecure = isSecure;
+      return (B) this;
+    }
+
+    /**
+     * Setup basic authentication from a string formatted as 
username:password. If the string is
+     * Null then it doesn't do anything.
+     *
+     * @param credentials The username and password formatted as 
username:password
+     * @return this Builder
+     */
+    @SuppressWarnings("unchecked")
+    public B withOptionalBasicAuthCredentials(String credentials) {
+      if (credentials != null) {
+        if (credentials.indexOf(':') == -1) {
+          throw new IllegalStateException(
+              "Invalid Authentication credential formatting. Provide username 
and password in the 'username:password' format.");
+        }
+        String username = credentials.substring(0, credentials.indexOf(':'));
+        String password = credentials.substring(credentials.indexOf(':') + 1, 
credentials.length());
+        withBasicAuthCredentials(username, password);
+      }
+      return (B) this;
+    }
+
+    public Integer getMaxConnectionsPerHost() {
+      return maxConnectionsPerHost;
+    }
+
+    public Boolean getFollowRedirects() {
+      return followRedirects;
+    }
+
+    public String getProxyHost() {
+      return proxyHost;
+    }
+
+    public int getProxyPort() {
+      return proxyPort;
+    }
+
+    public boolean isProxyIsSocks4() {
+      return proxyIsSocks4;
+    }
+
+    public boolean isProxyIsSecure() {
+      return proxyIsSecure;
+    }
+
+    public ExecutorService getExecutor() {
+      return executor;
+    }
+  }
 }
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java
deleted file mode 100644
index 50ab6f883d9..00000000000
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.solr.client.solrj.impl;
-
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-import org.apache.solr.client.solrj.request.RequestWriter;
-import org.apache.solr.client.solrj.response.ResponseParser;
-
-public abstract class HttpSolrClientBuilderBase<
-    B extends HttpSolrClientBuilderBase<?, ?>, C extends HttpSolrClientBase> {
-
-  protected Long idleTimeoutMillis;
-  protected Long connectionTimeoutMillis;
-  protected Long requestTimeoutMillis;
-  protected String basicAuthAuthorizationStr;
-  protected Boolean followRedirects;
-  protected String baseSolrUrl;
-  protected RequestWriter requestWriter;
-  protected ResponseParser responseParser;
-  protected String defaultCollection;
-  protected Set<String> urlParamNames;
-  protected Integer maxConnectionsPerHost;
-  protected ExecutorService executor;
-  protected final boolean defaultUseHttp1_1 = Boolean.getBoolean("solr.http1");
-  protected Boolean useHttp1_1;
-  protected String proxyHost;
-  protected int proxyPort;
-  protected boolean proxyIsSocks4;
-  protected boolean proxyIsSecure;
-
-  public abstract C build();
-
-  /**
-   * Provide a seed HttpSolrClient for the builder values, values can still be 
overridden by using
-   * builder methods
-   */
-  @SuppressWarnings("unchecked")
-  public B withHttpClient(C httpSolrClient) {
-    if (this.basicAuthAuthorizationStr == null) {
-      this.basicAuthAuthorizationStr = 
httpSolrClient.basicAuthAuthorizationStr;
-    }
-    if (this.requestTimeoutMillis == null) {
-      this.requestTimeoutMillis = httpSolrClient.requestTimeoutMillis;
-    }
-    if (this.requestWriter == null) {
-      this.requestWriter = httpSolrClient.requestWriter;
-    }
-    if (this.responseParser == null) {
-      this.responseParser = httpSolrClient.parser;
-    }
-    if (this.urlParamNames == null) {
-      this.urlParamNames = httpSolrClient.urlParamNames;
-    }
-    return (B) (this);
-  }
-
-  /** Provides the Base Solr Url. */
-  @SuppressWarnings("unchecked")
-  public B withBaseSolrUrl(String baseSolrUrl) {
-    this.baseSolrUrl = baseSolrUrl;
-    return (B) this;
-  }
-
-  /** Provides a {@link RequestWriter} for created clients to use when handing 
requests. */
-  @SuppressWarnings("unchecked")
-  public B withRequestWriter(RequestWriter requestWriter) {
-    this.requestWriter = requestWriter;
-    return (B) this;
-  }
-
-  /** Provides a {@link ResponseParser} for created clients to use when 
handling requests. */
-  @SuppressWarnings("unchecked")
-  public B withResponseParser(ResponseParser responseParser) {
-    this.responseParser = responseParser;
-    return (B) this;
-  }
-
-  /** Sets a default for core or collection based requests. */
-  @SuppressWarnings("unchecked")
-  public B withDefaultCollection(String defaultCoreOrCollection) {
-    this.defaultCollection = defaultCoreOrCollection;
-    return (B) this;
-  }
-
-  @SuppressWarnings("unchecked")
-  public B withFollowRedirects(boolean followRedirects) {
-    this.followRedirects = followRedirects;
-    return (B) this;
-  }
-
-  @SuppressWarnings("unchecked")
-  public B withExecutor(ExecutorService executor) {
-    this.executor = executor;
-    return (B) this;
-  }
-
-  @SuppressWarnings("unchecked")
-  public B withBasicAuthCredentials(String user, String pass) {
-    if (user != null || pass != null) {
-      if (user == null || pass == null) {
-        throw new IllegalStateException(
-            "Invalid Authentication credentials. Either both username and 
password or none must be provided");
-      }
-    }
-    this.basicAuthAuthorizationStr =
-        HttpSolrClientBase.basicAuthCredentialsToAuthorizationString(user, 
pass);
-    return (B) this;
-  }
-
-  /**
-   * Expert Method
-   *
-   * @param urlParamNames set of param keys that are only sent via the query 
string. Note that the
-   *     param will be sent as a query string if the key is part of this Set 
or the SolrRequest's
-   *     query params.
-   * @see org.apache.solr.client.solrj.SolrRequest#getQueryParams
-   */
-  @SuppressWarnings("unchecked")
-  public B withTheseParamNamesInTheUrl(Set<String> urlParamNames) {
-    this.urlParamNames = urlParamNames;
-    return (B) this;
-  }
-
-  /**
-   * Set maxConnectionsPerHost for http1 connections, maximum number http2 
connections is limited to
-   * 4
-   */
-  @SuppressWarnings("unchecked")
-  public B withMaxConnectionsPerHost(int max) {
-    this.maxConnectionsPerHost = max;
-    return (B) this;
-  }
-
-  /**
-   * The max time a connection can be idle (that is, without traffic of bytes 
in either direction).
-   * Sometimes called a "socket timeout". Note: not applicable to the JDK 
HttpClient.
-   */
-  @SuppressWarnings("unchecked")
-  public B withIdleTimeout(long idleConnectionTimeout, TimeUnit unit) {
-    this.idleTimeoutMillis = 
TimeUnit.MILLISECONDS.convert(idleConnectionTimeout, unit);
-    return (B) this;
-  }
-
-  public long getIdleTimeoutMillis() {
-    return idleTimeoutMillis != null && idleTimeoutMillis > 0
-        ? idleTimeoutMillis
-        : SolrHttpConstants.DEFAULT_SO_TIMEOUT;
-  }
-
-  /** The max time a connection can take to connect to destinations. */
-  @SuppressWarnings("unchecked")
-  public B withConnectionTimeout(long connectionTimeout, TimeUnit unit) {
-    this.connectionTimeoutMillis = 
TimeUnit.MILLISECONDS.convert(connectionTimeout, unit);
-    return (B) this;
-  }
-
-  public long getConnectionTimeoutMillis() {
-    return connectionTimeoutMillis != null && connectionTimeoutMillis > 0
-        ? connectionTimeoutMillis
-        : SolrHttpConstants.DEFAULT_CONNECT_TIMEOUT;
-  }
-
-  /** Set a timeout for requests to receive a response. */
-  @SuppressWarnings("unchecked")
-  public B withRequestTimeout(long requestTimeout, TimeUnit unit) {
-    this.requestTimeoutMillis = TimeUnit.MILLISECONDS.convert(requestTimeout, 
unit);
-    return (B) this;
-  }
-
-  public long getRequestTimeoutMillis() {
-    return requestTimeoutMillis != null && requestTimeoutMillis > 0
-        ? requestTimeoutMillis
-        : getIdleTimeoutMillis();
-  }
-
-  /**
-   * If true, prefer http1.1 over http2. If not set, the default is determined 
by system property
-   * 'solr.http1'. Otherwise, false.
-   *
-   * @param useHttp1_1 prefer http1.1?
-   * @return this Builder
-   */
-  @SuppressWarnings("unchecked")
-  public B useHttp1_1(boolean useHttp1_1) {
-    this.useHttp1_1 = useHttp1_1;
-    return (B) this;
-  }
-
-  /**
-   * Return whether the HttpSolrClient built will prefer http1.1 over http2.
-   *
-   * @return whether to prefer http1.1
-   */
-  public boolean shouldUseHttp1_1() {
-    return useHttp1_1 != null ? useHttp1_1 : defaultUseHttp1_1;
-  }
-
-  /**
-   * Setup a proxy
-   *
-   * @param host The proxy host
-   * @param port The proxy port
-   * @param isSocks4 If true creates an SOCKS 4 proxy, otherwise creates an 
HTTP proxy
-   * @param isSecure If true enables the secure flag on the proxy
-   * @return this Builder
-   */
-  @SuppressWarnings("unchecked")
-  public B withProxyConfiguration(String host, int port, boolean isSocks4, 
boolean isSecure) {
-    this.proxyHost = host;
-    this.proxyPort = port;
-    this.proxyIsSocks4 = isSocks4;
-    this.proxyIsSecure = isSecure;
-    return (B) this;
-  }
-
-  /**
-   * Setup basic authentication from a string formatted as username:password. 
If the string is Null
-   * then it doesn't do anything.
-   *
-   * @param credentials The username and password formatted as 
username:password
-   * @return this Builder
-   */
-  @SuppressWarnings("unchecked")
-  public B withOptionalBasicAuthCredentials(String credentials) {
-    if (credentials != null) {
-      if (credentials.indexOf(':') == -1) {
-        throw new IllegalStateException(
-            "Invalid Authentication credential formatting. Provide username 
and password in the 'username:password' format.");
-      }
-      String username = credentials.substring(0, credentials.indexOf(':'));
-      String password = credentials.substring(credentials.indexOf(':') + 1, 
credentials.length());
-      withBasicAuthCredentials(username, password);
-    }
-    return (B) this;
-  }
-
-  public Integer getMaxConnectionsPerHost() {
-    return maxConnectionsPerHost;
-  }
-
-  public Boolean getFollowRedirects() {
-    return followRedirects;
-  }
-
-  public String getProxyHost() {
-    return proxyHost;
-  }
-
-  public int getProxyPort() {
-    return proxyPort;
-  }
-
-  public boolean isProxyIsSocks4() {
-    return proxyIsSocks4;
-  }
-
-  public boolean isProxyIsSecure() {
-    return proxyIsSecure;
-  }
-
-  public ExecutorService getExecutor() {
-    return executor;
-  }
-}
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBAsyncSolrClient.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBAsyncSolrClient.java
index 48dab986d80..5a91c0314ba 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBAsyncSolrClient.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBAsyncSolrClient.java
@@ -37,7 +37,7 @@ import org.slf4j.MDC;
 public abstract class LBAsyncSolrClient extends LBSolrClient {
   // formerly known as LBHttp2SolrClient, using Http2SolrClient (jetty)
 
-  protected final HttpSolrClientBase solrClient;
+  protected final HttpSolrClient solrClient;
 
   protected LBAsyncSolrClient(Builder<?> builder) {
     super(builder);
@@ -45,7 +45,7 @@ public abstract class LBAsyncSolrClient extends LBSolrClient {
   }
 
   @Override
-  protected HttpSolrClientBase getClient(Endpoint endpoint) {
+  protected HttpSolrClient getClient(Endpoint endpoint) {
     return solrClient;
   }
 
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java
index 8b39d069188..eefbd08b2b1 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java
@@ -168,7 +168,7 @@ public abstract class LBSolrClient extends SolrClient {
     solrQuery.setDistrib(false);
   }
 
-  public static class Builder<C extends HttpSolrClientBase> {
+  public static class Builder<C extends HttpSolrClient> {
 
     private final C solrClient;
     private final Endpoint[] solrEndpoints;
@@ -618,10 +618,10 @@ public abstract class LBSolrClient extends SolrClient {
   private NamedList<Object> doRequest(
       SolrClient solrClient, String baseUrl, String collection, SolrRequest<?> 
solrRequest)
       throws SolrServerException, IOException {
-    // Some implementations of LBSolrClient.getClient(...) return a 
HttpSolrClientBase that may not
+    // Some implementations of LBSolrClient.getClient(...) return a 
HttpSolrClient that may not
     // be pointed at the desired URL (or any URL for that matter).  We 
special-case that here to
     // ensure the appropriate URL is provided.
-    if (solrClient instanceof HttpSolrClientBase hasReqWithUrl) {
+    if (solrClient instanceof HttpSolrClient hasReqWithUrl) {
       return hasReqWithUrl.requestWithBaseUrl(baseUrl, solrRequest, 
collection);
     }
 
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
index 3d6ff7ca62f..294b5b05e38 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
@@ -109,9 +109,8 @@ public class ClusterStateProviderTest extends 
SolrCloudTestCase {
         new String[] {"http2ClusterStateProvider"}, new String[] 
{"zkClientClusterStateProvider"});
   }
 
-  static class ClosingHttpClusterStateProvider
-      extends HttpClusterStateProvider<HttpSolrClientBase> {
-    public ClosingHttpClusterStateProvider(List<String> solrUrls, 
HttpSolrClientBase httpClient)
+  static class ClosingHttpClusterStateProvider extends 
HttpClusterStateProvider<HttpSolrClient> {
+    public ClosingHttpClusterStateProvider(List<String> solrUrls, 
HttpSolrClient httpClient)
         throws Exception {
       super(solrUrls, httpClient);
     }
@@ -130,7 +129,7 @@ public class ClusterStateProviderTest extends 
SolrCloudTestCase {
   private static HttpClusterStateProvider<?> http2ClusterStateProvider(String 
userAgent) {
     try {
       var useJdkProvider = random().nextBoolean();
-      HttpSolrClientBase client;
+      HttpSolrClient client;
 
       if (userAgent != null) {
         if (useJdkProvider) {
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClientTest.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClientTest.java
index f306dc36edc..13e790b60b2 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClientTest.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJdkSolrClientTest.java
@@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 public class ConcurrentUpdateJdkSolrClientTest extends 
ConcurrentUpdateSolrClientTestBase {
 
   @Override
-  public HttpSolrClientBase solrClient(Integer overrideIdleTimeoutMs) {
+  public HttpSolrClient solrClient(Integer overrideIdleTimeoutMs) {
     var builder =
         new 
HttpJdkSolrClient.Builder().withSSLContext(MockTrustManager.ALL_TRUSTING_SSL_CONTEXT);
     if (overrideIdleTimeoutMs != null) {
@@ -35,7 +35,7 @@ public class ConcurrentUpdateJdkSolrClientTest extends 
ConcurrentUpdateSolrClien
 
   @Override
   public ConcurrentUpdateBaseSolrClient concurrentClient(
-      HttpSolrClientBase solrClient,
+      HttpSolrClient solrClient,
       String baseUrl,
       String defaultCollection,
       int queueSize,
@@ -59,7 +59,7 @@ public class ConcurrentUpdateJdkSolrClientTest extends 
ConcurrentUpdateSolrClien
       String serverUrl,
       int queueSize,
       int threadCount,
-      HttpSolrClientBase solrClient,
+      HttpSolrClient solrClient,
       AtomicInteger successCounter,
       AtomicInteger failureCounter,
       StringBuilder errors) {
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTestBase.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTestBase.java
index 3ccb0f39011..29e73a44007 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTestBase.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTestBase.java
@@ -63,10 +63,10 @@ import org.slf4j.LoggerFactory;
 public abstract class ConcurrentUpdateSolrClientTestBase extends 
SolrTestCaseJ4 {
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  public abstract HttpSolrClientBase solrClient(Integer overrideIdleTimeoutMs);
+  public abstract HttpSolrClient solrClient(Integer overrideIdleTimeoutMs);
 
   public abstract ConcurrentUpdateBaseSolrClient concurrentClient(
-      HttpSolrClientBase solrClient,
+      HttpSolrClient solrClient,
       String baseUrl,
       String defaultCollection,
       int queueSize,
@@ -77,7 +77,7 @@ public abstract class ConcurrentUpdateSolrClientTestBase 
extends SolrTestCaseJ4
       String serverUrl,
       int queueSize,
       int threadCount,
-      HttpSolrClientBase solrClient,
+      HttpSolrClient solrClient,
       AtomicInteger successCounter,
       AtomicInteger failureCounter,
       StringBuilder errors);
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
index 707e665d97a..fe159e4ad3f 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
@@ -191,7 +191,7 @@ public class HttpJdkSolrClientTest extends 
HttpSolrClientTestBase {
   public void testAsyncGet() throws Exception {
     String url = solrTestRule.getBaseUrl() + DEBUG_SERVLET_PATH;
     ResponseParser rp = new XMLResponseParser();
-    HttpSolrClientBuilderBase<?, ?> b =
+    HttpSolrClient.BuilderBase<?, ?> b =
         builder(url, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT).withResponseParser(rp);
     super.testQueryAsync(b);
   }
@@ -559,7 +559,7 @@ public class HttpJdkSolrClientTest extends 
HttpSolrClientTestBase {
 
   @Override
   @SuppressWarnings(value = "unchecked")
-  protected <B extends HttpSolrClientBuilderBase<?, ?>> B builder(
+  protected <B extends HttpSolrClient.BuilderBase<?, ?>> B builder(
       String url, int connectionTimeout, int socketTimeout) {
     HttpJdkSolrClient.Builder b =
         new HttpJdkSolrClient.Builder(url)
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBadInputTest.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBadInputTest.java
index c80338e412b..e9c4e9e093a 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBadInputTest.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBadInputTest.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrClient;
-import org.apache.solr.client.solrj.apache.HttpSolrClient;
 import org.apache.solr.common.util.EnvUtils;
 import org.apache.solr.util.ExternalPaths;
 import org.apache.solr.util.SolrJettyTestRule;
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientTestBase.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientTestBase.java
index 771e6e1db58..319d82a1c6a 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientTestBase.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientTestBase.java
@@ -106,7 +106,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     super.tearDown();
   }
 
-  protected abstract <B extends HttpSolrClientBuilderBase<?, ?>> B builder(
+  protected abstract <B extends HttpSolrClient.BuilderBase<?, ?>> B builder(
       String url, int connectionTimeout, int socketTimeout);
 
   protected abstract String expectedUserAgent();
@@ -235,7 +235,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     assertEquals(expectedUserAgent(), DebugServlet.headers.get("user-agent"));
   }
 
-  public void testGetById(HttpSolrClientBase client) throws Exception {
+  public void testGetById(HttpSolrClient client) throws Exception {
     DebugServlet.clear();
     Collection<String> ids = List.of("a");
     try {
@@ -263,7 +263,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
    * test that SolrExceptions thrown by HttpSolrClient can correctly 
encapsulate http status codes
    * even when not on the list of ErrorCodes solr may return.
    */
-  public void testSolrExceptionCodeNotFromSolr(HttpSolrClientBase client)
+  public void testSolrExceptionCodeNotFromSolr(HttpSolrClient client)
       throws IOException, SolrServerException {
     final int status = 527;
     assertEquals(
@@ -287,7 +287,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     XML
   }
 
-  protected void testUpdate(HttpSolrClientBase client, WT wt, String 
contentType, String docIdValue)
+  protected void testUpdate(HttpSolrClient client, WT wt, String contentType, 
String docIdValue)
       throws Exception {
     DebugServlet.clear();
     UpdateRequest req = new UpdateRequest();
@@ -327,7 +327,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
   }
 
   protected void testCollectionParameters(
-      HttpSolrClientBase baseUrlClient, HttpSolrClientBase 
collection1UrlClient)
+      HttpSolrClient baseUrlClient, HttpSolrClient collection1UrlClient)
       throws IOException, SolrServerException {
     try {
       SolrInputDocument doc = new SolrInputDocument();
@@ -359,7 +359,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     }
   }
 
-  protected void verifyServletState(HttpSolrClientBase client, SolrRequest<?> 
request) {
+  protected void verifyServletState(HttpSolrClient client, SolrRequest<?> 
request) {
     // check query String
     Iterator<String> paramNames = 
request.getParams().getParameterNamesIterator();
     while (paramNames.hasNext()) {
@@ -387,7 +387,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     final String clientUrl = solrTestRule.getBaseUrl() + DEBUG_SERVLET_PATH;
     UpdateRequest req = new UpdateRequest();
 
-    try (HttpSolrClientBase client =
+    try (HttpSolrClient client =
         builder(clientUrl, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT)
             .withDefaultCollection(DEFAULT_COLLECTION)
             .withTheseParamNamesInTheUrl(Set.of("serverOnly"))
@@ -405,7 +405,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
       // test without server query params
       DebugServlet.clear();
     }
-    try (HttpSolrClientBase client =
+    try (HttpSolrClient client =
         builder(clientUrl, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT)
             .withTheseParamNamesInTheUrl(Set.of())
             .build()) {
@@ -421,7 +421,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
       // test with both request and server query params
       DebugServlet.clear();
     }
-    try (HttpSolrClientBase client =
+    try (HttpSolrClient client =
         builder(clientUrl, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT)
             .withTheseParamNamesInTheUrl(Set.of("serverOnly", "both"))
             .build()) {
@@ -434,7 +434,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
       }
       verifyServletState(client, req);
     }
-    try (HttpSolrClientBase client =
+    try (HttpSolrClient client =
         builder(clientUrl, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT)
             .withTheseParamNamesInTheUrl(Set.of("serverOnly", "both"))
             .build()) {
@@ -457,7 +457,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     }
   }
 
-  protected void testGetRawStream(HttpSolrClientBase client) throws Exception {
+  protected void testGetRawStream(HttpSolrClient client) throws Exception {
     DebugServlet.clear();
     final var req = new QueryRequest(params("q", "*:*"));
     req.setResponseParser(new InputStreamResponseParser("xml"));
@@ -470,7 +470,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     IOUtils.closeQuietly((InputStream) stream);
   }
 
-  protected void testSetCredentialsExplicitly(HttpSolrClientBase client) {
+  protected void testSetCredentialsExplicitly(HttpSolrClient client) {
     QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
     try {
       ignoreException("Error from server");
@@ -490,7 +490,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
         authorizationHeader);
   }
 
-  protected void testPerRequestCredentials(HttpSolrClientBase client) {
+  protected void testPerRequestCredentials(HttpSolrClient client) {
     QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
     r.setBasicAuthCredentials("foo3", "per-request");
     try {
@@ -512,7 +512,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
         authorizationHeader);
   }
 
-  protected void testNoCredentials(HttpSolrClientBase client) {
+  protected void testNoCredentials(HttpSolrClient client) {
     QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
     try {
       ignoreException("Error from server");
@@ -526,7 +526,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
         DebugServlet.headers.containsKey("authorization"));
   }
 
-  protected void testUseOptionalCredentials(HttpSolrClientBase client) {
+  protected void testUseOptionalCredentials(HttpSolrClient client) {
     QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
     try {
       ignoreException("Error from server");
@@ -546,7 +546,7 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
         authorizationHeader);
   }
 
-  protected void testUseOptionalCredentialsWithNull(HttpSolrClientBase client) 
{
+  protected void testUseOptionalCredentialsWithNull(HttpSolrClient client) {
     // username foo, password with embedded colon separator is "expli:cit".
     QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
     try {
@@ -565,12 +565,12 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
   protected void testUpdateAsync() throws Exception {
     ResponseParser rp = new XMLResponseParser();
     String url = solrTestRule.getBaseUrl();
-    HttpSolrClientBuilderBase<?, ?> b =
+    HttpSolrClient.BuilderBase<?, ?> b =
         builder(url, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT).withResponseParser(rp);
     int limit = 10;
     CountDownLatch latch = new CountDownLatch(limit);
 
-    try (HttpSolrClientBase client = b.build()) {
+    try (HttpSolrClient client = b.build()) {
 
       // ensure the collection is empty to start
       client.deleteByQuery(DEFAULT_COLLECTION, "*:*");
@@ -602,14 +602,14 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     }
   }
 
-  protected void testQueryAsync(HttpSolrClientBuilderBase<?, ?> builder) 
throws Exception {
+  protected void testQueryAsync(HttpSolrClient.BuilderBase<?, ?> builder) 
throws Exception {
     DebugServlet.clear();
     DebugServlet.addResponseHeader("Content-Type", "application/xml; 
charset=UTF-8");
     int limit = 10;
 
     List<CompletableFuture<NamedList<Object>>> futures = new ArrayList<>();
 
-    try (HttpSolrClientBase client = builder.build()) {
+    try (HttpSolrClient client = builder.build()) {
       for (int i = 0; i < limit; i++) {
         DebugServlet.responseBodyByQueryFragment.put(
             ("id=KEY-" + i),
@@ -640,10 +640,10 @@ public abstract class HttpSolrClientTestBase extends 
SolrTestCaseJ4 {
     DebugServlet.clear();
     DebugServlet.addResponseHeader("Content-Type", "Wrong Content Type!");
     String url = solrTestRule.getBaseUrl() + DEBUG_SERVLET_PATH;
-    HttpSolrClientBuilderBase<?, ?> b =
+    HttpSolrClient.BuilderBase<?, ?> b =
         builder(url, DEFAULT_CONNECTION_TIMEOUT, 
DEFAULT_CONNECTION_TIMEOUT).withResponseParser(rp);
 
-    try (HttpSolrClientBase client = b.build()) {
+    try (HttpSolrClient client = b.build()) {
       QueryRequest query = new QueryRequest(new MapSolrParams(Map.of("id", 
"1")));
       CompletableFuture<NamedList<Object>> future = client.requestAsync(query, 
DEFAULT_COLLECTION);
       ExecutionException ee = null;
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrBackend.java 
b/solr/test-framework/src/java/org/apache/solr/SolrBackend.java
index db6c3f5ad09..1f08705a9f0 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrBackend.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrBackend.java
@@ -24,7 +24,7 @@ import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.GenericSolrRequest;
 import org.apache.solr.client.solrj.request.MetricsRequest;
@@ -117,7 +117,7 @@ public interface SolrBackend extends AutoCloseable {
   default String getBaseUrl(Random r) {
     // Get live nodes and pick one randomly
     SolrClient adminClient = getSolrClient();
-    if (adminClient instanceof HttpSolrClientBase httpSolrClient) {
+    if (adminClient instanceof HttpSolrClient httpSolrClient) {
       return httpSolrClient.getBaseURL();
     } else if (adminClient instanceof CloudSolrClient cloudClient) {
       var liveNodes = cloudClient.getClusterStateProvider().getLiveNodes();
diff --git 
a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
 
b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
index 04f58e00a61..76bcd7749a3 100644
--- 
a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
+++ 
b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
@@ -150,7 +150,6 @@ public class HttpSolrClient extends SolrClient {
   private final int connectionTimeout;
   private final int soTimeout;
 
-  /** Use the builder to create this client */
   protected HttpSolrClient(Builder builder) {
     this.baseUrl = builder.baseSolrUrl;
     if (baseUrl.endsWith("/")) {
@@ -831,14 +830,14 @@ public class HttpSolrClient extends SolrClient {
       this.responseParser = new JavaBinResponseParser();
     }
 
-    /** Chooses whether created {@link HttpSolrClient}s use compression by 
default. */
+    /** Chooses whether created clients use compression by default. */
     public Builder allowCompression(boolean compression) {
       this.compression = compression;
       return this;
     }
 
     /**
-     * Adds to the set of params that the created {@link HttpSolrClient} will 
add on all requests
+     * Adds to the set of params that the created client will add on all 
requests
      *
      * @param params a set of parameters to add to the invariant-params list. 
These params must be
      *     unique and may not duplicate a param already in the invariant list.
diff --git 
a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/SolrPortAwareCookieSpecFactory.java
 
b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/SolrPortAwareCookieSpecFactory.java
index 64af36f273f..aadcf2ad9ac 100644
--- 
a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/SolrPortAwareCookieSpecFactory.java
+++ 
b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/SolrPortAwareCookieSpecFactory.java
@@ -31,6 +31,7 @@ import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 
 @SuppressWarnings("deprecation")
+@Deprecated
 public class SolrPortAwareCookieSpecFactory implements CookieSpecFactory, 
CookieSpecProvider {
   public static final String POLICY_NAME = "solr-portaware";
   private final CookieSpec cookieSpec;
diff --git 
a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/package-info.java
 
b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/package-info.java
index bfdeeef2287..31cd26e17ea 100644
--- 
a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/package-info.java
+++ 
b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/package-info.java
@@ -16,4 +16,5 @@
  */
 
 /** Apache HttpClient based {@link org.apache.solr.client.solrj.SolrClient} 
implementations */
+@Deprecated
 package org.apache.solr.client.solrj.apache;

Reply via email to