Как отменить изменения мета-классов после выполнения GroovyShell? - PullRequest
10 голосов
/ 23 октября 2009

Например, если я выполняю скрипт Groovy, который изменяет мета класс String, добавляя метод foo ()

GroovyShell shell1 = new GroovyShell();
shell1.evaluate("String.metaClass.foo = {-> delegate.toUpperCase()}");

когда после этого я создаю новую оболочку и выполняю ее, изменения все еще остаются

GroovyShell shell2 = new GroovyShell();
Object result = shell2.evaluate("'a'.foo()");

Есть ли способ отменить все изменения мета-классов после выполнения GroovyShell? Я пытался

shell1.getClassLoader().clearCache();

и

shell1.resetLoadedClasses();

но это не изменило.

Ответы [ 3 ]

12 голосов
/ 28 октября 2009

Вы можете использовать

GroovySystem.metaClassRegistry.removeMetaClass(String.class);

чтобы отменить все изменения, внесенные в мета-класс String.

Кроме того, вы можете изменить только мета-класс определенного экземпляра String, поэтому не все экземпляры String будут затронуты.

2 голосов
/ 12 февраля 2016

Вы также можете использовать MetaClassRegistryCleaner.

Перед выполнением некоторых изменений метакласса вы можете сделать

MetaClassRegistryCleaner registryCleaner = MetaClassRegistryCleaner.createAndRegister()
GroovySystem.metaClassRegistry.addMetaClassRegistryChangeEventListener(registryCleaner)

А когда вы хотите сбросить изменения метакласса в состояние, в котором они были ранее.

Вы можете сделать

registryCleaner.clean()  
GroovySystem.metaClassRegistry.removeMetaClassRegistryChangeEventListener(registryCleaner)

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

0 голосов
/ 15 марта 2012

Я понимаю, что это несколько более старый вопрос, но это первый результат в Google, когда я искал точно такую ​​же проблему.

Решение, которое я выбрал, состояло в том, чтобы поместить groovy в новый загрузчик классов (с помощью plexus-classworlds), поэтому, когда скрипт завершится, загрузчик классов будет удален (и поэтому любые изменения в метаклассе также будут удалены).

...