Java NoClassDefFoundError при вызове собственного класса из инструментированного метода

Я работаю над набором простых агентов Java, которые помогут мне (и, надеюсь, другим) устранять неполадки в приложениях Java. Один из агентов, который я хотел бы создать, представляет собой метод JComponent.getToolTipText(), позволяющий быстро идентифицировать любой класс GUI, просто наведя на него курсор мыши.

Вы можете найти код моего трансформатора и остальную часть проекта здесь:

http://sfn.cvs.sourceforge.net/viewvc/sfn/core/src/main/java/org/leplus/sfn/transformer/JComponentTransformer.java?view=markup

Я запускаю свой тестовый графический интерфейс с подключенным агентом следующим образом:

$ java -javaagent:target/jars/sfn-0.1-agent.jar=JComponent -cp lib/jars/bcel-5.2.jar:target/jars/sfn-0.1-test.jar:target/jars/sfn-0.1-agent.jar org.leplus.sfn.test.Main

sfn-0.1-agent.jar содержит класс org.leplus.sfn.transformer.JComponentTransformer. sfn-0.1-test.jar содержит класс org.leplus.sfn.test.Main.

Вот что печатает приложение, когда я запускаю его и навожу на него мышь:

Loading agent: JComponent
Instrumentation ready!
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/leplus/sfn/tracer/ComponentTracer
 at javax.swing.JComponent.getToolTipText(JComponent.java)
 at javax.swing.ToolTipManager$insideTimerAction.actionPerformed(ToolTipManager.java:662)
...

Что меня удивляет, так это то, что если я изменю свой преобразователь на вызов любого класса из JRE, он сработает. Но это не работает, когда я вызываю свой собственный класс org.leplus.sfn.tracer.ComponentTracer. Мое первое предположение было проблемой пути к классам, но ComponentTracer находится как в пути к классам, так и в банке агента. Так что я потерян.

Если кто-то из вас видит, где я что-то упускаю.

Ваше здоровье,

Том


person Thomas Leplus    schedule 01.01.2011    source источник


Ответы (2)


Это проблема с загрузчиком классов. Вы инструментируете класс (javax.swing.JComponent), управляемый загрузчиком классов начальной загрузки, и ссылаетесь на класс (org.leplus.sfn.tracer.ComponentTracer), управляемый системным загрузчиком классов.

Если вы поместите свой класс ComponentTracer в загрузчик классов начальной загрузки, проблема должна исчезнуть.

java -Xbootclasspath/p:<path/to/jar/containing/ComponentTracer> -javaagent:...
person axw    schedule 02.01.2011
comment
Для будущих читателей: загрузчик классов bootstrap также называется первичным загрузчиком классов во многих источниках. Точно так же загрузчик системного класса иногда называют загрузчиком класса приложения. - person Duncan Jones; 23.04.2014

Попробуйте запустить с -DDEBUG, так как это может показать вам больше информации.

Кроме того, я вижу здесь целевой каталог. http://sfn.cvs.sourceforge.net/viewvc/sfn/core/target/ Он содержит папку классов, но не папку jars? Убедитесь, что пути jar указаны относительно корня проекта.

person jmort253    schedule 02.01.2011