Browse Source

HADOOP-18931. FileSystem.getFileSystemClass() to log the jar the .class came from (#6197)

Set the log level of logger org.apache.hadoop.fs.FileSystem to DEBUG to see this.

Contributed by Viraj Jasani
Viraj Jasani 10 months ago
parent
commit
acec539ab3

+ 9 - 1
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java

@@ -3581,7 +3581,15 @@ public abstract class FileSystem extends Configured
       throw new UnsupportedFileSystemException("No FileSystem for scheme "
           + "\"" + scheme + "\"");
     }
-    LOGGER.debug("FS for {} is {}", scheme, clazz);
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("FS for {} is {}", scheme, clazz);
+      final String jarLocation = ClassUtil.findContainingJar(clazz);
+      if (jarLocation != null) {
+        LOGGER.debug("Jar location for {} : {}", clazz, jarLocation);
+      } else {
+        LOGGER.debug("Class location for {} : {}", clazz, ClassUtil.findClassLocation(clazz));
+      }
+    }
     return clazz;
   }
 

+ 17 - 5
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ClassUtil.java

@@ -36,13 +36,25 @@ public class ClassUtil {
    * @return a jar file that contains the class, or null.
    */
   public static String findContainingJar(Class<?> clazz) {
-    ClassLoader loader = clazz.getClassLoader();
-    String classFile = clazz.getName().replaceAll("\\.", "/") + ".class";
+    return findContainingResource(clazz.getClassLoader(), clazz.getName(), "jar");
+  }
+
+  /**
+   * Find the absolute location of the class.
+   *
+   * @param clazz the class to find.
+   * @return the class file with absolute location, or null.
+   */
+  public static String findClassLocation(Class<?> clazz) {
+    return findContainingResource(clazz.getClassLoader(), clazz.getName(), "file");
+  }
+
+  private static String findContainingResource(ClassLoader loader, String clazz, String resource) {
+    String classFile = clazz.replaceAll("\\.", "/") + ".class";
     try {
-      for(final Enumeration<URL> itr = loader.getResources(classFile);
-          itr.hasMoreElements();) {
+      for (final Enumeration<URL> itr = loader.getResources(classFile); itr.hasMoreElements();) {
         final URL url = itr.nextElement();
-        if ("jar".equals(url.getProtocol())) {
+        if (resource.equals(url.getProtocol())) {
           String toReturn = url.getPath();
           if (toReturn.startsWith("file:")) {
             toReturn = toReturn.substring("file:".length());

+ 35 - 9
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestClassUtil.java

@@ -20,21 +20,47 @@ package org.apache.hadoop.util;
 
 import java.io.File;
 
-import org.junit.Assert;
+import org.apache.hadoop.fs.viewfs.ViewFileSystem;
 
-import org.apache.log4j.Logger;
+import org.assertj.core.api.Assertions;
 import org.junit.Test;
 
 public class TestClassUtil {
+
   @Test(timeout=10000)
   public void testFindContainingJar() {
-    String containingJar = ClassUtil.findContainingJar(Logger.class);
-    Assert.assertNotNull("Containing jar not found for Logger", 
-        containingJar);
+    String containingJar = ClassUtil.findContainingJar(Assertions.class);
+    Assertions
+        .assertThat(containingJar)
+        .describedAs("Containing jar for %s", Assertions.class)
+        .isNotNull();
     File jarFile = new File(containingJar);
-    Assert.assertTrue("Containing jar does not exist on file system ",
-        jarFile.exists());
-    Assert.assertTrue("Incorrect jar file " + containingJar,
-        jarFile.getName().matches("reload4j.*[.]jar"));
+    Assertions
+        .assertThat(jarFile)
+        .describedAs("Containing jar %s", jarFile)
+        .exists();
+    Assertions
+        .assertThat(jarFile.getName())
+        .describedAs("Containing jar name %s", jarFile.getName())
+        .matches("assertj-core.*[.]jar");
+  }
+
+  @Test(timeout = 10000)
+  public void testFindContainingClass() {
+    String classFileLocation = ClassUtil.findClassLocation(ViewFileSystem.class);
+    Assertions
+        .assertThat(classFileLocation)
+        .describedAs("Class path for %s", ViewFileSystem.class)
+        .isNotNull();
+    File classFile = new File(classFileLocation);
+    Assertions
+        .assertThat(classFile)
+        .describedAs("Containing class file %s", classFile)
+        .exists();
+    Assertions
+        .assertThat(classFile.getName())
+        .describedAs("Containing class file name %s", classFile.getName())
+        .matches("ViewFileSystem.class");
   }
+
 }