From 069c6c62def4a0f94382e9f149581d8e22f6d31c Mon Sep 17 00:00:00 2001 From: Vinod Kumar Vavilapalli Date: Mon, 11 Apr 2016 12:00:51 -0700 Subject: [PATCH] HADOOP-12406. Fixed AbstractMapWritable.readFields to use the thread's ClassLoader to load class instead of System ClassLoader. Contributed by Nadeem Douba. --- .../apache/hadoop/io/AbstractMapWritable.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java index 7dd9e69b82..44e0bdce5e 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java @@ -181,20 +181,22 @@ public void write(DataOutput out) throws IOException { public void readFields(DataInput in) throws IOException { // Get the number of "unknown" classes - newClasses = in.readByte(); - + + // Use the classloader of the current thread to load classes instead of the + // system-classloader so as to support both client-only and inside-a-MR-job + // use-cases. The context-loader by default eventually falls back to the + // system one, so there should be no cases where changing this is an issue. + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + // Then read in the class names and add them to our tables - for (int i = 0; i < newClasses; i++) { byte id = in.readByte(); String className = in.readUTF(); try { - addToMap(Class.forName(className), id); - + addToMap(classLoader.loadClass(className), id); } catch (ClassNotFoundException e) { - throw new IOException("can't find class: " + className + " because "+ - e.getMessage()); + throw new IOException(e); } } }