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