Classpath 地獄是 Java 開發者永恆痛點:同名類多版本共存、類加載器委派機制、隱式依賴衝突。本文介紹一個極簡工具 JWhich,利用 Class.getResource() 委派給類加載器,精準定位類文件實際加載路徑 (目錄或 JAR 內部),原理通透、代碼不足 40 行、即拿即用。
CLASSPATH 環境變量或 java -cp 指定類搜索路徑 (目錄、JAR、ZIP);、Unix :public class JWhich {
public static void which(String className) {
// 1. 格式化為資源路徑:/com/example/Foo.class
if (!className.startsWith("/")) className = "/" + className;
className = className.replace('.', '/') + ".class";
// 2. 詢問當前類的類加載器 (委派鏈自動生效)
URL classUrl = new JWhich().getClass().getResource(className);
// 3. 輸出結果
if (classUrl != null) {
System.out.println("\nClass '" + className.substring(1) + "' found in\n'" + classUrl.getFile() + "'");
} else {
System.out.println("\nClass '" + className.substring(1) + "' not found in\n'" + System.getProperty("java.class.path") + "'");
}
}
public static void main(String[] args) {
if (args.length > 0) {
which(args[0]);
} else {
System.err.println("Usage: java JWhich ");
}
}
}
> java JWhich com.clarkware.ejb.ShoppingCartBean
Class 'com/clarkware/ejb/ShoppingCartBean.class' found in
'/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class'
> java JWhich javax.servlet.http.HttpServlet
Class 'javax/servlet/http/HttpServlet.class' found in
'file:/home/mclark/lib/servlet.jar!/javax/servlet/http/HttpServlet.class'
file:/path/to.jar!/package/Class.class — 類在 JAR 內部,! 分隔 JAR 路徑與內部條目/absolute/path/to/Class.class — 類在目錄中null,輸出當前 java.class.path 供排查Class.getResource(String name) 委派給 ClassLoader.getResource(name)URLURL.getFile() 返回路徑部分 (含 JAR 內部路徑語法)ClassLoader.getResources() 返回 Enumeration,展示同名類所有位置 (被隱藏的版本)ApplicationRunner 中調用 JWhich 核心類 (如 org.springframework.core.io.ClassPathResource),啟動失敗快速定位衝突arthas> sc -d com.example.Foo 列出類加載器、源碼路徑、字節碼詳情,功能更強大Bootstrap ClassLoader (jrt:/java.base 等模塊)
↑
Platform ClassLoader (jrt:/java.sql 等平台模塊)
↑
Application ClassLoader (CLASSPATH / -cp / 模塊路徑)
↑
自定義 ClassLoader (Tomcat WebAppClassLoader, Spring FatJarLauncher, OSGi, ...)
JDK 9+ 模塊系統引入 module-path、--add-reads、--add-exports,類加載邊界更嚴格,JWhich 仍能正確反映運行時可見性。
JWhich 用 「詢問類加載器而非解析 CLASSPATH 字符串」 的反直覺思路,徹底解決「到底加載了哪個版本」的疑難雜癥。將其納入項目啟動自檢、CI 流水線依賴衝突檢測、線上 Arthas 診斷工具箱,讓 Classpath 問題無處遁形。