ソースを参照

Fix Build to correctly treat URLs and not leak a file handle.

Closes #14595

Squashed commit of the following:

commit d0b2b262e9dcdbc2aee163b9a84db082c8b5b96b
Author: Robert Muir <rmuir@apache.org>
Date:   Fri Nov 6 22:36:54 2015 -0500

    Switch to JarInputStream, to contain suppressforbidden. Also add a test that fails if path is not accessible (regardless of whether its a jar)

commit f99c1d240db23ceb2a06987b3bd69eae0229550b
Author: Robert Muir <rmuir@apache.org>
Date:   Fri Nov 6 22:16:16 2015 -0500

    remove leniency in i/o here

commit b160d4303ee81a8c9298729596ecbc893f5f8894
Author: Robert Muir <rmuir@apache.org>
Date:   Fri Nov 6 21:58:21 2015 -0500

    Fix Build to correctly treat URLs and to not leak a file handle
Robert Muir 10 年 前
コミット
f03196193f

+ 34 - 12
core/src/main/java/org/elasticsearch/Build.java

@@ -20,37 +20,59 @@
 package org.elasticsearch;
 
 import org.elasticsearch.common.SuppressForbidden;
+import org.elasticsearch.common.io.PathUtils;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 
 import java.io.IOException;
-import java.util.jar.JarFile;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
 
 /**
  */
-@SuppressForbidden(reason = "needs JarFile to read the manifest")
 public class Build {
 
     public static final Build CURRENT;
 
     static {
-        String shortHash = "Unknown";
-        String date = "Unknown";
+        final String shortHash;
+        final String date;
 
-        String path = Build.class.getProtectionDomain().getCodeSource().getLocation().getPath();
-        try {
-            JarFile jar = new JarFile(path);
-            Manifest manifest = jar.getManifest();
-            shortHash = manifest.getMainAttributes().getValue("Change");
-            date = manifest.getMainAttributes().getValue("Build-Date");
-        } catch (IOException e) {
-            // just ignore...
+        Path path = getElasticsearchCodebase();
+        if (path.toString().endsWith(".jar")) {
+            try (JarInputStream jar = new JarInputStream(Files.newInputStream(path))) {
+                Manifest manifest = jar.getManifest();
+                shortHash = manifest.getMainAttributes().getValue("Change");
+                date = manifest.getMainAttributes().getValue("Build-Date");
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            // not running from a jar (unit tests, IDE)
+            shortHash = "Unknown";
+            date = "Unknown";
         }
 
         CURRENT = new Build(shortHash, date);
     }
 
+    /**
+     * Returns path to elasticsearch codebase path
+     */
+    @SuppressForbidden(reason = "looks up path of elasticsearch.jar directly")
+    static Path getElasticsearchCodebase() {
+        URL url = Build.class.getProtectionDomain().getCodeSource().getLocation();
+        try {
+            return PathUtils.get(url.toURI());
+        } catch (URISyntaxException bogus) {
+            throw new RuntimeException(bogus);
+        }
+    }
+
     private String shortHash;
     private String date;
 

+ 1 - 1
core/src/main/java/org/elasticsearch/indices/memory/IndexingMemoryController.java

@@ -390,7 +390,7 @@ public class IndexingMemoryController extends AbstractLifecycleComponent<Indexin
     /** ask this shard to check now whether it is inactive, and reduces its indexing and translog buffers if so.  returns Boolean.TRUE if
      *  it did deactive, Boolean.FALSE if it did not, and null if the shard is unknown */
     protected Boolean checkIdle(ShardId shardId) {
-        final String ignoreReason;
+        String ignoreReason; // eclipse compiler does not know it is really final
         final IndexShard shard = getShard(shardId);
         if (shard != null) {
             try {

+ 39 - 0
core/src/test/java/org/elasticsearch/BuildTests.java

@@ -0,0 +1,39 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch;
+
+import org.elasticsearch.test.ESTestCase;
+
+import java.io.IOException;
+import java.nio.file.AccessMode;
+import java.nio.file.Path;
+
+public class BuildTests extends ESTestCase {
+
+    /** Asking for the jar metadata should not throw exception in tests, no matter how configured */
+    public void testJarMetadata() throws IOException {
+        Path path = Build.getElasticsearchCodebase();
+        // throws exception if does not exist, or we cannot access it
+        path.getFileSystem().provider().checkAccess(path, AccessMode.READ);
+        // these should never be null
+        assertNotNull(Build.CURRENT.date());
+        assertNotNull(Build.CURRENT.shortHash());
+    }
+}