From 240fddcf17ff4ff78342512e56acc1c60d446ff9 Mon Sep 17 00:00:00 2001 From: Viraj Jasani Date: Fri, 14 Jun 2024 10:14:54 -0800 Subject: [PATCH] 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 --- .../java/org/apache/hadoop/fs/FileSystem.java | 10 ++++- .../org/apache/hadoop/util/ClassUtil.java | 22 +++++++--- .../org/apache/hadoop/util/TestClassUtil.java | 44 +++++++++++++++---- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java index 2155e17328a66..38ec611451750 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java @@ -3581,7 +3581,15 @@ public static Class getFileSystemClass(String scheme, 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; } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ClassUtil.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ClassUtil.java index 44c94669f515f..c17445c57ce54 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ClassUtil.java +++ b/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 itr = loader.getResources(classFile); - itr.hasMoreElements();) { + for (final Enumeration 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()); diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestClassUtil.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestClassUtil.java index 04337929abd9f..3a7e12e8f0375 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestClassUtil.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestClassUtil.java @@ -20,21 +20,47 @@ 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"); } + }