Source:
<code>public Object evaluate(ClassLoader loader, Binding binding) throws Exception { if (!calledConfiguring) { throw new IllegalStateException("you need to call configuring or a related method before using GroovyScript"); } URLClassLoader urlcl = null; ClassLoader memoryProtectedLoader = null; List<ClasspathEntry> cp = getClasspath(); if (!cp.isEmpty()) { List<URL> urlList = new ArrayList<URL>(cp.size()); for (ClasspathEntry entry : cp) { ScriptApproval.get().using(entry); urlList.add(entry.getURL()); } loader = urlcl = new URLClassLoader(urlList.toArray(new URL[urlList.size()]), loader); } try { loader = GroovySandbox.createSecureClassLoader(loader); <START> Field loaderF = GroovyShell.class.getDeclaredField("loader"); <END> loaderF.setAccessible(true); GroovyShell sh; if (sandbox) { CompilerConfiguration cc = GroovySandbox.createSecureCompilerConfiguration(); sh = new GroovyShell(loader, binding, cc); memoryProtectedLoader = new CleanGroovyClassLoader(loader, cc); loaderF.set(sh, memoryProtectedLoader); try { return GroovySandbox.run(sh.parse(script), Whitelist.all()); } catch (RejectedAccessException x) { throw ScriptApproval.get().accessRejected(x, ApprovalContext.create()); } } else { sh = new GroovyShell(loader, binding); memoryProtectedLoader = new CleanGroovyClassLoader(loader); loaderF.set(sh, memoryProtectedLoader); return sh.evaluate(ScriptApproval.get().using(script, GroovyLanguage.get())); } } finally { try { loader = null; cleanUpLoader(memoryProtectedLoader, new HashSet<ClassLoader>(), new HashSet<Class<?>>()); } catch (Exception x) { LOGGER.log(Level.WARNING, "failed to clean up memory " , x); } if (urlcl != null) { urlcl.close(); } } }</code><technical_language>need catch NoSuchFieldException quietly fall gracefully, in case this code is refactored in a future version of Groovy. (I do _not_ recommend swallowing other reflection exceptions-log WARNINGs: expected. I.e., do repeat this mistake: <LINK_0></technical_language>

Target:
public Object evaluate(ClassLoader loader, Binding binding) throws Exception { if (!calledConfiguring) { throw new IllegalStateException("you need to call configuring or a related method before using GroovyScript"); } URLClassLoader urlcl = null; ClassLoader memoryProtectedLoader = null; List<ClasspathEntry> cp = getClasspath(); if (!cp.isEmpty()) { List<URL> urlList = new ArrayList<URL>(cp.size()); for (ClasspathEntry entry : cp) { ScriptApproval.get().using(entry); urlList.add(entry.getURL()); } loader = urlcl = new URLClassLoader(urlList.toArray(new URL[urlList.size()]), loader); } boolean canDoCleanup = false; try { loader = GroovySandbox.createSecureClassLoader(loader); Field loaderF = null; try { loaderF = GroovyShell.class.getDeclaredField("loader"); loaderF.setAccessible(true); canDoCleanup = true; } catch (NoSuchFieldException nsme) { LOGGER.log(Level.FINE, "GroovyShell fields have changed, field loader no longer exists -- memory leak fixes won't work"); } GroovyShell sh; if (sandbox) { CompilerConfiguration cc = GroovySandbox.createSecureCompilerConfiguration(); sh = new GroovyShell(loader, binding, cc); if (canDoCleanup) { memoryProtectedLoader = new CleanGroovyClassLoader(loader, cc); loaderF.set(sh, memoryProtectedLoader); } try { return GroovySandbox.run(sh.parse(script), Whitelist.all()); } catch (RejectedAccessException x) { throw ScriptApproval.get().accessRejected(x, ApprovalContext.create()); } } else { sh = new GroovyShell(loader, binding); if (canDoCleanup) { memoryProtectedLoader = new CleanGroovyClassLoader(loader); loaderF.set(sh, memoryProtectedLoader); } return sh.evaluate(ScriptApproval.get().using(script, GroovyLanguage.get())); } } finally { try { if (canDoCleanup) { cleanUpLoader(memoryProtectedLoader, new HashSet<ClassLoader>(), new HashSet<Class<?>>()); } } catch (Exception x) { LOGGER.log(Level.WARNING, "failed to clean up memory " , x); } if (urlcl != null) { urlcl.close(); } } }