From 974c7491782da4072f684881150a222fa3f77ab3 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Wed, 18 Jan 2023 17:06:14 -0500 Subject: [PATCH 01/11] SOLR-16628: Ensure that InputStreams are closed after Xml parsing --- .../src/java/org/apache/solr/core/SolrConfig.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/core/SolrConfig.java b/solr/core/src/java/org/apache/solr/core/SolrConfig.java index a3be18156c5..cce7d5bda8b 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrConfig.java +++ b/solr/core/src/java/org/apache/solr/core/SolrConfig.java @@ -172,8 +172,8 @@ private class ResourceProvider implements Function { InputStream in; String fileName; - ResourceProvider(SolrResourceLoader loader, String res) throws IOException { - this.in = loader.openResource(res); + ResourceProvider(InputStream in) throws IOException { + this.in = in; if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) { ZkSolrResourceLoader.ZkByteArrayInputStream zkin = (ZkSolrResourceLoader.ZkByteArrayInputStream) in; @@ -393,14 +393,22 @@ private SolrConfig( } private IndexSchemaFactory.VersionedConfig readXml(SolrResourceLoader loader, String name) { + InputStream in = null; try { - ResourceProvider rp = new ResourceProvider(loader, name); + in = loader.openResource(name); + ResourceProvider rp = new ResourceProvider(in); XmlConfigFile xml = new XmlConfigFile(loader, rp, name, null, "/config/", null); return new IndexSchemaFactory.VersionedConfig( rp.zkVersion, new DataConfigNode(new DOMConfigNode(xml.getDocument().getDocumentElement()))); } catch (IOException e) { throw new SolrException(ErrorCode.SERVER_ERROR, e); + } finally { + // according to spec, XML parser should close InputStream when parsing is complete. + // But in the event that this doesn't happen (either because an exception is + // thrown or because of an error in parser implementation, here we ensure that it + // is closed. + IOUtils.closeQuietly(in); } } From f198643ed7bb858c135e16e862608ab58f210996 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Wed, 18 Jan 2023 17:18:44 -0500 Subject: [PATCH 02/11] close InputStream within XmlConfigFile ctor as well (instead?) --- .../src/java/org/apache/solr/core/XmlConfigFile.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java b/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java index 080e2ee0bd6..53b41c255b4 100644 --- a/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java +++ b/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java @@ -38,6 +38,7 @@ import org.apache.solr.cloud.ZkSolrResourceLoader; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.DOMUtil; +import org.apache.solr.common.util.IOUtils; import org.apache.solr.util.SafeXMLParsing; import org.apache.solr.util.SystemIdResolver; import org.slf4j.Logger; @@ -119,9 +120,10 @@ public XmlConfigFile( this.name = name; this.prefix = (prefix != null && !prefix.endsWith("/")) ? prefix + '/' : prefix; + InputStream in = null; try { if (is == null && fileSupplier != null) { - InputStream in = fileSupplier.apply(name); + in = fileSupplier.apply(name); if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) { zkVersion = ((ZkSolrResourceLoader.ZkByteArrayInputStream) in).getStat().getVersion(); log.debug("loaded config {} with version {} ", name, zkVersion); @@ -138,6 +140,12 @@ public XmlConfigFile( } catch (SAXException e) { SolrException.log(log, "Exception during parsing file: " + name, e); throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); + } finally { + // according to spec, XML parser should close InputStream when parsing is complete. + // But in the event that this doesn't happen (either because an exception is + // thrown or because of an error in parser implementation, here we ensure that it + // is closed. + IOUtils.closeQuietly(in); } if (substituteProps != null) { DOMUtil.substituteProperties(doc, getSubstituteProperties()); From b6487869eec05cad5478fea05fc8bf224ccb8129 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 09:44:24 -0500 Subject: [PATCH 03/11] use try-with-resources where possible --- .../core/src/java/org/apache/solr/core/SolrConfig.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/core/SolrConfig.java b/solr/core/src/java/org/apache/solr/core/SolrConfig.java index cce7d5bda8b..5d4ed3aba29 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrConfig.java +++ b/solr/core/src/java/org/apache/solr/core/SolrConfig.java @@ -393,9 +393,7 @@ private SolrConfig( } private IndexSchemaFactory.VersionedConfig readXml(SolrResourceLoader loader, String name) { - InputStream in = null; - try { - in = loader.openResource(name); + try (InputStream in = loader.openResource(name)) { ResourceProvider rp = new ResourceProvider(in); XmlConfigFile xml = new XmlConfigFile(loader, rp, name, null, "/config/", null); return new IndexSchemaFactory.VersionedConfig( @@ -403,12 +401,6 @@ private IndexSchemaFactory.VersionedConfig readXml(SolrResourceLoader loader, St new DataConfigNode(new DOMConfigNode(xml.getDocument().getDocumentElement()))); } catch (IOException e) { throw new SolrException(ErrorCode.SERVER_ERROR, e); - } finally { - // according to spec, XML parser should close InputStream when parsing is complete. - // But in the event that this doesn't happen (either because an exception is - // thrown or because of an error in parser implementation, here we ensure that it - // is closed. - IOUtils.closeQuietly(in); } } From 9507e1ae3be06daaf7400fa41e77a75d3fb55981 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 09:45:10 -0500 Subject: [PATCH 04/11] prefer a more succinct comment --- solr/core/src/java/org/apache/solr/core/XmlConfigFile.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java b/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java index 53b41c255b4..3433635002d 100644 --- a/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java +++ b/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java @@ -141,10 +141,7 @@ public XmlConfigFile( SolrException.log(log, "Exception during parsing file: " + name, e); throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); } finally { - // according to spec, XML parser should close InputStream when parsing is complete. - // But in the event that this doesn't happen (either because an exception is - // thrown or because of an error in parser implementation, here we ensure that it - // is closed. + // XML Parser should close but in exceptional cases might not; so let's be safe IOUtils.closeQuietly(in); } if (substituteProps != null) { From cd4923ff78ae43d80b2b43029ff282e5322a8e13 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 09:54:12 -0500 Subject: [PATCH 05/11] ensure schema InputStream is always closed --- .../solr/schema/IndexSchemaFactory.java | 3 +- .../schema/ManagedIndexSchemaFactory.java | 154 +++++++++--------- 2 files changed, 81 insertions(+), 76 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java index f3690e9aee1..2b6fce05316 100644 --- a/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java @@ -134,8 +134,7 @@ public static ConfigSetService.ConfigResource getConfigResource( private static VersionedConfig loadConfig( InputStream schemaInputStream, SolrResourceLoader loader, String name) { - try { - InputStream is = (schemaInputStream == null ? loader.openResource(name) : schemaInputStream); + try (InputStream is = (schemaInputStream == null ? loader.openResource(name) : schemaInputStream)) { ConfigNode node = getParsedSchema(is, loader, name); int version = is instanceof ZkSolrResourceLoader.ZkByteArrayInputStream 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 7dd6a81ebc9..4d114218663 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -198,88 +198,94 @@ public ManagedIndexSchema create( this.loader = config.getResourceLoader(); InputStream schemaInputStream = null; - if (null == resourceName) { - resourceName = IndexSchema.DEFAULT_SCHEMA_FILE; - } - - int schemaZkVersion = -1; - if (!(loader instanceof ZkSolrResourceLoader)) { - schemaInputStream = readSchemaLocally(); - } else { // ZooKeeper - final ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) loader; - final SolrZkClient zkClient = zkLoader.getZkController().getZkClient(); - final String managedSchemaPath = lookupZKManagedSchemaPath(); - managedSchemaResourceName = - managedSchemaPath.substring(managedSchemaPath.lastIndexOf("/") + 1); // not loving this - Stat stat = new Stat(); - try { - // Attempt to load the managed schema - byte[] data = zkClient.getData(managedSchemaPath, null, stat, true); - schemaZkVersion = stat.getVersion(); - schemaInputStream = - new ZkSolrResourceLoader.ZkByteArrayInputStream(data, managedSchemaPath, stat); - loadedResource = managedSchemaResourceName; - warnIfNonManagedSchemaExists(); - } catch (InterruptedException e) { - // Restore the interrupted status - Thread.currentThread().interrupt(); - log.warn("", e); - } catch (KeeperException.NoNodeException e) { - log.info( - "The schema is configured as managed, but managed schema resource {} not found - loading non-managed schema {} instead", - managedSchemaResourceName, - resourceName); - } catch (KeeperException e) { - String msg = "Error attempting to access " + managedSchemaPath; - log.error(msg, e); - throw new SolrException(ErrorCode.SERVER_ERROR, msg, e); + try { + if (null == resourceName) { + resourceName = IndexSchema.DEFAULT_SCHEMA_FILE; } - if (null == schemaInputStream) { - // The managed schema file could not be found - load the non-managed schema + + int schemaZkVersion = -1; + if (!(loader instanceof ZkSolrResourceLoader)) { + schemaInputStream = readSchemaLocally(); + } else { // ZooKeeper + final ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) loader; + final SolrZkClient zkClient = zkLoader.getZkController().getZkClient(); + final String managedSchemaPath = lookupZKManagedSchemaPath(); + managedSchemaResourceName = + managedSchemaPath.substring(managedSchemaPath.lastIndexOf("/") + 1); // not loving this + Stat stat = new Stat(); try { - schemaInputStream = loader.openResource(resourceName); - loadedResource = resourceName; - shouldUpgrade = true; - } catch (IOException e) { + // Attempt to load the managed schema + byte[] data = zkClient.getData(managedSchemaPath, null, stat, true); + schemaZkVersion = stat.getVersion(); + schemaInputStream = + new ZkSolrResourceLoader.ZkByteArrayInputStream(data, managedSchemaPath, stat); + loadedResource = managedSchemaResourceName; + warnIfNonManagedSchemaExists(); + } catch (InterruptedException e) { + // Restore the interrupted status + Thread.currentThread().interrupt(); + log.warn("", e); + } catch (KeeperException.NoNodeException e) { + log.info( + "The schema is configured as managed, but managed schema resource {} not found - loading non-managed schema {} instead", + managedSchemaResourceName, + resourceName); + } catch (KeeperException e) { + String msg = "Error attempting to access " + managedSchemaPath; + log.error(msg, e); + throw new SolrException(ErrorCode.SERVER_ERROR, msg, e); + } + if (null == schemaInputStream) { + // The managed schema file could not be found - load the non-managed schema try { - // Retry to load the managed schema, in case it was created since the first attempt - byte[] data = zkClient.getData(managedSchemaPath, null, stat, true); - schemaZkVersion = stat.getVersion(); - schemaInputStream = new ByteArrayInputStream(data); - loadedResource = managedSchemaPath; - warnIfNonManagedSchemaExists(); - } catch (Exception e1) { - if (e1 instanceof InterruptedException) { - Thread.currentThread().interrupt(); // Restore the interrupted status + schemaInputStream = loader.openResource(resourceName); + loadedResource = resourceName; + shouldUpgrade = true; + } catch (IOException e) { + try { + // Retry to load the managed schema, in case it was created since the first attempt + byte[] data = zkClient.getData(managedSchemaPath, null, stat, true); + schemaZkVersion = stat.getVersion(); + schemaInputStream = new ByteArrayInputStream(data); + loadedResource = managedSchemaPath; + warnIfNonManagedSchemaExists(); + } catch (Exception e1) { + if (e1 instanceof InterruptedException) { + Thread.currentThread().interrupt(); // Restore the interrupted status + } + final String msg = + "Error loading both non-managed schema '" + + resourceName + + "' and managed schema '" + + managedSchemaResourceName + + "'"; + log.error(msg, e); + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, msg, e); } - final String msg = - "Error loading both non-managed schema '" - + resourceName - + "' and managed schema '" - + managedSchemaResourceName - + "'"; - log.error(msg, e); - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, msg, e); } } } + InputSource inputSource = new InputSource(schemaInputStream); + inputSource.setSystemId(SystemIdResolver.createSystemIdFromResourceName(loadedResource)); + try { + schema = + new ManagedIndexSchema( + config, + loadedResource, + IndexSchemaFactory.getConfigResource( + configSetService, schemaInputStream, loader, managedSchemaResourceName), + isMutable, + managedSchemaResourceName, + schemaZkVersion, + getSchemaUpdateLock()); + } catch (Exception e) { + throw new SolrException(ErrorCode.SERVER_ERROR, "Error loading parsing schema", e); + } + } finally { + // XML Parser should close but in exceptional cases might not; so let's be safe + IOUtils.closeQuietly(schemaInputStream); } - InputSource inputSource = new InputSource(schemaInputStream); - inputSource.setSystemId(SystemIdResolver.createSystemIdFromResourceName(loadedResource)); - try { - schema = - new ManagedIndexSchema( - config, - loadedResource, - IndexSchemaFactory.getConfigResource( - configSetService, schemaInputStream, loader, managedSchemaResourceName), - isMutable, - managedSchemaResourceName, - schemaZkVersion, - getSchemaUpdateLock()); - } catch (Exception e) { - throw new SolrException(ErrorCode.SERVER_ERROR, "Error loading parsing schema", e); - } + if (shouldUpgrade) { // Persist the managed schema if it doesn't already exist synchronized (schema.getSchemaUpdateLock()) { From f12517d7d7020910b664f0771b613e2f4ecb9778 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 10:38:56 -0500 Subject: [PATCH 06/11] spotlessApply fix formatting issue --- .../src/java/org/apache/solr/schema/IndexSchemaFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java index 2b6fce05316..594d8620f49 100644 --- a/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java @@ -134,7 +134,8 @@ public static ConfigSetService.ConfigResource getConfigResource( private static VersionedConfig loadConfig( InputStream schemaInputStream, SolrResourceLoader loader, String name) { - try (InputStream is = (schemaInputStream == null ? loader.openResource(name) : schemaInputStream)) { + try (InputStream is = + (schemaInputStream == null ? loader.openResource(name) : schemaInputStream)) { ConfigNode node = getParsedSchema(is, loader, name); int version = is instanceof ZkSolrResourceLoader.ZkByteArrayInputStream From 3a047d404b4e994865711229329a7461a751897b Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 11:19:22 -0500 Subject: [PATCH 07/11] `loadedResource` can and should be a local, not instance, variable --- .../solr/schema/ManagedIndexSchemaFactory.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 4d114218663..d3783173c7f 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -76,7 +76,6 @@ public SolrResourceLoader getResourceLoader() { private SolrCore core; private ZkIndexSchemaReader zkIndexSchemaReader; - private String loadedResource; private boolean shouldUpgrade = false; @Override @@ -197,6 +196,7 @@ public ManagedIndexSchema create( this.config = config; this.loader = config.getResourceLoader(); InputStream schemaInputStream = null; + String loadedResource = null; try { if (null == resourceName) { @@ -205,7 +205,9 @@ public ManagedIndexSchema create( int schemaZkVersion = -1; if (!(loader instanceof ZkSolrResourceLoader)) { - schemaInputStream = readSchemaLocally(); + String[] loadedResourceRef = new String[1]; + schemaInputStream = readSchemaLocally(loadedResourceRef); + loadedResource = loadedResourceRef[0]; } else { // ZooKeeper final ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) loader; final SolrZkClient zkClient = zkLoader.getZkController().getZkClient(); @@ -265,6 +267,7 @@ public ManagedIndexSchema create( } } } + assert loadedResource != null; InputSource inputSource = new InputSource(schemaInputStream); inputSource.setSystemId(SystemIdResolver.createSystemIdFromResourceName(loadedResource)); try { @@ -296,8 +299,9 @@ public ManagedIndexSchema create( return schema; } - private InputStream readSchemaLocally() { + private InputStream readSchemaLocally(String[] loadedResourceRef) { InputStream schemaInputStream = null; + String loadedResource = null; try { // Attempt to load the managed schema final Path managedSchemaPath = lookupLocalManagedSchemaPath(); @@ -329,6 +333,8 @@ private InputStream readSchemaLocally() { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, msg, e); } } + assert loadedResource != null; + loadedResourceRef[0] = loadedResource; return schemaInputStream; } From a14fc44849f0b6bed1eda6814d1cf9fd675281b3 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 14:26:52 -0500 Subject: [PATCH 08/11] annotate ManagedIndexSchemaFactory class as NotThreadSafe --- solr/core/build.gradle | 2 ++ .../java/org/apache/solr/schema/ManagedIndexSchemaFactory.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/solr/core/build.gradle b/solr/core/build.gradle index 1031ecf1740..0d2b6b59193 100644 --- a/solr/core/build.gradle +++ b/solr/core/build.gradle @@ -115,6 +115,8 @@ dependencies { implementation 'commons-cli:commons-cli' + implementation 'net.jcip:jcip-annotations' + implementation 'org.locationtech.spatial4j:spatial4j' implementation 'com.fasterxml.jackson.core:jackson-annotations' 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 d3783173c7f..fc8b9263c45 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -24,6 +24,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; + +import net.jcip.annotations.NotThreadSafe; import org.apache.commons.io.IOUtils; import org.apache.solr.cloud.ZkController; import org.apache.solr.cloud.ZkSolrResourceLoader; @@ -48,6 +50,7 @@ import org.xml.sax.InputSource; /** Factory for ManagedIndexSchema */ +@NotThreadSafe public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements SolrCoreAware { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); public static final String UPGRADED_SCHEMA_EXTENSION = ".bak"; From 3ee812ef5624882804d6766d8b12a4e006d4613d Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 19 Jan 2023 16:01:45 -0500 Subject: [PATCH 09/11] reformat imports with spotlessApply --- .../java/org/apache/solr/schema/ManagedIndexSchemaFactory.java | 1 - 1 file changed, 1 deletion(-) 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 fc8b9263c45..1b3d8b8645b 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -24,7 +24,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; - import net.jcip.annotations.NotThreadSafe; import org.apache.commons.io.IOUtils; import org.apache.solr.cloud.ZkController; From 6216132d940c514c80bc4b69708dbe6d25823bb1 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Thu, 26 Jan 2023 10:10:59 -0500 Subject: [PATCH 10/11] add CHANGES.txt entry for 9.2.0 --- solr/CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 8f5bcafe43a..506d4603a34 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -176,6 +176,8 @@ Bug Fixes * SOLR-16621: Admin UI fails to grant user permissions that have wildcard role (janhoy) +* SOLR-16628: Ensure that InputStreams are closed after Xml parsing (Michael Gibney, David Smiley, Kevin Risden) + Build --------------------- * Upgrade forbiddenapis to 3.4 (Uwe Schindler) From 39c5620cd8f7ae96f98dde384b443ebe6d6ff318 Mon Sep 17 00:00:00 2001 From: Michael Gibney Date: Fri, 27 Jan 2023 13:57:06 -0500 Subject: [PATCH 11/11] avoid passing schema resource by array arg side-effect --- .../solr/schema/ManagedIndexSchemaFactory.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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 1b3d8b8645b..15db3cd9837 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -24,6 +24,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Map.Entry; import net.jcip.annotations.NotThreadSafe; import org.apache.commons.io.IOUtils; import org.apache.solr.cloud.ZkController; @@ -207,9 +209,9 @@ public ManagedIndexSchema create( int schemaZkVersion = -1; if (!(loader instanceof ZkSolrResourceLoader)) { - String[] loadedResourceRef = new String[1]; - schemaInputStream = readSchemaLocally(loadedResourceRef); - loadedResource = loadedResourceRef[0]; + Entry localSchemaInput = readSchemaLocally(); + loadedResource = localSchemaInput.getKey(); + schemaInputStream = localSchemaInput.getValue(); } else { // ZooKeeper final ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) loader; final SolrZkClient zkClient = zkLoader.getZkController().getZkClient(); @@ -301,7 +303,7 @@ public ManagedIndexSchema create( return schema; } - private InputStream readSchemaLocally(String[] loadedResourceRef) { + private Entry readSchemaLocally() { InputStream schemaInputStream = null; String loadedResource = null; try { @@ -336,8 +338,7 @@ private InputStream readSchemaLocally(String[] loadedResourceRef) { } } assert loadedResource != null; - loadedResourceRef[0] = loadedResource; - return schemaInputStream; + return new SimpleImmutableEntry<>(loadedResource, schemaInputStream); } /** Return whether a non-managed schema exists, either in local storage or on ZooKeeper. */