فهرست منبع

HADOOP-419. Fix a NullPointerException finding the ClassLoader when using libhdfs. Contributed by Owen.

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/trunk@438143 13f79535-47bb-0310-9956-ffa450edef68
Doug Cutting 18 سال پیش
والد
کامیت
8689fba665

+ 4 - 1
CHANGES.txt

@@ -89,7 +89,7 @@ Trunk (unreleased changes)
 22. HADOOP-437.  contrib/streaming: Add support for gzipped inputs.
     (Michel Tourn via cutting)
 
-32. HADOOP-463.  Add variable expansion to config files.
+23. HADOOP-463.  Add variable expansion to config files.
     Configuration property values may now contain variable
     expressions.  A variable is referenced with the syntax
     '${variable}'.  Variables values are found first in the
@@ -98,6 +98,9 @@ Trunk (unreleased changes)
     under ${hadoop.tmp.dir}, which is, by default,
     /tmp/hadoop-${user.name}.  (Michel Tourn via cutting)
 
+24. HADOOP-419. Fix a NullPointerException finding the ClassLoader
+    when using libhdfs.  (omalley via cutting)
+
 
 Release 0.5.0 - 2006-08-04
 

+ 27 - 4
src/java/org/apache/hadoop/conf/Configuration.java

@@ -75,9 +75,14 @@ public class Configuration {
   private ArrayList finalResources = new ArrayList();
 
   private Properties properties;
-  private ClassLoader classLoader = 
-    Thread.currentThread().getContextClassLoader();
-
+  private ClassLoader classLoader;
+  {
+    classLoader = Thread.currentThread().getContextClassLoader();
+    if (classLoader == null) {
+      classLoader = Configuration.class.getClassLoader();
+    }
+  }
+  
   /** A new configuration. */
   public Configuration() {
     if (LOG.isDebugEnabled()) {
@@ -293,6 +298,16 @@ public class Configuration {
     return (String[])values.toArray(new String[values.size()]);
   }
 
+  /**
+   * Load a class by name.
+   * @param name the class name
+   * @return the class object
+   * @throws ClassNotFoundException if the class is not found
+   */
+  public Class getClassByName(String name) throws ClassNotFoundException {
+    return Class.forName(name, true, classLoader);
+  }
+  
   /** Returns the value of the <code>name</code> property as a Class.  If no
    * such property is specified, then <code>defaultValue</code> is returned.
    */
@@ -301,7 +316,7 @@ public class Configuration {
     if (valueString == null)
       return defaultValue;
     try {
-      return Class.forName(valueString, true, classLoader);
+      return getClassByName(valueString);
     } catch (ClassNotFoundException e) {
       throw new RuntimeException(e);
     }
@@ -565,6 +580,14 @@ public class Configuration {
     }
   }
 
+  /**
+   * Get the class loader for this job.
+   * @return the correct class loader
+   */
+  public ClassLoader getClassLoader() {
+    return classLoader;
+  }
+  
   /**
    * Set the class loader that will be used to load the various objects.
    * @param classLoader the new class loader

+ 12 - 14
src/java/org/apache/hadoop/io/ObjectWritable.java

@@ -21,8 +21,7 @@ import java.lang.reflect.Array;
 import java.io.*;
 import java.util.*;
 
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.*;
 
 /** A polymorphic Writable that writes an instance with it's class name.
  * Handles arrays, strings and primitive types without a Writable wrapper.
@@ -61,7 +60,7 @@ public class ObjectWritable implements Writable, Configurable {
   }
   
   public void write(DataOutput out) throws IOException {
-    writeObject(out, instance, declaredClass);
+    writeObject(out, instance, declaredClass, conf);
   }
 
   private static final Map PRIMITIVE_NAMES = new HashMap();
@@ -77,10 +76,11 @@ public class ObjectWritable implements Writable, Configurable {
     PRIMITIVE_NAMES.put("void", Void.TYPE);
   }
 
-  private static class NullInstance implements Writable {
+  private static class NullInstance extends Configured implements Writable {
     private Class declaredClass;
-    public NullInstance() {}
-    public NullInstance(Class declaredClass) {
+    public NullInstance() { super(null); }
+    public NullInstance(Class declaredClass, Configuration conf) {
+      super(conf);
       this.declaredClass = declaredClass;
     }
     public void readFields(DataInput in) throws IOException {
@@ -88,8 +88,7 @@ public class ObjectWritable implements Writable, Configurable {
       declaredClass = (Class)PRIMITIVE_NAMES.get(className);
       if (declaredClass == null) {
         try {
-          declaredClass =
-            Thread.currentThread().getContextClassLoader().loadClass(className);
+          declaredClass = getConf().getClassByName(className);
         } catch (ClassNotFoundException e) {
           throw new RuntimeException(e.toString());
         }
@@ -103,10 +102,11 @@ public class ObjectWritable implements Writable, Configurable {
   /** Write a {@link Writable}, {@link String}, primitive type, or an array of
    * the preceding. */
   public static void writeObject(DataOutput out, Object instance,
-                                 Class declaredClass) throws IOException {
+                                 Class declaredClass, 
+                                 Configuration conf) throws IOException {
 
     if (instance == null) {                       // null
-      instance = new NullInstance(declaredClass);
+      instance = new NullInstance(declaredClass, conf);
       declaredClass = Writable.class;
     }
 
@@ -117,7 +117,7 @@ public class ObjectWritable implements Writable, Configurable {
       out.writeInt(length);
       for (int i = 0; i < length; i++) {
         writeObject(out, Array.get(instance, i),
-                    declaredClass.getComponentType());
+                    declaredClass.getComponentType(), conf);
       }
       
     } else if (declaredClass == String.class) {   // String
@@ -171,9 +171,7 @@ public class ObjectWritable implements Writable, Configurable {
     Class declaredClass = (Class)PRIMITIVE_NAMES.get(className);
     if (declaredClass == null) {
       try {
-        declaredClass =
-          Class.forName(className, true, 
-                        Thread.currentThread().getContextClassLoader());
+        declaredClass = conf.getClassByName(className);
       } catch (ClassNotFoundException e) {
         throw new RuntimeException("readObject can't find class", e);
       }

+ 4 - 4
src/java/org/apache/hadoop/io/SequenceFile.java

@@ -853,13 +853,13 @@ public class SequenceFile {
         UTF8 className = new UTF8();
         
         className.readFields(in);                   // read key class name
-        this.keyClass = WritableName.getClass(className.toString());
+        this.keyClass = WritableName.getClass(className.toString(), conf);
         
         className.readFields(in);                   // read val class name
-        this.valClass = WritableName.getClass(className.toString());
+        this.valClass = WritableName.getClass(className.toString(), conf);
       } else {
-        this.keyClass = WritableName.getClass(Text.readString(in));
-        this.valClass = WritableName.getClass(Text.readString(in));
+        this.keyClass = WritableName.getClass(Text.readString(in), conf);
+        this.valClass = WritableName.getClass(Text.readString(in), conf);
       }
 
       if (version > 2) {                          // if version > 2

+ 6 - 3
src/java/org/apache/hadoop/io/WritableName.java

@@ -19,6 +19,8 @@ package org.apache.hadoop.io;
 import java.util.HashMap;
 import java.io.IOException;
 
+import org.apache.hadoop.conf.Configuration;
+
 /** Utility to permit renaming of Writable implementation classes without
  * invalidiating files that contain their class name.
  * @author Doug Cutting
@@ -57,13 +59,14 @@ public class WritableName {
   }
 
   /** Return the class for a name.  Default is {@link Class#forName(String)}.*/
-  public static synchronized Class getClass(String name) throws IOException {
+  public static synchronized Class getClass(String name,
+                                            Configuration conf
+                                            ) throws IOException {
     Class writableClass = (Class)NAME_TO_CLASS.get(name);
     if (writableClass != null)
       return writableClass;
     try {
-      return Class.forName(name, true, 
-                           Thread.currentThread().getContextClassLoader());
+      return conf.getClassByName(name);
     } catch (ClassNotFoundException e) {
       IOException newE = new IOException("WritableName can't load class");
       newE.initCause(e);

+ 2 - 1
src/java/org/apache/hadoop/ipc/RPC.java

@@ -97,7 +97,8 @@ public class RPC {
       UTF8.writeString(out, methodName);
       out.writeInt(parameterClasses.length);
       for (int i = 0; i < parameterClasses.length; i++) {
-        ObjectWritable.writeObject(out, parameters[i], parameterClasses[i]);
+        ObjectWritable.writeObject(out, parameters[i], parameterClasses[i],
+                                   conf);
       }
     }
 

+ 1 - 1
src/java/org/apache/hadoop/util/ReflectionUtils.java

@@ -40,7 +40,7 @@ public class ReflectionUtils {
         try {
             Constructor meth = theClass.getDeclaredConstructor(emptyArray);
             meth.setAccessible(true);
-            result = meth.newInstance(emptyArray);
+            result = meth.newInstance();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }