diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 8286065dffe..df7db59b977 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -223,6 +223,8 @@ Bug Fixes * SOLR-11971: Don't allow referal to external resources in DataImportHandler's dataConfig request parameter. (麦 香浓郁, Uwe Schindler) +* SOLR-12021: Fixed a bug in ApiSpec and other JSON resource loading that was causing unclosed file handles (hossman) + Optimizations ---------------------- diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java index 4ab24d2be3e..d35486e6c76 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java @@ -23,6 +23,7 @@ import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.lang.invoke.MethodHandles; +import java.net.URL; import java.net.URLDecoder; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; @@ -200,9 +201,17 @@ public class Utils { } } - public static Object fromJSONResource(String resourceName){ - return fromJSON(Utils.class.getClassLoader().getResourceAsStream(resourceName)); - + public static Object fromJSONResource(String resourceName) { + final URL resource = Utils.class.getClassLoader().getResource(resourceName); + if (null == resource) { + throw new IllegalArgumentException("invalid resource name: " + resourceName); + } + try (InputStream stream = resource.openStream()) { + return fromJSON(stream); + } catch (IOException e) { + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, + "Resource error: " + e.getMessage(), e); + } } public static JSONParser getJSONParser(Reader reader){ JSONParser parser = new JSONParser(reader); diff --git a/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java b/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java index 4edef90b43d..28c001935df 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/ValidatingJsonMap.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -313,17 +314,22 @@ public class ValidatingJsonMap implements Map { } public static ValidatingJsonMap parse(String resourceName, String includeLocation) { - InputStream is = ValidatingJsonMap.class.getClassLoader().getResourceAsStream(resourceName); - if (is == null) + final URL resource = ValidatingJsonMap.class.getClassLoader().getResource(resourceName); + if (null == resource) { throw new RuntimeException("invalid API spec: " + resourceName); + } ValidatingJsonMap map = null; - try { - map = fromJSON(is, includeLocation); - } catch (Exception e) { - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error in JSON : " + resourceName, e); + try (InputStream is = resource.openStream()) { + try { + map = fromJSON(is, includeLocation); + } catch (Exception e) { + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error in JSON : " + resourceName, e); + } + } catch (IOException ioe) { + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, + "Unable to read resource: " + resourceName, ioe); } if (map == null) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Empty value for " + resourceName); - return getDeepCopy(map, 5, false); }