You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2012/05/16 20:50:32 UTC

[32/44] git commit: Convert TestNG to Spock

Convert TestNG to Spock


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/99f88df2
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/99f88df2
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/99f88df2

Branch: refs/heads/master
Commit: 99f88df25dbe753eca5742f2189fbe6f7a713651
Parents: a1da91b
Author: Howard M. Lewis Ship <hl...@gmail.com>
Authored: Mon Apr 16 10:55:43 2012 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Wed May 16 11:49:41 2012 -0700

----------------------------------------------------------------------
 .../org/apache/tapestry/ioc/EagerLoadSpec.groovy   |   24 +
 .../org/apache/tapestry/ioc/ReloadSpec.groovy      |  403 +++++++++++++++
 .../apache/tapestry5/ioc/EagerLoadServiceImpl.java |    4 +-
 .../tapestry5/ioc/EagerProxyReloadModule.java      |    4 +-
 .../java/org/apache/tapestry5/ioc/ReloadTest.java  |  399 --------------
 5 files changed, 432 insertions(+), 402 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/99f88df2/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/EagerLoadSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/EagerLoadSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/EagerLoadSpec.groovy
new file mode 100644
index 0000000..4ee948a
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/EagerLoadSpec.groovy
@@ -0,0 +1,24 @@
+package org.apache.tapestry.ioc
+
+import org.apache.tapestry5.ioc.EagerProxyReloadModule
+
+
+class EagerLoadSpec extends IOCSpecification {
+
+    def "proxied service does eager load"()
+    {
+        expect:
+
+        EagerProxyReloadModule.eagerLoadServiceDidLoad == false
+
+        when:
+
+        buildRegistry EagerProxyReloadModule
+
+        performRegistryStartup()
+
+        then:
+
+        EagerProxyReloadModule.eagerLoadServiceDidLoad == true
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/99f88df2/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/ReloadSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/ReloadSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/ReloadSpec.groovy
new file mode 100644
index 0000000..a9ca812
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry/ioc/ReloadSpec.groovy
@@ -0,0 +1,403 @@
+package org.apache.tapestry.ioc
+
+import org.apache.tapestry5.internal.plastic.PlasticInternalUtils
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter
+import org.apache.tapestry5.ioc.Registry
+import org.apache.tapestry5.ioc.RegistryBuilder
+import org.apache.tapestry5.services.UpdateListenerHub
+import spock.lang.AutoCleanup
+import spock.lang.Specification
+import com.example.*
+
+import static org.apache.tapestry5.internal.plastic.asm.Opcodes.*
+
+class ReloadSpec extends Specification {
+
+    private static final String PACKAGE = "com.example";
+
+    private static final String CLASS = PACKAGE + ".ReloadableServiceImpl";
+
+    private static final String BASE_CLASS = PACKAGE + ".BaseReloadableServiceImpl";
+
+
+    @AutoCleanup("shutdown")
+    Registry registry
+
+    @AutoCleanup("deleteDir")
+    File classesDir
+
+    ClassLoader classLoader
+
+    File classFile;
+
+    def createRegistry() {
+        registry = new RegistryBuilder(classLoader).add(ReloadModule).build()
+    }
+
+    /** Any unrecognized methods are evaluated against the registry. */
+    def methodMissing(String name, args) {
+        registry."$name"(* args)
+    }
+
+
+    def setup() {
+        def uid = UUID.randomUUID().toString()
+
+        classesDir = new File(System.getProperty("java.io.tmpdir"), uid)
+
+        def classesURL = new URL("file:" + classesDir.getCanonicalPath() + "/")
+
+        classLoader = new URLClassLoader([classesURL] as URL[],
+                Thread.currentThread().contextClassLoader)
+
+        classFile = new File(classesDir, PlasticInternalUtils.toClassPath(CLASS))
+    }
+
+    def createImplementationClass(String status) {
+        createImplementationClass CLASS, status
+    }
+
+    def createImplementationClass(String className, String status) {
+
+        String internalName = PlasticInternalUtils.toInternalName className
+
+        createClassWriter(internalName, "java/lang/Object", ACC_PUBLIC).with {
+
+            // Add default constructor
+
+            visitMethod(ACC_PUBLIC, "<init>", "()V", null, null).with {
+                visitCode()
+                visitVarInsn ALOAD, 0
+                visitMethodInsn INVOKESPECIAL, "java/lang/Object", "<init>", "()V"
+                visitInsn RETURN
+                visitMaxs 1, 1
+                visitEnd()
+            }
+
+
+            visitMethod(ACC_PUBLIC, "getStatus", "()Ljava/lang/String;", null, null).with {
+                visitCode()
+                visitLdcInsn status
+                visitInsn ARETURN
+                visitMaxs 1, 1
+                visitEnd()
+            }
+
+            visitEnd()
+
+            writeBytecode it, internalName
+        }
+
+    }
+
+    def createClassWriter(String internalName, String baseClassInternalName, int classModifiers) {
+        ClassWriter cw = new ClassWriter(0);
+
+        cw.visit V1_5, classModifiers, internalName, null,
+                baseClassInternalName, [
+                        PlasticInternalUtils.toInternalName(ReloadableService.name)
+                ] as String[]
+
+
+        return cw
+    }
+
+
+    def writeBytecode(ClassWriter cw, String internalName) {
+        byte[] bytecode = cw.toByteArray();
+
+        writeBytecode(bytecode, pathForInternalName(internalName))
+    }
+
+    def writeBytecode(byte[] bytecode, String path) {
+        File file = new File(path)
+
+        file.parentFile.mkdirs()
+
+        file.withOutputStream { it.write bytecode }
+    }
+
+
+    def pathForInternalName(String internalName) {
+        return String.format("%s/%s.class",
+                classesDir.getAbsolutePath(),
+                internalName)
+    }
+
+    def update() {
+        getService(UpdateListenerHub).fireCheckForUpdates()
+    }
+
+    def "reload a service implementation"() {
+
+        when:
+
+        createImplementationClass "initial"
+
+        createRegistry()
+
+        ReloadableService reloadable = getService(ReloadableService);
+
+        update()
+
+        then:
+
+        reloadable.status == "initial"
+
+        when:
+
+        update()
+
+        touch classFile
+
+        createImplementationClass "updated"
+
+        then:
+
+        // Changes do not take effect until after update check
+
+        reloadable.status == "initial"
+
+        when:
+
+        update()
+
+        then:
+
+        reloadable.status == "updated"
+    }
+
+    def "reload a base class"() {
+
+        setup:
+
+        def baseClassInternalName = PlasticInternalUtils.toInternalName BASE_CLASS
+        def internalName = PlasticInternalUtils.toInternalName CLASS
+
+        createImplementationClass BASE_CLASS, "initial from base"
+
+        createClassWriter(internalName, baseClassInternalName, ACC_PUBLIC).with {
+
+            visitMethod(ACC_PUBLIC, "<init>", "()V", null, null).with {
+                visitCode()
+                visitVarInsn ALOAD, 0
+                visitMethodInsn INVOKESPECIAL, baseClassInternalName, "<init>", "()V"
+                visitInsn RETURN
+                visitMaxs 1, 1
+                visitEnd()
+            }
+
+            visitEnd()
+
+            writeBytecode it, internalName
+        }
+
+        createRegistry()
+
+        when:
+
+        ReloadableService reloadable = getService(ReloadableService)
+
+        update()
+
+        then:
+
+        reloadable.status == "initial from base"
+
+        when:
+
+        touch(new File(pathForInternalName(baseClassInternalName)))
+
+        createImplementationClass BASE_CLASS, "updated from base"
+
+        update()
+
+        then:
+
+        reloadable.status == "updated from base"
+    }
+
+    def "deleting an implementation class results in a runtime exception when reloading"() {
+
+        when:
+
+        createImplementationClass "before delete"
+
+        createRegistry()
+
+        ReloadableService reloadable = getService ReloadableService
+
+        then:
+
+        reloadable.status == "before delete"
+
+        assert classFile.exists()
+
+        when:
+
+        classFile.delete()
+
+        update()
+
+        reloadable.getStatus()
+
+        then:
+
+        RuntimeException e = thrown()
+
+        e.message.contains "Unable to reload class $CLASS"
+    }
+
+
+    def "reload a proxy object"() {
+        when:
+
+        createImplementationClass "initial proxy"
+
+        createRegistry()
+
+        def clazz = classLoader.loadClass CLASS
+
+        ReloadableService reloadable = proxy(ReloadableService, clazz)
+
+        then:
+
+        reloadable.status == "initial proxy"
+
+        when:
+
+        touch classFile
+
+        createImplementationClass "updated proxy"
+
+        update()
+
+        then:
+
+        reloadable.status == "updated proxy"
+
+        when:
+
+        touch classFile
+
+        createImplementationClass "re-updated proxy"
+
+        update()
+
+        then:
+
+        reloadable.status == "re-updated proxy"
+    }
+
+    def "check exception message for invalid service implementation (lacking a public constructor)"() {
+
+        when:
+
+        createImplementationClass "initial"
+
+        createRegistry()
+
+        ReloadableService reloadable = getService ReloadableService
+
+        touch classFile
+
+        createInvalidImplementationClass()
+
+        update()
+
+        reloadable.getStatus()
+
+        then:
+
+        Exception e = thrown()
+
+        e.message == "Service implementation class com.example.ReloadableServiceImpl does not have a suitable public constructor."
+    }
+
+    def "ensure ReloadAware services are notified when services are reloaded"() {
+
+        when:
+
+        registry = new RegistryBuilder().add(ReloadAwareModule).build()
+
+        then:
+
+        ReloadAwareModule.counterInstantiations == 0
+        ReloadAwareModule.counterReloads == 0
+
+        when:
+
+        Counter counter = proxy(Counter, CounterImpl)
+
+        then:
+
+        ReloadAwareModule.counterInstantiations == 0
+
+        expect:
+
+        counter.increment() == 1
+        counter.increment() == 2
+
+        ReloadAwareModule.counterInstantiations == 1
+
+        when:
+
+        def classURL = CounterImpl.getResource("CounterImpl.class")
+        def classFile = new File(classURL.toURI())
+
+        touch classFile
+
+        update()
+
+        // Check that the internal state has reset
+
+        assert counter.increment() == 1
+
+        then:
+
+        ReloadAwareModule.counterInstantiations == 2
+        ReloadAwareModule.counterReloads == 1
+    }
+
+    def createInvalidImplementationClass() {
+        def internalName = PlasticInternalUtils.toInternalName CLASS
+
+        createClassWriter(internalName, "java/lang/Object", ACC_PUBLIC).with {
+
+            visitMethod(ACC_PROTECTED, "<init>", "()V", null, null).with {
+                visitVarInsn ALOAD, 0
+                visitMethodInsn INVOKESPECIAL, "java/lang/Object", "<init>", "()V"
+                visitInsn RETURN
+                visitMaxs 1, 1
+                visitEnd()
+            }
+
+            visitEnd()
+
+            writeBytecode it, internalName
+        }
+    }
+
+
+    def touch(File f) {
+        long startModified = f.lastModified();
+
+        int index = 0;
+
+        while (true) {
+            f.setLastModified System.currentTimeMillis()
+
+            long newModified = f.lastModified()
+
+            if (newModified != startModified) {
+                return;
+            }
+
+            // Sleep an ever increasing amount, to ensure that the filesystem
+            // catches the change to the file. The Ubuntu CI Server appears
+            // to need longer waits.
+
+            Thread.sleep 50 * (2 ^ index++)
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/99f88df2/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerLoadServiceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerLoadServiceImpl.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerLoadServiceImpl.java
index b578092..f73eb86 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerLoadServiceImpl.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerLoadServiceImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2012 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -21,6 +21,6 @@ public class EagerLoadServiceImpl implements EagerLoadService
 {
     public EagerLoadServiceImpl()
     {
-        ReloadTest.eagerLoadServiceWasInstantiated = true;
+        EagerProxyReloadModule.eagerLoadServiceDidLoad = true;
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/99f88df2/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerProxyReloadModule.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerProxyReloadModule.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerProxyReloadModule.java
index 12e16b3..8859003 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerProxyReloadModule.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/EagerProxyReloadModule.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2012 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@ package org.apache.tapestry5.ioc;
 
 public class EagerProxyReloadModule
 {
+    public static boolean eagerLoadServiceDidLoad;
+
     public static void bind(ServiceBinder binder)
     {
         binder.bind(EagerLoadService.class, EagerLoadServiceImpl.class);

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/99f88df2/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ReloadTest.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ReloadTest.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ReloadTest.java
deleted file mode 100644
index a802c24..0000000
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/ReloadTest.java
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright 2010, 2011 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.apache.tapestry5.ioc;
-
-import com.example.*;
-import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
-import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
-import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
-import org.apache.tapestry5.ioc.test.IOCTestCase;
-import org.apache.tapestry5.services.UpdateListenerHub;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-import static org.apache.tapestry5.internal.plastic.asm.Opcodes.*;
-
-/**
- * Test the ability to perform live class reloading of a service implementation.
- */
-@SuppressWarnings("unchecked")
-public class ReloadTest extends IOCTestCase
-{
-    private static final String PACKAGE = "com.example";
-
-    private static final String CLASS = PACKAGE + ".ReloadableServiceImpl";
-
-    private static final String BASE_CLASS = PACKAGE + ".BaseReloadableServiceImpl";
-
-    private File classesDir;
-
-    private ClassLoader classLoader;
-
-    public static boolean eagerLoadServiceWasInstantiated;
-
-    private File classFile;
-
-    @BeforeClass
-    public void setup() throws Exception
-    {
-        String uid = Long.toHexString(System.currentTimeMillis());
-
-        classesDir = new File(System.getProperty("java.io.tmpdir"), uid);
-
-        // URLClassLoader REQUIRES that File URLs end with a slash! That's a half hour of my life gone!
-
-        URL classesURL = new URL("file:" + classesDir.getCanonicalPath() + "/");
-
-        System.out.println("Reload classes dir: " + classesURL);
-
-        classLoader = new URLClassLoader(new URL[]
-                {classesURL}, Thread.currentThread().getContextClassLoader());
-
-        classFile = new File(classesDir, "com/example/ReloadableServiceImpl.class");
-    }
-
-    @Test
-    public void reload_a_service_implementation() throws Exception
-    {
-        // First, create the initial implementation
-
-        createImplementationClass("initial");
-
-        Registry registry = createRegistry();
-
-        ReloadableService reloadable = registry.getService(ReloadableService.class);
-
-        fireUpdateCheck(registry);
-
-        assertEquals(reloadable.getStatus(), "initial");
-
-        fireUpdateCheck(registry);
-
-        touch(classFile);
-
-        createImplementationClass("updated");
-
-        // Doesn't take effect until after the update check
-
-        assertEquals(reloadable.getStatus(), "initial");
-
-        fireUpdateCheck(registry);
-
-        assertEquals(reloadable.getStatus(), "updated");
-
-        registry.shutdown();
-    }
-
-    @Test
-    public void reload_a_base_class() throws Exception
-    {
-        String baseClassInternalName = PlasticInternalUtils.toInternalName(BASE_CLASS);
-        String internalName = PlasticInternalUtils.toInternalName(CLASS);
-
-        createImplementationClass(BASE_CLASS, "initial from base");
-
-
-        ClassWriter cw = createClassWriter(internalName, baseClassInternalName, ACC_PUBLIC);
-
-        // Add default constructor
-
-        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
-        mv.visitCode();
-        mv.visitVarInsn(ALOAD, 0);
-        mv.visitMethodInsn(INVOKESPECIAL, baseClassInternalName, "<init>", "()V");
-        mv.visitInsn(RETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        cw.visitEnd();
-
-        writeBytecode(cw, internalName);
-
-        Registry registry = createRegistry();
-
-        ReloadableService reloadable = registry.getService(ReloadableService.class);
-
-        fireUpdateCheck(registry);
-
-        assertEquals(reloadable.getStatus(), "initial from base");
-
-        touch(new File(pathForInternalName(baseClassInternalName)));
-
-        createImplementationClass(BASE_CLASS, "updated from base");
-
-        fireUpdateCheck(registry);
-
-        assertEquals(reloadable.getStatus(), "updated from base");
-
-        registry.shutdown();
-
-    }
-
-    @Test
-    public void delete_class() throws Exception
-    {
-        createImplementationClass("before delete");
-
-        Registry registry = createRegistry();
-
-        ReloadableService reloadable = registry.getService(ReloadableService.class);
-
-        assertEquals(reloadable.getStatus(), "before delete");
-
-        assertTrue(classFile.exists(), "The class file must exist.");
-
-        classFile.delete();
-
-        fireUpdateCheck(registry);
-
-        try
-        {
-            reloadable.getStatus();
-            unreachable();
-        } catch (RuntimeException ex)
-        {
-            assertMessageContains(ex, "Unable to reload", CLASS);
-        }
-
-        registry.shutdown();
-    }
-
-    @Test
-    public void reload_a_proxy_object() throws Exception
-    {
-        createImplementationClass("initial proxy");
-
-        Registry registry = createRegistry();
-
-        Class<ReloadableService> clazz = (Class<ReloadableService>) classLoader.loadClass(CLASS);
-
-        ReloadableService reloadable = registry.proxy(ReloadableService.class, clazz);
-
-        assertEquals(reloadable.getStatus(), "initial proxy");
-
-        touch(classFile);
-
-        createImplementationClass("updated proxy");
-
-        fireUpdateCheck(registry);
-
-        assertEquals(reloadable.getStatus(), "updated proxy");
-
-        touch(classFile);
-
-        createImplementationClass("re-updated proxy");
-
-        fireUpdateCheck(registry);
-
-        assertEquals(reloadable.getStatus(), "re-updated proxy");
-
-        registry.shutdown();
-    }
-
-    private void fireUpdateCheck(Registry registry)
-    {
-        registry.getService(UpdateListenerHub.class).fireCheckForUpdates();
-    }
-
-    private Registry createRegistry()
-    {
-        RegistryBuilder builder = new RegistryBuilder(classLoader);
-
-        builder.add(ReloadModule.class);
-
-        return builder.build();
-    }
-
-    @Test
-    public void invalid_service_implementation() throws Exception
-    {
-        createImplementationClass("initial");
-
-        Registry registry = createRegistry();
-
-        ReloadableService reloadable = registry.getService(ReloadableService.class);
-
-        touch(classFile);
-
-        createInvalidImplentationClass();
-
-        fireUpdateCheck(registry);
-
-        try
-        {
-            reloadable.getStatus();
-
-            unreachable();
-        } catch (Exception ex)
-        {
-            assertEquals(ex.getMessage(),
-                    "Service implementation class com.example.ReloadableServiceImpl does not have a suitable public constructor.");
-        }
-
-        registry.shutdown();
-    }
-
-    private void createImplementationClass(String status) throws Exception
-    {
-        createImplementationClass(CLASS, status);
-    }
-
-    private void createImplementationClass(String className, String status) throws Exception
-    {
-        String internalName = PlasticInternalUtils.toInternalName(className);
-
-        ClassWriter cw = createClassWriter(internalName, "java/lang/Object", ACC_PUBLIC);
-
-        // Add default constructor
-
-        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
-        mv.visitCode();
-        mv.visitVarInsn(ALOAD, 0);
-        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
-        mv.visitInsn(RETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-
-        mv = cw.visitMethod(ACC_PUBLIC, "getStatus", "()Ljava/lang/String;", null, null);
-        mv.visitCode();
-        mv.visitLdcInsn(status);
-        mv.visitInsn(ARETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        cw.visitEnd();
-
-        writeBytecode(cw, internalName);
-    }
-
-    private ClassWriter createClassWriter(String internalName, String baseClassInternalName, int classModifiers)
-    {
-        ClassWriter cw = new ClassWriter(0);
-
-        cw.visit(V1_5, classModifiers, internalName, null,
-                baseClassInternalName, new String[]{
-                PlasticInternalUtils.toInternalName(ReloadableService.class.getName())
-        });
-
-        return cw;
-    }
-
-    private void writeBytecode(ClassWriter cw, String internalName) throws Exception
-    {
-        byte[] bytecode = cw.toByteArray();
-
-        writeBytecode(bytecode, pathForInternalName(internalName));
-    }
-
-    private String pathForInternalName(String internalName)
-    {
-        return String.format("%s/%s.class",
-                classesDir.getAbsolutePath(),
-                internalName);
-    }
-
-    private void writeBytecode(byte[] bytecode, String path) throws Exception
-    {
-        File file = new File(path);
-
-        file.getParentFile().mkdirs();
-
-        OutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
-
-        stream.write(bytecode);
-
-        stream.close();
-    }
-
-    private void createInvalidImplentationClass() throws Exception
-    {
-        String internalName = PlasticInternalUtils.toInternalName(CLASS);
-
-        ClassWriter cw = createClassWriter(internalName, "java/lang/Object", ACC_PUBLIC);
-
-        // Add default constructor
-
-        MethodVisitor mv = cw.visitMethod(ACC_PROTECTED, "<init>", "()V", null, null);
-        mv.visitVarInsn(ALOAD, 0);
-        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
-        mv.visitInsn(RETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        // Notice the  class is abstract, so no implementation.
-
-        cw.visitEnd();
-
-        writeBytecode(cw, internalName);
-    }
-
-    @Test
-    public void eager_load_service_with_proxy()
-    {
-        eagerLoadServiceWasInstantiated = false;
-
-        Registry r = new RegistryBuilder().add(EagerProxyReloadModule.class).build();
-
-        r.performRegistryStartup();
-
-        assertTrue(eagerLoadServiceWasInstantiated);
-    }
-
-    @Test
-    public void reload_aware() throws Exception
-    {
-        Registry r = buildRegistry(ReloadAwareModule.class);
-
-        assertEquals(ReloadAwareModule.counterInstantiations, 0);
-        assertEquals(ReloadAwareModule.counterReloads, 0);
-
-        Counter counter = r.proxy(Counter.class, CounterImpl.class);
-
-        assertEquals(ReloadAwareModule.counterInstantiations, 0);
-
-        assertEquals(counter.increment(), 1);
-        assertEquals(counter.increment(), 2);
-
-        assertEquals(ReloadAwareModule.counterInstantiations, 1);
-
-        URL classURL = CounterImpl.class.getResource("CounterImpl.class");
-
-        File classFile = new File(classURL.toURI());
-
-        touch(classFile);
-
-        assertEquals(ReloadAwareModule.counterInstantiations, 1);
-        assertEquals(ReloadAwareModule.counterReloads, 0);
-
-        fireUpdateCheck(r);
-
-        assertEquals(ReloadAwareModule.counterInstantiations, 2);
-        assertEquals(ReloadAwareModule.counterReloads, 1);
-
-        // Check that internal state has reset
-
-        assertEquals(counter.increment(), 1);
-
-        r.shutdown();
-    }
-}