Re: Instrumentation of JComponent
On Sep 21, 5:29 pm, Alessio Stalla <alessiosta...@gmail.com> wrote:
On Sep 20, 11:29 am, Lethal Possum <lethal.pos...@gmail.com> wrote:
Hello everyone,
I am working on a little project to learn how to use the
Instrumentation framework work. I want to append the current class
name in the tooltip of every JComponent. Seems simple enough, right.
So I started by writing a basic ClassFileTransformer that prints every
class name. I also created a very simple GUI to test my transformer.
It all seems to work fine except that it never see the class
JComponent. At some point it prints "javax/swing/JComponent$1" but
never "javax/swing/JComponent". However if I debug my test code, I can
see that if I leave the mouse over the test label, I stop in my
breakpoint in JComponent.getToolTipText(). How is that possible
without loading the JComponent class? Or am I not understanding what's
going on here?
I've copied my source code below. Thanks in advance for your help.
Cheers,
Tom
=== Source code ===
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class Premain {
public static void premain(String agentArguments, Instr=
umentation
instrumentation) {
instrumentation.addTransformer(new Clas=
sFileTransformer() {
public byte[] transform(ClassLo=
ader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
lassFormatException {
sName);
return classfileBuffer;
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("test");
label.setToolTipText("test");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
}
Wild guess: since your premain method is in the same class as
createAndShowGUI, chances are that when loading the Premain class the
classes referenced by it are also loaded, before premain is run. And
in turn, the classes referenced by them. That's why you see neither
JComponent nor JLabel (nor, I guess, JFrame). As for JComponent$1,
maybe there's some optimization that makes inner classes only be
loaded when they're first accessed.
Cheers,
Alessio
Yes, I think you are right Alessio! I moved my test code (the methods
main() and createAndShowGUI()) to a separate class and now I see them
being passed through my agent. I guess previously they were loaded
before the agent itself.
That's great, thanks so much to all of you for your help.
Cheers,
Tom