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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With