簡體   English   中英

字節碼操作/增強和 Java Instrumentation API

[英]Bytecode manipulation/enhancement and Java Instrumentation API

我很難理解字節碼操作/增強和 Java Instrumentation API 之間的依賴關系。

根據我對執行任何字節碼操作/增強的理解,我們有兩種選擇

  • 構建時 - Java 類被編譯為*.class然后應該執行一些其他庫/應用程序來進行操作。
  • 加載時間 - 僅通過使用 Java Instrumentation API,這意味着必須提供特定的 javaagent。

我不確定的事情:

  • 是否有諸如構建時字節碼操作之類的東西,哪些框架/庫支持該操作(例如 Javassist、ASM),它們是使用一些通用方法還是僅讀取和解析字節碼,然后為您提供修改它的方法?

  • 加載時操作是否僅依賴於 Java Instrumentation API? 意思是所有可用的框架/庫(例如 Javassist、ASM)都使用 javaagent 來進行操作?

請注意,我對這個主題的經驗非常少,所以我有可能誤解或遺漏了一些概念。 我試圖將這個復雜的主題歸結為一些簡單的解釋,即使它非常籠統或使用類比來演示。

將編譯后的 Java 類文件視為包含特定 Java 類的任何信息的byte[]數組。 在此上下文中,檢測是指將此字節數組后處理為不同形狀的過程,與何時或如何發生無關。 可以在編譯和類加載之間的任何時間應用檢測; 在 Java 中,一個類甚至可以在加載后進行檢測,但不能改變其形狀,即添加/刪除字段或方法。 但是無論何時應用檢測,概念都保持不變,即重新排列表示已編譯 Java 類的字節數組。

我知道的任何字節碼操作庫都允許處理來自任何來源的類文件。 通常,這些庫的最通用輸入是一個簡單的字節數組,為了方便,可以選擇從類加載器加載它。 可以通過ClassLoader.getResourceAsStream方法從類加載器中查找類文件,並將類文件的名稱作為參數。 例如:

classLoader.getResourceAsStream("some/Sample.class")

應該為虛構的some.Sample類解析類文件。 這通常是因為類文件(字節數組)需要由類加載器定位以在第一次請求時加載類。

在構建時,類文件通常位於特定文件夾中,例如在 Maven 構建的target/classes文件夾中。 要檢測這些類,您只需找到這些文件,將它們讀入字節數組,然后寫回更改后的結果。 例如,您可以通過編寫自己的 Maven 插件來做到這一點,例如,您可以在其中使用 ASM 來調整文件。 為方便起見,您也可以使用更高級的庫,例如Byte Buddy 的 Maven 插件,您可以在其中加載自己的插件,並完全避免 Maven 插件 API 甚至字節碼 API。 (有關信息,我是 Byte Buddy 的作者。)

在運行時,您可以執行非常相似的操作,即定位位於某個文件夾或jar文件中的類文件,找到這些類並在應用程序加載它們之前對其進行調整。 然而,這並不總是有效,因為 jar 文件也可能被其他也會受到影響的應用程序使用。 此外,它會要求您的用戶從他們的應用程序中明確激活此檢測。 因此,類文件的儀器使用Java代理是什么賦予了訪問常用於Instrumentation API是什么使這個方便多了。 API 允許在 Java 的內部類加載機制中安裝一個鈎子,這使得可以在加載之前調整類的字節數組:

instrumentation.addClassFileTransformer(
  (Module module, ClassLoader loader, String name, 
   Class<?> classIfLoaded, ProtectionDomain pd, byte[] classFile) -> {
     byte[] transformed = doSomethingWith(classFile);
     return transformed;
});

此更改隨后與應用程序隔離,並且不會更改原始類文件。 檢測 API 並不意味着使用任何庫來修改類文件,這完全取決於您,每個人都在使用某種庫,甚至直接操作字節數組。 像 Byte Buddy 這樣的高級庫甚至不需要您實現自己的類文件轉換器,而是通過AgentBuilder API 擁有自己的抽象,但它會在AgentBuilder創建類文件轉換器以利用檢測 API 的獨特功能. 但是,其他庫(例如 ASM 或 Javassist)與Instrumentation API 沒有關系,並且需要您實現自己的類文件轉換器,在其中使用這些庫的 API 來處理呈現的類文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM