You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/12/04 22:09:28 UTC

[groovy] branch master updated: minor edits

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 61c2ada  minor edits
61c2ada is described below

commit 61c2adaa6aef6668b8d1d792818fa4f07c64e613
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Dec 4 16:09:22 2021 -0600

    minor edits
---
 .../codehaus/groovy/runtime/ConversionHandler.java |  23 +-
 src/test/groovy/IllegalAccessTests.groovy          |   4 +-
 src/test/groovy/bugs/Groovy8815.groovy             |   9 +-
 src/test/groovy/bugs/Groovy9932.groovy             |  29 +-
 .../util/GroovyScriptEngineReloadingTest.groovy    | 546 ++++++++++-----------
 5 files changed, 285 insertions(+), 326 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java b/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
index 4e40d25..479e9cd 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
@@ -30,7 +30,6 @@ import java.io.Serializable;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -92,19 +91,22 @@ public abstract class ConversionHandler implements InvocationHandler, Serializab
      * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
      */
     @Override
-    public Object invoke(final Object proxy, Method method, Object[] args) throws Throwable {
+    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
         if (isDefaultMethod(method) && !defaultOverridden(method)) {
-            final VMPlugin plugin = VMPluginFactory.getPlugin();
-            Object handle = handleCache.computeIfAbsent(method, m -> plugin.getInvokeSpecialHandle(m, proxy));
+            VMPlugin plugin = VMPluginFactory.getPlugin();
+            Object handle = handleCache.computeIfAbsent(method, m ->
+                plugin.getInvokeSpecialHandle(m, proxy)
+            );
             return plugin.invokeHandle(handle, args);
         }
 
         if (!checkMethod(method)) {
             try {
                 if (method.getDeclaringClass() == GroovyObject.class) {
-                    if ("getMetaClass".equals(method.getName())) {
+                    switch (method.getName()) {
+                    case "getMetaClass":
                         return getMetaClass(proxy);
-                    } else if ("setMetaClass".equals(method.getName())) {
+                    case "setMetaClass":
                         return setMetaClass((MetaClass) args[0]);
                     }
                 }
@@ -121,16 +123,15 @@ public abstract class ConversionHandler implements InvocationHandler, Serializab
         }
     }
 
-    private boolean defaultOverridden(Method method) {
+    private boolean defaultOverridden(final Method method) {
         return delegate instanceof Map && ((Map) delegate).containsKey(method.getName());
     }
 
-    protected boolean isDefaultMethod(Method method) {
-        return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
-                Modifier.PUBLIC) && method.getDeclaringClass().isInterface();
+    protected boolean isDefaultMethod(final Method method) {
+        return method.isDefault();
     }
 
-    protected boolean checkMethod(Method method) {
+    protected boolean checkMethod(final Method method) {
         return isCoreObjectMethod(method);
     }
 
diff --git a/src/test/groovy/IllegalAccessTests.groovy b/src/test/groovy/IllegalAccessTests.groovy
index ceb5fca..256bfe0 100644
--- a/src/test/groovy/IllegalAccessTests.groovy
+++ b/src/test/groovy/IllegalAccessTests.groovy
@@ -30,8 +30,8 @@ import static org.junit.Assume.assumeTrue
  * Java via means such as reflection.
  *
  * In JDK versions < 9, Groovy supports permissive access and no warnings are given by the JDK.
- * In 9 <= JDK versions < 16, Groovy supports permissive access but the JDK gives illegal access warnings.
- * At some point, the JDK may further restrict permissive access and Groovy's support for this feature may be limited.
+ * In JDK versions in 9..15, Groovy supports permissive access but the JDK gives illegal access warnings.
+ * In JDK versions > 16, permissive access is restricted and Groovy's support for this feature is limited.
  */
 final class IllegalAccessTests {
 
diff --git a/src/test/groovy/bugs/Groovy8815.groovy b/src/test/groovy/bugs/Groovy8815.groovy
index e520b8c..f3dc49e 100644
--- a/src/test/groovy/bugs/Groovy8815.groovy
+++ b/src/test/groovy/bugs/Groovy8815.groovy
@@ -22,17 +22,10 @@ import org.codehaus.groovy.control.CompilerConfiguration
 import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
 import org.junit.Test
 
-import static groovy.test.GroovyAssert.isAtLeastJdk
-import static org.junit.Assume.assumeTrue
-
 final class Groovy8815 {
 
     @Test
     void testGenerics() {
-        // illegal access to `java.lang.reflect.Method.getGenericSignature`, i.e. `method.genericSignature` in the test
-        // but illegal access is not allowed by default since JDK 16
-        assumeTrue(!isAtLeastJdk('16.0'))
-
         def config = new CompilerConfiguration(
             targetDirectory: File.createTempDir(),
             jointCompilationOptions: [memStub: true]
@@ -75,7 +68,7 @@ final class Groovy8815 {
             def method = loader.loadClass('Service').getMethod('on', Class, Closure)
 
             // should not contain unresolved type parameter 'T'
-            assert method.genericSignature == '<E:LEvent<*>;>(Ljava/lang/Class;Lgroovy/lang/Closure;)LRegistration<Ljava/lang/Object;Ljava/util/function/Consumer<TE;>;>;'
+            assert method.genericReturnType.typeName == 'Registration<java.lang.Object, java.util.function.Consumer<E>>'
         } finally {
             parentDir.deleteDir()
             config.targetDirectory.deleteDir()
diff --git a/src/test/groovy/bugs/Groovy9932.groovy b/src/test/groovy/bugs/Groovy9932.groovy
index 856613e..d46988f 100644
--- a/src/test/groovy/bugs/Groovy9932.groovy
+++ b/src/test/groovy/bugs/Groovy9932.groovy
@@ -18,20 +18,21 @@
  */
 package groovy.bugs
 
-import groovy.mock.interceptor.MockFor
-import org.junit.Ignore
+import org.codehaus.groovy.control.CompilerConfiguration
 import org.junit.Test
 
+import static org.junit.Assume.assumeFalse
+
 final class Groovy9932 {
-    @Ignore
-    @Test
-    void testCallCurrentOnMock() {
-        def mockForHelper = new MockFor(Helper)
 
-        mockForHelper.demand.helperMethod { -> 'intercepted' }
-        mockForHelper.ignore('getMyString')
+    @Test
+    void testMockCallChain() {
+        assumeFalse(CompilerConfiguration.DEFAULT.isIndyEnabled())
 
-        mockForHelper.use {
+        new groovy.mock.interceptor.MockFor(Helper).tap {
+            demand.publicMethod { -> 'intercepted' }
+            ignore 'getMyString'
+        }.use {
             def helper = new Helper()
             assert helper.myString == 'intercepted'
         }
@@ -41,16 +42,14 @@ final class Groovy9932 {
         String myString
 
         Helper() {
-            myString = internalMethod()
+            myString = privateMethod()
         }
 
-        // separate method to ensure callCurrent is used.
-        // in the constructor it uses a direct call without checking stMC
-        private String internalMethod() {
-            return helperMethod()
+        private String privateMethod() {
+            return publicMethod()
         }
 
-        String helperMethod() {
+        String publicMethod() {
             return 'not intercepted'
         }
     }
diff --git a/src/test/groovy/util/GroovyScriptEngineReloadingTest.groovy b/src/test/groovy/util/GroovyScriptEngineReloadingTest.groovy
index 3e655fa..660f4dd 100644
--- a/src/test/groovy/util/GroovyScriptEngineReloadingTest.groovy
+++ b/src/test/groovy/util/GroovyScriptEngineReloadingTest.groovy
@@ -18,17 +18,32 @@
  */
 package groovy.util
 
-import groovy.test.GroovyTestCase
+import groovy.transform.AutoFinal
+import groovy.transform.Canonical
+import groovy.transform.TupleConstructor
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Test
 
-import java.util.concurrent.ConcurrentHashMap
-import org.codehaus.groovy.control.CompilerConfiguration
+import static groovy.test.GroovyAssert.shouldFail
 
-class GroovyScriptEngineReloadingTest extends GroovyTestCase {
-    GroovyScriptEngine gse
+@AutoFinal
+final class GroovyScriptEngineReloadingTest {
 
-    void setUp() {
-        MapFileSystem.instance.registerMapFileSystem()
-        makeGSE(null)
+    private GroovyScriptEngine gse
+
+    @BeforeClass
+    static void setUpTestSuite() {
+        URL.setURLStreamHandlerFactory(protocol -> {
+            if (protocol == MapUrlConnection.PROTOCOL) {
+                return new MapUrlHandler()
+            }
+        })
+    }
+
+    @Before
+    void setUpTestCase() {
+        makeGSE()
     }
 
     private void makeGSE(ClassLoader parent) {
@@ -36,16 +51,18 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
             gse = new GroovyScriptEngine([MapUrlConnection.URL_SCHEME] as String[]) {
                 long time = 1000
 
+                @Override
                 protected long getCurrentTime() {
-                    return time
+                    time
                 }
             }
         } else {
             gse = new GroovyScriptEngine([MapUrlConnection.URL_SCHEME] as String[], parent) {
                 long time = 1000
 
+                @Override
                 protected long getCurrentTime() {
-                    return time
+                    time
                 }
             }
         }
@@ -61,34 +78,88 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
 
         Binding binding = new Binding()
         int val = 0
-        binding.setVariable("val", val)
-        MapFileSystem.instance.modFile("s_1", "val = 1", gse.@time)
-        gse.run("s_1", binding)
+        binding.setVariable('val', val)
+        MapFileSystem.instance.modFile('s_1', 'val = 1', gse.@time)
+        gse.run('s_1', binding)
 
-        assert binding.getVariable("val") == 1
+        assert binding.getVariable('val') == 1
 
         sleep sleepTime
 
-        MapFileSystem.instance.modFile("s_1", "val = 2", gse.@time)
-        gse.run("s_1", binding)
+        MapFileSystem.instance.modFile('s_1', 'val = 2', gse.@time)
+        gse.run('s_1', binding)
 
-        assert binding.getVariable("val") == expected
+        assert binding.getVariable('val') == expected
+    }
+
+    /**
+     * The script passes the className of the class it's supposed to
+     * instantiate to this method, expecting a newly instantiated object
+     * in return.  The reason this is not done in the script is that
+     * we want to ensure that no unforeseen problems occur if
+     * the instantiation is not actually done inside the script,
+     * since real-world usages will likely require delegating that
+     * job.
+     */
+    private Object instantiate(String className, ClassLoader classLoader) {
+        Class clazz = null
+        try {
+            clazz = Class.forName(className, true, classLoader)
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Class.forName failed for $className", e);
+        }
+        try {
+            return clazz.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException("Could not instantiate object of class $className", e);
+        }
+    }
+
+    private void writeScript(int name) throws IOException {
+        def s = '''
+            def b = new Bean()
+            return b.getVal()
+        '''
+        MapFileSystem.instance.modFile("script${name}.groovy", s, gse.@time)
+    }
+
+    private void writeBean(int d) throws IOException {
+        def s = """
+            class Bean {
+                String prop0
+                String prop${d}
+                def getVal(){'$d'}
+            }
+        """
+        MapFileSystem.instance.modFile('Bean.groovy', s, gse.@time)
+    }
 
+    private void writeClassBean() {
+        def s = '''
+            class Bean {
+                def getVal(){this.class.hashCode()}
+            }
+        '''
+        MapFileSystem.instance.modFile('Bean.groovy', s, gse.@time)
     }
 
-    // test to ensure new source is no picked up
+    //--------------------------------------------------------------------------
+
+    @Test // ensures new source is no picked up
     void testIsSourceNewer() {
         execute(1000, 2000, 2)
         execute(1000, 5000, 2)
         execute(1000, 10000, 2)
     }
-    // test to ensure new source is ignored till minimumRecompilationIntervall is passed
+
+    @Test // ensures new source is ignored till minimumRecompilationIntervall is passed
     void testRecompilationIntervall() {
         execute(100000, 10000, 1)
         execute(100000, 10000, 1)
         execute(100000, 200000, 2)
     }
 
+    @Test
     void testRecompilingWithGenerics() {
         MapFileSystem.instance.modFile('BaseClass.groovy', 'abstract class BaseClass<T> extends Script {}', gse.@time)
 
@@ -106,11 +177,12 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
         sleep 1000
 
         // make a change to the sub-class so that it gets recompiled
-        MapFileSystem.instance.modFile('SubClass.groovy', subClassText + "\n", gse.@time)
+        MapFileSystem.instance.modFile('SubClass.groovy', subClassText + '\n', gse.@time)
         gse.loadScriptByName('SubClass.groovy')
 
     }
 
+    @Test
     void testDeleteDependent() {
         sleep 10000
         MapFileSystem.instance.modFile('ClassA.groovy', 'DependentClass ic = new DependentClass()', gse.@time as long)
@@ -124,66 +196,60 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
         assert clazz != null //classA is valid with dep removed
     }
 
+    @Test
     void testReloadWith2ScriptsDependentOnSameBeanAndReloadForSecond() {
         gse.config.minimumRecompilationInterval = 1000
         writeBean(1)
         writeScript(1)
 
-        def val1 = gse.run("script1.groovy", "")
-        assert val1 == '1', "script1 should have returned 1"
+        def val1 = gse.run('script1.groovy', '')
+        assert val1 == '1', 'script1 should have returned 1'
 
         sleep 1
         writeBean(2)
         writeScript(2)
-        val1 = gse.run("script1.groovy", "")
-        assert val1 == '1', "script1 should have returned 1"
+        val1 = gse.run('script1.groovy', '')
+        assert val1 == '1', 'script1 should have returned 1'
 
         sleep 10000
 
-        def val2 = gse.run("script2.groovy", "")
-        assert val2 == '2', "script2 should have returned 2"
+        def val2 = gse.run('script2.groovy', '')
+        assert val2 == '2', 'script2 should have returned 2'
     }
 
+    @Test
     void testReloadWith2ScriptsDependentOnSameBean() {
         gse.config.minimumRecompilationInterval = 1
         writeBean(1)
         writeScript(1)
         writeScript(2)
 
-        def val1 = gse.run("script2.groovy", "")
-        assert val1 == '1', "script2 should have returned 1"
+        def val1 = gse.run('script2.groovy', '')
+        assert val1 == '1', 'script2 should have returned 1'
 
-        def val2 = gse.run("script1.groovy", "")
-        assert val2 == '1', "script1 should have returned 1"
+        def val2 = gse.run('script1.groovy', '')
+        assert val2 == '1', 'script1 should have returned 1'
 
         sleep 10000
         writeBean(2)
 
-        def val3 = gse.run("script1.groovy", "")
+        def val3 = gse.run('script1.groovy', '')
         assert val3 == '2', "script1 should have returned 2 after bean was modified but returned $val3"
 
-        def val4 = gse.run("script2.groovy", "")
+        def val4 = gse.run('script2.groovy', '')
         assert val4 == '2', "script2 should have returned 2 after bean was modified but returned $val4"
     }
 
-    private void writeClassBean() {
-        def s = """
-            class Bean {
-                def getVal(){this.class.hashCode()}
-            }
-        """
-        MapFileSystem.instance.modFile("Bean.groovy", s, gse.@time)
-    }
-
+    @Test
     void testDependencyReloadNotTooOften() {
         gse.config.minimumRecompilationInterval = 1
         writeClassBean()
         writeScript(1)
         writeScript(2)
 
-        def beanClass1 = gse.run("script2.groovy", "")
-        def beanClass2 = gse.run("script1.groovy", "")
-        assert beanClass1 == beanClass2, "bean class should have been compiled only once"
+        def beanClass1 = gse.run('script2.groovy', '')
+        def beanClass2 = gse.run('script1.groovy', '')
+        assert beanClass1 == beanClass2, 'bean class should have been compiled only once'
         def oldBeanClass = beanClass1
 
         sleep 10000
@@ -191,217 +257,165 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
         writeScript(1)
         writeScript(2)
 
-        beanClass1 = gse.run("script2.groovy", "")
-        beanClass2 = gse.run("script1.groovy", "")
-        assert beanClass1 == beanClass2, "bean class should have been compiled only once"
-        assert beanClass1 != oldBeanClass, "bean class was not recompiled"
+        beanClass1 = gse.run('script2.groovy', '')
+        beanClass2 = gse.run('script1.groovy', '')
+        assert beanClass1 == beanClass2, 'bean class should have been compiled only once'
+        assert beanClass1 != oldBeanClass, 'bean class was not recompiled'
     }
 
+    @Test
     void testReloadWhenModifyingAllScripts() {
         gse.config.minimumRecompilationInterval = 1
         writeBean(1)
         writeScript(1)
         writeScript(2)
 
-        def val1 = gse.run("script2.groovy", "")
-        assert val1 == '1', "script2 should have returned 1"
+        def val1 = gse.run('script2.groovy', '')
+        assert val1 == '1', 'script2 should have returned 1'
 
-        def val2 = gse.run("script1.groovy", "")
-        assert val2 == '1', "script1 should have returned 1"
+        def val2 = gse.run('script1.groovy', '')
+        assert val2 == '1', 'script1 should have returned 1'
 
         // write Scripts stay the same, timestamps updated
         writeScript(1)
         writeScript(2)
         sleep 10000
 
-        val1 = gse.run("script2.groovy", "")
-        assert val1 == '1', "script2 should have returned 1"
-        val2 = gse.run("script1.groovy", "")
-        assert val2 == '1', "script1 should have returned 1"
+        val1 = gse.run('script2.groovy', '')
+        assert val1 == '1', 'script2 should have returned 1'
+        val2 = gse.run('script1.groovy', '')
+        assert val2 == '1', 'script1 should have returned 1'
 
         // Modify Bean to return new value
         sleep 10000
         writeBean(2)
 
-        def val3 = gse.run("script1.groovy", "")
+        def val3 = gse.run('script1.groovy', '')
         assert val3 == '2', "script1 should have returned 2 after bean was modified but returned $val3"
-        def val4 = gse.run("script2.groovy", "")
+        def val4 = gse.run('script2.groovy', '')
         assert val4 == '2', "script2 should have returned 2 after bean was modified but returned $val4"
     }
 
-    void writeScript(int name) throws IOException {
-        def s = """
-            def b = new Bean()
-            return b.getVal()
-        """
-        MapFileSystem.instance.modFile("script${name}.groovy", s, gse.@time)
-    }
-
-    void writeBean(int d) throws IOException {
-        def s = """
-            class Bean {
-                String prop0
-                String prop${d}
-                def getVal(){"$d"}
+    @Test
+    void testDynamicInstantiation() {
+        MapFileSystem.instance.modFile('script.groovy', '''
+            def obj = dynaInstantiate.instantiate(className, this.class.classLoader)
+            obj.modifyWidth(dim, addThis)
+            returnedMessage = obj.message
+       ''', 0)
+
+        MapFileSystem.instance.modFile('com/company/MakeMeSuper.groovy', '''
+            package com.company
+            import com.company.util.*
+            class MakeMeSuper{
+                private HelperIntf helper = new Helper()
+                def getMessage() {
+                    helper.getMessage()
+                }
             }
-        """
-        MapFileSystem.instance.modFile("Bean.groovy", s, gse.@time)
-    }
+        ''', 0)
 
-    void testDynamicInstantiation() throws Exception {
-        MapFileSystem.instance.modFile("script.groovy",
-                """
-               def obj = dynaInstantiate.instantiate(className, getClass().getClassLoader())
-               obj.modifyWidth(dim, addThis)
-               returnedMessage = obj.message
-           """, 0)
-
-        MapFileSystem.instance.modFile("com/company/MakeMeSuper.groovy",
-                """
-              package com.company
-              import com.company.util.*
-              class MakeMeSuper{
-                 private HelperIntf helper = new Helper()
-                 def getMessage(){
-                         helper.getMessage()
-                 }
-              }
-          """, 0)
-
-        MapFileSystem.instance.modFile("com/company/MakeMe.groovy",
-                """
-              package com.company
-              class MakeMe extends MakeMeSuper{
-                 def modifyWidth(dim, addThis){
+        MapFileSystem.instance.modFile('com/company/MakeMe.groovy', '''
+            package com.company
+            class MakeMe extends MakeMeSuper{
+                def modifyWidth(dim, addThis){
                     dim.width += addThis
-                 }
-              }
-          """, 0)
-
-        MapFileSystem.instance.modFile("com/company/util/HelperIntf.groovy",
-                """
-              package com.company.util
-              interface HelperIntf{
+                }
+            }
+        ''', 0)
+
+        MapFileSystem.instance.modFile('com/company/util/HelperIntf.groovy', '''
+            package com.company.util
+            interface HelperIntf {
                  public String getMessage();
-              }
-          """, 0)
-
-        MapFileSystem.instance.modFile("com/company/util/Helper.groovy",
-                """
-              package com.company.util
-              class Helper implements HelperIntf{
-                 public String getMessage(){
-                       'worked'
-                 }
-              }
-           """, 0)
+            }
+        ''', 0)
+
+        MapFileSystem.instance.modFile('com/company/util/Helper.groovy', '''
+            package com.company.util
+            class Helper implements HelperIntf {
+                public String getMessage() {
+                    'worked'
+                }
+            }
+        ''', 0)
 
         //Code run in the script will modify this dimension object.
-        MyDimension dim = new MyDimension();
+        MyDimension dim = new MyDimension()
 
-        Binding binding = new Binding();
-        binding.setVariable("dim", dim);
-        binding.setVariable("dynaInstantiate", this);
+        Binding binding = new Binding()
+        binding.setVariable('dim', dim)
+        binding.setVariable('dynaInstantiate', this)
 
-        binding.setVariable("className", "com.company.MakeMe");
+        binding.setVariable('className', 'com.company.MakeMe')
 
-        int addThis = 3;
-        binding.setVariable("addThis", addThis);
+        int addThis = 3
+        binding.setVariable('addThis', addThis)
 
-        gse.run("script.groovy", binding);
+        gse.run('script.groovy', binding)
 
         //The script instantiated com.company.MakeMe via our own
         //instantiate method.  The instantiated object modified the
         //width of our Dimension object, adding the value of our
         //'addThis' variable to it.
-        assertEquals(new MyDimension(addThis, 0), dim);
+        assert dim == new MyDimension(addThis, 0)
 
-        assertEquals('worked', binding.getVariable("returnedMessage"))
-    }
-
-    /**
-     * The script passes the className of the class it's supposed to
-     * instantiate to this method, expecting a newly instantiated object
-     * in return.  The reason this is not done in the script is that
-     * we want to ensure that no unforeseen problems occur if
-     * the instantiation is not actually done inside the script,
-     * since real-world usages will likely require delegating that
-     * job.
-     */
-    Object instantiate(String className, ClassLoader classLoader) {
-        Class clazz = null;
-        try {
-            clazz = Class.forName(className, true, classLoader);
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("Class.forName failed for  " + className, ex);
-        }
-        try {
-            return clazz.newInstance();
-        } catch (Exception ex) {
-            throw new RuntimeException("Could not instantiate object of class " + className, ex);
-        }
+        assert binding.getVariable('returnedMessage') == 'worked'
     }
 
     /**
      * Test for GROOVY-3281, to ensure details passed through CompilerConfiguration are inherited by GSE.
      */
+    @Test
     void testCompilerConfigurationInheritance() {
-        CompilerConfiguration cc = new CompilerConfiguration();
-        cc.scriptBaseClass = CustomBaseClass.name
-
-        GroovyClassLoader cl = new GroovyClassLoader(this.class.getClassLoader(), cc)
-        makeGSE(cl);
+        def cc = new org.codehaus.groovy.control.CompilerConfiguration(scriptBaseClass: CustomBaseClass.name)
+        def cl = new GroovyClassLoader(this.class.classLoader, cc)
+        makeGSE(cl)
 
         MapFileSystem.instance.modFile(
-                "groovyScriptEngineSampleScript.groovy",
+                'groovyScriptEngineSampleScript.groovy',
                 'println "Hello Guillaume, is it a Groovy day?"', 0)
-        def aScript = gse.createScript("groovyScriptEngineSampleScript.groovy", new Binding())
+        def aScript = gse.createScript('groovyScriptEngineSampleScript.groovy', new Binding())
 
         assert aScript instanceof CustomBaseClass
     }
 
-    /** GROOVY-3893 */
+    @Test // GROOVY-3893
     void testGSEWithNoScriptRoots() {
         shouldFail ResourceException, {
             String[] emptyScriptRoots = []
             GroovyScriptEngine gse = new GroovyScriptEngine(emptyScriptRoots)
-            gse.run("unknownScriptName", "")
+            gse.run('unknownScriptName', '')
         }
     }
 
-    /** GROOVY-6203 */
+    @Test // GROOVY-6203
     void testGSEBaseClass() {
-        CompilerConfiguration cc = new CompilerConfiguration()
-        cc.setScriptBaseClass(CustomBaseClass.name)
-
-        makeGSE(null)
-        gse.setConfig(cc)
+        gse.config = new org.codehaus.groovy.control.CompilerConfiguration(scriptBaseClass: CustomBaseClass.name)
 
         MapFileSystem.instance.modFile(
-                "Groovy6203Helper.groovy",
+                'Groovy6203Helper.groovy',
                 'println "Hello Guillaume, is it a Groovy day?"', 0)
 
-        def script = gse.createScript("Groovy6203Helper.groovy", new Binding())
+        def script = gse.createScript('Groovy6203Helper.groovy', new Binding())
         assert script instanceof CustomBaseClass
     }
 
-    /** GROOVY-4013 */
+    @Test // GROOVY-4013
     void testGSENoCachingOfInnerClasses() {
-        MapFileSystem.instance.modFile("Groovy4013Helper.groovy",
-                """
-               import java.awt.event.*
-               import java.awt.*
-               class Groovy4013Helper
-               {
-                  def initPanel()
-                  {
-                       def b = new Button('click me')
-                       b.addActionListener( new ActionListener(){
-                           public void actionPerformed(ActionEvent e) {}
-                       })
-                  }
-               }
-           """, 0)
+        MapFileSystem.instance.modFile('Groovy4013Helper.groovy', '''
+            import java.awt.event.*
+            import java.awt.*
+            class Groovy4013Helper {
+                def initPanel() {
+                    def b = new Button('click me')
+                    b.addActionListener(new ActionListener() {
+                        public void actionPerformed(ActionEvent e) {
+                        }
+                    })
+                }
+            }
+        ''', 0)
 
         def klazz = gse.loadScriptByName('Groovy4013Helper.groovy')
         assert klazz.name == 'Groovy4013Helper'
@@ -410,42 +424,42 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
         assert klazz.name == 'Groovy4013Helper' // we should still get the outer class, not inner one
     }
 
-    /** GROOVY-4234 */
+    @Test // GROOVY-4234
     void testGSERunningAScriptThatHasMultipleClasses() {
-        MapFileSystem.instance.modFile("Groovy4234Helper.groovy",
-                """
-              class Foo4234 {
-                  static main(args){
-                      //println "Running Foo4234 -> main()"
-                  }
-              }
-              class Bar4234 { }
-          """, 0)
-
-        //println "testGSELoadingAScriptThatHasMultipleClasses - Run 1"
-        gse.run("Groovy4234Helper.groovy", new Binding())
-
-        //println "testGSELoadingAScriptThatHasMultipleClasses - Run 2"
-        gse.run("Groovy4234Helper.groovy", new Binding())
+        MapFileSystem.instance.modFile('Groovy4234Helper.groovy', '''
+            class Foo4234 {
+                static main(args) {
+                    //println 'Running Foo4234 -> main()'
+                }
+            }
+            class Bar4234 {
+            }
+        ''', 0)
+
+        //println 'testGSELoadingAScriptThatHasMultipleClasses - Run 1'
+        gse.run('Groovy4234Helper.groovy', new Binding())
+
+        //println 'testGSELoadingAScriptThatHasMultipleClasses - Run 2'
+        gse.run('Groovy4234Helper.groovy', new Binding())
     }
 
-    /** GROOVY-2811 and GROOVY-4286  */
+    @Test // GROOVY-2811, GROOVY-4286
     void testReloadingInterval() {
         gse.config.minimumRecompilationInterval = 1500
         def binding = new Binding([:])
-        def scriptName = "gse.groovy"
+        def scriptName = 'gse.groovy'
 
-        MapFileSystem.instance.modFile(scriptName, "1", 0)
+        MapFileSystem.instance.modFile(scriptName, '1', 0)
         sleep 1000
         // first time, the script is compiled and cached
         assert gse.run(scriptName, binding) == 1
 
-        MapFileSystem.instance.modFile(scriptName, "12", gse.@time)
+        MapFileSystem.instance.modFile(scriptName, '12', gse.@time)
         sleep 3000
         // the file was updated, and we waited for more than the minRecompilationInterval
         assert gse.run(scriptName, binding) == 12
 
-        MapFileSystem.instance.modFile(scriptName, "123", gse.@time)
+        MapFileSystem.instance.modFile(scriptName, '123', gse.@time)
         sleep 1000
         // still the old result, as we didn't wait more than the minRecompilationInterval
         assert gse.run(scriptName, binding) == 12
@@ -455,29 +469,17 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
         assert gse.run(scriptName, binding) == 123
     }
 
+    //--------------------------------------------------------------------------
 
-    class MapFileEntry {
+    @TupleConstructor
+    static class MapFileEntry {
         String content
         long lutime
-
-        MapFileEntry(String content, long lutime) {
-            this.content = content
-            this.lutime = lutime
-        }
     }
 
     @Singleton
-    class MapFileSystem {
-
-        public final ConcurrentHashMap<String, MapFileEntry> fileCache = new ConcurrentHashMap<String, MapFileEntry>()
-        private boolean registered = false
-
-        void registerMapFileSystem() {
-            if (!registered) {
-                URL.setURLStreamHandlerFactory(new MapUrlFactory())
-                registered = true
-            }
-        }
+    static class MapFileSystem {
+        public final Map<String, MapFileEntry> fileCache = new java.util.concurrent.ConcurrentHashMap<>()
 
         void modFile(String name, String content, long lutime) {
             if (fileCache.containsKey(name)) {
@@ -502,104 +504,68 @@ class GroovyScriptEngineReloadingTest extends GroovyTestCase {
         }
     }
 
-    class MapUrlHandler extends URLStreamHandler {
-
-        MapUrlHandler() {
-            super()
-        }
-
+    static class MapUrlHandler extends URLStreamHandler {
+        @Override
         protected URLConnection openConnection(URL u) throws IOException {
             return new MapUrlConnection(u)
         }
 
+        @Override
         protected void parseURL(URL u, String spec, int start, int limit) {
             super.parseURL(u, spec, start, limit)
         }
     }
 
-    class MapUrlConnection extends URLConnection {
-        String getContentEncoding() {
-            return CHARSET
-        }
+    static class MapUrlConnection extends URLConnection {
+
+        public static final String CHARSET = 'UTF-8'
+        public static final String PROTOCOL = 'map'
+        public static final String URL_HOST = 'local'
+        public static final String URL_SCHEME = PROTOCOL + '://' + URL_HOST + '/'
 
-        Object getContent() throws IOException {
-            return super.content
+        private String name
+
+        MapUrlConnection(URL url) {
+            super(url)
+            name = url.file
+            if (name.startsWith('/'))
+                name = name.substring(1)
         }
 
-        public static final String CHARSET = "UTF-8"
-        public static final String URL_HOST = "local"
-        public static final String PROTOCOL = "map"
-        public static final String URL_SCHEME = PROTOCOL + "://" + URL_HOST + "/"
+        @Override
+        void connect() throws IOException {
+        }
 
-        private String name
+        @Override
+        String getContentEncoding() {
+            return CHARSET
+        }
 
+        @Override
         InputStream getInputStream() throws IOException {
-            // System.out.println(name+"\t"+MapFileSystem.fileCache.get(name).content);
             if (MapFileSystem.instance.fileCache.containsKey(name)) {
                 String content = MapFileSystem.instance.fileCache.get(name).content
                 return new ByteArrayInputStream(content.getBytes(CHARSET))
             } else {
-                throw new IOException("file not found" + name)
+                throw new IOException('file not found' + name)
             }
         }
 
+        @Override
         long getLastModified() {
             long lastmodified = 0
             if (MapFileSystem.instance.fileCache.containsKey(name)) {
                 lastmodified = MapFileSystem.instance.fileCache.get(name).lutime
             }
-            // System.out.println(name+"\t"+lastmodified);
             return lastmodified
         }
-
-        URL getURL() {
-            return super.getURL()
-        }
-
-        MapUrlConnection(URL url) {
-            super(url)
-            name = url.getFile()
-            if (name.startsWith("/")) {
-                name = name.substring(1)
-            }
-        }
-
-        void connect() throws IOException {}
-    }
-
-    class MapUrlFactory implements URLStreamHandlerFactory {
-
-        MapUrlFactory() {
-            super()
-        }
-
-        URLStreamHandler createURLStreamHandler(String protocol) {
-            if (MapUrlConnection.PROTOCOL.equals(protocol)) {
-                return new MapUrlHandler()
-            } else {
-                return null
-            }
-        }
     }
 
+    @Canonical
     static class MyDimension {
-        int width
-        int height
-
-        MyDimension(int x, int y) {
-            width = x
-            height = y
-        }
-
-        MyDimension() {
-            width = 0
-            height = 0
-        }
-
-        boolean equals(o) { o.width == width && o.height == height }
-
-        int hashCode() { width + 13 * height }
+        int width, height
     }
 
-    static abstract class CustomBaseClass extends Script {}
+    static abstract class CustomBaseClass extends Script {
+    }
 }