Today I was exploring classes of huge applications (like jboss server with apps) with javaagent and instrumentation on my openjdk 7. I called retransform on all classes every 10 seconds, so their bytecode got in my ClassFileTransformer implementation.
My implementation simply keeps track of how bytecode of classes changes over time. First of all, I was surprised, that order of fields and methods, method access modifiers, contents of constant pool and other such things vary from one check to the other. But, still, it is documented.
What is not documented - that some items may be created in class'es constant pool and injected into methods. For now I noticed that to happen with numeric values (Longs, Doubles, Floats and such).
This is how it looks in javap; before:
pool:
...
#17 Float NaNf
method:
#1 fload #17 //NaNf
...
After something changed class during runtime:
pool:
...
#17 Float NaNf
#18 Float NaNf
method:
#1 fload #18 //NaNf <- look, it loads #18 now
I double checked, that no other transformers or agents are attached.
Why can't JVM just leave my bytecode the same? Where can I read about such optimisations/transformations (or what else is it)? I read JVM sources, but these only confused me more.
I'm just trying to create some kind of realtime bytecode verificator - a security tool.