It does not perform any bytecode instrumentation manipulation / alteration but rather loads all classes available / loaded by the JVM in context into a UI in which it organizes classes by package namespace into a hierarchical tree structure.
This utility comes handy when you need to introspect class bytecode blueprint signatures that may be in question at runtime, similar to the javap utility that ships with jdk.
According to the specs the agent jar must contain:
(note that redefinitions + transformations are not set since neither is needed here)
MANIFEST.MF
...
Agent-Class: org.martin.agent.jvm.JvmAgent
Premain-Class: org.martin.agent.jvm.JvmAgent
Boot-Class-Path: jvmagent_1_0_0.jar
Can-Redefine-Classes: false
Can-Retransform-Classes: false
and method premain (similar to a 'main') signature hook is as follows:
org.martin.agent.jvm.JvmAgent
public static void premain(String agentArgs, Instrumentation inst) { ... }
once we have instrumentation access we can then:
[1] register a custom class transformer
instrumentation.addTransformer( new MyClassLoadTransformer() );
...
class MyClassLoadTransformer implements ClassFileTransformer {
public byte[] transform(
ClassLoader loader,
String fullyQualifiedClassName,
Class classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classofileBuffer) throws IllegalClassFormatException {
// illustration here!
}
}
[2] and invoke the instrumentation method:
final Class[] clsArr = instrumentation.getAllLoadedClasses();
which feeds the UI by representing pkgs hierarchicaly in a tree:
[1] download jar (only 22+k) and place it either in /lib or /bin of your app
[2] Then you just need to add -javaagent parameter such as:
java -javaagent:jvmagent_1_0_0.jar ...(more options here)
(depending on where it is : relative path -javaagent:../lib/jvmagent_1_0_0.jar , so configure accordingly!)
Agent will launch and load a UI with an initial draw, if your bootstrap process takes a bit longer then at any point you can press refresh button to re-load jvm state, the jvm + your application will be dynamically loading on demand classes based on the dependencies needed, so refresh accordingly.
Bytecode class dump disassembler credits.
Conclusion
Now imagine taking this concept further, profilers per say, or by using bytecode manipulation libraries such as asm or javassist an example is javarebel which allows reloading classes dynamically at runtime (even if making significant changes) without needing to restart container. I do have a working version agent where does hotswap (as long as new bytecode respects same signature and only changes within method implementation), however JVM can become very stale if you violate that limitation (at least up until now in jdk 6+).
Till next time, cheers!






