Является ли BCEL == monkeypatching для Java?
На днях коллега указал мне на BCEL, который, насколько я могу судить по его объяснениям и краткому прочтению, является способом изменения во время выполнения байтового кода. Моей первой мыслью было то, что это звучало опасно, а второй мыслью было, что это звучало круто. Затем я еще немного подумал и вспомнил пост кодирующего ужаса об исправлении обезьян и понял, что это в основном то же самое. Кто-нибудь когда-либо использовал BCEL для чего-нибудь практичного? Я прав, что это в основном исправление обезьян во время выполнения, или я что-то упустил?
5 ответов
Это немного более низкоуровневое исправление, чем классическое исправление обезьян, и, насколько я понимаю, классы, уже загруженные в виртуальную машину, не обновляются. Он поддерживает только повторное сохранение в файлы классов, но не изменяет классы времени выполнения.
Из часто задаваемых вопросов BCEL:
В: Могу ли я создавать или изменять классы динамически с помощью BCEL?
A: BCEL содержит полезные классы в пакете util, а именно ClassLoader и JavaWrapper. Посмотрите на пример ProxyCreator.
Но monkeypatching это... ммм... спорно, и вы, вероятно, не следует использовать, если ваш язык не поддерживает его.
Если у вас есть хороший вариант использования, могу ли я предложить встраивать Jython?
Посмотрите этот пример из реального мира: Jawk - Compiler Module. BCEL полезен для компиляции вашего пользовательского языка.
BCEL не поддерживает исправление обезьян, он просто манипулирует байт-кодом и, возможно, загружает его в пользовательский загрузчик классов. Однако вы можете реализовать monkey patching на JVM, используя такие библиотеки, как BCEL и агент Java. Агент Java (загруженный аргумент -javaagent) может получить доступ к API инструментария и изменить загруженные классы. Это не сложно реализовать через несколько мостов.
Но помни:
- Я не уверен, что вам нужно использовать -javaagent.
- На любом языке исправление обезьян может привести к плохо предсказуемому поведению.
- Вы можете изменить метод. Теоретически, вы также можете добавить некоторый метод, но вам нужно скомпилировать проект с использованием измененных (исправленных) классов. Я думаю, что это причинит много боли, и оно того не стоит. Существуют альтернативные языки, которые поддерживают его (например, Groovy) или поддерживают нечто подобное (например, неявные преобразования в Scala).
- Лучше хорошо спроектировать свой API, чем использовать патчи для обезьян. Это может быть весьма полезно для сторонних библиотек.
Вы могли бы смотреть на это как на исправление обезьяны. Я предпочитаю не использовать его (возможно, я никогда не сталкивался с хорошим вариантом использования для него?), Но быть знакомым с ним (чтобы иметь представление о том, как Spring и Hibenrate его используют и почему).