You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by js...@apache.org on 2017/04/16 16:18:11 UTC

[3/8] geode git commit: GEODE-2686: Remove JarClassLoader

http://git-wip-us.apache.org/repos/asf/geode/blob/6fd2d123/geode-core/src/test/java/org/apache/geode/internal/ClassPathLoaderTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/ClassPathLoaderTest.java b/geode-core/src/test/java/org/apache/geode/internal/ClassPathLoaderTest.java
index 6baddaf..0d26caf 100755
--- a/geode-core/src/test/java/org/apache/geode/internal/ClassPathLoaderTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/ClassPathLoaderTest.java
@@ -14,7 +14,9 @@
  */
 package org.apache.geode.internal;
 
-import static org.junit.Assert.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.io.BufferedInputStream;
 import java.io.File;
@@ -62,7 +64,22 @@ public class ClassPathLoaderTest {
   public void testLatestExists() throws Exception {
     System.out.println("\nStarting ClassPathLoaderTest#testLatestExists");
 
-    assertNotNull(ClassPathLoader.getLatest());
+    assertThat(ClassPathLoader.getLatest()).isNotNull();
+  }
+
+  @Test
+  public void testZeroLengthFile() throws IOException, ClassNotFoundException {
+    assertThatThrownBy(() -> {
+      ClassPathLoader.getLatest().getJarDeployer().deploy(new String[] {"JarDeployerDUnitZLF.jar"},
+          new byte[][] {new byte[0]});
+    }).isInstanceOf(IllegalArgumentException.class);
+
+    assertThatThrownBy(() -> {
+      ClassPathLoader.getLatest().getJarDeployer().deploy(
+          new String[] {"JarDeployerDUnitZLF1.jar", "JarDeployerDUnitZLF2.jar"},
+          new byte[][] {new ClassBuilder().createJarFromName("JarDeployerDUnitZLF1"), new byte[0]});
+
+    }).isInstanceOf(IllegalArgumentException.class);
   }
 
   /**
@@ -73,13 +90,10 @@ public class ClassPathLoaderTest {
   public void testForNameThrowsClassNotFoundException() throws Exception {
     System.out.println("\nStarting ClassPathLoaderTest#testForNameThrowsClassNotFoundException");
 
-    try {
-      String classToLoad = "com.nowhere.DoesNotExist";
-      ClassPathLoader.getLatest().forName(classToLoad);
-      fail();
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
+    String classToLoad = "com.nowhere.DoesNotExist";
+
+    assertThatThrownBy(() -> ClassPathLoader.getLatest().forName(classToLoad))
+        .isInstanceOf(ClassNotFoundException.class);
   }
 
   /**
@@ -92,7 +106,7 @@ public class ClassPathLoaderTest {
 
     String classToLoad = "org.apache.geode.internal.classpathloaderjunittest.DoesExist";
     Class<?> clazz = ClassPathLoader.getLatest().forName(classToLoad);
-    assertNotNull(clazz);
+    assertThat(clazz).isNotNull();
   }
 
   /**
@@ -105,10 +119,10 @@ public class ClassPathLoaderTest {
 
     String resourceToGet = "org/apache/geode/internal/classpathloaderjunittest/DoesExist.class";
     URL url = ClassPathLoader.getLatest().getResource(resourceToGet);
-    assertNotNull(url);
+    assertThat(url).isNotNull();
 
     InputStream is = url != null ? url.openStream() : null;
-    assertNotNull(is);
+    assertThat(is).isNotNull();
 
     int totalBytesRead = 0;
     byte[] input = new byte[256];
@@ -122,7 +136,7 @@ public class ClassPathLoaderTest {
 
     // if the following fails then maybe javac changed and DoesExist.class
     // contains other than 374 bytes of data... consider updating this test
-    assertEquals(GENERATED_CLASS_BYTES_COUNT, totalBytesRead);
+    assertThat(totalBytesRead).isEqualTo(GENERATED_CLASS_BYTES_COUNT);
   }
 
   /**
@@ -135,12 +149,12 @@ public class ClassPathLoaderTest {
 
     String resourceToGet = "org/apache/geode/internal/classpathloaderjunittest/DoesExist.class";
     Enumeration<URL> urls = ClassPathLoader.getLatest().getResources(resourceToGet);
-    assertNotNull(urls);
-    assertTrue(urls.hasMoreElements());
+    assertThat(urls).isNotNull();
+    assertThat(urls.hasMoreElements()).isTrue();
 
     URL url = urls.nextElement();
     InputStream is = url != null ? url.openStream() : null;
-    assertNotNull(is);
+    assertThat(is).isNotNull();
 
     int totalBytesRead = 0;
     byte[] input = new byte[256];
@@ -154,7 +168,7 @@ public class ClassPathLoaderTest {
 
     // if the following fails then maybe javac changed and DoesExist.class
     // contains other than 374 bytes of data... consider updating this test
-    assertEquals(GENERATED_CLASS_BYTES_COUNT, totalBytesRead);
+    assertThat(totalBytesRead).isEqualTo(GENERATED_CLASS_BYTES_COUNT);
   }
 
   /**
@@ -167,7 +181,7 @@ public class ClassPathLoaderTest {
 
     String resourceToGet = "org/apache/geode/internal/classpathloaderjunittest/DoesExist.class";
     InputStream is = ClassPathLoader.getLatest().getResourceAsStream(resourceToGet);
-    assertNotNull(is);
+    assertThat(is).isNotNull();
 
     int totalBytesRead = 0;
     byte[] input = new byte[256];
@@ -181,7 +195,7 @@ public class ClassPathLoaderTest {
 
     // if the following fails then maybe javac changed and DoesExist.class
     // contains other than 374 bytes of data... consider updating this test
-    assertEquals(GENERATED_CLASS_BYTES_COUNT, totalBytesRead);
+    assertThat(totalBytesRead).isEqualTo(GENERATED_CLASS_BYTES_COUNT);
   }
 
   /**
@@ -197,44 +211,22 @@ public class ClassPathLoaderTest {
     String classToLoad = "com.nowhere.TestGeneratingClassLoader";
 
     Class<?> clazz = gcl.loadClass(classToLoad);
-    assertNotNull(clazz);
-    assertEquals(classToLoad, clazz.getName());
+    assertThat(clazz).isNotNull();
+    assertThat(clazz.getName()).isEqualTo(classToLoad);
 
     Object obj = clazz.newInstance();
-    assertEquals(clazz.getName(), obj.getClass().getName());
+    assertThat(obj.getClass().getName()).isEqualTo(clazz.getName());
 
-    try {
+    assertThatThrownBy(() -> {
       Class.forName(classToLoad);
-      fail("Should have thrown ClassNotFoundException");
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
+    }).isInstanceOf(ClassNotFoundException.class);
 
     Class<?> clazzForName = Class.forName(classToLoad, true, gcl);
-    assertNotNull(clazzForName);
-    assertEquals(clazz, clazzForName);
+    assertThat(clazzForName).isNotNull();
+    assertThat(clazzForName).isEqualTo(clazz);
 
     Object objForName = clazzForName.newInstance();
-    assertEquals(classToLoad, objForName.getClass().getName());
-  }
-
-  /**
-   * Verifies that custom loader is used to load class.
-   */
-  @Test
-  public void testForNameWithCustomLoader() throws Exception {
-    System.out.println("\nStarting ClassPathLoaderTest#testForNameWithCustomLoader");
-
-    ClassPathLoader dcl = ClassPathLoader.createWithDefaults(false);
-    dcl = dcl.addOrReplace(new GeneratingClassLoader());
-
-    String classToLoad = "com.nowhere.TestForNameWithCustomLoader";
-    Class<?> clazz = dcl.forName(classToLoad);
-    assertNotNull(clazz);
-    assertEquals(classToLoad, clazz.getName());
-
-    Object obj = clazz.newInstance();
-    assertEquals(classToLoad, obj.getClass().getName());
+    assertThat(objForName.getClass().getName()).isEqualTo(classToLoad);
   }
 
   /**
@@ -251,7 +243,7 @@ public class ClassPathLoaderTest {
     String classToLoad = "[Ljava.lang.String;";
     Class<?> clazz = null;
     clazz = dcl.forName(classToLoad);
-    assertEquals(classToLoad, clazz.getName());
+    assertThat(clazz.getName()).isEqualTo(classToLoad);
   }
 
   /**
@@ -265,33 +257,27 @@ public class ClassPathLoaderTest {
     final ClassPathLoader dcl = ClassPathLoader.createWithDefaults(false);
     final String classToLoad = "com.nowhere.TestForNameWithTCCL";
 
-    try {
+    assertThatThrownBy(() -> {
       dcl.forName(classToLoad);
-      fail("Should have thrown ClassNotFoundException");
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
+
+    }).isInstanceOf(ClassNotFoundException.class);
 
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     try {
       // ensure that TCCL is only CL that can find this class
       Thread.currentThread().setContextClassLoader(new GeneratingClassLoader());
       Class<?> clazz = dcl.forName(classToLoad);
-      assertNotNull(clazz);
+      assertThat(clazz).isNotNull();
       Object instance = clazz.newInstance();
-      assertNotNull(instance);
-      assertEquals(classToLoad, instance.getClass().getName());
+      assertThat(instance).isNotNull();
+      assertThat(instance.getClass().getName()).isEqualTo(classToLoad);
     } finally {
       Thread.currentThread().setContextClassLoader(cl);
     }
 
-    try {
+    assertThatThrownBy(() -> {
       dcl.forName(classToLoad);
-      fail("Should have thrown ClassNotFoundException");
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
-
+    }).isInstanceOf(ClassNotFoundException.class);
   }
 
   /**
@@ -305,20 +291,17 @@ public class ClassPathLoaderTest {
     ClassLoader cl = new NullClassLoader();
     String classToLoad = "java.lang.String";
 
-    try {
+    assertThatThrownBy(() -> {
       Class.forName(classToLoad, true, cl);
-      fail();
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
+    }).isInstanceOf(ClassNotFoundException.class);
 
     String resourceToGet = "java/lang/String.class";
 
     URL url = cl.getResource(resourceToGet);
-    assertNull(url);
+    assertThat(url).isNull();
 
     InputStream is = cl.getResourceAsStream(resourceToGet);
-    assertNull(is);
+    assertThat(is).isNull();
   }
 
   /**
@@ -333,15 +316,15 @@ public class ClassPathLoaderTest {
     String classToLoad = "java.lang.String";
 
     Class<?> clazz = Class.forName(classToLoad, true, cl);
-    assertNotNull(clazz);
+    assertThat(clazz).isNotNull();
 
     String resourceToGet = "java/lang/String.class";
 
     URL url = cl.getResource(resourceToGet);
-    assertNotNull(url);
+    assertThat(url).isNotNull();
 
     InputStream is = cl.getResourceAsStream(resourceToGet);
-    assertNotNull(is);
+    assertThat(is).isNotNull();
   }
 
   /**
@@ -355,28 +338,19 @@ public class ClassPathLoaderTest {
     ClassLoader cl = new BrokenClassLoader();
 
     String classToLoad = "java.lang.String";
-    try {
+
+    assertThatThrownBy(() -> {
       Class.forName(classToLoad, true, cl);
-      fail();
-    } catch (ClassNotFoundException e) {
-      throw e;
-    } catch (BrokenError expected) {
-      // Expected
-    }
+    }).isInstanceOf(BrokenError.class);
 
     String resourceToGet = "java/lang/String.class";
-    try {
+    assertThatThrownBy(() -> {
       cl.getResource(resourceToGet);
-      fail();
-    } catch (BrokenError expected) {
-      // Expected
-    }
-    try {
+    }).isInstanceOf(BrokenError.class);
+
+    assertThatThrownBy(() -> {
       cl.getResourceAsStream(resourceToGet);
-      fail();
-    } catch (BrokenError expected) {
-      // Expected
-    }
+    }).isInstanceOf(BrokenError.class);
   }
 
   /**
@@ -390,7 +364,6 @@ public class ClassPathLoaderTest {
     System.out.println("\nStarting ClassPathLoaderTest#testBrokenTCCLThrowsErrors");
 
     ClassPathLoader dcl = ClassPathLoader.createWithDefaults(false);
-    dcl.addOrReplace(new NullClassLoader());
 
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     try {
@@ -398,29 +371,18 @@ public class ClassPathLoaderTest {
       Thread.currentThread().setContextClassLoader(new BrokenClassLoader());
 
       String classToLoad = "java.lang.String";
-      try {
+      assertThatThrownBy(() -> {
         dcl.forName(classToLoad);
-        fail();
-      } catch (ClassNotFoundException e) {
-        throw e;
-      } catch (BrokenError expected) {
-        // Expected
-      }
+      }).isInstanceOf(BrokenError.class);
 
       String resourceToGet = "java/lang/String.class";
-      try {
+      assertThatThrownBy(() -> {
         dcl.getResource(resourceToGet);
-        fail();
-      } catch (BrokenError expected) {
-        // Expected
-      }
+      }).isInstanceOf(BrokenError.class);
 
-      try {
+      assertThatThrownBy(() -> {
         dcl.getResourceAsStream(resourceToGet);
-        fail();
-      } catch (BrokenError expected) {
-        // Expected
-      }
+      }).isInstanceOf(BrokenError.class);
     } finally {
       Thread.currentThread().setContextClassLoader(cl);
     }
@@ -436,7 +398,6 @@ public class ClassPathLoaderTest {
 
     // create DCL such that parent cannot find anything
     ClassPathLoader dcl = ClassPathLoader.createWithDefaults(true);
-    dcl.addOrReplace(new NullClassLoader());
 
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     try {
@@ -445,52 +406,13 @@ public class ClassPathLoaderTest {
 
       String classToLoad = "java.lang.String";
       Class<?> clazz = dcl.forName(classToLoad);
-      assertNotNull(clazz);
+      assertThat(clazz).isNotNull();
 
       String resourceToGet = "java/lang/String.class";
       URL url = dcl.getResource(resourceToGet);
-      assertNotNull(url);
+      assertThat(url).isNotNull();
       InputStream is = dcl.getResourceAsStream(resourceToGet);
-      assertNotNull(is);
-    } finally {
-      Thread.currentThread().setContextClassLoader(cl);
-    }
-  }
-
-  /**
-   * Verifies that the 3rd custom loader will find the class. Parent cannot find it and TCCL is
-   * broken. This verifies that all custom loaders are checked and that the custom loaders are all
-   * checked before TCCL.
-   */
-  @Test
-  public void testForNameWithMultipleCustomLoaders() throws Exception {
-    System.out.println("\nStarting ClassPathLoaderTest#testForNameWithMultipleCustomLoaders");
-
-    // create DCL such that the 3rd loader should find the class
-    // first custom loader becomes parent which won't find anything
-    ClassPathLoader dcl = ClassPathLoader.createWithDefaults(false);
-    final GeneratingClassLoader generatingClassLoader = new GeneratingClassLoader();
-    dcl = dcl.addOrReplace(generatingClassLoader);
-    dcl = dcl.addOrReplace(new SimpleClassLoader(getClass().getClassLoader()));
-    dcl = dcl.addOrReplace(new NullClassLoader());
-
-    String classToLoad = "com.nowhere.TestForNameWithMultipleCustomLoaders";
-
-    ClassLoader cl = Thread.currentThread().getContextClassLoader();
-    try {
-      // set TCCL to throw errors which makes sure we find before checking TCCL
-      Thread.currentThread().setContextClassLoader(new BrokenClassLoader());
-
-      Class<?> clazz = dcl.forName(classToLoad);
-      assertNotNull(clazz);
-      assertEquals(classToLoad, clazz.getName());
-      assertTrue("Class not loaded by a GeneratingClassLoader.",
-          clazz.getClassLoader() instanceof GeneratingClassLoader);
-      assertEquals("Class not loaded by generatingClassLoader.", generatingClassLoader,
-          clazz.getClassLoader());
-
-      Object obj = clazz.newInstance();
-      assertEquals(classToLoad, obj.getClass().getName());
+      assertThat(is).isNotNull();
     } finally {
       Thread.currentThread().setContextClassLoader(cl);
     }
@@ -508,28 +430,24 @@ public class ClassPathLoaderTest {
 
     String classToLoad = "com.nowhere.TestExcludeTCCL";
 
-    try {
+    assertThatThrownBy(() -> {
       dcl.forName(classToLoad);
-      fail("Should have thrown ClassNotFoundException");
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
+
+    }).isInstanceOf(ClassNotFoundException.class);
 
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
     try {
-      // ensure that TCCL is only CL that can find this class
       Thread.currentThread().setContextClassLoader(new GeneratingClassLoader());
-      dcl.forName(classToLoad);
-      fail("Should have thrown ClassNotFoundException");
-    } catch (ClassNotFoundException expected) {
-      // Expected
+
+      assertThatThrownBy(() -> {
+        dcl.forName(classToLoad);
+      }).isInstanceOf(ClassNotFoundException.class);
     } finally {
       Thread.currentThread().setContextClassLoader(cl);
     }
-
   }
 
-
   /**
    * Verifies that <tt>getResource</tt> will skip TCCL if <tt>excludeThreadContextClassLoader</tt>
    * has been set to true.
@@ -541,13 +459,13 @@ public class ClassPathLoaderTest {
     ClassPathLoader dcl = ClassPathLoader.createWithDefaults(true);
 
     String resourceToGet = "com/nowhere/testGetResourceExcludeTCCL.rsc";
-    assertNull(dcl.getResource(resourceToGet));
+    assertThat(dcl.getResource(resourceToGet)).isNull();
 
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     try {
       // ensure that TCCL is only CL that can find this resource
       Thread.currentThread().setContextClassLoader(new GeneratingClassLoader());
-      assertNull(dcl.getResource(resourceToGet));
+      assertThat(dcl.getResource(resourceToGet)).isNull();
     } finally {
       Thread.currentThread().setContextClassLoader(cl);
     }
@@ -564,161 +482,18 @@ public class ClassPathLoaderTest {
     ClassPathLoader dcl = ClassPathLoader.createWithDefaults(true);
 
     String resourceToGet = "com/nowhere/testGetResourceAsStreamExcludeTCCL.rsc";
-    assertNull(dcl.getResourceAsStream(resourceToGet));
+    assertThat(dcl.getResourceAsStream(resourceToGet)).isNull();
 
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     try {
       // ensure that TCCL is only CL that can find this resource
       Thread.currentThread().setContextClassLoader(new GeneratingClassLoader());
-      assertNull(dcl.getResourceAsStream(resourceToGet));
-    } finally {
-      Thread.currentThread().setContextClassLoader(cl);
-    }
-  }
-
-  @Test
-  public void testAddFindsLatestClassLoader() throws Exception {
-    System.out.println("\nStarting ClassPathLoaderTest#testAddFindsLatestClassLoader");
-
-    ClassPathLoader dcl = ClassPathLoader.createWithDefaults(false);
-    dcl = dcl.addOrReplace(new GeneratingClassLoader());
-
-    String classToLoad = "com.nowhere.TestAddFindsLatestClassLoader";
-    Class<?> clazz = dcl.forName(classToLoad);
-    assertNotNull(clazz);
-
-    dcl = dcl.addOrReplace(new BrokenClassLoader());
-
-    try {
-      dcl.forName(classToLoad);
-      fail();
-    } catch (BrokenError expected) {
-      // Expected
-    }
-  }
-
-  /**
-   * Verifies removing a ClassLoader.
-   */
-  @Test
-  public void testRemoveClassLoader() throws Exception {
-    System.out.println("\nStarting ClassPathLoaderTest#testRemoveClassLoader");
-
-    GeneratingClassLoader genClassLoader = new GeneratingClassLoader();
-    ClassPathLoader cpl = ClassPathLoader.createWithDefaults(false);
-    cpl = cpl.addOrReplace(genClassLoader);
-
-    String classToLoad = "com.nowhere.TestRemoveClassLoader";
-    Class<?> clazz = cpl.forName(classToLoad);
-    assertNotNull(clazz);
-
-    cpl = cpl.remove(genClassLoader);
-
-    try {
-      clazz = cpl.forName(classToLoad);
-      fail();
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
-  }
-
-  /**
-   * Verifies that a ClassLoader will be replaced when added more than once.
-   */
-  @Test
-  public void testClassLoaderReplace() throws Exception {
-    System.out.println("\nStarting ClassPathLoaderTest#testClassLoaderReplace");
-
-    String class1ToLoad = "ClassA";
-    String class2ToLoad = "ClassB";
-
-    ClassPathLoader cpl = ClassPathLoader.createWithDefaults(false);
-    cpl = cpl.addOrReplace(new OneClassClassLoader(class1ToLoad));
-
-    try {
-      @SuppressWarnings("unused")
-      Class<?> clazz = cpl.forName(class1ToLoad);
-    } catch (ClassNotFoundException unexpected) {
-      fail();
-    }
-
-    try {
-      @SuppressWarnings("unused")
-      Class<?> clazz = cpl.forName(class2ToLoad);
-      fail();
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
-
-    cpl = cpl.addOrReplace(new OneClassClassLoader(class2ToLoad));
-    try {
-      @SuppressWarnings("unused")
-      Class<?> clazz = cpl.forName(class2ToLoad);
-    } catch (ClassNotFoundException unexpected) {
-      fail();
-    }
-
-    try {
-      @SuppressWarnings("unused")
-      Class<?> clazz = cpl.forName(class1ToLoad);
-      fail();
-    } catch (ClassNotFoundException expected) {
-      // Expected
-    }
-  }
-
-  @Test
-  public void testAsClassLoaderLoadClassWithMultipleCustomLoaders() throws Exception {
-    System.out.println(
-        "\nStarting ClassPathLoaderTest#testAsClassLoaderLoadClassWithMultipleCustomLoaders");
-
-    // create DCL such that the 3rd loader should find the class
-    // first custom loader becomes parent which won't find anything
-    ClassPathLoader dcl = ClassPathLoader.createWithDefaults(false);
-    final GeneratingClassLoader generatingClassLoader = new GeneratingClassLoader();
-    dcl = dcl.addOrReplace(generatingClassLoader);
-    dcl = dcl.addOrReplace(new SimpleClassLoader(getClass().getClassLoader()));
-    dcl = dcl.addOrReplace(new NullClassLoader());
-
-    final String classToLoad = "com.nowhere.TestForNameWithMultipleCustomLoaders";
-
-    ClassLoader cl = Thread.currentThread().getContextClassLoader();
-    try {
-      // set TCCL to throw errors which makes sure we find before checking TCCL
-      Thread.currentThread().setContextClassLoader(new BrokenClassLoader());
-
-      final ClassLoader classLoader = dcl.asClassLoader();
-      final Class<?> clazz = classLoader.loadClass(classToLoad);
-      assertNotNull(clazz);
-      assertEquals(classToLoad, clazz.getName());
-      assertTrue(clazz.getClassLoader() instanceof GeneratingClassLoader);
-      assertEquals(generatingClassLoader, clazz.getClassLoader());
-
-      final Object obj = clazz.newInstance();
-      assertEquals(classToLoad, obj.getClass().getName());
-
-      final Class<?> clazz2 = dcl.forName(classToLoad);
-      assertSame("Should load same class as calling classLoader.", clazz, clazz2);
-
-      final Class<?> clazz3 = Class.forName(classToLoad, true, classLoader);
-      assertSame("Should load same class as calling classLoader.", clazz, clazz3);
-
+      assertThat(dcl.getResourceAsStream(resourceToGet)).isNull();
     } finally {
       Thread.currentThread().setContextClassLoader(cl);
     }
   }
 
-  private static void exploreClassLoaders() {
-    System.out.println("Thread.currentThread().getContextClassLoader()...");
-    exploreClassLoader(Thread.currentThread().getContextClassLoader(), 1);
-
-    System.out.println("class.getClassLoader()...");
-    exploreClassLoader(ClassPathLoaderTest.class.getClassLoader(), 1);
-
-    System.out.println("ClassLoader.getSystemClassLoader()...");
-    exploreClassLoader(ClassLoader.getSystemClassLoader(), 1);
-  }
-
   private static void exploreClassLoader(ClassLoader cl, int indent) {
     String prefix = "";
     for (int i = 0; i < indent; i++) {
@@ -734,8 +509,9 @@ public class ClassPathLoaderTest {
       URL[] urls = ((URLClassLoader) cl).getURLs();
       StringBuilder sb = new StringBuilder(prefix).append("ClassLoader getURLs = [");
       for (int i = 0; i < urls.length; i++) {
-        if (i > 0)
+        if (i > 0) {
           sb.append(", ");
+        }
         sb.append(urls[i].toString());
       }
       sb.append("]");
@@ -816,7 +592,7 @@ public class ClassPathLoaderTest {
     /**
      * Currently unused but potentially useful for some future test. This causes this loader to only
      * generate a class that the parent could not find.
-     *
+     * 
      * @param parent the parent class loader to check with first
      */
     @SuppressWarnings("unused")

http://git-wip-us.apache.org/repos/asf/geode/blob/6fd2d123/geode-core/src/test/java/org/apache/geode/internal/DeployedJarJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/DeployedJarJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/DeployedJarJUnitTest.java
new file mode 100644
index 0000000..7216463
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/DeployedJarJUnitTest.java
@@ -0,0 +1,538 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You 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.geode.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.internal.cache.execute.FunctionContextImpl;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Random;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * TODO: Need to fix this testDeclarableFunctionsWithParms and testClassOnClasspath on Windows:
+ */
+@Category(IntegrationTest.class)
+public class DeployedJarJUnitTest {
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+  private final ClassBuilder classBuilder = new ClassBuilder();
+
+  @Before
+  public void setup() throws Exception {
+    File workingDir = temporaryFolder.newFolder();
+
+    ClassPathLoader.setLatestToDefault(workingDir);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    for (String functionName : FunctionService.getRegisteredFunctions().keySet()) {
+      FunctionService.unregisterFunction(functionName);
+    }
+
+    ClassPathLoader.setLatestToDefault();
+  }
+
+  @Test
+  public void testIsValidJarContent() throws IOException {
+    assertTrue(
+        DeployedJar.isValidJarContent(this.classBuilder.createJarFromName("JarClassLoaderJUnitA")));
+  }
+
+  @Test
+  public void testIsInvalidJarContent() {
+    assertFalse(DeployedJar.isValidJarContent("INVALID JAR CONTENT".getBytes()));
+  }
+
+  @Test
+  public void testClassOnClasspath() throws Exception {
+    // Deploy the first JAR file and make sure the class is on the Classpath
+    byte[] jarBytes =
+        this.classBuilder.createJarFromClassContent("com/jcljunit/JarClassLoaderJUnitA",
+            "package com.jcljunit; public class JarClassLoaderJUnitA {}");
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnit.jar", jarBytes);
+
+    try {
+      ClassPathLoader.getLatest().forName("com.jcljunit.JarClassLoaderJUnitA");
+    } catch (ClassNotFoundException cnfex) {
+      fail("JAR file not correctly added to Classpath");
+    }
+
+    // Update the JAR file and make sure the first class is no longer on the Classpath
+    // and the second one is.
+    jarBytes = this.classBuilder.createJarFromClassContent("com/jcljunit/JarClassLoaderJUnitB",
+        "package com.jcljunit; public class JarClassLoaderJUnitB {}");
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnit.jar", jarBytes);
+
+    try {
+      ClassPathLoader.getLatest().forName("com.jcljunit.JarClassLoaderJUnitB");
+    } catch (ClassNotFoundException cnfex) {
+      fail("JAR file not correctly added to Classpath");
+    }
+
+    try {
+      ClassPathLoader.getLatest().forName("com.jcljunit.JarClassLoaderJUnitA");
+      fail("Class should not be found on Classpath");
+    } catch (ClassNotFoundException expected) { // expected
+    }
+
+  }
+
+  @Test
+  public void testFailingCompilation() throws Exception {
+    StringBuffer stringBuffer = new StringBuffer();
+    stringBuffer.append("import org.apache.geode.cache.Declarable;");
+    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
+    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
+    stringBuffer.append("public class JarClassLoaderJUnitFunction implements Function {}");
+    String functionString = stringBuffer.toString();
+
+    try {
+      this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
+      fail("This code should have failed to compile and thrown an exception");
+    } catch (Exception ex) {
+      // All good
+    }
+  }
+
+  @Test
+  public void testFunctions() throws IOException, ClassNotFoundException {
+    // Test creating a JAR file with a function
+    StringBuffer stringBuffer = new StringBuffer();
+    stringBuffer.append("import java.util.Properties;");
+    stringBuffer.append("import org.apache.geode.cache.Declarable;");
+    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
+    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
+    stringBuffer.append("public class JarClassLoaderJUnitFunction implements Function {");
+    stringBuffer.append("public void init(Properties props) {}");
+    stringBuffer.append("public boolean hasResult() {return true;}");
+    stringBuffer.append(
+        "public void execute(FunctionContext context) {context.getResultSender().lastResult(\"GOODv1\");}");
+    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}");
+    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
+    stringBuffer.append("public boolean isHA() {return false;}}");
+    String functionString = stringBuffer.toString();
+
+    byte[] jarBytes =
+        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
+
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnit.jar", jarBytes);
+
+    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
+    assertNotNull(function);
+    TestResultSender resultSender = new TestResultSender();
+    FunctionContext functionContext = new FunctionContextImpl(function.getId(), null, resultSender);
+    function.execute(functionContext);
+    assertEquals("GOODv1", (String) resultSender.getResults());
+
+    // Test updating the function with a new JAR file
+    functionString = functionString.replace("v1", "v2");
+    jarBytes =
+        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnit.jar", jarBytes);
+
+    function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
+    assertNotNull(function);
+    resultSender = new TestResultSender();
+    functionContext = new FunctionContextImpl(function.getId(), null, resultSender);
+    function.execute(functionContext);
+    assertEquals("GOODv2", (String) resultSender.getResults());
+
+    // Test returning null for the Id
+    String functionNullIdString =
+        functionString.replace("return \"JarClassLoaderJUnitFunction\"", "return null");
+    jarBytes = this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction",
+        functionNullIdString);
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnit.jar", jarBytes);
+
+    assertNull(FunctionService.getFunction("JarClassLoaderJUnitFunction"));
+
+    // Test removing the JAR
+    ClassPathLoader.getLatest().getJarDeployer().undeploy("JarClassLoaderJUnit.jar");
+    assertNull(FunctionService.getFunction("JarClassLoaderJUnitFunction"));
+  }
+
+  /**
+   * Ensure that abstract functions aren't added to the Function Service.
+   */
+  @Test
+  public void testAbstractFunction() throws IOException, ClassNotFoundException {
+    // Add an abstract Function to the Classpath
+    StringBuffer stringBuffer = new StringBuffer();
+    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
+    stringBuffer.append("public abstract class JarClassLoaderJUnitFunction implements Function {");
+    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}}");
+    String functionString = stringBuffer.toString();
+
+    byte[] jarBytes =
+        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitFunction.jar",
+        jarBytes);
+
+    try {
+      ClassPathLoader.getLatest().forName("JarClassLoaderJUnitFunction");
+    } catch (ClassNotFoundException cnfex) {
+      fail("JAR file not correctly added to Classpath");
+    }
+
+    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
+    assertNull(function);
+  }
+
+  @Test
+  public void testDeclarableFunctionsWithNoCacheXml() throws Exception {
+
+    final String jarName = "JarClassLoaderJUnitNoXml.jar";
+
+    // Add a Declarable Function without parameters for the class to the Classpath
+    StringBuffer stringBuffer = new StringBuffer();
+    stringBuffer.append("import java.util.Properties;");
+    stringBuffer.append("import org.apache.geode.cache.Declarable;");
+    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
+    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
+    stringBuffer
+        .append("public class JarClassLoaderJUnitFunctionNoXml implements Function, Declarable {");
+    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunctionNoXml\";}");
+    stringBuffer.append("public void init(Properties props) {}");
+    stringBuffer.append(
+        "public void execute(FunctionContext context) {context.getResultSender().lastResult(\"NOPARMSv1\");}");
+    stringBuffer.append("public boolean hasResult() {return true;}");
+    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
+    stringBuffer.append("public boolean isHA() {return false;}}");
+    String functionString = stringBuffer.toString();
+
+    byte[] jarBytes = this.classBuilder
+        .createJarFromClassContent("JarClassLoaderJUnitFunctionNoXml", functionString);
+
+    ClassPathLoader.getLatest().getJarDeployer().deploy(jarName, jarBytes);
+
+    try {
+      ClassPathLoader.getLatest().forName("JarClassLoaderJUnitFunctionNoXml");
+    } catch (ClassNotFoundException cnfex) {
+      fail("JAR file not correctly added to Classpath");
+    }
+
+    // Check to see if the function without parameters executes correctly
+    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunctionNoXml");
+    assertNotNull(function);
+    TestResultSender resultSender = new TestResultSender();
+    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
+    assertEquals("NOPARMSv1", (String) resultSender.getResults());
+  }
+
+  @Test
+  public void testDependencyBetweenJars() throws IOException, ClassNotFoundException {
+    final File parentJarFile = temporaryFolder.newFile("JarClassLoaderJUnitParent.jar");
+    final File usesJarFile = temporaryFolder.newFile("JarClassLoaderJUnitUses.jar");
+
+    JarDeployer jarDeployer = ClassPathLoader.getLatest().getJarDeployer();
+
+    // Write out a JAR files.
+    StringBuffer stringBuffer = new StringBuffer();
+    stringBuffer.append("package jcljunit.parent;");
+    stringBuffer.append("public class JarClassLoaderJUnitParent {");
+    stringBuffer.append("public String getValueParent() {");
+    stringBuffer.append("return \"PARENT\";}}");
+
+    byte[] jarBytes = this.classBuilder.createJarFromClassContent(
+        "jcljunit/parent/JarClassLoaderJUnitParent", stringBuffer.toString());
+    writeJarBytesToFile(parentJarFile, jarBytes);
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitParent.jar", jarBytes);
+
+    stringBuffer = new StringBuffer();
+    stringBuffer.append("package jcljunit.uses;");
+    stringBuffer.append("public class JarClassLoaderJUnitUses {");
+    stringBuffer.append("public String getValueUses() {");
+    stringBuffer.append("return \"USES\";}}");
+
+    jarBytes = this.classBuilder.createJarFromClassContent("jcljunit/uses/JarClassLoaderJUnitUses",
+        stringBuffer.toString());
+    writeJarBytesToFile(usesJarFile, jarBytes);
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitUses.jar", jarBytes);
+
+    stringBuffer = new StringBuffer();
+    stringBuffer.append("package jcljunit.function;");
+    stringBuffer.append("import jcljunit.parent.JarClassLoaderJUnitParent;");
+    stringBuffer.append("import jcljunit.uses.JarClassLoaderJUnitUses;");
+    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
+    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
+    stringBuffer.append(
+        "public class JarClassLoaderJUnitFunction  extends JarClassLoaderJUnitParent implements Function {");
+    stringBuffer.append("private JarClassLoaderJUnitUses uses = new JarClassLoaderJUnitUses();");
+    stringBuffer.append("public boolean hasResult() {return true;}");
+    stringBuffer.append(
+        "public void execute(FunctionContext context) {context.getResultSender().lastResult(getValueParent() + \":\" + uses.getValueUses());}");
+    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}");
+    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
+    stringBuffer.append("public boolean isHA() {return false;}}");
+
+    ClassBuilder functionClassBuilder = new ClassBuilder();
+    functionClassBuilder.addToClassPath(parentJarFile.getAbsolutePath());
+    functionClassBuilder.addToClassPath(usesJarFile.getAbsolutePath());
+    jarBytes = functionClassBuilder.createJarFromClassContent(
+        "jcljunit/function/JarClassLoaderJUnitFunction", stringBuffer.toString());
+
+
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitFunction.jar",
+        jarBytes);
+
+
+    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
+    assertNotNull(function);
+    TestResultSender resultSender = new TestResultSender();
+    FunctionContext functionContext = new FunctionContextImpl(function.getId(), null, resultSender);
+    function.execute(functionContext);
+    assertEquals("PARENT:USES", (String) resultSender.getResults());
+  }
+
+  @Test
+  public void testFindResource() throws IOException, ClassNotFoundException {
+    final String fileName = "file.txt";
+    final String fileContent = "FILE CONTENT";
+
+    byte[] jarBytes = this.classBuilder.createJarFromFileContent(fileName, fileContent);
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitResource.jar",
+        jarBytes);
+
+    InputStream inputStream = ClassPathLoader.getLatest().getResourceAsStream(fileName);
+    assertNotNull(inputStream);
+
+    final byte[] fileBytes = new byte[fileContent.length()];
+    inputStream.read(fileBytes);
+    inputStream.close();
+    assertTrue(fileContent.equals(new String(fileBytes)));
+  }
+
+  @Test
+  public void testUpdateClassInJar() throws IOException, ClassNotFoundException {
+    // First use of the JAR file
+    byte[] jarBytes = this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitTestClass",
+        "public class JarClassLoaderJUnitTestClass { public Integer getValue5() { return new Integer(5); } }");
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitUpdate.jar", jarBytes);
+
+    try {
+      Class<?> clazz = ClassPathLoader.getLatest().forName("JarClassLoaderJUnitTestClass");
+      Object object = clazz.newInstance();
+      Method getValue5Method = clazz.getMethod("getValue5", new Class[] {});
+      Integer value = (Integer) getValue5Method.invoke(object, new Object[] {});
+      assertEquals(value.intValue(), 5);
+
+    } catch (InvocationTargetException itex) {
+      fail("JAR file not correctly added to Classpath" + itex);
+    } catch (NoSuchMethodException nsmex) {
+      fail("JAR file not correctly added to Classpath" + nsmex);
+    } catch (InstantiationException iex) {
+      fail("JAR file not correctly added to Classpath" + iex);
+    } catch (IllegalAccessException iaex) {
+      fail("JAR file not correctly added to Classpath" + iaex);
+    } catch (ClassNotFoundException cnfex) {
+      fail("JAR file not correctly added to Classpath" + cnfex);
+    }
+
+    // Now create an updated JAR file and make sure that the method from the new
+    // class is available.
+    jarBytes = this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitTestClass",
+        "public class JarClassLoaderJUnitTestClass { public Integer getValue10() { return new Integer(10); } }");
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitUpdate.jar", jarBytes);
+
+
+    try {
+      Class<?> clazz = ClassPathLoader.getLatest().forName("JarClassLoaderJUnitTestClass");
+      Object object = clazz.newInstance();
+      Method getValue10Method = clazz.getMethod("getValue10", new Class[] {});
+      Integer value = (Integer) getValue10Method.invoke(object, new Object[] {});
+      assertEquals(value.intValue(), 10);
+
+    } catch (InvocationTargetException itex) {
+      fail("JAR file not correctly added to Classpath" + itex);
+    } catch (NoSuchMethodException nsmex) {
+      fail("JAR file not correctly added to Classpath" + nsmex);
+    } catch (InstantiationException iex) {
+      fail("JAR file not correctly added to Classpath" + iex);
+    } catch (IllegalAccessException iaex) {
+      fail("JAR file not correctly added to Classpath" + iaex);
+    } catch (ClassNotFoundException cnfex) {
+      fail("JAR file not correctly added to Classpath" + cnfex);
+    }
+  }
+
+  @Test
+  public void testMultiThread() throws IOException, ClassNotFoundException {
+    // Add two JARs to the classpath
+    byte[] jarBytes = this.classBuilder.createJarFromName("JarClassLoaderJUnitA");
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitA.jar", jarBytes);
+
+    jarBytes = this.classBuilder.createJarFromClassContent("com/jcljunit/JarClassLoaderJUnitB",
+        "package com.jcljunit; public class JarClassLoaderJUnitB {}");
+    ClassPathLoader.getLatest().getJarDeployer().deploy("JarClassLoaderJUnitB.jar", jarBytes);
+
+    String[] classNames = new String[] {"JarClassLoaderJUnitA", "com.jcljunit.JarClassLoaderJUnitB",
+        "NON-EXISTENT CLASS"};
+
+    // Spawn some threads which try to instantiate these classes
+    final int threadCount = 10;
+    final int numLoops = 1000;
+    final CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount + 1);
+    for (int i = 0; i < threadCount; i++) {
+      new ForNameExerciser(cyclicBarrier, numLoops, classNames).start();
+    }
+
+    // Wait for all of the threads to be ready
+    try {
+      cyclicBarrier.await();
+    } catch (InterruptedException iex) {
+      fail("Interrupted while waiting for barrier");
+    } catch (BrokenBarrierException bbex) {
+      fail("Broken barrier while waiting");
+    }
+
+    // Loop while each thread tries N times to instantiate a non-existent class
+    for (int i = 0; i < numLoops; i++) {
+      try {
+        cyclicBarrier.await(5, TimeUnit.SECONDS);
+      } catch (InterruptedException iex) {
+        fail("Interrupted while waiting for barrier");
+      } catch (TimeoutException tex) {
+        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+        long[] threadIds = threadMXBean.findDeadlockedThreads();
+
+        if (threadIds != null) {
+          StringBuffer deadLockTrace = new StringBuffer();
+          for (long threadId : threadIds) {
+            ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId, 100);
+            deadLockTrace.append(threadInfo.getThreadName()).append("\n");
+            for (StackTraceElement stackTraceElem : threadInfo.getStackTrace()) {
+              deadLockTrace.append("\t").append(stackTraceElem).append("\n");
+            }
+          }
+
+          fail("Deadlock with trace:\n" + deadLockTrace.toString());
+        }
+
+        fail("Timeout while waiting for barrier - no deadlock detected");
+      } catch (BrokenBarrierException bbex) {
+        fail("Broken barrier while waiting");
+      }
+    }
+  }
+
+
+  private void writeJarBytesToFile(File jarFile, byte[] jarBytes) throws IOException {
+    final OutputStream outStream = new FileOutputStream(jarFile);
+    outStream.write(jarBytes);
+    outStream.close();
+  }
+
+  private static class TestResultSender implements ResultSender<Object> {
+    private Object result;
+
+    public TestResultSender() {}
+
+    protected Object getResults() {
+      return this.result;
+    }
+
+    @Override
+    public void lastResult(final Object lastResult) {
+      this.result = lastResult;
+    }
+
+    @Override
+    public void sendResult(final Object oneResult) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendException(final Throwable t) {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  static final Random random = new Random();
+
+  private class ForNameExerciser extends Thread {
+    private final CyclicBarrier cyclicBarrier;
+    private final int numLoops;
+    private final String[] classNames;
+
+    ForNameExerciser(final CyclicBarrier cyclicBarrier, final int numLoops,
+        final String[] classNames) {
+      this.cyclicBarrier = cyclicBarrier;
+      this.numLoops = numLoops;
+      this.classNames = classNames;
+    }
+
+    @Override
+    public void run() {
+      try {
+        this.cyclicBarrier.await();
+      } catch (InterruptedException iex) {
+        fail("Interrupted while waiting for latch");
+      } catch (BrokenBarrierException bbex) {
+        fail("Broken barrier while waiting");
+      }
+      for (int i = 0; i < this.numLoops; i++) {
+        try {
+          // Random select a name from the list of class names and try to load it
+          String className = this.classNames[random.nextInt(this.classNames.length)];
+          ClassPathLoader.getLatest().forName(className);
+        } catch (ClassNotFoundException expected) { // expected
+        }
+        try {
+          this.cyclicBarrier.await();
+        } catch (InterruptedException iex) {
+          fail("Interrupted while waiting for barrrier");
+        } catch (BrokenBarrierException bbex) {
+          fail("Broken barrier while waiting");
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/6fd2d123/geode-core/src/test/java/org/apache/geode/internal/JarClassLoaderJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/JarClassLoaderJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/JarClassLoaderJUnitTest.java
deleted file mode 100644
index adc1d2e..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/JarClassLoaderJUnitTest.java
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You 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.geode.internal;
-
-import static org.apache.geode.distributed.ConfigurationProperties.*;
-import static org.junit.Assert.*;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Properties;
-import java.util.Random;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.regex.Pattern;
-
-import org.junit.After;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.cache.execute.Function;
-import org.apache.geode.cache.execute.FunctionContext;
-import org.apache.geode.cache.execute.FunctionService;
-import org.apache.geode.cache.execute.ResultSender;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.execute.FunctionContextImpl;
-import org.apache.geode.test.junit.categories.IntegrationTest;
-
-/**
- * TODO: Need to fix this testDeclarableFunctionsWithParms and testClassOnClasspath on Windows:
- */
-@Category(IntegrationTest.class)
-public class JarClassLoaderJUnitTest {
-
-  private static final String JAR_PREFIX = "vf.gf#";
-
-  private final ClassBuilder classBuilder = new ClassBuilder();
-  final Pattern pattern = Pattern.compile("^" + JAR_PREFIX + "JarClassLoaderJUnit.*#\\d++$");
-
-  private InternalCache cache;
-
-  @After
-  public void tearDown() throws Exception {
-    for (ClassLoader classLoader : ClassPathLoader.getLatest().getClassLoaders()) {
-      if (classLoader instanceof JarClassLoader) {
-        JarClassLoader jarClassLoader = (JarClassLoader) classLoader;
-        if (jarClassLoader.getJarName().startsWith("JarClassLoaderJUnit")) {
-          ClassPathLoader.getLatest().removeAndSetLatest(jarClassLoader);
-        }
-      }
-    }
-    for (String functionName : FunctionService.getRegisteredFunctions().keySet()) {
-      if (functionName.startsWith("JarClassLoaderJUnit")) {
-        FunctionService.unregisterFunction(functionName);
-      }
-    }
-
-    if (this.cache != null) {
-      this.cache.close();
-    }
-
-    deleteSavedJarFiles();
-  }
-
-  @Test
-  public void testValidJarContent() throws IOException {
-    assertTrue(JarClassLoader
-        .isValidJarContent(this.classBuilder.createJarFromName("JarClassLoaderJUnitA")));
-  }
-
-  @Test
-  public void testInvalidJarContent() {
-    assertFalse(JarClassLoader.isValidJarContent("INVALID JAR CONTENT".getBytes()));
-  }
-
-  @Test
-  public void testClassOnClasspath() throws IOException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#1");
-    final File jarFile2 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#2");
-    ClassPathLoader classPathLoader = ClassPathLoader.createWithDefaults(false);
-
-    // Deploy the first JAR file and make sure the class is on the Classpath
-    byte[] jarBytes =
-        this.classBuilder.createJarFromClassContent("com/jcljunit/JarClassLoaderJUnitA",
-            "package com.jcljunit; public class JarClassLoaderJUnitA {}");
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader = new JarClassLoader(jarFile1, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-
-    try {
-      classPathLoader.forName("com.jcljunit.JarClassLoaderJUnitA");
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath");
-    }
-
-    // Update the JAR file and make sure the first class is no longer on the Classpath
-    // and the second one is.
-    jarBytes = this.classBuilder.createJarFromClassContent("com/jcljunit/JarClassLoaderJUnitB",
-        "package com.jcljunit; public class JarClassLoaderJUnitB {}");
-    writeJarBytesToFile(jarFile2, jarBytes);
-    classLoader = new JarClassLoader(jarFile2, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-
-    try {
-      classPathLoader.forName("com.jcljunit.JarClassLoaderJUnitB");
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath");
-    }
-
-    try {
-      classPathLoader.forName("com.jcljunit.JarClassLoaderJUnitA");
-      fail("Class should not be found on Classpath");
-    } catch (ClassNotFoundException expected) { // expected
-    }
-
-    classPathLoader.remove(classLoader);
-  }
-
-  @Test
-  public void testFailingCompilation() throws Exception {
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("import org.apache.geode.cache.Declarable;");
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
-    stringBuffer.append("public class JarClassLoaderJUnitFunction implements Function {}");
-    String functionString = stringBuffer.toString();
-
-    try {
-      this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-      fail("This code should have failed to compile and thrown an exception");
-    } catch (Exception ex) {
-      // All good
-    }
-  }
-
-  @Test
-  public void testFunctions() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#1");
-    final File jarFile2 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#2");
-    ClassPathLoader classPathLoader = ClassPathLoader.createWithDefaults(false);
-
-    // Test creating a JAR file with a function
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("import java.util.Properties;");
-    stringBuffer.append("import org.apache.geode.cache.Declarable;");
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
-    stringBuffer.append("public class JarClassLoaderJUnitFunction implements Function {");
-    stringBuffer.append("public void init(Properties props) {}");
-    stringBuffer.append("public boolean hasResult() {return true;}");
-    stringBuffer.append(
-        "public void execute(FunctionContext context) {context.getResultSender().lastResult(\"GOODv1\");}");
-    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}");
-    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
-    stringBuffer.append("public boolean isHA() {return false;}}");
-    String functionString = stringBuffer.toString();
-
-    byte[] jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader = new JarClassLoader(jarFile1, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
-    assertNotNull(function);
-    TestResultSender resultSender = new TestResultSender();
-    FunctionContext functionContext = new FunctionContextImpl(function.getId(), null, resultSender);
-    function.execute(functionContext);
-    assertEquals("GOODv1", (String) resultSender.getResults());
-
-    // Test updating the function with a new JAR file
-    functionString = functionString.replace("v1", "v2");
-    jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile2, jarBytes);
-    classLoader = new JarClassLoader(jarFile2, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
-    assertNotNull(function);
-    resultSender = new TestResultSender();
-    functionContext = new FunctionContextImpl(function.getId(), null, resultSender);
-    function.execute(functionContext);
-    assertEquals("GOODv2", (String) resultSender.getResults());
-
-    // Test returning null for the Id
-    String functionNullIdString =
-        functionString.replace("return \"JarClassLoaderJUnitFunction\"", "return null");
-    jarBytes = this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction",
-        functionNullIdString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    classLoader = new JarClassLoader(jarFile1, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-    assertNull(FunctionService.getFunction("JarClassLoaderJUnitFunction"));
-
-    // Test removing the JAR
-    classPathLoader = classPathLoader.remove(classLoader);
-    assertNull(FunctionService.getFunction("JarClassLoaderJUnitFunction"));
-  }
-
-  /**
-   * Ensure that abstract functions aren't added to the Function Service.
-   */
-  @Test
-  public void testAbstractFunction() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#1");
-
-    Properties properties = new Properties();
-    properties.setProperty(MCAST_PORT, "0");
-    CacheFactory cacheFactory = new CacheFactory(properties);
-    this.cache = (InternalCache) cacheFactory.create();
-
-    // Add an abstract Function to the Classpath
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("public abstract class JarClassLoaderJUnitFunction implements Function {");
-    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}}");
-    String functionString = stringBuffer.toString();
-
-    byte[] jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader =
-        new JarClassLoader(jarFile1, "JarClassLoaderJUnitFunction.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    try {
-      ClassPathLoader.getLatest().forName("JarClassLoaderJUnitFunction");
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath");
-    }
-
-    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
-    assertNull(function);
-  }
-
-  @Test
-  public void testDeclarableFunctionsWithNoCacheXml() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnitNoXml.jar#1");
-
-    // Add a Declarable Function without parameters for the class to the Classpath
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("import java.util.Properties;");
-    stringBuffer.append("import org.apache.geode.cache.Declarable;");
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
-    stringBuffer
-        .append("public class JarClassLoaderJUnitFunctionNoXml implements Function, Declarable {");
-    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunctionNoXml\";}");
-    stringBuffer.append("public void init(Properties props) {}");
-    stringBuffer.append(
-        "public void execute(FunctionContext context) {context.getResultSender().lastResult(\"NOPARMSv1\");}");
-    stringBuffer.append("public boolean hasResult() {return true;}");
-    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
-    stringBuffer.append("public boolean isHA() {return false;}}");
-    String functionString = stringBuffer.toString();
-
-    byte[] jarBytes = this.classBuilder
-        .createJarFromClassContent("JarClassLoaderJUnitFunctionNoXml", functionString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader =
-        new JarClassLoader(jarFile1, "JarClassLoaderJUnitFunctionNoXml.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    try {
-      ClassPathLoader.getLatest().forName("JarClassLoaderJUnitFunctionNoXml");
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath");
-    }
-
-    // Check to see if the function without parameters executes correctly
-    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunctionNoXml");
-    assertNotNull(function);
-    TestResultSender resultSender = new TestResultSender();
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("NOPARMSv1", (String) resultSender.getResults());
-  }
-
-  @Test
-  public void testDeclarableFunctionsWithoutParms() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#1");
-    final File jarFile2 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#2");
-
-    Properties properties = new Properties();
-    properties.setProperty(MCAST_PORT, "0");
-    CacheFactory cacheFactory = new CacheFactory(properties);
-    this.cache = (InternalCache) cacheFactory.create();
-
-    // Add a Declarable Function without parameters for the class to the Classpath
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("import java.util.Properties;");
-    stringBuffer.append("import org.apache.geode.cache.Declarable;");
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
-    stringBuffer
-        .append("public class JarClassLoaderJUnitFunction implements Function, Declarable {");
-    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}");
-    stringBuffer.append("public void init(Properties props) {}");
-    stringBuffer.append(
-        "public void execute(FunctionContext context) {context.getResultSender().lastResult(\"NOPARMSv1\");}");
-    stringBuffer.append("public boolean hasResult() {return true;}");
-    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
-    stringBuffer.append("public boolean isHA() {return false;}}");
-    String functionString = stringBuffer.toString();
-
-    byte[] jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader =
-        new JarClassLoader(jarFile1, "JarClassLoaderJUnitFunction.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    try {
-      ClassPathLoader.getLatest().forName("JarClassLoaderJUnitFunction");
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath");
-    }
-
-    // Create a cache.xml file and configure the cache with it
-    stringBuffer = new StringBuffer();
-    stringBuffer.append("<?xml version=\"1.0\"?>");
-    stringBuffer.append("<!DOCTYPE cache PUBLIC");
-    stringBuffer.append("  \"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN\"");
-    stringBuffer.append("  \"http://www.gemstone.com/dtd/cache7_0.dtd\">");
-    stringBuffer.append("<cache>");
-    stringBuffer.append("  <function-service>");
-    stringBuffer.append("    <function>");
-    stringBuffer.append("      <class-name>JarClassLoaderJUnitFunction</class-name>");
-    stringBuffer.append("    </function>");
-    stringBuffer.append(" </function-service>");
-    stringBuffer.append("</cache>");
-    String cacheXmlString = stringBuffer.toString();
-    this.cache.loadCacheXml(new ByteArrayInputStream(cacheXmlString.getBytes()));
-
-    // Check to see if the function without parameters executes correctly
-    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
-    assertNotNull(function);
-    TestResultSender resultSender = new TestResultSender();
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("NOPARMSv1", (String) resultSender.getResults());
-
-    // Update the second function (change the value returned from execute) by deploying a JAR file
-    functionString = functionString.replace("v1", "v2");
-    jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile2, jarBytes);
-
-    classLoader = new JarClassLoader(jarFile2, "JarClassLoaderJUnitFunction.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    // Check to see if the updated function without parameters executes correctly
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("NOPARMSv2", (String) resultSender.getResults());
-  }
-
-  @Test
-  public void testDeclarableFunctionsWithParms() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#1");
-    final File jarFile2 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#2");
-
-    Properties properties = new Properties();
-    properties.setProperty(MCAST_PORT, "0");
-    CacheFactory cacheFactory = new CacheFactory(properties);
-    this.cache = (InternalCache) cacheFactory.create();
-
-    // Add a Declarable Function with parameters to the class to the Classpath
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("import java.util.Properties;");
-    stringBuffer.append("import org.apache.geode.cache.Declarable;");
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
-    stringBuffer
-        .append("public class JarClassLoaderJUnitFunction implements Function, Declarable {");
-    stringBuffer.append("private Properties properties;");
-    stringBuffer.append(
-        "public String getId() {if(this.properties==null) {return \"JarClassLoaderJUnitFunction\";} else {return (String) this.properties.get(\"id\");}}");
-    stringBuffer.append("public void init(Properties props) {properties = props;}");
-    stringBuffer.append(
-        "public void execute(FunctionContext context) {context.getResultSender().lastResult(properties.get(\"returnValue\") + \"v1\");}");
-    stringBuffer.append("public boolean hasResult() {return true;}");
-    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
-    stringBuffer.append("public boolean isHA() {return false;}}");
-    String functionString = stringBuffer.toString();
-
-    byte[] jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader =
-        new JarClassLoader(jarFile1, "JarClassLoaderJUnitFunction.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    try {
-      ClassPathLoader.getLatest().forName("JarClassLoaderJUnitFunction");
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath");
-    }
-
-    // Create a cache.xml file and configure the cache with it
-    stringBuffer = new StringBuffer();
-    stringBuffer.append("<?xml version=\"1.0\"?>");
-    stringBuffer.append("<!DOCTYPE cache PUBLIC");
-    stringBuffer.append("  \"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN\"");
-    stringBuffer.append("  \"http://www.gemstone.com/dtd/cache7_0.dtd\">");
-    stringBuffer.append("<cache>");
-    stringBuffer.append("  <function-service>");
-    stringBuffer.append("    <function>");
-    stringBuffer.append("      <class-name>JarClassLoaderJUnitFunction</class-name>");
-    stringBuffer.append(
-        "      <parameter name=\"id\"><string>JarClassLoaderJUnitFunctionA</string></parameter>");
-    stringBuffer.append("      <parameter name=\"returnValue\"><string>DOG</string></parameter>");
-    stringBuffer.append("    </function>");
-    stringBuffer.append("    <function>");
-    stringBuffer.append("      <class-name>JarClassLoaderJUnitFunction</class-name>");
-    stringBuffer.append(
-        "      <parameter name=\"id\"><string>JarClassLoaderJUnitFunctionB</string></parameter>");
-    stringBuffer.append("      <parameter name=\"returnValue\"><string>CAT</string></parameter>");
-    stringBuffer.append("    </function>");
-    stringBuffer.append(" </function-service>");
-    stringBuffer.append("</cache>");
-    String cacheXmlString = stringBuffer.toString();
-    this.cache.loadCacheXml(new ByteArrayInputStream(cacheXmlString.getBytes()));
-
-    // Check to see if the functions with parameters execute correctly
-    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunctionA");
-    assertNotNull(function);
-    TestResultSender resultSender = new TestResultSender();
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("DOGv1", (String) resultSender.getResults());
-
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunctionB");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("CATv1", (String) resultSender.getResults());
-
-    // Update the first function (change the value returned from execute)
-    functionString = functionString.replace("v1", "v2");
-    jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile2, jarBytes);
-    classLoader = new JarClassLoader(jarFile2, "JarClassLoaderJUnitFunction.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    // Check to see if the updated functions with parameters execute correctly
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunctionA");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("DOGv2", (String) resultSender.getResults());
-
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunctionB");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("CATv2", (String) resultSender.getResults());
-
-    // Update cache xml to add a new function and replace an existing one
-    cacheXmlString =
-        cacheXmlString.replace("JarClassLoaderJUnitFunctionA", "JarClassLoaderJUnitFunctionC")
-            .replace("CAT", "BIRD");
-    this.cache.loadCacheXml(new ByteArrayInputStream(cacheXmlString.getBytes()));
-
-    // Update the first function (change the value returned from execute)
-    functionString = functionString.replace("v2", "v3");
-    jarBytes =
-        this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitFunction", functionString);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    classLoader = new JarClassLoader(jarFile1, "JarClassLoaderJUnitFunction.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    // Check to see if the updated functions with parameters execute correctly
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunctionA");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("DOGv3", (String) resultSender.getResults());
-
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunctionC");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("DOGv3", (String) resultSender.getResults());
-
-    function = FunctionService.getFunction("JarClassLoaderJUnitFunctionB");
-    assertNotNull(function);
-    function.execute(new FunctionContextImpl(function.getId(), null, resultSender));
-    assertEquals("BIRDv3", (String) resultSender.getResults());
-  }
-
-  @Test
-  public void testDependencyBetweenJars() throws IOException, ClassNotFoundException {
-    final File parentJarFile = new File(JAR_PREFIX + "JarClassLoaderJUnitParent.jar#1");
-    final File usesJarFile = new File(JAR_PREFIX + "JarClassLoaderJUnitUses.jar#1");
-    final File functionJarFile = new File(JAR_PREFIX + "JarClassLoaderJUnitFunction.jar#1");
-
-    // Write out a JAR files.
-    StringBuffer stringBuffer = new StringBuffer();
-    stringBuffer.append("package jcljunit.parent;");
-    stringBuffer.append("public class JarClassLoaderJUnitParent {");
-    stringBuffer.append("public String getValueParent() {");
-    stringBuffer.append("return \"PARENT\";}}");
-
-    byte[] jarBytes = this.classBuilder.createJarFromClassContent(
-        "jcljunit/parent/JarClassLoaderJUnitParent", stringBuffer.toString());
-    writeJarBytesToFile(parentJarFile, jarBytes);
-    JarClassLoader parentClassLoader =
-        new JarClassLoader(parentJarFile, "JarClassLoaderJUnitParent.jar", jarBytes);
-
-    stringBuffer = new StringBuffer();
-    stringBuffer.append("package jcljunit.uses;");
-    stringBuffer.append("public class JarClassLoaderJUnitUses {");
-    stringBuffer.append("public String getValueUses() {");
-    stringBuffer.append("return \"USES\";}}");
-
-    jarBytes = this.classBuilder.createJarFromClassContent("jcljunit/uses/JarClassLoaderJUnitUses",
-        stringBuffer.toString());
-    writeJarBytesToFile(usesJarFile, jarBytes);
-    JarClassLoader usesClassLoader =
-        new JarClassLoader(usesJarFile, "JarClassLoaderJUnitUses.jar", jarBytes);
-
-    stringBuffer = new StringBuffer();
-    stringBuffer.append("package jcljunit.function;");
-    stringBuffer.append("import jcljunit.parent.JarClassLoaderJUnitParent;");
-    stringBuffer.append("import jcljunit.uses.JarClassLoaderJUnitUses;");
-    stringBuffer.append("import org.apache.geode.cache.execute.Function;");
-    stringBuffer.append("import org.apache.geode.cache.execute.FunctionContext;");
-    stringBuffer.append(
-        "public class JarClassLoaderJUnitFunction  extends JarClassLoaderJUnitParent implements Function {");
-    stringBuffer.append("private JarClassLoaderJUnitUses uses = new JarClassLoaderJUnitUses();");
-    stringBuffer.append("public boolean hasResult() {return true;}");
-    stringBuffer.append(
-        "public void execute(FunctionContext context) {context.getResultSender().lastResult(getValueParent() + \":\" + uses.getValueUses());}");
-    stringBuffer.append("public String getId() {return \"JarClassLoaderJUnitFunction\";}");
-    stringBuffer.append("public boolean optimizeForWrite() {return false;}");
-    stringBuffer.append("public boolean isHA() {return false;}}");
-
-    ClassBuilder functionClassBuilder = new ClassBuilder();
-    functionClassBuilder.addToClassPath(parentJarFile.getAbsolutePath());
-    functionClassBuilder.addToClassPath(usesJarFile.getAbsolutePath());
-    jarBytes = functionClassBuilder.createJarFromClassContent(
-        "jcljunit/function/JarClassLoaderJUnitFunction", stringBuffer.toString());
-    writeJarBytesToFile(functionJarFile, jarBytes);
-    JarClassLoader functionClassLoader =
-        new JarClassLoader(functionJarFile, "JarClassLoaderJUnitFunction.jar", jarBytes);
-
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(functionClassLoader);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(parentClassLoader);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(usesClassLoader);
-
-    functionClassLoader.loadClassesAndRegisterFunctions();
-
-    Function function = FunctionService.getFunction("JarClassLoaderJUnitFunction");
-    assertNotNull(function);
-    TestResultSender resultSender = new TestResultSender();
-    FunctionContext functionContext = new FunctionContextImpl(function.getId(), null, resultSender);
-    function.execute(functionContext);
-    assertEquals("PARENT:USES", (String) resultSender.getResults());
-  }
-
-  @Test
-  public void testFindResource() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnitResource.jar#1");
-    ClassPathLoader classPathLoader = ClassPathLoader.createWithDefaults(false);
-    final String fileName = "file.txt";
-    final String fileContent = "FILE CONTENT";
-
-    byte[] jarBytes = this.classBuilder.createJarFromFileContent(fileName, fileContent);
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader =
-        new JarClassLoader(jarFile1, "JarClassLoaderJUnitResource.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    InputStream inputStream = classLoader.getResourceAsStream(fileName);
-    assertNotNull(inputStream);
-
-    final byte[] fileBytes = new byte[fileContent.length()];
-    inputStream.read(fileBytes);
-    inputStream.close();
-    assertTrue(fileContent.equals(new String(fileBytes)));
-  }
-
-  @Test
-  public void testUpdateClassInJar() throws IOException, ClassNotFoundException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#1");
-    final File jarFile2 = new File(JAR_PREFIX + "JarClassLoaderJUnit.jar#2");
-    ClassPathLoader classPathLoader = ClassPathLoader.createWithDefaults(false);
-
-    // First use of the JAR file
-    byte[] jarBytes = this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitTestClass",
-        "public class JarClassLoaderJUnitTestClass { public Integer getValue5() { return new Integer(5); } }");
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader = new JarClassLoader(jarFile1, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    try {
-      Class<?> clazz = classPathLoader.forName("JarClassLoaderJUnitTestClass");
-      Object object = clazz.newInstance();
-      Method getValue5Method = clazz.getMethod("getValue5", new Class[] {});
-      Integer value = (Integer) getValue5Method.invoke(object, new Object[] {});
-      assertEquals(value.intValue(), 5);
-
-    } catch (InvocationTargetException itex) {
-      fail("JAR file not correctly added to Classpath" + itex);
-    } catch (NoSuchMethodException nsmex) {
-      fail("JAR file not correctly added to Classpath" + nsmex);
-    } catch (InstantiationException iex) {
-      fail("JAR file not correctly added to Classpath" + iex);
-    } catch (IllegalAccessException iaex) {
-      fail("JAR file not correctly added to Classpath" + iaex);
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath" + cnfex);
-    }
-
-    // Now create an updated JAR file and make sure that the method from the new
-    // class is available.
-    jarBytes = this.classBuilder.createJarFromClassContent("JarClassLoaderJUnitTestClass",
-        "public class JarClassLoaderJUnitTestClass { public Integer getValue10() { return new Integer(10); } }");
-    writeJarBytesToFile(jarFile2, jarBytes);
-    classLoader = new JarClassLoader(jarFile2, "JarClassLoaderJUnit.jar", jarBytes);
-    classPathLoader = classPathLoader.addOrReplace(classLoader);
-    classLoader.loadClassesAndRegisterFunctions();
-
-    try {
-      Class<?> clazz = classPathLoader.forName("JarClassLoaderJUnitTestClass");
-      Object object = clazz.newInstance();
-      Method getValue10Method = clazz.getMethod("getValue10", new Class[] {});
-      Integer value = (Integer) getValue10Method.invoke(object, new Object[] {});
-      assertEquals(value.intValue(), 10);
-
-    } catch (InvocationTargetException itex) {
-      fail("JAR file not correctly added to Classpath" + itex);
-    } catch (NoSuchMethodException nsmex) {
-      fail("JAR file not correctly added to Classpath" + nsmex);
-    } catch (InstantiationException iex) {
-      fail("JAR file not correctly added to Classpath" + iex);
-    } catch (IllegalAccessException iaex) {
-      fail("JAR file not correctly added to Classpath" + iaex);
-    } catch (ClassNotFoundException cnfex) {
-      fail("JAR file not correctly added to Classpath" + cnfex);
-    }
-  }
-
-  @Test
-  public void testMultiThread() throws IOException {
-    final File jarFile1 = new File(JAR_PREFIX + "JarClassLoaderJUnitA.jar#1");
-    final File jarFile2 = new File(JAR_PREFIX + "JarClassLoaderJUnitB.jar#1");
-
-    // Add two JARs to the classpath
-    byte[] jarBytes = this.classBuilder.createJarFromName("JarClassLoaderJUnitA");
-    writeJarBytesToFile(jarFile1, jarBytes);
-    JarClassLoader classLoader = new JarClassLoader(jarFile1, "JarClassLoaderJUnitA.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-
-    jarBytes = this.classBuilder.createJarFromClassContent("com/jcljunit/JarClassLoaderJUnitB",
-        "package com.jcljunit; public class JarClassLoaderJUnitB {}");
-    writeJarBytesToFile(jarFile2, jarBytes);
-    classLoader = new JarClassLoader(jarFile2, "JarClassLoaderJUnitB.jar", jarBytes);
-    ClassPathLoader.getLatest().addOrReplaceAndSetLatest(classLoader);
-
-    String[] classNames = new String[] {"JarClassLoaderJUnitA", "com.jcljunit.JarClassLoaderJUnitB",
-        "NON-EXISTENT CLASS"};
-
-    // Spawn some threads which try to instantiate these classes
-    final int threadCount = 10;
-    final int numLoops = 1000;
-    final CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount + 1);
-    for (int i = 0; i < threadCount; i++) {
-      new ForNameExerciser(cyclicBarrier, numLoops, classNames).start();
-    }
-
-    // Wait for all of the threads to be ready
-    try {
-      cyclicBarrier.await();
-    } catch (InterruptedException iex) {
-      fail("Interrupted while waiting for barrier");
-    } catch (BrokenBarrierException bbex) {
-      fail("Broken barrier while waiting");
-    }
-
-    // Loop while each thread tries N times to instantiate a non-existent class
-    for (int i = 0; i < numLoops; i++) {
-      try {
-        cyclicBarrier.await(5, TimeUnit.SECONDS);
-      } catch (InterruptedException iex) {
-        fail("Interrupted while waiting for barrier");
-      } catch (TimeoutException tex) {
-        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-        long[] threadIds = threadMXBean.findDeadlockedThreads();
-
-        if (threadIds != null) {
-          StringBuffer deadLockTrace = new StringBuffer();
-          for (long threadId : threadIds) {
-            ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId, 100);
-            deadLockTrace.append(threadInfo.getThreadName()).append("\n");
-            for (StackTraceElement stackTraceElem : threadInfo.getStackTrace()) {
-              deadLockTrace.append("\t").append(stackTraceElem).append("\n");
-            }
-          }
-
-          fail("Deadlock with trace:\n" + deadLockTrace.toString());
-        }
-
-        fail("Timeout while waiting for barrier - no deadlock detected");
-      } catch (BrokenBarrierException bbex) {
-        fail("Broken barrier while waiting");
-      }
-    }
-  }
-
-  private void deleteSavedJarFiles() {
-    File dirFile = new File(".");
-
-    // Find all created JAR files
-    File[] oldJarFiles = dirFile.listFiles(new FilenameFilter() {
-      @Override
-      public boolean accept(final File file, final String name) {
-        return JarClassLoaderJUnitTest.this.pattern.matcher(name).matches();
-      }
-    });
-
-    // Now delete them
-    if (oldJarFiles != null) {
-      for (File oldJarFile : oldJarFiles) {
-        if (!oldJarFile.delete()) {
-          RandomAccessFile randomAccessFile = null;
-          try {
-            randomAccessFile = new RandomAccessFile(oldJarFile, "rw");
-            randomAccessFile.setLength(0);
-          } catch (IOException ioex) {
-            fail("IOException when trying to deal with a stubborn JAR file");
-          } finally {
-            try {
-              if (randomAccessFile != null) {
-                randomAccessFile.close();
-              }
-            } catch (IOException ioex) {
-              fail("IOException when trying to deal with a stubborn JAR file");
-            }
-          }
-          oldJarFile.deleteOnExit();
-        }
-      }
-    }
-  }
-
-  private void writeJarBytesToFile(File jarFile, byte[] jarBytes) throws IOException {
-    final OutputStream outStream = new FileOutputStream(jarFile);
-    outStream.write(jarBytes);
-    outStream.close();
-  }
-
-  private static class TestResultSender implements ResultSender<Object> {
-    private Object result;
-
-    public TestResultSender() {}
-
-    protected Object getResults() {
-      return this.result;
-    }
-
-    @Override
-    public void lastResult(final Object lastResult) {
-      this.result = lastResult;
-    }
-
-    @Override
-    public void sendResult(final Object oneResult) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void sendException(final Throwable t) {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  static final Random random = new Random();
-
-  private class ForNameExerciser extends Thread {
-    private final CyclicBarrier cyclicBarrier;
-    private final int numLoops;
-    private final String[] classNames;
-
-    ForNameExerciser(final CyclicBarrier cyclicBarrier, final int numLoops,
-        final String[] classNames) {
-      this.cyclicBarrier = cyclicBarrier;
-      this.numLoops = numLoops;
-      this.classNames = classNames;
-    }
-
-    @Override
-    public void run() {
-      try {
-        this.cyclicBarrier.await();
-      } catch (InterruptedException iex) {
-        fail("Interrupted while waiting for latch");
-      } catch (BrokenBarrierException bbex) {
-        fail("Broken barrier while waiting");
-      }
-      for (int i = 0; i < this.numLoops; i++) {
-        try {
-          // Random select a name from the list of class names and try to load it
-          String className = this.classNames[random.nextInt(this.classNames.length)];
-          ClassPathLoader.getLatest().forName(className);
-        } catch (ClassNotFoundException expected) { // expected
-        }
-        try {
-          this.cyclicBarrier.await();
-        } catch (InterruptedException iex) {
-          fail("Interrupted while waiting for barrrier");
-        } catch (BrokenBarrierException bbex) {
-          fail("Broken barrier while waiting");
-        }
-      }
-    }
-  }
-}