Explorar o código

HADOOP-12615. Fix NPE in MiniKMS.start(). Contributed by Wei-Chiu Chuang.

Change-Id: Ie3e148bd1401618b1737a577957298bf622891f4
Zhe Zhang %!s(int64=9) %!d(string=hai) anos
pai
achega
f5756a2038

+ 2 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -543,6 +543,8 @@ Trunk (Unreleased)
     HADOOP-12638. UnsatisfiedLinkError while checking ISA-L in checknative
     command. (Kai Sasaki via Colin P. McCabe)
 
+    HADOOP-12615. Fix NPE in MiniKMS.start(). (Wei-Chiu Chuang via zhz)
+
   OPTIMIZATIONS
 
     HADOOP-7761. Improve the performance of raw comparisons. (todd)

+ 30 - 0
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ThreadUtil.java

@@ -22,6 +22,9 @@ import org.apache.commons.logging.LogFactory;
 
 import org.apache.hadoop.classification.InterfaceStability;
 
+import java.io.IOException;
+import java.io.InputStream;
+
 @InterfaceStability.Evolving
 public class ThreadUtil {
   
@@ -46,4 +49,31 @@ public class ThreadUtil {
       }
     }
   }
+
+  /**
+   * Convenience method that returns a resource as inputstream from the
+   * classpath.
+   * <p>
+   * It first attempts to use the Thread's context classloader and if not
+   * set it uses the class' classloader.
+   *
+   * @param resourceName resource to retrieve.
+   *
+   * @throws IOException thrown if resource cannot be loaded
+   * @return inputstream with the resource.
+   */
+  public static InputStream getResourceAsStream(String resourceName)
+      throws IOException {
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    if (cl == null) {
+      throw new IOException("Can not read resource file '" + resourceName +
+          "' because class loader of the current thread is null");
+    }
+    InputStream is = cl.getResourceAsStream(resourceName);
+    if (is == null) {
+      throw new IOException("Can not read resource file '" +
+          resourceName + "'");
+    }
+    return is;
+  }
 }

+ 1 - 5
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/VersionInfo.java

