HADOOP-6881. Make WritableComparator initialize classes when looking for their raw comparator, as classes often register raw comparators in their initializer, which are no longer automatically run in Java 6 when a class is referenced. Contributed by omalley.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@979485 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0d005c52ae
commit
ba54f8b7e7
@ -151,6 +151,11 @@ Trunk (unreleased changes)
|
||||
HADOOP-6536. Fixes FileUtil.fullyDelete() not to delete the contents of
|
||||
the sym-linked directory. (Ravi Gummadi via amareshwari)
|
||||
|
||||
HADOOP-6881. Make WritableComparator intialize classes when
|
||||
looking for their raw comparator, as classes often register raw
|
||||
comparators in initializers, which are no longer automatically run
|
||||
in Java 6 when a class is referenced. (cutting via omalley)
|
||||
|
||||
Release 0.21.0 - Unreleased
|
||||
|
||||
INCOMPATIBLE CHANGES
|
||||
|
@ -42,13 +42,38 @@ public class WritableComparator implements RawComparator {
|
||||
new HashMap<Class, WritableComparator>(); // registry
|
||||
|
||||
/** Get a comparator for a {@link WritableComparable} implementation. */
|
||||
public static synchronized WritableComparator get(Class<? extends WritableComparable> c) {
|
||||
public static synchronized
|
||||
WritableComparator get(Class<? extends WritableComparable> c) {
|
||||
WritableComparator comparator = comparators.get(c);
|
||||
if (comparator == null)
|
||||
if (comparator == null) {
|
||||
// force the static initializers to run
|
||||
forceInit(c);
|
||||
// look to see if it is defined now
|
||||
comparator = comparators.get(c);
|
||||
// if not, use the generic one
|
||||
if (comparator == null) {
|
||||
comparator = new WritableComparator(c, true);
|
||||
comparators.put(c, comparator);
|
||||
}
|
||||
}
|
||||
return comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force initialization of the static members.
|
||||
* As of Java 5, referencing a class doesn't force it to initialize. Since
|
||||
* this class requires that the classes be initialized to declare their
|
||||
* comparators, we force that initialization to happen.
|
||||
* @param cls the class to initialize
|
||||
*/
|
||||
private static void forceInit(Class<?> cls) {
|
||||
try {
|
||||
Class.forName(cls.getName(), true, cls.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException("Can't initialize class " + cls, e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Register an optimized comparator for a {@link WritableComparable}
|
||||
* implementation. */
|
||||
public static synchronized void define(Class c,
|
||||
|
@ -96,4 +96,27 @@ public static Writable testWritable(Writable before
|
||||
return after;
|
||||
}
|
||||
|
||||
private static class FrobComparator extends WritableComparator {
|
||||
public FrobComparator() { super(Frob.class); }
|
||||
@Override public int compare(byte[] b1, int s1, int l1,
|
||||
byte[] b2, int s2, int l2) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Frob implements WritableComparable {
|
||||
static { // register default comparator
|
||||
WritableComparator.define(Frob.class, new FrobComparator());
|
||||
}
|
||||
@Override public void write(DataOutput out) throws IOException {}
|
||||
@Override public void readFields(DataInput in) throws IOException {}
|
||||
@Override public int compareTo(Object o) { return 0; }
|
||||
}
|
||||
|
||||
/** Test that comparator is defined. */
|
||||
public static void testGetComparator() throws Exception {
|
||||
assert(WritableComparator.get(Frob.class) instanceof FrobComparator);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user