Reputation: 101
As part of our instrumentation tool suite, we have a static prepass that modifies some methods of a class and then marks those methods with a user defined attribute. When the application is run, if the class file is presented directly to the the transform() method, i.e. it is the first load of the class, I can see these attributes. But if I use retransformClasses(), then when I get control in at the transform() method my attributes have been deleted. I can see why the JVM might discard unknown attributes when recreating the class bytes to pass to transform(), but I cannot find any documentation verifying and/or describing this behavior.
How can I accomplish this goal? I can see no guarantee that the same does not happen for RuntimeVisible annotations. And even if they are preserved, they are so much more difficult to work with than attributes I would like to avoid that approach.
Any ideas on how to add 'notes' to a method that are preserved through retransformClasses()?
Thanks for any suggestions.
Upvotes: 1
Views: 50
Reputation: 98600
Once a class file is loaded, HotSpot JVM does not preserve the original bytecode. Instead, it reconstitutes the bytecode from the internal VM representation when needed. The attributes that VM does not understand are not restored.
The documentation to retransformClasses
explicitly mentions this possibility:
The initial class file bytes represent the bytes passed to ClassLoader.defineClass or redefineClasses (before any transformations were applied), however they might not exactly match them. The constant pool might not have the same layout or contents. The constant pool may have more or fewer entries. Constant pool entries may be in a different order; however, constant pool indices in the bytecodes of methods will correspond. Some attributes may not be present. Where order is not meaningful, for example the order of methods, order might not be preserved.
In the mean time, RuntimeVisibleAnnotations
attribute is understood by the JVM. Moreover, there is Java API to access them, therefore JVM cannot throw them away during transformation. HotSpot JVM indeed writes RuntimeVisibleAnnotations
when reconstituting the bytecode.
So, your best bet is to use annotations - after all, they are designed exactly for marking members with user-defined metadata.
Upvotes: 1