You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WebSphere Liberty、Tomcat 8及Java代码中查看类加载路径

问题:定位WebSphere Liberty与Tomcat中自研类和第三方类的加载来源

我想查看自研类与第三方类在WebSphere Liberty和Apache Tomcat中的加载来源。使用-verbose:class参数时,只看到大量Liberty相关路径,找不到目标第三方类的路径。比如想定位org/apache/log4j/Logger.class的位置,试过Reflections库,不确定是否适用;也试过通过ClassLoader获取资源的方法(代码如下),但没找到目标内容——编译时类是存在的,却没法通过这种方式找到第三方类路径。

尝试的代码

final ClassLoader loader = ServletVers2.class.getClassLoader();
System.out.println(loader.getResource("com/ca/services/servlet/ServletVers2.class"));
System.out.println(loader.getResource("com/ca/apps/shared/utils/BuildVersion.class"));

final ClassLoader classloader2 = ClassLoader.getSystemClassLoader();
final ClassLoader classloader3 = ClassLoader.getSystemClassLoader().getParent();

System.out.println(loader.getResource("org/apache/logging/log4j/LogManager.class"));
System.out.println(loader.getResource("org/apache/log4j/Logger.class"));

System.out.println(classloader2.getResource("org/apache/logging/log4j/LogManager.class"));
System.out.println(classloader2.getResource("org/apache/log4j/Logger.class"));

System.out.println(classloader3.getResource("org/apache/logging/log4j/LogManager.class"));
System.out.println(classloader3.getResource("org/apache/log4j/Logger.class"));

Reflections reflections = new Reflections("com.apps.shared.utils.BuildVersion", new SubTypesScanner(false));
解决方法

1. 正确使用-verbose:class参数

  • WebSphere Liberty:在server.xml中添加<jvmOptions>-verbose:class</jvmOptions>,启动服务器后,查看日志并过滤目标类,比如用grep "org.apache.log4j.Logger"(Linux)或findstr "org.apache.log4j.Logger"(Windows)快速定位。
  • Tomcat:修改catalina.sh(Linux)或catalina.bat(Windows),添加JAVA_OPTS="-verbose:class $JAVA_OPTS",启动后查看控制台或catalina.out日志,同样过滤目标类即可找到加载路径。

2. 优化ClassLoader获取类路径的代码

直接通过加载类后获取其代码源位置,比getResource更可靠:

// 获取Log4j Logger类的加载路径示例
try {
    Class<?> loggerClass = Class.forName("org.apache.log4j.Logger");
    URL codeLocation = loggerClass.getProtectionDomain().getCodeSource().getLocation();
    System.out.println("Logger类加载路径: " + codeLocation);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

注意:如果类由Bootstrap ClassLoader加载(如JDK核心类),getCodeSource()可能返回null,属于正常情况。

3. Reflections库的正确用法

Reflections适合扫描类资源,调整扫描规则后可以定位类路径:

// 扫描org.apache.log4j包下的所有class文件并输出路径
Reflections reflections = new Reflections("org.apache.log4j", new ResourcesScanner());
Set<String> classResources = reflections.getResources(Pattern.compile(".*\\.class"));
for (String resPath : classResources) {
    URL resourceUrl = reflections.getResource(resPath);
    System.out.println(resPath + " 所在路径: " + resourceUrl);
}

4. 容器专属工具

  • WebSphere Liberty:使用wsadmin工具执行dumpClassLoading命令,生成类加载详细报告,报告中会包含所有类的来源信息。
  • Tomcat:在conf/logging.properties中添加org.apache.catalina.loader.level = FINE,启用类加载日志,启动后查看日志即可获取类加载的详细路径。

内容的提问来源于stack exchange,提问作者Berlin Brown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:25:48