首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 運行時精準定位類所屬 JAR 包:ProtectionDomain 實戰

     編輯:Java 綜合教學

痛點:類路徑衝突,到底載入了哪個 JAR?

專案同時引入 json-lib-2.2.3-jdk15.jar 與 json-lib-2.4-jdk15.jar,代碼使用 JSONArray 時,究竟載入哪個版本?IDE 提示不一定可靠,運行時動態檢測才是鐵證。

核心代碼(通用工具法)

public static void printClassSource(Class clazz) {
    ProtectionDomain pd = clazz.getProtectionDomain();
    CodeSource cs = pd.getCodeSource();
    if (cs != null) {
        System.out.println("來源位置: " + cs.getLocation());
    } else {
        System.out.println("系統類/引導類加載器載入,無 CodeSource");
    }
}

// 呼叫示例
public static void main(String[] args) {
    printClassSource(JSONArray.class);
}

輸出示例

來源位置: file:/C:/Users/lenovo/Desktop/treedemo/WebRoot/WEB-INF/lib/json-lib-2.2.3-jdk15.jar

原理解析

  • Class.getProtectionDomain() → 取得類的保護域(含權限與代碼來源)。
  • ProtectionDomain.getCodeSource() → 返回 CodeSource,封裝 URL location(JAR 路徑或目錄)與簽名證書。
  • CodeSource.getLocation() → 具體 JAR 檔案或 Class 目錄的 file:/ URL。

進階:批量掃描衝突類

public static void scanDuplicateClasses(String packagePrefix) {
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    try {
        Enumeration resources = cl.getResources(packagePrefix.replace('.', '/'));
        while (resources.hasMoreElements()) {
            URL url = resources.nextElement();
            System.out.println("資源路徑: " + url);
            // 若為 jar: 協議可進一步解析 JAR 內部類
        }
    } catch (IOException e) { e.printStackTrace(); }
}

Maven 依賴衝突解決配套

  • mvn dependency:tree -Dverbose 查看完整依賴樹與衝突標記 (*)。
  • mvn dependency:analyze 檢測未聲明/未使用依賴。
  • 在 <dependencyManagement> 統一版本,或用 <exclusion> 排除傳遞性依賴。
  • 強制版本:<dependency><groupId>...</groupId><artifactId>...</artifactId><version>2.4</version></dependency>。

一行代碼,秒定 JAR 歸屬。遇到 NoSuchMethodError、ClassCastException、行為不符預期時,優先用此法驗證實際載入版本,避免盲目猜測浪費時間。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved