2013-09-23 26 views
2

當我嘗試查找使用Javaagent的示例時,在大多數情況下,它們都是使用字節碼的示例。這些示例使用第三方庫,如Javaassist。Javaagent。做什麼的?

據我所知,在Java中沒有使用字節碼的標準方法,無論如何你必須求助於這些庫。

所以,我試圖在調用defineClass()之前在我自己的自定義類加載器中使用這些庫。當然,它工作得很好。我可以用同樣的方法改變字節碼,就好像我用ClassFileTransformertransform()方法來做。

我是否正確理解javaagents有另一個有用的功能,反過來又是它們的主要功能?因爲首先,javaagent爲您提供了一個Instrumentation對象,Java規範說明instrument包主要用於處理字節碼。但是爲什麼我需要這樣做,如果我只是可以實現我自己的類加載器(在引入instrument包之前我可以做的事情)?

回答

3

Instrumentation API可以在運行時使用,無需觸摸代碼或編譯的字節碼。你可以測試每個已編譯的java程序(即使沒有代碼)。

+0

你能舉個例子嗎? –

+1

http://www.javabeat.net/2012/06/introduction-to-java-agents/# – isnot2bad

+0

我很抱歉,但他們在文章中所做的一切都是使用ASM進行字節碼轉換。類加載器也可以做到這一點。 –

2

我認爲使用javaagent是不同的,因爲它不是你的應用程序的一部分。您可以編寫例如分析代理並將其用於任何應用程序。

+0

這是非常明智的。 但據我瞭解Mockito例如使用javaagent來操作字節碼。 Mockito將javaagent附加到JVM。但如果它是他們的javaagent的唯一目的,他們可以簡單地使用他們自己的類加載器。 也許我不明白的東西=) –

+0

我認爲Mockito在運行時建立代理,就像Spring AOP一樣,儘管它只是我的猜測 –

1

不要混淆Javaagents和Instrumentation。一個Java代理可以使用檢測,但不一定。它可以使用Java平臺提供的所有其他功能。不使用檢測的代理的典型示例是JMX代理。看看JVisualVM提供什麼工具。它的大部分功能(除了分析器)都是通過JMX代理提供的,而不使用儀器。

順便說一句,關於你的問題關於儀器和類裝載機之間的區別。自定義類加載器不能改變通過引導類加載器加載的類,如java.lang.Object(儘管在做這件事之前你應該三思而後行)。此外,您的自定義類加載器必須實現原始類加載器語義才能工作。否則,例如如果您嘗試使用委託攔截加載,那麼當JVM嘗試解析依賴關係時,您的類加載器將會錯過所有加載的類。而且由應用程序(例如由RMI)創建的另一個ClassLoader加載的所有類都不會被您的自定義類加載器處理。

因此,Instrumentation增加了一種方法來處理與其ClassLoader無關的類,並且(可選)甚至允許在加載後根據需要更改它們。