HBASE-22458: TestClassFinder fails when run on JDK11
Signed-off-by: Sean Busbey <busbey@apache.org>
This commit is contained in:
parent
c2cf06d0bf
commit
0445186f1a
|
@ -49,6 +49,7 @@ public class ClassFinder {
|
||||||
private FileNameFilter fileNameFilter;
|
private FileNameFilter fileNameFilter;
|
||||||
private ClassFilter classFilter;
|
private ClassFilter classFilter;
|
||||||
private FileFilter fileFilter;
|
private FileFilter fileFilter;
|
||||||
|
private ClassLoader classLoader;
|
||||||
|
|
||||||
public interface ResourcePathFilter {
|
public interface ResourcePathFilter {
|
||||||
boolean isCandidatePath(String resourcePath, boolean isJar);
|
boolean isCandidatePath(String resourcePath, boolean isJar);
|
||||||
|
@ -114,16 +115,27 @@ public class ClassFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassFinder() {
|
// To control which classloader to use while trying to find jars/classes
|
||||||
this(null, null, null);
|
public ClassFinder(ClassLoader classLoader) {
|
||||||
|
this(null, null, null, classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassFinder(ResourcePathFilter resourcePathFilter,
|
public ClassFinder() {
|
||||||
FileNameFilter fileNameFilter, ClassFilter classFilter) {
|
this(ClassLoader.getSystemClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassFinder(ResourcePathFilter resourcePathFilter, FileNameFilter fileNameFilter,
|
||||||
|
ClassFilter classFilter) {
|
||||||
|
this(resourcePathFilter, fileNameFilter, classFilter, ClassLoader.getSystemClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassFinder(ResourcePathFilter resourcePathFilter, FileNameFilter fileNameFilter,
|
||||||
|
ClassFilter classFilter, ClassLoader classLoader) {
|
||||||
this.resourcePathFilter = resourcePathFilter;
|
this.resourcePathFilter = resourcePathFilter;
|
||||||
this.classFilter = classFilter;
|
this.classFilter = classFilter;
|
||||||
this.fileNameFilter = fileNameFilter;
|
this.fileNameFilter = fileNameFilter;
|
||||||
this.fileFilter = new FileFilterWithName(fileNameFilter);
|
this.fileFilter = new FileFilterWithName(fileNameFilter);
|
||||||
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,7 +159,7 @@ public class ClassFinder {
|
||||||
final String path = packageName.replace('.', '/');
|
final String path = packageName.replace('.', '/');
|
||||||
final Pattern jarResourceRe = Pattern.compile("^file:(.+\\.jar)!/" + path + "$");
|
final Pattern jarResourceRe = Pattern.compile("^file:(.+\\.jar)!/" + path + "$");
|
||||||
|
|
||||||
Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources(path);
|
Enumeration<URL> resources = this.classLoader.getResources(path);
|
||||||
List<File> dirs = new ArrayList<>();
|
List<File> dirs = new ArrayList<>();
|
||||||
List<String> jars = new ArrayList<>();
|
List<String> jars = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -270,7 +282,7 @@ public class ClassFinder {
|
||||||
private Class<?> makeClass(String className, boolean proceedOnExceptions)
|
private Class<?> makeClass(String className, boolean proceedOnExceptions)
|
||||||
throws ClassNotFoundException, LinkageError {
|
throws ClassNotFoundException, LinkageError {
|
||||||
try {
|
try {
|
||||||
Class<?> c = Class.forName(className, false, this.getClass().getClassLoader());
|
Class<?> c = Class.forName(className, false, classLoader);
|
||||||
boolean isCandidateClass = null == classFilter || classFilter.isCandidateClass(c);
|
boolean isCandidateClass = null == classFilter || classFilter.isCandidateClass(c);
|
||||||
return isCandidateClass ? c : null;
|
return isCandidateClass ? c : null;
|
||||||
} catch (NoClassDefFoundError|ClassNotFoundException classNotFoundEx) {
|
} catch (NoClassDefFoundError|ClassNotFoundException classNotFoundEx) {
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -73,6 +72,8 @@ public class TestClassFinder {
|
||||||
|
|
||||||
private static String basePath = null;
|
private static String basePath = null;
|
||||||
|
|
||||||
|
private static CustomClassloader classLoader;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void createTestDir() throws IOException {
|
public static void createTestDir() throws IOException {
|
||||||
basePath = testUtil.getDataTestDir(TestClassFinder.class.getSimpleName()).toString();
|
basePath = testUtil.getDataTestDir(TestClassFinder.class.getSimpleName()).toString();
|
||||||
|
@ -86,6 +87,8 @@ public class TestClassFinder {
|
||||||
}
|
}
|
||||||
assertTrue(testDir.mkdirs());
|
assertTrue(testDir.mkdirs());
|
||||||
LOG.info("Using new, clean directory=" + testDir);
|
LOG.info("Using new, clean directory=" + testDir);
|
||||||
|
|
||||||
|
classLoader = new CustomClassloader(new URL[0], ClassLoader.getSystemClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
@ -102,7 +105,7 @@ public class TestClassFinder {
|
||||||
packageAndLoadJar(c1, c3);
|
packageAndLoadJar(c1, c3);
|
||||||
packageAndLoadJar(c2);
|
packageAndLoadJar(c2);
|
||||||
|
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
Set<Class<?>> allClasses = allClassesFinder.findClasses(
|
Set<Class<?>> allClasses = allClassesFinder.findClasses(
|
||||||
makePackageName("", counter), false);
|
makePackageName("", counter), false);
|
||||||
assertEquals(3, allClasses.size());
|
assertEquals(3, allClasses.size());
|
||||||
|
@ -116,7 +119,7 @@ public class TestClassFinder {
|
||||||
packageAndLoadJar(c1, c2);
|
packageAndLoadJar(c1, c2);
|
||||||
packageAndLoadJar(c1);
|
packageAndLoadJar(c1);
|
||||||
|
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
Set<Class<?>> allClasses = allClassesFinder.findClasses(
|
Set<Class<?>> allClasses = allClassesFinder.findClasses(
|
||||||
makePackageName("", counter), false);
|
makePackageName("", counter), false);
|
||||||
assertEquals(2, allClasses.size());
|
assertEquals(2, allClasses.size());
|
||||||
|
@ -134,7 +137,7 @@ public class TestClassFinder {
|
||||||
packageAndLoadJar(c1, c2);
|
packageAndLoadJar(c1, c2);
|
||||||
packageAndLoadJar(c3);
|
packageAndLoadJar(c3);
|
||||||
|
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
Set<Class<?>> nestedClasses = allClassesFinder.findClasses(
|
Set<Class<?>> nestedClasses = allClassesFinder.findClasses(
|
||||||
makePackageName(NESTED, counter), false);
|
makePackageName(NESTED, counter), false);
|
||||||
assertEquals(2, nestedClasses.size());
|
assertEquals(2, nestedClasses.size());
|
||||||
|
@ -156,7 +159,7 @@ public class TestClassFinder {
|
||||||
return !fileName.startsWith(PREFIX);
|
return !fileName.startsWith(PREFIX);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ClassFinder incClassesFinder = new ClassFinder(null, notExcNameFilter, null);
|
ClassFinder incClassesFinder = new ClassFinder(null, notExcNameFilter, null, classLoader);
|
||||||
Set<Class<?>> incClasses = incClassesFinder.findClasses(
|
Set<Class<?>> incClasses = incClassesFinder.findClasses(
|
||||||
makePackageName("", counter), false);
|
makePackageName("", counter), false);
|
||||||
assertEquals(1, incClasses.size());
|
assertEquals(1, incClasses.size());
|
||||||
|
@ -176,7 +179,7 @@ public class TestClassFinder {
|
||||||
return !c.getSimpleName().startsWith(PREFIX);
|
return !c.getSimpleName().startsWith(PREFIX);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ClassFinder incClassesFinder = new ClassFinder(null, null, notExcClassFilter);
|
ClassFinder incClassesFinder = new ClassFinder(null, null, notExcClassFilter, classLoader);
|
||||||
Set<Class<?>> incClasses = incClassesFinder.findClasses(
|
Set<Class<?>> incClasses = incClassesFinder.findClasses(
|
||||||
makePackageName("", counter), false);
|
makePackageName("", counter), false);
|
||||||
assertEquals(1, incClasses.size());
|
assertEquals(1, incClasses.size());
|
||||||
|
@ -215,7 +218,7 @@ public class TestClassFinder {
|
||||||
return !isJar || !resourcePath.equals(excludedJarResource);
|
return !isJar || !resourcePath.equals(excludedJarResource);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ClassFinder incClassesFinder = new ClassFinder(notExcJarFilter, null, null);
|
ClassFinder incClassesFinder = new ClassFinder(notExcJarFilter, null, null, classLoader);
|
||||||
Set<Class<?>> incClasses = incClassesFinder.findClasses(
|
Set<Class<?>> incClasses = incClassesFinder.findClasses(
|
||||||
makePackageName("", counter), false);
|
makePackageName("", counter), false);
|
||||||
assertEquals(1, incClasses.size());
|
assertEquals(1, incClasses.size());
|
||||||
|
@ -231,7 +234,7 @@ public class TestClassFinder {
|
||||||
final String classNamePrefix = name.getMethodName();
|
final String classNamePrefix = name.getMethodName();
|
||||||
String pkgNameSuffix = name.getMethodName();
|
String pkgNameSuffix = name.getMethodName();
|
||||||
LOG.info("Created jar " + createAndLoadJar(pkgNameSuffix, classNamePrefix, counter));
|
LOG.info("Created jar " + createAndLoadJar(pkgNameSuffix, classNamePrefix, counter));
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
String pkgName = makePackageName(pkgNameSuffix, counter);
|
String pkgName = makePackageName(pkgNameSuffix, counter);
|
||||||
Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
|
Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
|
||||||
assertTrue("Classes in " + pkgName, allClasses.size() > 0);
|
assertTrue("Classes in " + pkgName, allClasses.size() > 0);
|
||||||
|
@ -262,10 +265,10 @@ public class TestClassFinder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
String pkgName = makePackageName(pkgNameSuffix, counter);
|
String pkgName = makePackageName(pkgNameSuffix, counter);
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
|
Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
|
||||||
assertTrue("Classes in " + pkgName, allClasses.size() > 0);
|
assertTrue("Classes in " + pkgName, allClasses.size() > 0);
|
||||||
ClassFinder notThisClassFinder = new ClassFinder(null, notThisFilter, null);
|
ClassFinder notThisClassFinder = new ClassFinder(null, notThisFilter, null, classLoader);
|
||||||
Set<Class<?>> notAllClasses = notThisClassFinder.findClasses(pkgName, false);
|
Set<Class<?>> notAllClasses = notThisClassFinder.findClasses(pkgName, false);
|
||||||
assertFalse(contains(notAllClasses, classNameToFilterOut));
|
assertFalse(contains(notAllClasses, classNameToFilterOut));
|
||||||
assertEquals(allClasses.size() - 1, notAllClasses.size());
|
assertEquals(allClasses.size() - 1, notAllClasses.size());
|
||||||
|
@ -287,10 +290,10 @@ public class TestClassFinder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
String pkgName = makePackageName(pkgNameSuffix, counter);
|
String pkgName = makePackageName(pkgNameSuffix, counter);
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
|
Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
|
||||||
assertTrue("Classes in " + pkgName, allClasses.size() > 0);
|
assertTrue("Classes in " + pkgName, allClasses.size() > 0);
|
||||||
ClassFinder notThisClassFinder = new ClassFinder(null, null, notThisFilter);
|
ClassFinder notThisClassFinder = new ClassFinder(null, null, notThisFilter, classLoader);
|
||||||
Set<Class<?>> notAllClasses = notThisClassFinder.findClasses(pkgName, false);
|
Set<Class<?>> notAllClasses = notThisClassFinder.findClasses(pkgName, false);
|
||||||
assertFalse(contains(notAllClasses, clazz.getSimpleName()));
|
assertFalse(contains(notAllClasses, clazz.getSimpleName()));
|
||||||
assertEquals(allClasses.size() - 1, notAllClasses.size());
|
assertEquals(allClasses.size() - 1, notAllClasses.size());
|
||||||
|
@ -307,7 +310,7 @@ public class TestClassFinder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
String thisPackage = this.getClass().getPackage().getName();
|
String thisPackage = this.getClass().getPackage().getName();
|
||||||
ClassFinder notThisClassFinder = new ClassFinder(notExcJarFilter, null, null);
|
ClassFinder notThisClassFinder = new ClassFinder(notExcJarFilter, null, null, classLoader);
|
||||||
Set<Class<?>> notAllClasses = notThisClassFinder.findClasses(thisPackage, false);
|
Set<Class<?>> notAllClasses = notThisClassFinder.findClasses(thisPackage, false);
|
||||||
assertFalse(notAllClasses.contains(this.getClass()));
|
assertFalse(notAllClasses.contains(this.getClass()));
|
||||||
}
|
}
|
||||||
|
@ -316,7 +319,7 @@ public class TestClassFinder {
|
||||||
public void testClassFinderDefaultsToOwnPackage() throws Exception {
|
public void testClassFinderDefaultsToOwnPackage() throws Exception {
|
||||||
// Correct handling of nested packages is tested elsewhere, so here we just assume
|
// Correct handling of nested packages is tested elsewhere, so here we just assume
|
||||||
// pkgClasses is the correct answer that we don't have to check.
|
// pkgClasses is the correct answer that we don't have to check.
|
||||||
ClassFinder allClassesFinder = new ClassFinder();
|
ClassFinder allClassesFinder = new ClassFinder(classLoader);
|
||||||
Set<Class<?>> pkgClasses = allClassesFinder.findClasses(
|
Set<Class<?>> pkgClasses = allClassesFinder.findClasses(
|
||||||
ClassFinder.class.getPackage().getName(), false);
|
ClassFinder.class.getPackage().getName(), false);
|
||||||
Set<Class<?>> defaultClasses = allClassesFinder.findClasses(false);
|
Set<Class<?>> defaultClasses = allClassesFinder.findClasses(false);
|
||||||
|
@ -334,8 +337,8 @@ public class TestClassFinder {
|
||||||
|
|
||||||
private static Class<?> makeClass(String nestedPkgSuffix,
|
private static Class<?> makeClass(String nestedPkgSuffix,
|
||||||
String className, long counter) throws ClassNotFoundException {
|
String className, long counter) throws ClassNotFoundException {
|
||||||
return Class.forName(
|
String name = makePackageName(nestedPkgSuffix, counter) + "." + className + counter;
|
||||||
makePackageName(nestedPkgSuffix, counter) + "." + className + counter);
|
return Class.forName(name, true, classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String makePackageName(String nestedSuffix, long counter) {
|
private static String makePackageName(String nestedSuffix, long counter) {
|
||||||
|
@ -415,11 +418,19 @@ public class TestClassFinder {
|
||||||
// Add the file to classpath.
|
// Add the file to classpath.
|
||||||
File jarFile = new File(path);
|
File jarFile = new File(path);
|
||||||
assertTrue(jarFile.exists());
|
assertTrue(jarFile.exists());
|
||||||
URLClassLoader urlClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
|
classLoader.addURL(jarFile.toURI().toURL());
|
||||||
Method method = URLClassLoader.class
|
|
||||||
.getDeclaredMethod("addURL", new Class[] { URL.class });
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(urlClassLoader, new Object[] { jarFile.toURI().toURL() });
|
|
||||||
return jarFile.getAbsolutePath();
|
return jarFile.getAbsolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Java 11 workaround - Custom class loader to expose addUrl method of URLClassLoader
|
||||||
|
private static class CustomClassloader extends URLClassLoader {
|
||||||
|
|
||||||
|
public CustomClassloader(URL[] urls, ClassLoader parentLoader) {
|
||||||
|
super(urls, parentLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addURL(URL url) {
|
||||||
|
super.addURL(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue