MAPREDUCE-6619. HADOOP_CLASSPATH is overwritten in MR container. Contributed by Junping Du

(cherry picked from commit da18bbedaf)
This commit is contained in:
Jian He 2016-01-27 13:16:36 -08:00
parent bc00b8ce9e
commit d83b124c97
3 changed files with 62 additions and 0 deletions

View File

@ -397,6 +397,9 @@ Release 2.8.0 - UNRELEASED
MAPREDUCE-6610. JobHistoryEventHandler should not swallow timeline response
(Li Lu via jianhe)
MAPREDUCE-6619. HADOOP_CLASSPATH is overwritten in MR container.
(Junping Du via jianhe)
Release 2.7.3 - UNRELEASED
INCOMPATIBLE CHANGES

View File

@ -261,6 +261,10 @@ hadoopClasspathEnvVar, crossPlatformifyMREnv(conf, Environment.PWD),
addClasspathToEnv(environment, classpathEnvVar, conf);
addClasspathToEnv(environment, hadoopClasspathEnvVar, conf);
// MAPREDUCE-6619, retain $HADOOP_CLASSPATH
MRApps.addToEnvironment(environment, hadoopClasspathEnvVar,
System.getenv(hadoopClasspathEnvVar), conf);
if (userClassesTakesPrecedence) {
MRApps.setMRFrameworkClasspath(environment, conf);
}

View File

@ -30,8 +30,10 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -239,6 +241,12 @@ public void testSetClasspathWithArchives () throws IOException {
testTGZ.getAbsolutePath())).toString();
conf.set(MRJobConfig.CLASSPATH_ARCHIVES, testTGZQualifiedPath);
conf.set(MRJobConfig.CACHE_ARCHIVES, testTGZQualifiedPath + "#testTGZ");
// add hadoop.tgz to env HADOOP_CLASSPATH
Map<String, String> newEnv = new HashMap<String, String>();
newEnv.put(ApplicationConstants.Environment.HADOOP_CLASSPATH.name(),
"hadoop.tgz");
setEnv(newEnv);
Map<String, String> environment = new HashMap<String, String>();
MRApps.setClasspath(environment, conf);
assertTrue(environment.get(ApplicationConstants.Environment.CLASSPATH.name()).startsWith(
@ -268,6 +276,53 @@ public void testSetClasspathWithArchives () throws IOException {
assertTrue(environment.get(
ApplicationConstants.Environment.HADOOP_CLASSPATH.name()).
contains("testTGZ"));
assertTrue(environment.get(
ApplicationConstants.Environment.HADOOP_CLASSPATH.name()).
contains("hadoop.tgz"));
}
// Only set env in runtime but not get persistent in OS (Linux or Windows)
@SuppressWarnings({"unchecked", "rawtypes"})
private static void setEnv(Map<String, String> newEnv) {
try {
// Hack for Windows
Class<?> processEnvClass =
Class.forName("java.lang.ProcessEnvironment");
Field theEnvField =
processEnvClass.getDeclaredField("theEnvironment");
theEnvField.setAccessible(true);
Map<String, String> currentEnv =
(Map<String, String>)theEnvField.get(null);
currentEnv.putAll(newEnv);
Field caseInsensitiveEnvField =
processEnvClass.getDeclaredField("theCaseInsensitiveEnvironment");
caseInsensitiveEnvField.setAccessible(true);
Map<String, String> ciEnv =
(Map<String, String>)caseInsensitiveEnvField.get(null);
ciEnv.putAll(newEnv);
} catch (NoSuchFieldException e) {
// Hack for Linux
try {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for (Class cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
map.putAll(newEnv);
}
}
} catch (Exception e1) {
LOG.error("Hack env on Linux doesn't work:", e1);
throw new RuntimeException(e1);
}
} catch (Exception e) {
LOG.error("Hack env on Windows doesn't work:", e);
throw new RuntimeException(e);
}
}
@Test (timeout = 120000)