HADOOP-11211. mapreduce.job.classloader.system.classes semantics should be order-independent. (Yitong Zhou via gera)
(cherry picked from commit 0bcea111e5
)
This commit is contained in:
parent
c8eb139977
commit
8437c31b67
|
@ -199,6 +199,9 @@ Release 2.7.0 - UNRELEASED
|
||||||
|
|
||||||
HADOOP-11386. Replace \n by %n in format hadoop-common format strings.
|
HADOOP-11386. Replace \n by %n in format hadoop-common format strings.
|
||||||
(Li Lu via wheat9)
|
(Li Lu via wheat9)
|
||||||
|
|
||||||
|
HADOOP-11211. mapreduce.job.classloader.system.classes semantics should be
|
||||||
|
be order-independent. (Yitong Zhou via gera)
|
||||||
|
|
||||||
Release 2.6.0 - 2014-11-18
|
Release 2.6.0 - 2014-11-18
|
||||||
|
|
||||||
|
|
|
@ -216,28 +216,43 @@ public class ApplicationClassLoader extends URLClassLoader {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a class should be included as a system class.
|
||||||
|
*
|
||||||
|
* A class is a system class if and only if it matches one of the positive
|
||||||
|
* patterns and none of the negative ones.
|
||||||
|
*
|
||||||
|
* @param name the class name to check
|
||||||
|
* @param systemClasses a list of system class configurations.
|
||||||
|
* @return true if the class is a system class
|
||||||
|
*/
|
||||||
public static boolean isSystemClass(String name, List<String> systemClasses) {
|
public static boolean isSystemClass(String name, List<String> systemClasses) {
|
||||||
|
boolean result = false;
|
||||||
if (systemClasses != null) {
|
if (systemClasses != null) {
|
||||||
String canonicalName = name.replace('/', '.');
|
String canonicalName = name.replace('/', '.');
|
||||||
while (canonicalName.startsWith(".")) {
|
while (canonicalName.startsWith(".")) {
|
||||||
canonicalName=canonicalName.substring(1);
|
canonicalName=canonicalName.substring(1);
|
||||||
}
|
}
|
||||||
for (String c : systemClasses) {
|
for (String c : systemClasses) {
|
||||||
boolean result = true;
|
boolean shouldInclude = true;
|
||||||
if (c.startsWith("-")) {
|
if (c.startsWith("-")) {
|
||||||
c = c.substring(1);
|
c = c.substring(1);
|
||||||
result = false;
|
shouldInclude = false;
|
||||||
}
|
}
|
||||||
if (canonicalName.startsWith(c)) {
|
if (canonicalName.startsWith(c)) {
|
||||||
if ( c.endsWith(".") // package
|
if ( c.endsWith(".") // package
|
||||||
|| canonicalName.length() == c.length() // class
|
|| canonicalName.length() == c.length() // class
|
||||||
|| canonicalName.length() > c.length() // nested
|
|| canonicalName.length() > c.length() // nested
|
||||||
&& canonicalName.charAt(c.length()) == '$' ) {
|
&& canonicalName.charAt(c.length()) == '$' ) {
|
||||||
return result;
|
if (shouldInclude) {
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class TestApplicationClassLoader {
|
||||||
assertEquals(jarFile.toURI().toURL(), urls[2]);
|
assertEquals(jarFile.toURI().toURL(), urls[2]);
|
||||||
// nofile should be ignored
|
// nofile should be ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsSystemClass() {
|
public void testIsSystemClass() {
|
||||||
testIsSystemClassInternal("");
|
testIsSystemClassInternal("");
|
||||||
|
@ -112,8 +112,12 @@ public class TestApplicationClassLoader {
|
||||||
classes("-org.example.Foo,org.example.")));
|
classes("-org.example.Foo,org.example.")));
|
||||||
assertTrue(isSystemClass("org.example.Bar" + nestedClass,
|
assertTrue(isSystemClass("org.example.Bar" + nestedClass,
|
||||||
classes("-org.example.Foo.,org.example.")));
|
classes("-org.example.Foo.,org.example.")));
|
||||||
|
assertFalse(isSystemClass("org.example.Foo" + nestedClass,
|
||||||
|
classes("org.example.,-org.example.Foo")));
|
||||||
|
assertFalse(isSystemClass("org.example.Foo" + nestedClass,
|
||||||
|
classes("org.example.Foo,-org.example.Foo")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> classes(String classes) {
|
private List<String> classes(String classes) {
|
||||||
return Lists.newArrayList(Splitter.on(',').split(classes));
|
return Lists.newArrayList(Splitter.on(',').split(classes));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1798,10 +1798,23 @@
|
||||||
<value></value>
|
<value></value>
|
||||||
<description>Used to override the default definition of the system classes for
|
<description>Used to override the default definition of the system classes for
|
||||||
the job classloader. The system classes are a comma-separated list of
|
the job classloader. The system classes are a comma-separated list of
|
||||||
classes that should be loaded from the system classpath, not the
|
patterns that indicate whether to load a class from the system classpath,
|
||||||
user-supplied JARs, when mapreduce.job.classloader is enabled. Names ending
|
instead from the user-supplied JARs, when mapreduce.job.classloader is
|
||||||
in '.' (period) are treated as package names, and names starting with a '-'
|
enabled.
|
||||||
are treated as negative matches.
|
|
||||||
|
A positive pattern is defined as:
|
||||||
|
1. A single class name 'C' that matches 'C' and transitively all nested
|
||||||
|
classes 'C$*' defined in C;
|
||||||
|
2. A package name ending with a '.' (e.g., "com.example.") that matches
|
||||||
|
all classes from that package.
|
||||||
|
A negative pattern is defined by a '-' in front of a positive pattern
|
||||||
|
(e.g., "-com.example.").
|
||||||
|
|
||||||
|
A class is considered a system class if and only if it matches one of the
|
||||||
|
positive patterns and none of the negative ones. More formally:
|
||||||
|
A class is a member of the inclusion set I if it matches one of the positive
|
||||||
|
patterns. A class is a member of the exclusion set E if it matches one of
|
||||||
|
the negative patterns. The set of system classes S = I \ E.
|
||||||
</description>
|
</description>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue