You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ds...@apache.org on 2026/07/22 21:32:08 UTC
(solr) branch branch_10x updated (0fb828eec20 -> a29dc588028)
This is an automated email from the ASF dual-hosted git repository.
dsmiley pushed a change to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git
from 0fb828eec20 SOLR-18304: Optimize collapse performance for String fields (#4621)
new cd746f33bc6 SOLR-18294: Fix flaky IndexFetcherPacketProtocolTest (#4624)
new 0dc9b3cdc14 SOLR-3284: fix RemoteSolrException NPE when remoteError is null (#4637)
new ca51b1b33c2 SOLR-17707: HttpJdkSolrClient fix thread leak when async request fails (#4639)
new 03b1a5eb0a3 Use makePath helper consistently across codebase when writing to Zookeeper (#4636)
new a29dc588028 used EnvUtils for system properties in core (#4629)
The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../PR#4629-envutils-core-properties.yml | 7 ++
.../SOLR-17707-httpjdk-async-thread-leak.yml | 11 ++
.../src/java/org/apache/solr/cli/AuthTool.java | 5 +-
.../org/apache/solr/cli/ConfigSetUploadTool.java | 3 +-
.../src/java/org/apache/solr/cli/CreateTool.java | 5 +-
.../core/src/java/org/apache/solr/cli/SolrCLI.java | 5 +-
.../src/java/org/apache/solr/cli/ZkCpTool.java | 3 +-
.../java/org/apache/solr/cloud/SolrZkServer.java | 4 +-
.../cloud/api/collections/OverseerRoleCmd.java | 7 +-
.../impl/PlacementPluginFactoryLoader.java | 3 +-
.../org/apache/solr/core/ConfigSetService.java | 6 +-
.../java/org/apache/solr/core/CoreContainer.java | 25 ++--
.../src/java/org/apache/solr/core/NodeConfig.java | 4 +-
.../solr/core/OpenTelemetryConfigurator.java | 2 +-
.../java/org/apache/solr/core/SolrXmlConfig.java | 4 +-
.../src/java/org/apache/solr/core/ZkContainer.java | 2 +-
.../apache/solr/handler/admin/SolrEnvironment.java | 5 +-
.../handler/component/HttpShardHandlerFactory.java | 3 +-
.../designer/SchemaDesignerConfigSetHelper.java | 2 +
.../solr/packagemanager/RepositoryManager.java | 15 +--
.../apache/solr/rest/ManagedResourceStorage.java | 9 +-
.../solr/schema/ManagedIndexSchemaFactory.java | 4 +-
.../apache/solr/servlet/CoreContainerProvider.java | 10 +-
.../apache/solr/servlet/LoadAdminUiServlet.java | 6 +-
.../org/apache/solr/util/FileTypeMagicUtil.java | 3 +-
.../org/apache/solr/util/StartupLoggingUtils.java | 6 +-
.../solr/util/circuitbreaker/CircuitBreaker.java | 2 +-
.../circuitbreaker/CircuitBreakerRegistry.java | 2 +-
.../solr/util/configuration/SSLConfigurations.java | 5 +-
.../SSLCredentialProviderFactory.java | 3 +-
.../providers/SysPropSSLCredentialProvider.java | 7 +-
.../apache/solr/util/tracing/SimplePropagator.java | 5 +-
.../handler/IndexFetcherPacketProtocolTest.java | 5 +-
.../org/apache/solr/common/cloud/SolrZkClient.java | 13 +-
.../solr/common/cloud/ZkMaintenanceUtils.java | 6 +-
.../solr/client/solrj/RemoteSolrException.java | 2 +-
.../solr/client/solrj/impl/HttpJdkSolrClient.java | 37 +++++-
.../solr/client/solrj/RemoteSolrExceptionTest.java | 54 +++++++++
.../client/solrj/impl/HttpJdkSolrClientTest.java | 135 +++++++++++++++++++++
39 files changed, 337 insertions(+), 98 deletions(-)
create mode 100644 changelog/unreleased/PR#4629-envutils-core-properties.yml
create mode 100644 changelog/unreleased/SOLR-17707-httpjdk-async-thread-leak.yml
create mode 100644 solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java
(solr) 02/05: SOLR-3284: fix RemoteSolrException NPE when remoteError is null (#4637)
Posted by ds...@apache.org.
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
commit 0dc9b3cdc145f2a62256d0f807385093a28d11a5
Author: Serhiy Bzhezytskyy <me...@serhiy-bzhezytskyy.com>
AuthorDate: Thu Jul 16 16:57:45 2026 +0300
SOLR-3284: fix RemoteSolrException NPE when remoteError is null (#4637)
A regression in Solr 10.0 for ConcurrentUpdateSolrClient
(cherry picked from commit 59b23fd8f184c867e30d66e7f0eca6bb69e2d6b4)
---
.../solr/client/solrj/RemoteSolrException.java | 2 +-
.../solr/client/solrj/RemoteSolrExceptionTest.java | 54 ++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java b/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java
index 4552fe0cd9d..a8110be3c80 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java
@@ -63,7 +63,7 @@ public final class RemoteSolrException extends SolrException {
public RemoteSolrException(String remoteHost, int code, Object remoteError, boolean skipRetry) {
super(ErrorCode.getErrorCode(code), "Error from server at " + remoteHost);
this.skipRetry = skipRetry;
- setDetails(List.of(Map.of("remoteHost", remoteHost, "remoteError", remoteError)));
+ setDetails(List.of(Utils.makeMap("remoteHost", remoteHost, "remoteError", remoteError)));
if (remoteError != null) {
String remoteErrorMessageSuffix = getRemoteErrorMessageSuffix(remoteError, "");
if (remoteErrorMessageSuffix.length() > 2) {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java
new file mode 100644
index 00000000000..cb211e90925
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.SolrTestCase;
+import org.junit.Test;
+
+/** Unit tests for {@link RemoteSolrException}. */
+public class RemoteSolrExceptionTest extends SolrTestCase {
+
+ /**
+ * A null remoteError must not throw: it happens whenever the server's error body can't be parsed
+ * (e.g. ConcurrentUpdateSolrClient passes a null error), and the constructor is expected to
+ * tolerate it. The consumers of the resulting exception must also tolerate the null.
+ */
+ @Test
+ public void testNullRemoteErrorDoesNotThrow() {
+ RemoteSolrException e = new RemoteSolrException("http://host:8983/solr", 500, null);
+ assertEquals(500, e.code());
+ assertNull(e.getRemoteErrorObject());
+
+ // consumers of the exception must tolerate the null remoteError entry
+ assertNotNull(e.getMessage());
+ List<Map<String, Object>> details = e.getDetails();
+ assertEquals(1, details.size());
+ assertEquals("http://host:8983/solr", details.get(0).get("remoteHost"));
+ assertNull(details.get(0).get("remoteError"));
+ }
+
+ /** A non-null remoteError is still recorded and readable back. */
+ @Test
+ public void testRemoteErrorIsRecorded() {
+ Map<String, Object> remoteError = Map.of("msg", "boom", "code", 500);
+ RemoteSolrException e = new RemoteSolrException("http://host:8983/solr", 500, remoteError);
+ assertEquals(500, e.code());
+ assertEquals(remoteError, e.getRemoteErrorObject());
+ }
+}
(solr) 04/05: Use makePath helper consistently across codebase when writing to Zookeeper (#4636)
Posted by ds...@apache.org.
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
commit 03b1a5eb0a33c7d097b6f347df1d34f6c7b0369d
Author: Eric Pugh <ep...@opensourceconnections.com>
AuthorDate: Sat Jul 18 07:25:23 2026 -0400
Use makePath helper consistently across codebase when writing to Zookeeper (#4636)
(cherry picked from commit 16c1f81f9588c0d85b15ee60b1355ef59b882874)
---
solr/core/src/java/org/apache/solr/cli/AuthTool.java | 5 +++--
.../solr/cloud/api/collections/OverseerRoleCmd.java | 7 +------
.../handler/designer/SchemaDesignerConfigSetHelper.java | 2 ++
.../org/apache/solr/packagemanager/RepositoryManager.java | 15 ++++-----------
.../java/org/apache/solr/rest/ManagedResourceStorage.java | 9 ++-------
.../org/apache/solr/schema/ManagedIndexSchemaFactory.java | 4 +---
.../java/org/apache/solr/common/cloud/SolrZkClient.java | 13 ++++++++++++-
.../org/apache/solr/common/cloud/ZkMaintenanceUtils.java | 6 +-----
8 files changed, 26 insertions(+), 35 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/cli/AuthTool.java b/solr/core/src/java/org/apache/solr/cli/AuthTool.java
index 1e6a2985330..df0133cfead 100644
--- a/solr/core/src/java/org/apache/solr/cli/AuthTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/AuthTool.java
@@ -267,7 +267,8 @@ public class AuthTool extends ToolBase {
if (!updateIncludeFileOnly) {
echoIfVerbose("Uploading following security.json: " + securityJson);
try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli, zkHost)) {
- zkClient.setData("/security.json", securityJson.getBytes(StandardCharsets.UTF_8));
+ zkClient.makePath(
+ "/security.json", securityJson.getBytes(StandardCharsets.UTF_8), false);
}
}
@@ -368,7 +369,7 @@ public class AuthTool extends ToolBase {
echoIfVerbose("Uploading following security.json: {}");
try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli, zkHost)) {
- zkClient.setData("/security.json", "{}".getBytes(StandardCharsets.UTF_8));
+ zkClient.makePath("/security.json", "{}".getBytes(StandardCharsets.UTF_8), false);
}
}
}
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java
index f33e317f998..f789455c0d6 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/OverseerRoleCmd.java
@@ -33,7 +33,6 @@ import org.apache.solr.common.util.CollectionUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.Utils;
import org.apache.solr.logging.DeprecationLog;
-import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,11 +106,7 @@ public class OverseerRoleCmd implements CollApiCmds.CollectionApiCommand {
nodeList.remove(node);
}
- if (nodeExists) {
- zkClient.setData(ZkStateReader.ROLES, Utils.toJSON(roles));
- } else {
- zkClient.create(ZkStateReader.ROLES, Utils.toJSON(roles), CreateMode.PERSISTENT);
- }
+ zkClient.makePath(ZkStateReader.ROLES, Utils.toJSON(roles), false);
runPrioritizer();
}
diff --git a/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java b/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
index 907e0933acf..1af273cc9d0 100644
--- a/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
+++ b/solr/core/src/java/org/apache/solr/handler/designer/SchemaDesignerConfigSetHelper.java
@@ -918,6 +918,8 @@ class SchemaDesignerConfigSetHelper implements SchemaDesignerConstants {
for (String path : langFilesToRestore) {
String copyToPath = path.replace(origPathDir, replacePathDir);
try {
+ // Only restore files that are missing -- do not overwrite an existing file with the
+ // copyFrom version.
if (!zkClient.exists(copyToPath)) {
zkClient.makePath(copyToPath, false);
zkClient.setData(copyToPath, zkClient.getData(path, null, null));
diff --git a/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java b/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java
index 940bb536f16..29a86c75e0a 100644
--- a/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java
+++ b/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java
@@ -57,7 +57,6 @@ import org.apache.solr.packagemanager.SolrPackage.Artifact;
import org.apache.solr.packagemanager.SolrPackage.SolrPackageRelease;
import org.apache.solr.pkg.PackageAPI;
import org.apache.solr.pkg.SolrPackageLoader;
-import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -123,16 +122,10 @@ public class RepositoryManager {
@SuppressWarnings({"unchecked"})
List<PackageRepository> repos = getMapper().readValue(existingRepositoriesJson, List.class);
repos.add(new DefaultPackageRepository(repoName, uri));
- if (packageManager.zkClient.exists(PackageUtils.REPOSITORIES_ZK_PATH) == false) {
- packageManager.zkClient.create(
- PackageUtils.REPOSITORIES_ZK_PATH,
- getMapper().writeValueAsString(repos).getBytes(StandardCharsets.UTF_8),
- CreateMode.PERSISTENT);
- } else {
- packageManager.zkClient.setData(
- PackageUtils.REPOSITORIES_ZK_PATH,
- getMapper().writeValueAsString(repos).getBytes(StandardCharsets.UTF_8));
- }
+ packageManager.zkClient.makePath(
+ PackageUtils.REPOSITORIES_ZK_PATH,
+ getMapper().writeValueAsString(repos).getBytes(StandardCharsets.UTF_8),
+ false);
try (InputStream is = new URI(uri + "/publickey.der").toURL().openStream()) {
addKey(is.readAllBytes(), repoName + ".der");
diff --git a/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java b/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
index 54e6838902b..7bcf1af467a 100644
--- a/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
+++ b/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
@@ -308,13 +308,8 @@ public abstract class ManagedResourceStorage {
public void close() {
byte[] znodeData = toByteArray();
try {
- if (zkClient.exists(znodePath)) {
- zkClient.setData(znodePath, znodeData);
- log.info("Wrote {} bytes to existing znode {}", znodeData.length, znodePath);
- } else {
- zkClient.makePath(znodePath, znodeData);
- log.info("Wrote {} bytes to new znode {}", znodeData.length, znodePath);
- }
+ zkClient.makePath(znodePath, znodeData, false);
+ log.info("Wrote {} bytes to znode {}", znodeData.length, znodePath);
} catch (Exception e) {
// have to throw a runtimer here as we're in close,
// which doesn't throw IOException
diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
index 83797b7c0f8..05f78633718 100644
--- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
+++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
@@ -30,7 +30,6 @@ import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.IOUtils;
import org.apache.solr.common.util.NamedList;
@@ -487,8 +486,7 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol
// First, copy the non-managed schema znode content to the upgraded schema znode
byte[] bytes = zkController.getZkClient().getData(nonManagedSchemaPath, null, null);
final String upgradedSchemaPath = nonManagedSchemaPath + UPGRADED_SCHEMA_EXTENSION;
- ZkMaintenanceUtils.ensureExists(upgradedSchemaPath, zkController.getZkClient());
- zkController.getZkClient().setData(upgradedSchemaPath, bytes);
+ zkController.getZkClient().makePath(upgradedSchemaPath, bytes, false);
// Then delete the non-managed schema znode
if (zkController.getZkClient().exists(nonManagedSchemaPath)) {
try {
diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
index 164af46dc05..729beb65471 100644
--- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
@@ -493,6 +493,13 @@ public class SolrZkClient implements Closeable {
makePath(path, null, CreateMode.PERSISTENT, null, failOnExists, 0);
}
+ /**
+ * Creates the path in ZooKeeper, creating each node as necessary.
+ *
+ * @param data to set on the last zkNode
+ * @param failOnExists if {@code true}, fail if the last zkNode already exists; if {@code false},
+ * an existing zkNode's data is overwritten instead, making this a safe create-or-update
+ */
public void makePath(String path, byte[] data, boolean failOnExists)
throws KeeperException, InterruptedException {
makePath(path, data, CreateMode.PERSISTENT, null, failOnExists, 0);
@@ -711,7 +718,11 @@ public class SolrZkClient implements Closeable {
}
}
- /** Write data to ZooKeeper. */
+ /**
+ * Write data to ZooKeeper. The node at {@code path} must already exist; throws {@link
+ * NoNodeException} otherwise. Use {@link #makePath(String, byte[], boolean) makePath(path, data,
+ * false)} instead if the node may not exist yet.
+ */
public Stat setData(String path, byte[] data) throws KeeperException, InterruptedException {
return setData(path, data, -1);
}
diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
index 4efb0827413..7e3f7f80675 100644
--- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
@@ -351,11 +351,7 @@ public class ZkMaintenanceUtils {
zkClient.setData(zkNode, file);
} else if (file.equals(rootPath)) {
// We are only uploading a single file, preVisitDirectory was never called
- if (zkClient.exists(zkPath)) {
- zkClient.setData(zkPath, file);
- } else {
- zkClient.makePath(zkPath, Files.readAllBytes(file), false);
- }
+ zkClient.makePath(zkPath, Files.readAllBytes(file), false);
} else {
// Skip path parts here because they should have been created during
// preVisitDirectory
(solr) 01/05: SOLR-18294: Fix flaky IndexFetcherPacketProtocolTest (#4624)
Posted by ds...@apache.org.
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
commit cd746f33bc6581dcda9d5bff224f67962d5424cf
Author: Shubham Ranjan <sh...@users.noreply.github.com>
AuthorDate: Wed Jul 15 21:39:43 2026 +0530
SOLR-18294: Fix flaky IndexFetcherPacketProtocolTest (#4624)
Test was using an incorrect 'DirContext' and failed periodically
based on test randomization.
(cherry picked from commit eb59a9a6db4a2ff982a3be8e3682456eb8c12fd1)
---
.../test/org/apache/solr/handler/IndexFetcherPacketProtocolTest.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/solr/core/src/test/org/apache/solr/handler/IndexFetcherPacketProtocolTest.java b/solr/core/src/test/org/apache/solr/handler/IndexFetcherPacketProtocolTest.java
index e9d639f1ab3..36d47427a4f 100644
--- a/solr/core/src/test/org/apache/solr/handler/IndexFetcherPacketProtocolTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/IndexFetcherPacketProtocolTest.java
@@ -227,10 +227,13 @@ public class IndexFetcherPacketProtocolTest extends SolrTestCaseJ4 {
/** Writes file content to a directory and serializes it using the replication packet protocol. */
private byte[] serializeFileToPacketStream(byte[] content, String fileName) throws Exception {
DirectoryFactory directoryFactory = h.getCore().getDirectoryFactory();
+ // Use the same REPLICATION DirContext that the sender (DirectoryFileStream) uses to read the
+ // file, so the write and the read target the same (unwrapped) delegate Directory. For
+ // REPLICATION/BACKUP, CachingDirectoryFactory.filterDirectory() unwraps to the raw delegate.
Directory dir =
directoryFactory.get(
h.getCore().getNewIndexDir(),
- DirectoryFactory.DirContext.DEFAULT,
+ DirectoryFactory.DirContext.REPLICATION,
h.getCore().getSolrConfig().indexConfig.lockType);
try {
(solr) 03/05: SOLR-17707: HttpJdkSolrClient fix thread leak when async request fails (#4639)
Posted by ds...@apache.org.
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
commit ca51b1b33c2eee6a69cd1eeb79fe29f81fb9ab3e
Author: Serhiy Bzhezytskyy <me...@serhiy-bzhezytskyy.com>
AuthorDate: Thu Jul 16 21:28:05 2026 +0300
SOLR-17707: HttpJdkSolrClient fix thread leak when async request fails (#4639)
Fixed HttpJdkSolrClient leaking an executor thread when an async request's connection failed while its body was still being written; enough such failures could exhaust the client's thread pool.
(cherry picked from commit aa9e3f1a7841e765d3806951e2d6f0460f6a057d)
---
.../SOLR-17707-httpjdk-async-thread-leak.yml | 11 ++
.../solr/client/solrj/impl/HttpJdkSolrClient.java | 37 +++++-
.../client/solrj/impl/HttpJdkSolrClientTest.java | 135 +++++++++++++++++++++
3 files changed, 177 insertions(+), 6 deletions(-)
diff --git a/changelog/unreleased/SOLR-17707-httpjdk-async-thread-leak.yml b/changelog/unreleased/SOLR-17707-httpjdk-async-thread-leak.yml
new file mode 100644
index 00000000000..f015a99b5f3
--- /dev/null
+++ b/changelog/unreleased/SOLR-17707-httpjdk-async-thread-leak.yml
@@ -0,0 +1,11 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+
+title: >
+ Fixed HttpJdkSolrClient leaking an executor thread when an async request's connection failed while
+ its body was still being written; enough such failures could exhaust the client's thread pool.
+type: fixed
+authors:
+ - name: Serhiy Bzhezytskyy
+links:
+ - name: SOLR-17707
+ url: https://issues.apache.org/jira/browse/SOLR-17707
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 1f88adc519f..111bfd1bc92 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
@@ -144,8 +144,10 @@ public class HttpJdkSolrClient extends HttpSolrClient {
protected CompletableFuture<HttpResponse<InputStream>> requestInputStreamAsync(
String baseUrl, final SolrRequest<?> solrRequest, String collection) {
try {
- HttpRequest httpRequest = prepareRequest(baseUrl, solrRequest, collection).reqb.build();
- return httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofInputStream());
+ PreparedRequest pReq = prepareRequest(baseUrl, solrRequest, collection);
+ return httpClient
+ .sendAsync(pReq.reqb.build(), HttpResponse.BodyHandlers.ofInputStream())
+ .whenComplete((httpResponse, throwable) -> releaseContentWriting(pReq));
} catch (Exception e) {
CompletableFuture<HttpResponse<InputStream>> cf = new CompletableFuture<>();
cf.completeExceptionally(e);
@@ -160,6 +162,7 @@ public class HttpJdkSolrClient extends HttpSolrClient {
PreparedRequest pReq = prepareRequest(null, solrRequest, collection);
return httpClient
.sendAsync(pReq.reqb.build(), HttpResponse.BodyHandlers.ofInputStream())
+ .whenComplete((httpResponse, throwable) -> releaseContentWriting(pReq))
.thenApply(
httpResponse -> {
try {
@@ -176,6 +179,21 @@ public class HttpJdkSolrClient extends HttpSolrClient {
}
}
+ private void releaseContentWriting(PreparedRequest pReq) {
+ if (pReq.contentWritingFuture != null) {
+ pReq.contentWritingFuture.cancel(true);
+ }
+ // Closing the sink is what unblocks a writer already stuck in the pipe; cancel() alone does
+ // not.
+ if (pReq.contentWritingSink != null) {
+ try {
+ pReq.contentWritingSink.close();
+ } catch (IOException e) {
+ log.warn("Could not close content-writing pipe", e);
+ }
+ }
+ }
+
@Override
public NamedList<Object> requestWithBaseUrl(
String baseUrl, SolrRequest<?> solrRequest, String collection)
@@ -271,7 +289,7 @@ public class HttpJdkSolrClient extends HttpSolrClient {
reqb.GET();
decorateRequest(reqb, solrRequest);
reqb.uri(new URI(url + queryParams.toQueryString()));
- return new PreparedRequest(reqb, null);
+ return new PreparedRequest(reqb, null, null);
}
private PreparedRequest preparePutOrPost(
@@ -303,6 +321,7 @@ public class HttpJdkSolrClient extends HttpSolrClient {
HttpRequest.BodyPublisher bodyPublisher;
Future<?> contentWritingFuture = null;
+ PipedInputStream contentWritingSink = null;
if (contentWriter != null) {
boolean success = maybeTryHeadRequest(url);
if (!success) {
@@ -310,7 +329,8 @@ public class HttpJdkSolrClient extends HttpSolrClient {
}
final PipedOutputStream source = new PipedOutputStream();
- final PipedInputStream sink = new PipedInputStream(source);
+ contentWritingSink = new PipedInputStream(source);
+ final PipedInputStream sink = contentWritingSink;
bodyPublisher = HttpRequest.BodyPublishers.ofInputStream(() -> sink);
contentWritingFuture =
@@ -352,20 +372,25 @@ public class HttpJdkSolrClient extends HttpSolrClient {
URI uriWithQueryParams = new URI(url + queryParams.toQueryString());
reqb.uri(uriWithQueryParams);
- return new PreparedRequest(reqb, contentWritingFuture);
+ return new PreparedRequest(reqb, contentWritingFuture, contentWritingSink);
}
protected static class PreparedRequest {
Future<?> contentWritingFuture;
+ PipedInputStream contentWritingSink;
HttpRequest.Builder reqb;
ResponseParser parserToUse;
String url;
- PreparedRequest(HttpRequest.Builder reqb, Future<?> contentWritingFuture) {
+ PreparedRequest(
+ HttpRequest.Builder reqb,
+ Future<?> contentWritingFuture,
+ PipedInputStream contentWritingSink) {
this.reqb = reqb;
this.contentWritingFuture = contentWritingFuture;
+ this.contentWritingSink = contentWritingSink;
}
}
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 73ff00474bb..79bfdb63e9c 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
@@ -20,15 +20,23 @@ package org.apache.solr.client.solrj.impl;
import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookieManager;
+import java.net.ServerSocket;
+import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import org.apache.lucene.util.NamedThreadFactory;
import org.apache.solr.client.api.util.SolrVersion;
@@ -38,6 +46,7 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.JavaBinRequestWriter;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.SolrQuery;
+import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.request.XMLRequestWriter;
import org.apache.solr.client.solrj.response.JavaBinResponseParser;
import org.apache.solr.client.solrj.response.ResponseParser;
@@ -132,6 +141,132 @@ public class HttpJdkSolrClientTest extends HttpSolrClientTestBase {
}
}
+ /**
+ * A large content-writing request whose connection drops while the body is still being written
+ * must not leave the body-writing thread blocked forever in {@code
+ * PipedInputStream.awaitSpace()}. The server accepts the connection but never reads the body, so
+ * the pipe buffer fills and the writer blocks; when the connection is then reset the writer must
+ * be released (SOLR-17707).
+ */
+ @Test
+ public void testStuckContentWritingThreadIsReleasedOnFailure() throws Exception {
+ // A body far larger than the PipedInputStream buffer and the socket buffers, so the writer is
+ // still blocked in awaitSpace() when the connection drops.
+ StringBuilder big = new StringBuilder();
+ while (big.length() < 8 * 1024 * 1024) {
+ big.append("id_").append(big.length()).append(' ');
+ }
+ UpdateRequest req = new UpdateRequest();
+ req.deleteByQuery(big.toString());
+
+ ExecutorService executor =
+ ExecutorUtil.newMDCAwareCachedThreadPool(new NamedThreadFactory("solr-17707-writer"));
+ try (StallThenResetServer server = new StallThenResetServer();
+ HttpJdkSolrClient client =
+ builder(server.baseUrl()).useHttp1_1(true).withExecutor(executor).build()) {
+
+ CompletableFuture<?> cf = client.requestAsync(req, null);
+ server.awaitConnected(30, TimeUnit.SECONDS);
+ Thread.sleep(1000); // let the writer fill the pipe and block in awaitSpace()
+ server.resetAll(); // drop the connection under the in-flight write
+
+ // The request settles (normally exceptionally, from the dropped connection); either way the
+ // point of the test is the thread check below, so just wait for it to complete.
+ cf.handle((r, t) -> null).get(30, TimeUnit.SECONDS);
+
+ // The writer thread must not remain blocked in the pipe after the request has failed.
+ assertTrue(
+ "content-writing thread leaked, still blocked after failure",
+ waitForNoBlockedWriter(15, TimeUnit.SECONDS));
+ } finally {
+ ExecutorUtil.shutdownAndAwaitTermination(executor);
+ }
+ }
+
+ private static boolean waitForNoBlockedWriter(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ long deadline = System.nanoTime() + unit.toNanos(timeout);
+ while (System.nanoTime() < deadline) {
+ if (!hasBlockedWriterThread()) {
+ return true;
+ }
+ Thread.sleep(100);
+ }
+ return !hasBlockedWriterThread();
+ }
+
+ private static boolean hasBlockedWriterThread() {
+ Thread[] threads = new Thread[Thread.activeCount() * 2];
+ int n = Thread.enumerate(threads);
+ for (int i = 0; i < n; i++) {
+ Thread t = threads[i];
+ if (t != null && t.getName().startsWith("solr-17707-writer")) {
+ for (StackTraceElement el : t.getStackTrace()) {
+ if ("awaitSpace".equals(el.getMethodName())) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /** A TCP server that accepts a connection, never reads the body, then resets on demand. */
+ private static class StallThenResetServer implements AutoCloseable {
+ private final ServerSocket serverSocket;
+ private final List<Socket> accepted = Collections.synchronizedList(new ArrayList<>());
+ private final CountDownLatch connected = new CountDownLatch(1);
+ private final AtomicBoolean closed = new AtomicBoolean(false);
+
+ StallThenResetServer() throws IOException {
+ this.serverSocket = new ServerSocket(0);
+ Thread acceptThread =
+ new Thread(
+ () -> {
+ while (!serverSocket.isClosed()) {
+ try {
+ Socket s = serverSocket.accept();
+ s.setSoLinger(true, 0); // close() sends RST rather than FIN
+ accepted.add(s);
+ connected.countDown();
+ // never read the body: the client's send buffer and the pipe fill up
+ } catch (IOException ignored) {
+ return;
+ }
+ }
+ },
+ "solr-17707-stall-server");
+ acceptThread.setDaemon(true);
+ acceptThread.start();
+ }
+
+ String baseUrl() {
+ return "http://127.0.0.1:" + serverSocket.getLocalPort() + "/solr";
+ }
+
+ void awaitConnected(long timeout, TimeUnit unit) throws InterruptedException {
+ connected.await(timeout, unit);
+ }
+
+ void resetAll() {
+ for (Socket s : accepted) {
+ try {
+ s.close();
+ } catch (IOException ignored) {
+ // ignore
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (closed.compareAndSet(false, true)) {
+ resetAll();
+ serverSocket.close();
+ }
+ }
+ }
+
@Override
protected void testQuerySetup(SolrRequest.METHOD method, ResponseParser rp) throws Exception {
DebugServlet.clear();
(solr) 05/05: used EnvUtils for system properties in core (#4629)
Posted by ds...@apache.org.
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
commit a29dc5880287ad41c0c0a66434a7266d6f63382b
Author: Prithvi S <pr...@gmail.com>
AuthorDate: Sat Jul 18 19:05:30 2026 +0530
used EnvUtils for system properties in core (#4629)
Can use either system properties or environment variables.
Co-authored-by: Eric Pugh <ep...@opensourceconnections.com>
(cherry picked from commit c0baa496c23fbb44d0818efed8d5f113cfeddea2)
---
.../PR#4629-envutils-core-properties.yml | 7 ++++++
.../org/apache/solr/cli/ConfigSetUploadTool.java | 3 ++-
.../src/java/org/apache/solr/cli/CreateTool.java | 5 +++--
.../core/src/java/org/apache/solr/cli/SolrCLI.java | 5 +++--
.../src/java/org/apache/solr/cli/ZkCpTool.java | 3 ++-
.../java/org/apache/solr/cloud/SolrZkServer.java | 4 ++--
.../impl/PlacementPluginFactoryLoader.java | 3 ++-
.../org/apache/solr/core/ConfigSetService.java | 6 +++---
.../java/org/apache/solr/core/CoreContainer.java | 25 ++++++++++++----------
.../src/java/org/apache/solr/core/NodeConfig.java | 4 ++--
.../solr/core/OpenTelemetryConfigurator.java | 2 +-
.../java/org/apache/solr/core/SolrXmlConfig.java | 4 ++--
.../src/java/org/apache/solr/core/ZkContainer.java | 2 +-
.../apache/solr/handler/admin/SolrEnvironment.java | 5 +++--
.../handler/component/HttpShardHandlerFactory.java | 3 ++-
.../apache/solr/servlet/CoreContainerProvider.java | 10 ++++-----
.../apache/solr/servlet/LoadAdminUiServlet.java | 6 +++---
.../org/apache/solr/util/FileTypeMagicUtil.java | 3 ++-
.../org/apache/solr/util/StartupLoggingUtils.java | 6 ++++--
.../solr/util/circuitbreaker/CircuitBreaker.java | 2 +-
.../circuitbreaker/CircuitBreakerRegistry.java | 2 +-
.../solr/util/configuration/SSLConfigurations.java | 5 +++--
.../SSLCredentialProviderFactory.java | 3 ++-
.../providers/SysPropSSLCredentialProvider.java | 7 ++----
.../apache/solr/util/tracing/SimplePropagator.java | 5 +++--
25 files changed, 75 insertions(+), 55 deletions(-)
diff --git a/changelog/unreleased/PR#4629-envutils-core-properties.yml b/changelog/unreleased/PR#4629-envutils-core-properties.yml
new file mode 100644
index 00000000000..f700119fe1b
--- /dev/null
+++ b/changelog/unreleased/PR#4629-envutils-core-properties.yml
@@ -0,0 +1,7 @@
+title: Core system properties can now also be configured via environment variables
+type: changed
+authors:
+ - name: Prithvi S
+links:
+ - name: PR#4629
+ url: https://github.com/apache/solr/pull/4629
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java b/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
index fdd2380f3a1..71daf15d338 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
@@ -23,6 +23,7 @@ import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkMaintenanceUtils;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.core.ConfigSetService;
import org.apache.solr.util.FileTypeMagicUtil;
import org.slf4j.Logger;
@@ -77,7 +78,7 @@ public class ConfigSetUploadTool extends ToolBase {
public void runImpl(CommandLine cli) throws Exception {
String zkHost = CLIUtils.getZkHost(cli);
- final String solrInstallDir = System.getProperty("solr.install.dir");
+ final String solrInstallDir = EnvUtils.getProperty("solr.install.dir");
Path solrInstallDirPath = Path.of(solrInstallDir);
String confName = cli.getOptionValue(CONF_NAME_OPTION);
diff --git a/solr/core/src/java/org/apache/solr/cli/CreateTool.java b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
index 036297d8d53..9878c6b9890 100644
--- a/solr/core/src/java/org/apache/solr/cli/CreateTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
@@ -40,6 +40,7 @@ import org.apache.solr.client.solrj.response.SystemInfoResponse;
import org.apache.solr.client.solrj.response.json.JsonMapResponseParser;
import org.apache.solr.cloud.ZkConfigSetService;
import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.ConfigSetService;
import org.noggit.CharArr;
@@ -140,7 +141,7 @@ public class CreateTool extends ToolBase {
String coreName = cli.getOptionValue(COLLECTION_NAME_OPTION);
String solrUrl = CLIUtils.normalizeSolrUrl(cli);
- final String solrInstallDir = System.getProperty("solr.install.dir");
+ final String solrInstallDir = EnvUtils.getProperty("solr.install.dir");
final String confDirName =
cli.getOptionValue(CONF_DIR_OPTION, DefaultValues.DEFAULT_CONFIG_SET);
@@ -223,7 +224,7 @@ public class CreateTool extends ToolBase {
throws Exception {
String collectionName = cli.getOptionValue(COLLECTION_NAME_OPTION);
- final String solrInstallDir = System.getProperty("solr.install.dir");
+ final String solrInstallDir = EnvUtils.getProperty("solr.install.dir");
String confName = cli.getOptionValue(CONF_NAME_OPTION);
String confDir = cli.getOptionValue(CONF_DIR_OPTION, DefaultValues.DEFAULT_CONFIG_SET);
Path solrInstallDirPath = Path.of(solrInstallDir);
diff --git a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
index e3458c3232b..263fb7a7da2 100755
--- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
@@ -45,6 +45,7 @@ import org.apache.commons.cli.help.TextHelpAppendable;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.common.util.ContentStreamBase;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SuppressForbidden;
import org.apache.solr.util.configuration.SSLConfigurationsFactory;
@@ -143,7 +144,7 @@ public class SolrCLI implements CLIO {
argList.addAll(dashDList);
// for SSL support, try to accommodate relative paths set for SSL store props
- String solrInstallDir = System.getProperty("solr.install.dir");
+ String solrInstallDir = EnvUtils.getProperty("solr.install.dir");
if (solrInstallDir != null) {
checkSslStoreSysProp(solrInstallDir, "keyStore");
checkSslStoreSysProp(solrInstallDir, "trustStore");
@@ -154,7 +155,7 @@ public class SolrCLI implements CLIO {
protected static void checkSslStoreSysProp(String solrInstallDir, String key) {
String sysProp = "javax.net.ssl." + key;
- String keyStore = System.getProperty(sysProp);
+ String keyStore = EnvUtils.getProperty(sysProp);
if (keyStore == null) return;
Path keyStoreFile = Path.of(keyStore);
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java b/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
index 4bf9a266315..2edaccee9df 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
@@ -31,6 +31,7 @@ import org.apache.solr.client.solrj.impl.SolrZkClientTimeout;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.util.Compressor;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.common.util.ZLibCompressor;
import org.apache.solr.core.NodeConfig;
@@ -154,7 +155,7 @@ public class ZkCpTool extends ToolBase {
if (dstIsZk) {
String solrHome = cli.getOptionValue(SOLR_HOME_OPTION);
if (StrUtils.isNullOrEmpty(solrHome)) {
- solrHome = System.getProperty("solr.home");
+ solrHome = EnvUtils.getProperty("solr.home");
}
if (solrHome != null) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java b/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
index cdd3ae90f86..3bbb010f486 100644
--- a/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
+++ b/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
@@ -104,7 +104,7 @@ public class SolrZkServer {
var zooCfgPath = Path.of(confHome).resolve("zoo.cfg");
if (!Files.exists(zooCfgPath)) {
log.info("Zookeeper configuration not found in {}, using built-in default", confHome);
- String solrInstallDir = System.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
+ String solrInstallDir = EnvUtils.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
if (solrInstallDir == null) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
@@ -142,7 +142,7 @@ public class SolrZkServer {
}
ensureZkMaxCnxnsConfigured();
- if (System.getProperty(ZK_WHITELIST_PROPERTY) == null) {
+ if (EnvUtils.getProperty(ZK_WHITELIST_PROPERTY) == null) {
System.setProperty(ZK_WHITELIST_PROPERTY, "ruok, mntr, conf");
}
AtomicReference<Exception> zkException = new AtomicReference<>();
diff --git a/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginFactoryLoader.java b/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginFactoryLoader.java
index 4df4616648a..00ee44f67b3 100644
--- a/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginFactoryLoader.java
+++ b/solr/core/src/java/org/apache/solr/cluster/placement/impl/PlacementPluginFactoryLoader.java
@@ -29,6 +29,7 @@ import org.apache.solr.cluster.placement.plugins.MinimizeCoresPlacementFactory;
import org.apache.solr.cluster.placement.plugins.RandomPlacementFactory;
import org.apache.solr.cluster.placement.plugins.SimplePlacementFactory;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.EnvUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -102,7 +103,7 @@ public class PlacementPluginFactoryLoader {
/** Returns the default {@link PlacementPluginFactory} */
public static PlacementPluginFactory<?> getDefaultPlacementPluginFactory() {
// Use the default provided by system properties.
- String defaultPluginId = System.getProperty(PLACEMENTPLUGIN_DEFAULT_SYSPROP);
+ String defaultPluginId = EnvUtils.getProperty(PLACEMENTPLUGIN_DEFAULT_SYSPROP);
if (defaultPluginId != null) {
log.info(
"Default replica placement plugin set in {} to {}",
diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
index d88b15e0c44..6976e65c84b 100644
--- a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
+++ b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
@@ -137,7 +137,7 @@ public abstract class ConfigSetService {
log.warn(
"The _default configset could not be uploaded. Please provide 'solr.configset.default.confdir' parameter that points to a configset {} {}",
"intended to be the default. Current 'solr.configset.default.confdir' value:",
- System.getProperty(SOLR_CONFIGSET_DEFAULT_CONFDIR));
+ EnvUtils.getProperty(SOLR_CONFIGSET_DEFAULT_CONFDIR));
} else {
this.uploadConfig(ConfigSetsHandler.DEFAULT_CONFIGSET_NAME, configDirPath);
}
@@ -165,7 +165,7 @@ public abstract class ConfigSetService {
* @see ConfigSetService#SOLR_CONFIGSET_DEFAULT_CONFDIR
*/
public static Path getDefaultConfigDirPath() {
- String confDir = System.getProperty(SOLR_CONFIGSET_DEFAULT_CONFDIR);
+ String confDir = EnvUtils.getProperty(SOLR_CONFIGSET_DEFAULT_CONFDIR);
if (confDir != null) {
Path path = Path.of(confDir);
if (Files.exists(path)) {
@@ -173,7 +173,7 @@ public abstract class ConfigSetService {
}
}
- String installDir = System.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
+ String installDir = EnvUtils.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
if (installDir != null) {
Path subPath = Path.of("server", "solr", "configsets", "_default", "conf");
Path path = Path.of(installDir).resolve(subPath);
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 0eb7b4a576c..d79c3b7b794 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -289,7 +289,7 @@ public class CoreContainer {
private final ObjectCache objectCache = new ObjectCache();
- public final NodeRoles nodeRoles = new NodeRoles(System.getProperty(NodeRoles.NODE_ROLES_PROP));
+ public final NodeRoles nodeRoles = new NodeRoles(EnvUtils.getProperty(NodeRoles.NODE_ROLES_PROP));
private final ExecutorService indexSearcherExecutor;
@@ -555,14 +555,17 @@ public class CoreContainer {
if (pluginClassName != null) {
log.debug("Authentication plugin class obtained from security.json: {}", pluginClassName);
- } else if (System.getProperty(AUTHENTICATION_PLUGIN_PROP) != null) {
- pluginClassName = System.getProperty(AUTHENTICATION_PLUGIN_PROP);
- log.debug(
- "Authentication plugin class obtained from system property '{}': {}",
- AUTHENTICATION_PLUGIN_PROP,
- pluginClassName);
} else {
- log.debug("No authentication plugin used.");
+ String authPluginProp = EnvUtils.getProperty(AUTHENTICATION_PLUGIN_PROP);
+ if (authPluginProp != null) {
+ pluginClassName = authPluginProp;
+ log.debug(
+ "Authentication plugin class obtained from system property '{}': {}",
+ AUTHENTICATION_PLUGIN_PROP,
+ pluginClassName);
+ } else {
+ log.debug("No authentication plugin used.");
+ }
}
SecurityPluginHolder<AuthenticationPlugin> old = authenticationPlugin;
SecurityPluginHolder<AuthenticationPlugin> authenticationPlugin = null;
@@ -1140,7 +1143,7 @@ public class CoreContainer {
}
if (authenticationPlugin != null
- && StrUtils.isNullOrEmpty(System.getProperty("solr.jetty.https.port"))) {
+ && StrUtils.isNullOrEmpty(EnvUtils.getProperty("solr.jetty.https.port"))) {
log.warn(
"Solr authentication is enabled, but SSL is off. Consider enabling SSL to protect user credentials and data with encryption.");
}
@@ -1767,7 +1770,7 @@ public class CoreContainer {
CoreInitFailedAction action =
CoreInitFailedAction.valueOf(
- System.getProperty(CoreInitFailedAction.class.getSimpleName(), "none"));
+ EnvUtils.getProperty(CoreInitFailedAction.class.getSimpleName(), "none"));
log.debug("CorruptIndexException while creating core, will attempt to repair via {}", action);
switch (action) {
@@ -2499,7 +2502,7 @@ public class CoreContainer {
}
public static void setWeakStringInterner() {
- boolean enable = "true".equals(System.getProperty("solr.use.str.intern", "true"));
+ boolean enable = "true".equals(EnvUtils.getProperty("solr.use.str.intern", "true"));
if (!enable) return;
Interner<String> interner = Interner.newWeakInterner();
ClusterState.setStrInternerParser(
diff --git a/solr/core/src/java/org/apache/solr/core/NodeConfig.java b/solr/core/src/java/org/apache/solr/core/NodeConfig.java
index 1634c2c29e8..53e9a07315b 100644
--- a/solr/core/src/java/org/apache/solr/core/NodeConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/NodeConfig.java
@@ -294,7 +294,7 @@ public class NodeConfig {
* @return path to install dir or null if solr.install.dir not set.
*/
public static Path getSolrInstallDir() {
- String prop = System.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
+ String prop = EnvUtils.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
if (prop == null || prop.isBlank()) {
log.debug("solr.install.dir property not initialized.");
return null;
@@ -644,7 +644,7 @@ public class NodeConfig {
this.solrHome = solrHome.toAbsolutePath();
this.coreRootDirectory = solrHome;
// always init from sysprop because <solrDataHome> config element may be missing
- setSolrDataHome(System.getProperty(SolrXmlConfig.SOLR_DATA_HOME));
+ setSolrDataHome(EnvUtils.getProperty(SolrXmlConfig.SOLR_DATA_HOME));
setConfigSetBaseDirectory("configsets");
this.metricsConfig = new MetricsConfig.MetricsConfigBuilder().build();
}
diff --git a/solr/core/src/java/org/apache/solr/core/OpenTelemetryConfigurator.java b/solr/core/src/java/org/apache/solr/core/OpenTelemetryConfigurator.java
index 1be4b0deb6b..b134877c8e7 100644
--- a/solr/core/src/java/org/apache/solr/core/OpenTelemetryConfigurator.java
+++ b/solr/core/src/java/org/apache/solr/core/OpenTelemetryConfigurator.java
@@ -160,7 +160,7 @@ public abstract class OpenTelemetryConfigurator implements NamedListInitializedP
*/
protected static String getConfig(String envName, Map<String, String> env) {
String sysName = envNameToSyspropName(envName);
- String sysValue = System.getProperty(sysName);
+ String sysValue = EnvUtils.getProperty(sysName);
String envValue = env.get(envName);
return sysValue != null ? sysValue : envValue;
}
diff --git a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
index c4b801a28bc..aa9ba040bf9 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
@@ -87,7 +87,7 @@ public class SolrXmlConfig {
}
// we always wrap if we might set a property -- never mutate the original props
final Properties results = (null == props ? new Properties() : new Properties(props));
- final String sysprop = System.getProperty(ZK_HOST);
+ final String sysprop = EnvUtils.getProperty(ZK_HOST);
if (StrUtils.isNotNullOrEmpty(sysprop)) {
results.setProperty(ZK_HOST, sysprop);
}
@@ -179,7 +179,7 @@ public class SolrXmlConfig {
"solr.xml does not exist in " + configFile.getParent() + " cannot start Solr");
}
log.info("solr.xml not found in SOLR_HOME, using built-in default");
- String solrInstallDir = System.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
+ String solrInstallDir = EnvUtils.getProperty(CoreContainerProvider.SOLR_INSTALL_DIR);
if (solrInstallDir == null) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
diff --git a/solr/core/src/java/org/apache/solr/core/ZkContainer.java b/solr/core/src/java/org/apache/solr/core/ZkContainer.java
index a0c2ae569d5..70e4f33bb76 100644
--- a/solr/core/src/java/org/apache/solr/core/ZkContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/ZkContainer.java
@@ -134,7 +134,7 @@ public class ZkContainer {
new ZkController(cc, zookeeperHost, zkClientConnectTimeout, config);
if (zkRun) {
- if (StrUtils.isNotNullOrEmpty(System.getProperty(HTTPS_PORT_PROP))) {
+ if (StrUtils.isNotNullOrEmpty(EnvUtils.getProperty(HTTPS_PORT_PROP))) {
// Embedded ZK and probably running with SSL
new ClusterProperties(zkController.getZkClient())
.setClusterProperty(ZkStateReader.URL_SCHEME, HTTPS);
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SolrEnvironment.java b/solr/core/src/java/org/apache/solr/handler/admin/SolrEnvironment.java
index 1d289ce0422..c3a297b33f4 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SolrEnvironment.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SolrEnvironment.java
@@ -21,6 +21,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.util.EnvUtils;
/**
* It is possible to define an environment code when starting Solr, through
@@ -87,8 +88,8 @@ public class SolrEnvironment {
*/
public static SolrEnvironment getFromSyspropOrClusterprop(ZkStateReader zkStateReader) {
String env = "unknown";
- if (System.getProperty("solr.environment") != null) {
- env = System.getProperty("solr.environment");
+ if (EnvUtils.getProperty("solr.environment") != null) {
+ env = EnvUtils.getProperty("solr.environment");
} else if (zkStateReader != null) {
env = zkStateReader.getClusterProperty("environment", "unknown");
}
diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
index 574a0b266a3..8fb82603629 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
@@ -445,7 +445,8 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory
if (isSolrSslEnabled != null) {
return isSolrSslEnabled ? "https" : "http";
}
- String urlScheme = getParameter(args, INIT_URL_SCHEME, System.getProperty(INIT_URL_SCHEME), sb);
+ String urlScheme =
+ getParameter(args, INIT_URL_SCHEME, EnvUtils.getProperty(INIT_URL_SCHEME), sb);
if (urlScheme != null && urlScheme.endsWith("://")) {
urlScheme = urlScheme.replace("://", "");
}
diff --git a/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java b/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
index 19d06f392b7..6e1446a9397 100644
--- a/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
+++ b/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
@@ -153,13 +153,13 @@ public class CoreContainerProvider implements ServletContextListener {
logWelcomeBanner(extraProperties);
- String muteConsole = System.getProperty(SOLR_LOG_MUTECONSOLE);
+ String muteConsole = EnvUtils.getProperty(SOLR_LOG_MUTECONSOLE);
if (muteConsole != null
&& !Arrays.asList("false", "0", "off", "no")
.contains(muteConsole.toLowerCase(Locale.ROOT))) {
StartupLoggingUtils.muteConsole();
}
- String logLevel = System.getProperty(SOLR_LOG_LEVEL);
+ String logLevel = EnvUtils.getProperty(SOLR_LOG_LEVEL);
if (logLevel != null) {
log.info("Log level override, property solr.log.level={}", logLevel);
StartupLoggingUtils.changeLogLevel(logLevel);
@@ -208,7 +208,7 @@ public class CoreContainerProvider implements ServletContextListener {
getSolrPort());
}
if (log.isInfoEnabled()) {
- log.info("\\__ \\/ _ \\ | '_| Install dir: {}", System.getProperty(SOLR_INSTALL_DIR));
+ log.info("\\__ \\/ _ \\ | '_| Install dir: {}", EnvUtils.getProperty(SOLR_INSTALL_DIR));
}
if (log.isInfoEnabled()) {
log.info("|___/\\___/_|_| Start time: {}", Instant.now());
@@ -241,7 +241,7 @@ public class CoreContainerProvider implements ServletContextListener {
"Solr typically starts with \"-XX:+CrashOnOutOfMemoryError\" that will crash on any OutOfMemoryError exception. "
+ "Unable to get the specific file due to an exception."
+ "The cause of the OOME will be logged in a crash file in the logs directory: %s",
- System.getProperty("solr.logs.dir"));
+ EnvUtils.getProperty("solr.logs.dir"));
log.info(logMessage, e);
}
}
@@ -316,7 +316,7 @@ public class CoreContainerProvider implements ServletContextListener {
// Now try system property
final String prop = "solr.solr.home";
source = "system property: " + prop;
- home = System.getProperty(prop);
+ home = EnvUtils.getProperty(prop);
}
if (null == home) {
diff --git a/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java b/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java
index 316e0eb59ca..83b5ef3fd8e 100644
--- a/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java
+++ b/solr/core/src/java/org/apache/solr/servlet/LoadAdminUiServlet.java
@@ -30,6 +30,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.output.CloseShieldOutputStream;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.core.SolrCore;
/**
@@ -40,8 +41,7 @@ import org.apache.solr.core.SolrCore;
public final class LoadAdminUiServlet extends HttpServlet {
// check system properties for whether the admin UI is disabled, default is false
- private static final boolean uiEnabled =
- Boolean.parseBoolean(System.getProperty("solr.ui.enabled", "true"));
+ private static final boolean uiEnabled = EnvUtils.getPropertyAsBool("solr.ui.enabled", true);
// list of comma separated URLs to inject into the CSP connect-src directive
public static final String SYSPROP_CSP_CONNECT_SRC_URLS = "solr.ui.headers.csp.connect-src.urls";
@@ -107,7 +107,7 @@ public final class LoadAdminUiServlet extends HttpServlet {
* concatenate them into a space-separated string that can be used in CSP connect-src directive
*/
private String generateCspConnectSrc() {
- String cspURLs = System.getProperty(SYSPROP_CSP_CONNECT_SRC_URLS, "");
+ String cspURLs = EnvUtils.getProperty(SYSPROP_CSP_CONNECT_SRC_URLS, "");
List<String> props = new ArrayList<>(Arrays.asList(cspURLs.split(",")));
props.add("'self'");
return String.join(" ", props);
diff --git a/solr/core/src/java/org/apache/solr/util/FileTypeMagicUtil.java b/solr/core/src/java/org/apache/solr/util/FileTypeMagicUtil.java
index f9e349b3f25..c803ec18469 100644
--- a/solr/core/src/java/org/apache/solr/util/FileTypeMagicUtil.java
+++ b/solr/core/src/java/org/apache/solr/util/FileTypeMagicUtil.java
@@ -32,6 +32,7 @@ import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.EnvUtils;
/** Utility class to guess the mime type of file based on its magic number. */
public class FileTypeMagicUtil implements ContentInfoUtil.ErrorCallBack {
@@ -194,7 +195,7 @@ public class FileTypeMagicUtil implements ContentInfoUtil.ErrorCallBack {
private static final Set<String> forbiddenTypes =
new HashSet<>(
Arrays.asList(
- System.getProperty(
+ EnvUtils.getProperty(
"solr.configset.upload.mimetypes.forbidden",
"application/x-java-applet,application/zip,application/x-tar,text/x-shellscript")
.split(",")));
diff --git a/solr/core/src/java/org/apache/solr/util/StartupLoggingUtils.java b/solr/core/src/java/org/apache/solr/util/StartupLoggingUtils.java
index 8fbebffcdd3..5c76d4882fb 100644
--- a/solr/core/src/java/org/apache/solr/util/StartupLoggingUtils.java
+++ b/solr/core/src/java/org/apache/solr/util/StartupLoggingUtils.java
@@ -210,9 +210,11 @@ public final class StartupLoggingUtils {
* "solr.logs.requestlog.enabled is set in solr/server/etc/jetty-requestlog.xml
*/
public static void checkRequestLogging() {
- // EnvUtils doesn't work here.
+ // Note: "solr.logs.requestlog.enabled" is deliberately excluded from EnvUtils
+ // env var mapping (see EnvToSyspropMappings.properties), so Boolean.getBoolean
+ // is the correct way to read it (it only looks at system properties).
boolean requestLogEnabled = Boolean.getBoolean("solr.logs.requestlog.enabled");
- String retainDays = System.getProperty("solr.logs.requestlog.retain.days");
+ String retainDays = EnvUtils.getProperty("solr.logs.requestlog.retain.days");
if (requestLogEnabled) {
if (retainDays == null) {
log.warn(
diff --git a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java
index e0829e6857b..dbab15f9800 100644
--- a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java
+++ b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreaker.java
@@ -83,7 +83,7 @@ public abstract class CircuitBreaker implements NamedListInitializedPlugin, Clos
private static SolrException.ErrorCode resolveExceptionErrorCode() {
int intCode = SolrException.ErrorCode.TOO_MANY_REQUESTS.code;
- String strCode = System.getProperty(SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE);
+ String strCode = EnvUtils.getProperty(SYSPROP_SOLR_CIRCUITBREAKER_ERRORCODE);
if (strCode != null) {
try {
intCode = Integer.parseInt(strCode);
diff --git a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerRegistry.java b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerRegistry.java
index 16b2f9c752d..a86f2381719 100644
--- a/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerRegistry.java
+++ b/solr/core/src/java/org/apache/solr/util/circuitbreaker/CircuitBreakerRegistry.java
@@ -128,7 +128,7 @@ public class CircuitBreakerRegistry implements Closeable {
private static String buildCircuitBreakerKey(String metricType, String thresholdProp) {
final var warnOnly = EnvUtils.getProperty(thresholdProp + SYSPROP_WARN_ONLY_SUFFIX, "false");
- return metricType + ":" + System.getProperty(thresholdProp) + ":" + warnOnly;
+ return metricType + ":" + EnvUtils.getProperty(thresholdProp) + ":" + warnOnly;
}
private static synchronized void initGlobal(CoreContainer coreContainer) {
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
index 5d5758b7948..90663bd313b 100644
--- a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
@@ -19,6 +19,7 @@ package org.apache.solr.util.configuration;
import java.lang.invoke.MethodHandles;
import java.util.List;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.common.util.StrUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,7 +61,7 @@ public class SSLConfigurations {
String clientTruststorePassword = getClientTrustStorePassword();
String truststorePassword = getTrustStorePassword();
- if (StrUtils.isNullOrEmpty(System.getProperty(SysProps.SSL_CLIENT_KEY_STORE_PASSWORD))
+ if (StrUtils.isNullOrEmpty(EnvUtils.getProperty(SysProps.SSL_CLIENT_KEY_STORE_PASSWORD))
&& !(StrUtils.isNullOrEmpty(clientKeystorePassword)
&& StrUtils.isNullOrEmpty(keystorePassword))) {
log.info("Setting {}", SysProps.SSL_CLIENT_KEY_STORE_PASSWORD);
@@ -68,7 +69,7 @@ public class SSLConfigurations {
SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
clientKeystorePassword != null ? clientKeystorePassword : keystorePassword);
}
- if (StrUtils.isNullOrEmpty(System.getProperty(SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD))
+ if (StrUtils.isNullOrEmpty(EnvUtils.getProperty(SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD))
&& !(StrUtils.isNullOrEmpty(clientTruststorePassword)
&& StrUtils.isNullOrEmpty(truststorePassword))) {
log.info("Setting {}", SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD);
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
index a0c79eec230..74ae38d1c54 100644
--- a/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.util.configuration.providers.EnvSSLCredentialProvider;
import org.apache.solr.util.configuration.providers.SysPropSSLCredentialProvider;
import org.slf4j.Logger;
@@ -42,7 +43,7 @@ public class SSLCredentialProviderFactory {
private String providerChain;
public SSLCredentialProviderFactory() {
- this.providerChain = System.getProperty(PROVIDER_CHAIN_KEY, DEFAULT_PROVIDER_CHAIN);
+ this.providerChain = EnvUtils.getProperty(PROVIDER_CHAIN_KEY, DEFAULT_PROVIDER_CHAIN);
}
public SSLCredentialProviderFactory(String providerChain) {
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java b/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java
index 52831a32dd3..1c78d29cd7a 100644
--- a/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java
+++ b/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java
@@ -18,6 +18,7 @@
package org.apache.solr.util.configuration.providers;
import java.util.EnumMap;
+import org.apache.solr.common.util.EnvUtils;
/** System property based SSL configuration provider */
public class SysPropSSLCredentialProvider extends AbstractSSLCredentialProvider {
@@ -28,10 +29,6 @@ public class SysPropSSLCredentialProvider extends AbstractSSLCredentialProvider
@Override
protected String getCredential(String syspropKey) {
- if (System.getProperty(syspropKey) != null) {
- return System.getProperty(syspropKey);
- } else {
- return null;
- }
+ return EnvUtils.getProperty(syspropKey);
}
}
diff --git a/solr/core/src/java/org/apache/solr/util/tracing/SimplePropagator.java b/solr/core/src/java/org/apache/solr/util/tracing/SimplePropagator.java
index 51944b08703..a626e55f707 100644
--- a/solr/core/src/java/org/apache/solr/util/tracing/SimplePropagator.java
+++ b/solr/core/src/java/org/apache/solr/util/tracing/SimplePropagator.java
@@ -25,6 +25,7 @@ import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.solr.common.util.EnvUtils;
import org.apache.solr.logging.MDCLoggingContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,11 +42,11 @@ public class SimplePropagator implements TextMapPropagator {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String TRACE_HOST_NAME =
- System.getProperty("solr.traceHostName", System.getProperty("host"));
+ EnvUtils.getProperty("solr.traceHostName", EnvUtils.getProperty("host"));
private static final TextMapPropagator INSTANCE = new SimplePropagator();
private static final ContextKey<String> TRACE_ID_KEY = ContextKey.named("trace_id");
- static final String TRACE_ID = System.getProperty("solr.traceIdHeader", "X-Trace-Id");
+ static final String TRACE_ID = EnvUtils.getProperty("solr.traceIdHeader", "X-Trace-Id");
private static final List<String> FIELDS = List.of(TRACE_ID);
private static final AtomicLong traceCounter = new AtomicLong(0);