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");
- }
- }
- }
- }
-}