Wie verwende ich Instrumentation.retransformClasses () korrekt aus dem asm-Code?

8

Ich benutze die asm-Bibliothek, um einige Java-Bytecode-Modifikationen durchzuführen - speziell um meine Klassen zu modifizieren, um eine neue Schnittstelle und zugehörige Methoden zu implementieren. Mein aktueller Ansatz ist die Verwendung der Core-API asm über einen Java-Agent. Ich möchte diesen dynamischen Ansatz beibehalten, anstatt .class-Dateien statisch zu ändern.

Auf einer höheren Ebene ist mein Problem, dass ich, wenn ich die Klasse A ändern möchte, die von B ausgeht, auch B modifizieren muss. (Wenn ich verstehe, wie Klassen in die JVM geladen werden, glaube ich, dass Klasse B wird immer vor der Klasse A an einen Transformator übergeben werden (Bitte korrigieren Sie mich, wenn ich falsch liege.) Angesichts dieser Annahme denke ich, dass ich dann zurückgehen und rücktransformieren B. Mein Ansatz ist in diesem Bit des Codes erfasst:

%Vor%

( inst ist ein Handle für Instrumentation , das im Konstruktor übergeben wird)

Der Teil, mit dem ich eine harte Zeit habe, ist der Block, der in den Kommentaren mit **2** markiert ist. Lassen Sie uns noch einmal sagen, dass A B erweitert und ich daran interessiert bin, A zu transformieren. Was ich erwarte, ist, dass ich den Namen der Superklasse (B) in **1** gedruckt sehe (aber nicht transformiert werde, weil ich nicht weiß) Ich denke, dass es im ersten Durchgang interessant ist. Und sobald ich zu **2** komme und feststelle, dass As Oberklasse B ist, sollte ich versuchen, B umzuwandeln. An dieser Stelle erwarte ich, dass diese Methode erneut aufgerufen wird ( via inst.retransformClasses() ) und ich würde sehen, dass B bei **1** gedruckt wird. Aber ich nicht. (Ich habe print-Anweisungen hinzugefügt und bin sicher, dass ich den retransform-Aufruf erreiche. Ich habe auch überprüft, dass Instrumentation.isRetransformClassesSupported() und Instrumentation.isModifiableClass(c) beide wahr zurückgeben).

Ich glaube, ich habe den Agenten richtig eingerichtet; Setzen Sie sowohl Can-Retransform-Klassen als auch Can-Redefine-Klassen im Manifest auf true. Wenn ich den Transformer zur Instrumentierung in der premain -Methode des Agenten hinzufüge, mache ich das auch:

%Vor%

Irgendwelche Erkenntnisse darüber, was ich hier falsch mache? Danke.

    
Jens 01.03.2012, 22:41
quelle

1 Antwort

1

Sie können Ihre Bytecode-Instrumentierungsstrategie ändern. Wenn Klasse B geladen wird, finden Sie alle Unterklassen und entscheiden an diesem Punkt, ob Sie die Klasse B jetzt ändern müssen. Dies kann optimiert werden, indem das Klassenmetadaten-Repository oder der Cache im Speicher (d. H. Informationen zur Klassenhierarchie) beibehalten werden, sodass Sie nicht jedes Mal Metadaten laden müssen.

    
Eugene Kuleshov 02.03.2012 18:57
quelle