@@ -43,11 +43,7 @@ public class VersionInfo {
     String versionInfoFile = component + "-version-info.properties";
     InputStream is = null;
     try {
-      is = Thread.currentThread().getContextClassLoader()
-        .getResourceAsStream(versionInfoFile);
-      if (is == null) {
-        throw new IOException("Resource not found");
-      }
+      is = ThreadUtil.getResourceAsStream(versionInfoFile);
       info.load(is);
     } catch (IOException ex) {
       LogFactory.getLog(getClass()).warn("Could not read '" +

+ 18 - 10
hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java

@@ -23,6 +23,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.security.ssl.SslSocketConnectorSecure;
+import org.apache.hadoop.util.ThreadUtil;
 import org.mortbay.jetty.Connector;
 import org.mortbay.jetty.Server;
 import org.mortbay.jetty.security.SslSocketConnector;
@@ -34,6 +35,7 @@ import java.io.FileWriter;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
+import java.io.IOException;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
 import java.net.ServerSocket;
@@ -149,16 +151,26 @@ public class MiniKMS {
     this.inPort = inPort;
   }
 
+  private void copyResource(String inputResourceName, File outputFile) throws
+      IOException {
+    InputStream is = null;
+    OutputStream os = null;
+    try {
+      is = ThreadUtil.getResourceAsStream(inputResourceName);
+      os = new FileOutputStream(outputFile);
+      IOUtils.copy(is, os);
+    } finally {
+      IOUtils.closeQuietly(is);
+      IOUtils.closeQuietly(os);
+    }
+  }
+
   public void start() throws Exception {
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     System.setProperty(KMSConfiguration.KMS_CONFIG_DIR, kmsConfDir);
     File aclsFile = new File(kmsConfDir, "kms-acls.xml");
     if (!aclsFile.exists()) {
-      InputStream is = cl.getResourceAsStream("mini-kms-acls-default.xml");
-      OutputStream os = new FileOutputStream(aclsFile);
-      IOUtils.copy(is, os);
-      is.close();
-      os.close();
+      copyResource("mini-kms-acls-default.xml", aclsFile);
     }
     File coreFile = new File(kmsConfDir, "core-site.xml");
     if (!coreFile.exists()) {
@@ -195,11 +207,7 @@ public class MiniKMS {
           "/kms-webapp/WEB-INF");
       webInf.mkdirs();
       new File(webInf, "web.xml").delete();
-      InputStream is = cl.getResourceAsStream("kms-webapp/WEB-INF/web.xml");
-      OutputStream os = new FileOutputStream(new File(webInf, "web.xml"));
-      IOUtils.copy(is, os);
-      is.close();
-      os.close();
+      copyResource("kms-webapp/WEB-INF/web.xml", new File(webInf, "web.xml"));
       webappPath = webInf.getParentFile().getAbsolutePath();
     } else {
       webappPath = cl.getResource("kms-webapp").getPath();

+ 10 - 4
hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSAudit.java

@@ -19,11 +19,15 @@ package org.apache.hadoop.crypto.key.kms.server;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FilterOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
 
 import org.apache.hadoop.crypto.key.kms.server.KMS.KMSOp;
+import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.util.ThreadUtil;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.PropertyConfigurator;
 import org.junit.After;
@@ -52,15 +56,17 @@ public class TestKMSAudit {
   }
 
   @Before
-  public void setUp() {
+  public void setUp() throws IOException {
     originalOut = System.err;
     memOut = new ByteArrayOutputStream();
     filterOut = new FilterOut(memOut);
     capturedOut = new PrintStream(filterOut);
     System.setErr(capturedOut);
-    PropertyConfigurator.configure(Thread.currentThread().
-        getContextClassLoader()
-        .getResourceAsStream("log4j-kmsaudit.properties"));
+    InputStream is =
+        ThreadUtil.getResourceAsStream("log4j-kmsaudit.properties");
+    PropertyConfigurator.configure(is);
+    IOUtils.closeStream(is);
+
     this.kmsAudit = new KMSAudit(1000);
   }
 

+ 29 - 3
hadoop-common-project/hadoop-minikdc/src/main/java/org/apache/hadoop/minikdc/MiniKdc.java

@@ -61,6 +61,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.IOException;
 import java.io.StringReader;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
@@ -389,6 +390,32 @@ public class MiniKdc {
     ds.getAdminSession().add(entry);
   }
 
+  /**
+   * Convenience method that returns a resource as inputstream from the
+   * classpath.
+   * <p>
+   * It first attempts to use the Thread's context classloader and if not
+   * set it uses the class' classloader.
+   *
+   * @param resourceName resource to retrieve.
+   *
+   * @throws IOException thrown if resource cannot be loaded
+   * @return inputstream with the resource.
+   */
+  public static InputStream getResourceAsStream(String resourceName)
+      throws IOException {
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    if (cl == null) {
+      cl = MiniKdc.class.getClassLoader();
+    }
+    InputStream is = cl.getResourceAsStream(resourceName);
+    if (is == null) {
+      throw new IOException("Can not read resource file '" +
+          resourceName + "'");
+    }
+    return is;
+  }
+
   private void initKDCServer() throws Exception {
     String orgName= conf.getProperty(ORG_NAME);
     String orgDomain = conf.getProperty(ORG_DOMAIN);
@@ -400,8 +427,7 @@ public class MiniKdc {
     map.put("3", orgDomain.toUpperCase(Locale.ENGLISH));
     map.put("4", bindAddress);
 
-    ClassLoader cl = Thread.currentThread().getContextClassLoader();
-    InputStream is1 = cl.getResourceAsStream("minikdc.ldiff");
+    InputStream is1 = getResourceAsStream("minikdc.ldiff");
 
     SchemaManager schemaManager = ds.getSchemaManager();
     LdifReader reader = null;
@@ -443,7 +469,7 @@ public class MiniKdc {
     kdc.start();
 
     StringBuilder sb = new StringBuilder();
-    InputStream is2 = cl.getResourceAsStream("minikdc-krb5.conf");
+    InputStream is2 = getResourceAsStream("minikdc-krb5.conf");
 
     BufferedReader r = null;