Index: common/src/java/org/apache/hadoop/hive/conf/HiveConf.java =================================================================== --- common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (revision 1408909) +++ common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (working copy) @@ -18,9 +18,10 @@ package org.apache.hadoop.hive.conf; +import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintStream; import java.net.URL; import java.util.HashMap; @@ -52,7 +53,7 @@ protected String auxJars; private static final Log l4j = LogFactory.getLog(HiveConf.class); private static URL hiveSiteURL = null; - private static URL confVarURL = null; + private static byte[] confVarByteArray = null; private static final Map vars = new HashMap(); @@ -787,35 +788,34 @@ } /** - * Writes the default ConfVars out to a temporary File and returns - * a URL pointing to the temporary file. + * Writes the default ConfVars out to a byte array and returns an input + * stream wrapping that byte array. + * * We need this in order to initialize the ConfVar properties - * in the underling Configuration object using the addResource(URL) + * in the underling Configuration object using the addResource(InputStream) * method. * - * Using Configuration.addResource(InputStream) would be a preferable - * approach, but it turns out that method is broken since Configuration - * tries to read the entire contents of the same InputStream repeatedly. + * It is important to use a LoopingByteArrayInputStream because it turns out + * addResource(InputStream) is broken since Configuration tries to read the + * entire contents of the same InputStream repeatedly without resetting it. + * LoopingByteArrayInputStream has special logic to handle this. */ - private static synchronized URL getConfVarURL() { - if (confVarURL == null) { + private static synchronized InputStream getConfVarInputStream() { + if (confVarByteArray == null) { try { Configuration conf = new Configuration(); - File confVarFile = File.createTempFile("hive-default-", ".xml"); - confVarFile.deleteOnExit(); applyDefaultNonNullConfVars(conf); - FileOutputStream fout = new FileOutputStream(confVarFile); - conf.writeXml(fout); - fout.close(); - confVarURL = confVarFile.toURI().toURL(); + ByteArrayOutputStream confVarBaos = new ByteArrayOutputStream(); + conf.writeXml(confVarBaos); + confVarByteArray = confVarBaos.toByteArray(); } catch (Exception e) { // We're pretty screwed if we can't load the default conf vars throw new RuntimeException("Failed to initialize default Hive configuration variables!", e); } } - return confVarURL; + return new LoopingByteArrayInputStream(confVarByteArray); } public static int getIntVar(Configuration conf, ConfVars var) { @@ -980,7 +980,7 @@ origProp = getAllProperties(); // Overlay the ConfVars. Note that this ignores ConfVars with null values - addResource(getConfVarURL()); + addResource(getConfVarInputStream()); // Overlay hive-site.xml if it exists if (hiveSiteURL != null) { Index: common/src/java/org/apache/hadoop/hive/conf/LoopingByteArrayInputStream.java =================================================================== --- common/src/java/org/apache/hadoop/hive/conf/LoopingByteArrayInputStream.java (revision 0) +++ common/src/java/org/apache/hadoop/hive/conf/LoopingByteArrayInputStream.java (revision 0) @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.hadoop.hive.conf; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +/** + * LoopingByteArrayInputStream. + * + * This was designed specifically to handle the problem in Hadoop's Configuration object that it + * tries to read the entire contents of the same InputStream repeatedly without resetting it. + * + * The Configuration object does attempt to close the InputStream though, so, since close does + * nothing for the ByteArrayInputStream object, override it to reset it. + */ +public class LoopingByteArrayInputStream extends ByteArrayInputStream { + + public LoopingByteArrayInputStream(byte[] buf) { + super(buf); + } + + @Override + public void close() throws IOException { + this.reset(); + // According to the Java documentation this does nothing, but just in case + super.close(); + } + +}