How do I undo meta class changes after executing GroovyShell?

橙三吉。 提交于 2019-12-18 05:50:13

问题


For example, if I execute a Groovy script, which modifies the String meta class, adding a method foo()

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

when I create a new shell after that and execute it, the changes are still there

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

Is there a way to undo all meta class changes after executing the GroovyShell? I tried

shell1.getClassLoader().clearCache();

and

shell1.resetLoadedClasses();

but that did not make a change.


回答1:


You can use

GroovySystem.metaClassRegistry.removeMetaClass(String.class);

to revert all changes made to the String meta class.

Alternatively you could only change the meta class of a certain String instance, thus not all instances of String would be affected.




回答2:


You can use MetaClassRegistryCleaner too.

Before doing some metaclass changes, you can do

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

And when you want to reset the metaclass changes to the state they were earlier.

You can do

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

This way you can reset all the metaclass changes made during the duration.




回答3:


I realise that this is a somewhat older question, but it's the first result on Google when I was searching for exactly the same issue.

The solution I chose was to put groovy into a new classloader (by using plexus-classworlds), so when the script is finished, the classloader is disposed (and so any changes to the metaclass are also disposed).



来源:https://stackoverflow.com/questions/1612569/how-do-i-undo-meta-class-changes-after-executing-groovyshell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!