diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 899afbb716..3c98eadad0 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/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) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ThreadUtil.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ThreadUtil.java index 86f523a9fc..ab7b5fdedd 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ThreadUtil.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ThreadUtil.java @@ -22,6 +22,9 @@ import org.apache.hadoop.classification.InterfaceStability; +import java.io.IOException; +import java.io.InputStream; + @InterfaceStability.Evolving public class ThreadUtil { @@ -46,4 +49,31 @@ public static void sleepAtLeastIgnoreInterrupts(long millis) { } } } + + /** + * Convenience method that returns a resource as inputstream from the + * classpath. + *

+ * 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; + } } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/VersionInfo.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/VersionInfo.java index 324c57f9a6..dc8d36959a 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/VersionInfo.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/VersionInfo.java @@ -43,11 +43,7 @@ protected VersionInfo(String component) { 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 '" + diff --git a/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java b/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java index eb640bbba7..f520edfa51 100644 --- a/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java +++ b/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.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.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 MiniKMS(String kmsConfDir, String log4ConfFile, String keyStore, 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 void start() throws Exception { "/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(); diff --git a/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSAudit.java b/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSAudit.java index f4962693c1..7e1c0d7b08 100644 --- a/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSAudit.java +++ b/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSAudit.java @@ -19,11 +19,15 @@ 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 void setOutputStream(OutputStream out) { } @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); } diff --git a/hadoop-common-project/hadoop-minikdc/src/main/java/org/apache/hadoop/minikdc/MiniKdc.java b/hadoop-common-project/hadoop-minikdc/src/main/java/org/apache/hadoop/minikdc/MiniKdc.java index 938836051e..a5253c4521 100644 --- a/hadoop-common-project/hadoop-minikdc/src/main/java/org/apache/hadoop/minikdc/MiniKdc.java +++ b/hadoop-common-project/hadoop-minikdc/src/main/java/org/apache/hadoop/minikdc/MiniKdc.java @@ -61,6 +61,7 @@ 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 @@ private void initDirectoryService() throws Exception { ds.getAdminSession().add(entry); } + /** + * Convenience method that returns a resource as inputstream from the + * classpath. + *

+ * 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 @@ private void initKDCServer() throws Exception { 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 @@ private void initKDCServer() throws Exception { kdc.start(); StringBuilder sb = new StringBuilder(); - InputStream is2 = cl.getResourceAsStream("minikdc-krb5.conf"); + InputStream is2 = getResourceAsStream("minikdc-krb5.conf"); BufferedReader r = null;