2013-09-23 6 views
2

Когда я пытаюсь найти примеры использования Javaagent, в большинстве случаев они являются примерами работы с байт-кодом. В этих примерах используются сторонние библиотеки, такие как Javaassist.Javaagent. Зачем?

Насколько я знаю, в Java нет стандартных средств для работы с байт-кодом, и в любом случае вам придется прибегать к библиотекам.

Итак, я попытался использовать эти библиотеки в своем собственном загрузчике классов перед вызовом defineClass(). И, конечно же, это сработало отлично. Я мог бы изменить байт-код таким же образом, как если бы я сделал это с помощью метода ClassFileTransformertransform().

Правильно ли я понимаю, что есть еще одна полезная функция javaagents, которая, в свою очередь, является их главной особенностью? Поскольку, прежде всего, javaagent дает вам объект Instrumentation, а спецификация Java говорит, что пакет instrument в основном используется для работы с байтовым кодом. Но зачем мне это делать, если я просто могу реализовать свой собственный загрузчик классов (что я мог бы сделать задолго до того, как был введен пакет instrument)?

ответ

3

Инструментарий API может использоваться во время работы, не касаясь кода или скомпилированного байтового кода. Вы можете использовать каждую скомпилированную java-программу (даже без кода).

+0

Не могли бы вы привести пример? –

+1

http://www.javabeat.net/2012/06/introduction-to-java-agents/# – isnot2bad

+0

Я смиренно сожалею, но все, что они сделали в статье, используется для преобразования байтового кода с ASM. То же самое можно сделать с помощью classloader –

2

Я думаю, что использование javaagent отличается от того, что оно не является частью вашего приложения. Вы можете написать, например, профилирующий агент и использовать его в любом приложении.

+0

Это довольно разумно. Но, насколько я понимаю, например, Mockito использует javaagent для управления байтовым кодом. Mockito присоединяет javaagent к JVM. Но если это единственная цель их javaagent, они могут просто использовать свой собственный загрузчик классов. Возможно, я что-то не понимаю =) –

+0

Я думаю, что Mockito строит прокси на лету во время выполнения, точно так же, как Spring AOP, хотя его единственная моя догадка –

1

Не смешивайте Javaagents и Instrumentation. Агент Java может использовать инструменты, но это не обязательно. Он может использовать все другие функции, предлагаемые платформой Java. Типичным примером агента, не использующего приборы, является агент JMX. Посмотрите, какие инструменты, например, JVisualVM. Большинство его функций (за исключением профилировщика) предоставляются через агента JMX без использования инструментов.

Кстати, в отношении вашего вопроса о разнице между инструментами и загрузчиками классов. Пользовательский загрузчик классов не может изменять классы, загружаемые через загрузчик классов загрузки, например java.lang.Object (хотя перед этим нужно подумать дважды). Кроме того, ваш пользовательский загрузчик классов должен был реализовать семантику оригинальных загрузчиков классов. В противном случае, например, если вы попытаетесь перехватить загрузку с помощью делегирования, ваш загрузчик классов пропустит все классы, загруженные, когда JVM попытается разрешить зависимости. И все классы, загруженные другим ClassLoader, созданные приложением (например, RMI), не будут обрабатываться вашим пользовательским загрузчиком классов.

Итак, Instrumentation добавляет способ обработки классов независимо от их ClassLoader и (опционально) даже позволяет их изменять по запросу после loading.