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
|
HADOOP-6536. Fixes FileUtil.fullyDelete() not to delete the contents of
|
||||||
the sym-linked directory. (Ravi Gummadi via amareshwari)
|
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
|
Release 0.21.0 - Unreleased
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
@ -42,13 +42,38 @@ public class WritableComparator implements RawComparator {
|
|||||||
new HashMap<Class, WritableComparator>(); // registry
|
new HashMap<Class, WritableComparator>(); // registry
|
||||||
|
|
||||||
/** Get a comparator for a {@link WritableComparable} implementation. */
|
/** 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);
|
WritableComparator comparator = comparators.get(c);
|
||||||
if (comparator == null)
|
if (comparator == null) {
|
||||||
comparator = new WritableComparator(c, true);
|
// 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;
|
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}
|
/** Register an optimized comparator for a {@link WritableComparable}
|
||||||
* implementation. */
|
* implementation. */
|
||||||
public static synchronized void define(Class c,
|
public static synchronized void define(Class c,
|
||||||
|
@ -96,4 +96,27 @@ public static Writable testWritable(Writable before
|
|||||||
return after;
|
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