2017-06-13 27 views
0

Java Agent提供了測試Java編程語言代碼所需的服務。 ClassFileTransformer是Java代理的實現,轉換髮生在JVM定義的類之前。唯一的方法transform需要實現,並且每個新的類定義都會調用它。如何Java Agent作品的說明:如何通過Java代理保存檢測到的java字節碼?

Java Agent

我想保存改動的代碼,這樣我就可以不插裝,每次運行儀表類文件。正如我檢查Interface Instrumentation,我沒有看到任何直接的API來保存轉換後的字節碼。我想知道是否可以使用Java Agent來實現我的目標或其他工具?

+0

你正在儀表自己的班級或第三方圖書館? – vempo

+0

@vempo我自己的類,示例代碼與可用的源代碼。 – Qoros

回答

1

您需要的是構建時或編譯時儀器,而不是運行時。大多數字節碼檢測工具都支持 - Javassist,AspectJ,ASM

實際上,您可以將由您的代理程序檢測的字節碼保存到.class文件,其結果只是表示類的字節數組。但是,您必須至少與代理程序一起運行您的程序,並確保您加載了所有需要儀器的類,以便爲每個類創建一個.class文件。所以我不推薦這種方法

if (shouldInstrument) { 

    CtClass cclass = pool.get(className.replaceAll("/", ".")); 

    // Instrument the class here 

    byte[] bytecode = cclass.toBytecode(); 

    File outputFile = new File(String.format("%s/%s.class", outputDirectory, className)); 
    Files.createDirectories(outputFile.getParentFile().toPath()); 

    try (FileOutputStream fos = new FileOutputStream(outputFile)) { 
     fos.write(bytecode); 
    } 

    return bytecode; 
} 

另外,如果你的目標是不污染的源代碼與樣板代碼一些功能添加到您自己的類,你可以操縱的源代碼,而不是字節碼。源 - >生成源 - >字節碼(編譯)。例如,使用註釋和自定義annotation processor

+0

謝謝。您提到將您的代理所檢測的字節碼保存到'.class'文件中。我嘗試過,但是我發現每個班級都會調用'transform'函數。我也嘗試將所有轉換後的代碼保存到一個類中,但它不起作用。 – Qoros

+0

我的意思是你可以只用你需要的類並將它們保存在相應的類文件中。 – vempo

+0

「最外層」是什麼意思?你在談論內部類嗎?我認爲你在這裏處理不正確的假設。在單個Java源文件中聲明的所有類仍然具有各自的.class文件。 transform()方法不是應用於Java源文件,而是應用於每個單獨的類 - 一次加載一個類。嘗試運行我的代碼和內部類,你會看到類似Test $ 1.class(匿名),Test $ Inner.class,Test $ Inner $ Deeper.class等 – vempo