You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by bu...@apache.org on 2019/06/13 14:26:38 UTC

[hbase] branch branch-2.1 updated: HBASE-22458: TestClassFinder fails when run on JDK11

This is an automated email from the ASF dual-hosted git repository.

busbey pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new b7f60bc  HBASE-22458: TestClassFinder fails when run on JDK11
b7f60bc is described below

commit b7f60bc87f6fdb7341d77dcfae73233a03646012
Author: Sakthi <sa...@gmail.com>
AuthorDate: Tue Jun 4 17:14:47 2019 -0700

    HBASE-22458: TestClassFinder fails when run on JDK11
    
    Signed-off-by: Sean Busbey <bu...@apache.org>
    (cherry picked from commit 0445186f1aa2955f575227fbd2dca316bcd70aa2)
---
 .../java/org/apache/hadoop/hbase/ClassFinder.java  | 22 +++++++--
 .../org/apache/hadoop/hbase/TestClassFinder.java   | 53 +++++++++++++---------
 2 files changed, 49 insertions(+), 26 deletions(-)

diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/ClassFinder.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/ClassFinder.java
index 9dccb29..b8ec0dd 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/ClassFinder.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/ClassFinder.java
@@ -49,6 +49,7 @@ public class ClassFinder {
   private FileNameFilter fileNameFilter;
   private ClassFilter classFilter;
   private FileFilter fileFilter;
+  private ClassLoader classLoader;
 
   public interface ResourcePathFilter {
     boolean isCandidatePath(String resourcePath, boolean isJar);
@@ -114,16 +115,27 @@ public class ClassFinder {
     }
   }
 
+  // To control which classloader to use while trying to find jars/classes
+  public ClassFinder(ClassLoader classLoader) {
+    this(null, null, null, classLoader);
+  }
+
   public ClassFinder() {
-    this(null, null, null);
+    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) {
+  public ClassFinder(ResourcePathFilter resourcePathFilter, FileNameFilter fileNameFilter,
+      ClassFilter classFilter, ClassLoader classLoader) {
     this.resourcePathFilter = resourcePathFilter;
     this.classFilter = classFilter;
     this.fileNameFilter = fileNameFilter;
     this.fileFilter = new FileFilterWithName(fileNameFilter);
+    this.classLoader = classLoader;
   }
 
   /**
@@ -147,7 +159,7 @@ public class ClassFinder {
     final String path = packageName.replace('.', '/');
     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<String> jars = new ArrayList<>();
 
@@ -270,7 +282,7 @@ public class ClassFinder {
   private Class<?> makeClass(String className, boolean proceedOnExceptions)
     throws ClassNotFoundException, LinkageError {
     try {
-      Class<?> c = Class.forName(className, false, this.getClass().getClassLoader());
+      Class<?> c = Class.forName(className, false, classLoader);
       boolean isCandidateClass = null == classFilter || classFilter.isCandidateClass(c);
       return isCandidateClass ? c : null;
     } catch (NoClassDefFoundError|ClassNotFoundException classNotFoundEx) {
diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestClassFinder.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestClassFinder.java
index 0b17359..21a092b 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestClassFinder.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestClassFinder.java
@@ -27,7 +27,6 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.HashSet;
@@ -73,6 +72,8 @@ public class TestClassFinder {
 
   private static String basePath = null;
 
+  private static CustomClassloader classLoader;
+
   @BeforeClass
   public static void createTestDir() throws IOException {
     basePath = testUtil.getDataTestDir(TestClassFinder.class.getSimpleName()).toString();
@@ -86,6 +87,8 @@ public class TestClassFinder {
     }
     assertTrue(testDir.mkdirs());
     LOG.info("Using new, clean directory=" + testDir);
+
+    classLoader = new CustomClassloader(new URL[0], ClassLoader.getSystemClassLoader());
   }
 
   @AfterClass
@@ -102,7 +105,7 @@ public class TestClassFinder {
     packageAndLoadJar(c1, c3);
     packageAndLoadJar(c2);
 
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     Set<Class<?>> allClasses = allClassesFinder.findClasses(
         makePackageName("", counter), false);
     assertEquals(3, allClasses.size());
@@ -116,7 +119,7 @@ public class TestClassFinder {
     packageAndLoadJar(c1, c2);
     packageAndLoadJar(c1);
 
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     Set<Class<?>> allClasses = allClassesFinder.findClasses(
         makePackageName("", counter), false);
     assertEquals(2, allClasses.size());
@@ -134,7 +137,7 @@ public class TestClassFinder {
     packageAndLoadJar(c1, c2);
     packageAndLoadJar(c3);
 
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     Set<Class<?>> nestedClasses = allClassesFinder.findClasses(
         makePackageName(NESTED, counter), false);
     assertEquals(2, nestedClasses.size());
@@ -156,7 +159,7 @@ public class TestClassFinder {
         return !fileName.startsWith(PREFIX);
       }
     };
-    ClassFinder incClassesFinder = new ClassFinder(null, notExcNameFilter, null);
+    ClassFinder incClassesFinder = new ClassFinder(null, notExcNameFilter, null, classLoader);
     Set<Class<?>> incClasses = incClassesFinder.findClasses(
         makePackageName("", counter), false);
     assertEquals(1, incClasses.size());
@@ -176,7 +179,7 @@ public class TestClassFinder {
         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(
         makePackageName("", counter), false);
     assertEquals(1, incClasses.size());
@@ -215,7 +218,7 @@ public class TestClassFinder {
         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(
         makePackageName("", counter), false);
     assertEquals(1, incClasses.size());
@@ -231,7 +234,7 @@ public class TestClassFinder {
     final String classNamePrefix = name.getMethodName();
     String pkgNameSuffix = name.getMethodName();
     LOG.info("Created jar " + createAndLoadJar(pkgNameSuffix, classNamePrefix, counter));
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     String pkgName = makePackageName(pkgNameSuffix, counter);
     Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
     assertTrue("Classes in " + pkgName, allClasses.size() > 0);
@@ -262,10 +265,10 @@ public class TestClassFinder {
       }
     };
     String pkgName = makePackageName(pkgNameSuffix, counter);
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
     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);
     assertFalse(contains(notAllClasses, classNameToFilterOut));
     assertEquals(allClasses.size() - 1, notAllClasses.size());
@@ -287,10 +290,10 @@ public class TestClassFinder {
       }
     };
     String pkgName = makePackageName(pkgNameSuffix, counter);
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     Set<Class<?>> allClasses = allClassesFinder.findClasses(pkgName, false);
     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);
     assertFalse(contains(notAllClasses, clazz.getSimpleName()));
     assertEquals(allClasses.size() - 1, notAllClasses.size());
@@ -307,7 +310,7 @@ public class TestClassFinder {
       }
     };
     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);
     assertFalse(notAllClasses.contains(this.getClass()));
   }
@@ -316,7 +319,7 @@ public class TestClassFinder {
   public void testClassFinderDefaultsToOwnPackage() throws Exception {
     // 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.
-    ClassFinder allClassesFinder = new ClassFinder();
+    ClassFinder allClassesFinder = new ClassFinder(classLoader);
     Set<Class<?>> pkgClasses = allClassesFinder.findClasses(
         ClassFinder.class.getPackage().getName(), false);
     Set<Class<?>> defaultClasses = allClassesFinder.findClasses(false);
@@ -334,8 +337,8 @@ public class TestClassFinder {
 
   private static Class<?> makeClass(String nestedPkgSuffix,
       String className, long counter) throws ClassNotFoundException {
-    return Class.forName(
-        makePackageName(nestedPkgSuffix, counter) + "." + className + counter);
+    String name = makePackageName(nestedPkgSuffix, counter) + "." + className + counter;
+    return Class.forName(name, true, classLoader);
   }
 
   private static String makePackageName(String nestedSuffix, long counter) {
@@ -415,11 +418,19 @@ public class TestClassFinder {
     // Add the file to classpath.
     File jarFile = new File(path);
     assertTrue(jarFile.exists());
-    URLClassLoader urlClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
-    Method method = URLClassLoader.class
-        .getDeclaredMethod("addURL", new Class[] { URL.class });
-    method.setAccessible(true);
-    method.invoke(urlClassLoader, new Object[] { jarFile.toURI().toURL() });
+    classLoader.addURL(jarFile.toURI().toURL());
     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);
+    }
+  }
 }