2012-12-19 3 views
1

Я пытаюсь написать библиотеку агентов Java, динамически загружаемую с помощью приложения api для ретрансляции некоторых методов (тех, которые появляются в стековых трассах определенных потоков) для записи метода ввода/выхода. Информация о входе/выходе метода затем экспортируется через пользовательский номер MBean.Собственные методы Retransform в библиотеке агентов инструментария Java

Мой текущий «прототип» работает до тех пор, пока инструментальные методы не являются родными.

В соответствии с документацией java.lang.instrument.Instrumentation#setNativeMethodPrefix() должно быть возможно, чтобы java-агенты заменили собственный метод неродным методом заглушки и добавили другой собственный метод с этим префиксом в его имя, которое затем привязано к исходному натурному методу собственный код.

Однако при реализации этого, я получаю эту ошибку:

java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method 

, который является правильным, так как я добавил новый нативный метод.

Выполняется только замена собственного метода на не-родной, но я не могу делегировать вызов обратно исходному натурному методу. Определение собственного метода в другом классе не работает, так как собственные методы просматриваются по имени и имени класса и нет nativeMethodClassSuffix или тому подобное. Определение другого класса с тем же именем в другом новом загрузчике классов будет работать, и я думаю, что с некоторыми отказами можно было бы делегировать вызов новому классу, но одна родная библиотека может быть привязана только к встроенным методам, загружаемым классами только одного класса class loader, поэтому я не буду правильно использовать родные методы.

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

+0

Ты нашел решение проблемы? У меня есть аналогичная проблема, и я буду признателен за некоторый код ссылки. – nadavy

+0

@nadavy no, я решил не использовать собственные методы и документировать это ограничение ссылкой на этот вопрос StackOverflow :) – mihi

+0

lol. Ну, это решение :-). Спасибо, что ответили! – nadavy

ответ

2

Is there anything obvious I'm missing here? My code is a bit too long to post here, if anyone thinks it helps I can try to build a small example java agent that shows the problem and link to it here.

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

Еще один вариант - изменить все ссылки на собственный метод, а не маскировать его. Таким образом вы все равно можете вызвать оригинальный метод, когда захотите.

+0

спасибо за ваш ответ. Я был сбит с толку, поскольку функция префикса нативного метода звучала так, как будто я должен был использовать. Изменение всех ссылок на метод в моей ситуации нецелесообразно, так как это потребует сканирования всех загруженных классов для ссылок. Спасибо в любом случае за быстрый ответ :) – mihi