2014-02-20 36 views
0

我想通過字節碼修改使用asm字節碼檢測庫加載一些對象。ASM不在類轉換中加載對象,但通常轉換工作正常

我正在使用retransformClasses()方法重新轉換類。

我加載這樣的對象:

super.visitVarInsn(Opcodes.ALOAD, 0); 
super.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc); 
super.visitMethodInsn(org.objectweb.asm.Opcodes.INVOKESTATIC, 
            "com/coolcoder/MyClass", 
            "objectCheckTest", 
            "(Ljava/lang/Object;)V");` 

的問題是,我的對象越來越使用ClassTransformer通常tranform()加載,但是當我使用Attach APIretranformClasses(),這些對象都沒有正在加載。奇怪的是,我也沒有收到任何字節碼錯誤。

我做錯了什麼?還是我錯過了一些關於retransform的複雜部分?

+0

確實是實際執行的轉型?即你可以添加一些調試輸出或其他東西來確保? –

+0

@AndreyBreslav:是的,轉型正在執行中。我在objectCheckTest()中添加了一些調試語句來驗證這一點,並且它們正在執行。 – DukeLover

+0

@AndreyBreslav:我認爲問題在於'redefination'。儘管我無法完全理解這個問題,但是我可以看到我正在執行這些字節碼修改的類,正在獲取'redefined'。對此有何想法? – DukeLover

回答

0

我已經能夠解決這個問題,但我不知道爲什麼它發生在第一位。 (1)我只在PUTFIELDPUTSTATIC操作碼上加載對象,即設置對象值時。

(2)在字節碼修改之後,類正在被重新定義,結果代碼片段不起作用。

(3)下次由於redefinition加載類時,該對象已被設置,因此不會再次調用該對象。 (4)現在,當我檢查GETFIELDGETSTATIC操作碼時,即當對象的值正在檢索並加載它時,我能夠查看其詳細信息。

我上面提到的相同方法在通常的transformation(即與premain一起運行)中工作正常。

關於redefinition這種不規則行爲的任何想法?

0

首先,在manifest.mf文件中,Can-Retransform-Classes屬性應爲true

和你ClassFileTransformer實例應該用在方法addTransformer參數canRetransform真正值增加。

這裏是另一個額外提示:

如果變壓器拋出一個異常(它沒有趕上),隨後變壓器仍將被調用,負載,重新定義或重新轉換後仍然會嘗試。因此,引發異常與返回null的效果相同。爲了防止在變壓器代碼中生成未經檢查的異常時的意外行爲,變壓器可以捕獲Throwable。如果變換器認爲classFileBuffer不代表有效格式化的類文件,則它應該拋出IllegalClassFormatException;儘管這與返回null的效果相同。它有助於記錄或調試格式損壞。

java api docs

因此,有可能將被JVM恰恰忽略了一些uncatched例外arised。 你可以把在try..catch

請原諒我的英語不好......