2008-09-03 10 views
3

На днях коллега указал мне на BCEL, который, насколько я могу судить по его объяснениям и быстрому прочтению, способ изменить во время выполнения байт-код. Сначала я подумал, что это звучит опасно, и я подумал, что это звучит круто. Затем я немного подумал, и я вспомнил codinghorror post on monkey-patching и понял, что это в основном то же самое. Кто-нибудь когда-либо использовал BCEL для чего-то практического? Правильно ли это, что это в основном врезка для обезьян, или я что-то упускаю?Is BCEL == monkeypatching для java?

+0

Другие люди используют asm (http://asm.ow2.org/) в наши дни. – 2011-09-23 14:00:12

ответ

1

Это немного более низкоуровневый, чем классический патч обезьяны, и из того, что я прочитал, классы, уже загруженные в виртуальную машину, не обновляются. Он поддерживает только сохранение его в файлах классов, не изменяя классы времени выполнения.

3

От FAQ BCEL по:

Q: Могу ли я создавать или изменять классы динамически с BCEL?

A: BCEL содержит полезные классы в пакете Util, а именно ClassLoader и JavaWrapper.Take взглянуть на ProxyCreator примере.

Но monkeypatching является ... uhm ... противоречивым, и вы, вероятно, не должны его использовать, если ваш язык его не поддерживает.

Если у вас есть хороший вариант использования, могу ли я предложить внедрить Jython?

0

Вы можете посмотреть на него как на патч обезьяны. Я предпочитаю не использовать его (возможно, я никогда не сталкивался с хорошим вариантом использования), но должен быть знаком с ним (чтобы понять, как Spring и Hibenrate используют его и почему).

0

См. Этот пример в реальном мире: Jawk - Compiler Module. BCEL полезен для «компиляции» пользовательского языка.

0

BCEL не поддерживает патч обезьяны, он просто управляет байт-кодом и, возможно, загружает его в пользовательский загрузчик классов. Однако вы можете реализовать monkeypatching на JVM, используя библиотеку, такую ​​как BCEL и агент Java. Агент Java (загруженный аргументом -javaagent) может обращаться к Инструментальному API-интерфейсу и изменять загруженные классы. Его не сложно реализовать через некоторые мосты.

Но помните:

  • Я не уверен, что, если возникнет необходимость использовать -javaagent является то, что вы хотите.
  • На любом языке исправление обезьян может привести к плохо прогнозируемому поведению.
  • Вы можете изменить метод. Теоретически вы также можете добавить какой-то метод, но вам нужно скомпилировать проект с измененными (исправленными) классами. Я думаю, что это вызвало бы большую боль, и это не стоит того. Существуют альтернативные языки, которые поддерживают его (например, Groovy) или поддерживают что-то подобное (например, неявные преобразования в Scala).
  • Лучше спроектировать ваш API, чем использовать исправление обезьяны. Это может быть весьма полезно для сторонних библиотек.