You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2022/02/16 09:15:12 UTC

[geode] branch support/1.14 updated: GEODE-9817: Enable customized source set paths for ClassAnalysisRule (#7367)

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

klund pushed a commit to branch support/1.14
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/support/1.14 by this push:
     new 8f3186c  GEODE-9817: Enable customized source set paths for ClassAnalysisRule (#7367)
8f3186c is described below

commit 8f3186cb74ccd2eb1ec8ba648c7a11b08d575962
Author: Kirk Lund <kl...@apache.org>
AuthorDate: Wed Feb 16 01:12:28 2022 -0800

    GEODE-9817: Enable customized source set paths for ClassAnalysisRule (#7367)
    
    Adds support for customizing source set paths of ClassAnalysisRule.
    
    PROBLEM
    
    Modules external to Geode must be structured the same as Geode
    source code in order to use ClassAnalysisRule and the
    Analyze*Serializables tests. This is necessary to better facilitate
    pluggability of modules that need to provide sanctioned serializable
    lists.
    
    SOLUTION
    
    Add source set path customization to ClassAnalysisRule, introduce
    a new layer of Analyze*Serializables test base classes that can be
    directly extended in order to customize source set paths in
    ClassAnalysisRule. Also includes improvements to some iterating
    of classes during analysis.
    
    [prereq for backport of GEODE-9980 and GEODE-9758]
    
    (cherry picked from commit 5d1e91932dff296632916a6ceccfb36039357acd)
---
 .../AnalyzeRedisSerializablesIntegrationTest.java  |  3 +-
 ...lyzeConnectorsSerializablesIntegrationTest.java |  2 +-
 .../AnalyzeCoreSerializablesIntegrationTest.java   |  3 +-
 .../AnalyzeCQSerializablesIntegrationTest.java     |  3 +-
 .../AnalyzeDUnitSerializablesIntegrationTest.java  |  4 +-
 .../AnalyzeGfshSerializablesIntegrationTest.java   |  3 +-
 .../AnalyzeJUnitSerializablesIntegrationTest.java  |  3 +-
 ....java => AnalyzeDataSerializablesTestBase.java} | 74 ++++++++++------------
 ...SerializablesWithClassAnalysisRuleTestBase.java | 26 ++++----
 ...Base.java => AnalyzeSerializablesTestBase.java} | 41 ++++++++----
 ...SerializablesWithClassAnalysisRuleTestBase.java | 23 ++++---
 ...nedSerializablesServiceIntegrationTestBase.java |  6 +-
 .../geode/test/junit/rules/ClassAnalysisRule.java  | 23 ++++---
 .../AnalyzeLuceneSerializablesIntegrationTest.java |  3 +-
 ...lyzeManagementSerializablesIntegrationTest.java |  2 +-
 ...lyzeMembershipSerializablesIntegrationTest.java |  2 +-
 ...alyzeMemcachedSerializablesIntegrationTest.java |  2 +-
 .../AnalyzePulseSerializablesIntegrationTest.java  |  3 +-
 ...eSerializationSerializablesIntegrationTest.java |  2 +-
 .../AnalyzeWANSerializablesIntegrationTest.java    |  3 +-
 .../AnalyzeWebApiSerializablesIntegrationTest.java |  3 +-
 21 files changed, 134 insertions(+), 100 deletions(-)

diff --git a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
index 7c89c5b..36efe19 100755
--- a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
+++ b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
@@ -22,7 +22,8 @@ import org.apache.geode.redis.internal.RedisSanctionedSerializablesService;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
-public class AnalyzeRedisSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeRedisSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java b/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java
index a5fa5a1..db50c2f 100644
--- a/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java
+++ b/geode-connectors/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeConnectorsSerializablesIntegrationTest.java
@@ -23,7 +23,7 @@ import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
 public class AnalyzeConnectorsSerializablesIntegrationTest
-    extends AnalyzeSerializablesJUnitTestBase {
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java
index 6832442..d93d8d1 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCoreSerializablesIntegrationTest.java
@@ -22,7 +22,8 @@ import org.apache.geode.internal.CoreSanctionedSerializablesService;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
-public class AnalyzeCoreSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeCoreSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java b/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java
index 96c036a..3235c7b 100755
--- a/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java
+++ b/geode-cq/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeCQSerializablesIntegrationTest.java
@@ -23,7 +23,8 @@ import org.apache.geode.test.junit.categories.ClientSubscriptionTest;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category({ClientSubscriptionTest.class, SerializationTest.class})
-public class AnalyzeCQSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeCQSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java b/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java
index f188c06..601b57c 100644
--- a/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java
+++ b/geode-dunit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeDUnitSerializablesIntegrationTest.java
@@ -27,7 +27,9 @@ import org.apache.geode.test.dunit.internal.Master;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
-public class AnalyzeDUnitSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeDUnitSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
+
   private static final Logger logger = LogService.getLogger();
 
   private static final Set<Class<?>> IGNORE_CLASSES = new HashSet<>();
diff --git a/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java b/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java
index fb4e398..1de44bf 100755
--- a/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java
+++ b/geode-gfsh/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeGfshSerializablesIntegrationTest.java
@@ -22,7 +22,8 @@ import org.apache.geode.management.internal.GfshSanctionedSerializablesService;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
-public class AnalyzeGfshSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeGfshSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java b/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java
index 6e4aeab..cc225ff 100644
--- a/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java
+++ b/geode-junit/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeJUnitSerializablesIntegrationTest.java
@@ -28,7 +28,8 @@ import org.apache.geode.test.junit.categories.SerializationTest;
 import org.apache.geode.test.junit.internal.JUnitSanctionedSerializablesService;
 
 @Category(SerializationTest.class)
-public class AnalyzeJUnitSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeJUnitSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   private static final Set<Class<?>> IGNORE_CLASSES = new HashSet<>(asList(
       PortfolioNoDS.class, PortfolioPdx.class));
diff --git a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesTestBase.java
similarity index 88%
rename from geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java
rename to geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesTestBase.java
index 173c58c..c8a9402 100644
--- a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesJUnitTestBase.java
+++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesTestBase.java
@@ -16,6 +16,7 @@ package org.apache.geode.codeAnalysis;
 
 import static java.util.Collections.emptyList;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchThrowable;
 import static org.assertj.core.api.Assertions.fail;
 import static org.junit.Assert.assertTrue;
 
@@ -36,7 +37,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
-import org.junit.AfterClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -47,18 +47,17 @@ import org.apache.geode.codeAnalysis.decode.CompiledMethod;
 import org.apache.geode.internal.serialization.BufferDataOutputStream;
 import org.apache.geode.internal.serialization.KnownVersion;
 import org.apache.geode.test.junit.categories.SerializationTest;
-import org.apache.geode.test.junit.rules.ClassAnalysisRule;
 
 /**
  * This abstract test class is the basis for all of our AnalyzeModuleNameSerializables tests.
  * Subclasses must provide serialization/deserialization methods.
  *
  * <p>
- * Most tests should subclass {@link AnalyzeSerializablesJUnitTestBase} instead of this
- * class because it ties into geode-core serialization and saves a lot of work.
+ * Most tests should subclass {@link AnalyzeSerializablesWithClassAnalysisRuleTestBase} instead of
+ * this class because it ties into geode-core serialization and saves a lot of work.
  */
 @Category({SerializationTest.class})
-public abstract class AnalyzeDataSerializablesJUnitTestBase {
+public abstract class AnalyzeDataSerializablesTestBase {
 
   private static final Path MODULE_ROOT = Paths.get("..", "..", "..").toAbsolutePath().normalize();
   private static final Path SOURCE_ROOT = MODULE_ROOT.resolve(Paths.get("src"));
@@ -100,14 +99,6 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase {
   @Rule
   public TestName testName = new TestName();
 
-  @Rule
-  public ClassAnalysisRule classProvider = new ClassAnalysisRule(getModuleName());
-
-  @AfterClass
-  public static void afterClass() {
-    ClassAnalysisRule.clearCache();
-  }
-
   /**
    * implement this to return your module's name, such as "geode-core"
    */
@@ -147,8 +138,10 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase {
     }
   }
 
+  protected abstract Map<String, CompiledClass> loadClasses();
+
   public void findClasses() throws Exception {
-    classes = classProvider.getClasses();
+    classes = loadClasses();
 
     List<String> excludedClasses = loadExcludedClasses(getResourceAsFile(EXCLUDED_CLASSES_TXT));
     List<String> openBugs = loadOpenBugs(getResourceAsFile(OPEN_BUGS_TXT));
@@ -209,9 +202,11 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase {
         final Object excludedInstance;
         try {
           excludedInstance = excludedClass.newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
+        } catch (IllegalAccessException | InstantiationException | NullPointerException e) {
           // okay - it's in the excludedClasses.txt file after all
-          // IllegalAccessException means that the constructor is private.
+          // IllegalAccessException: thrown when non-private constructor does not exist
+          // InstantiationException: thrown when no-arg constructor does not exist
+          // NullPointerException: thrown by constructors that fetch RMI dependencies
           continue;
         }
         serializeAndDeserializeObject(excludedInstance);
@@ -230,17 +225,33 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase {
     BufferDataOutputStream outputStream = new BufferDataOutputStream(KnownVersion.CURRENT);
     try {
       serializeObject(object, outputStream);
-    } catch (IOException e) {
+    } catch (IOException | NullPointerException e) {
       // some classes, such as BackupLock, are Serializable because the extend something
       // like ReentrantLock but we never serialize them & it doesn't work to try to do so
       System.out.println("Not Serializable: " + object.getClass().getName());
+      return;
+    } catch (Exception e) {
+      /*
+       * NOTE:
+       * this block catches Exception instead of CacheClosedException so that modules without
+       * dependency on geode-core can be tested with Analyze Serializables.
+       *
+       * ex: geode-membership does not depend on geode-core, so it cannot load CacheClosedException
+       */
+      if ("org.apache.geode.cache.CacheClosedException".equals(e.getClass().getName())) {
+        System.out
+            .println("I was unable to serialize " + object.getClass().getName() + " due to " + e);
+        e.printStackTrace();
+        return;
+      }
+      throw e;
     }
-    try {
-      deserializeObject(outputStream);
-      fail("I was able to deserialize " + object.getClass().getName());
-    } catch (InvalidClassException e) {
-      // expected
-    }
+
+    Throwable thrown = catchThrowable(() -> deserializeObject(outputStream));
+
+    assertThat(thrown)
+        .withFailMessage("I was able to deserialize " + object.getClass().getName())
+        .isInstanceOf(InvalidClassException.class);
   }
 
   private String toBuildPathString(File file) {
@@ -338,18 +349,7 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase {
   }
 
   File createEmptyFile(String fileName) throws IOException {
-    final String workingDir = System.getProperty("user.dir");
-    final String filePath;
-    if (isIntelliJDir(workingDir)) {
-      String buildDir = workingDir.replace(getModuleName(), "");
-      buildDir =
-          Paths.get(buildDir, "out", "production", "geode." + getModuleName() + ".integrationTest")
-              .toString();
-      filePath = buildDir + File.separator + fileName;
-    } else {
-      filePath = fileName;
-    }
-    File file = new File(filePath);
+    File file = new File(fileName);
     if (file.exists()) {
       assertThat(file.delete()).isTrue();
     }
@@ -358,10 +358,6 @@ public abstract class AnalyzeDataSerializablesJUnitTestBase {
     return file;
   }
 
-  private boolean isIntelliJDir(final String workingDir) {
-    return !workingDir.contains("build");
-  }
-
   /**
    * Use this method to get a resource stored in the test's resource directory
    */
diff --git a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesWithClassAnalysisRuleTestBase.java
old mode 100755
new mode 100644
similarity index 59%
copy from geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
copy to geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesWithClassAnalysisRuleTestBase.java
index 7c89c5b..3853d4c
--- a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
+++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeDataSerializablesWithClassAnalysisRuleTestBase.java
@@ -14,23 +14,27 @@
  */
 package org.apache.geode.codeAnalysis;
 
-import java.util.Optional;
+import java.util.Map;
 
-import org.junit.experimental.categories.Category;
+import org.junit.AfterClass;
+import org.junit.Rule;
 
-import org.apache.geode.redis.internal.RedisSanctionedSerializablesService;
-import org.apache.geode.test.junit.categories.SerializationTest;
+import org.apache.geode.codeAnalysis.decode.CompiledClass;
+import org.apache.geode.test.junit.rules.ClassAnalysisRule;
 
-@Category(SerializationTest.class)
-public class AnalyzeRedisSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public abstract class AnalyzeDataSerializablesWithClassAnalysisRuleTestBase
+    extends AnalyzeDataSerializablesTestBase {
 
-  @Override
-  protected String getModuleName() {
-    return "geode-apis-compatible-with-redis";
+  @Rule
+  public ClassAnalysisRule classProvider = new ClassAnalysisRule(getModuleName());
+
+  @AfterClass
+  public static void afterClass() {
+    ClassAnalysisRule.clearCache();
   }
 
   @Override
-  protected Optional<Class<?>> getModuleClass() {
-    return Optional.of(RedisSanctionedSerializablesService.class);
+  protected Map<String, CompiledClass> loadClasses() {
+    return classProvider.getClasses();
   }
 }
diff --git a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesTestBase.java
similarity index 93%
rename from geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java
rename to geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesTestBase.java
index d26a4cb..2d5dd3a 100644
--- a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesJUnitTestBase.java
+++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesTestBase.java
@@ -26,10 +26,10 @@ import java.io.Externalizable;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InvalidClassException;
 import java.io.Serializable;
 import java.io.UncheckedIOException;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Modifier;
 import java.nio.file.Path;
 import java.rmi.RemoteException;
@@ -42,8 +42,10 @@ import java.util.Properties;
 import java.util.Set;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.junit.rules.ErrorCollector;
 
 import org.apache.geode.CancelException;
 import org.apache.geode.DataSerializable;
@@ -64,8 +66,8 @@ import org.apache.geode.unsafe.internal.sun.reflect.ReflectionFactory;
  * InternalDataSerializer. It also performs initialization of the Geode TypeRegistry
  */
 @Category(SerializationTest.class)
-public abstract class AnalyzeSerializablesJUnitTestBase
-    extends AnalyzeDataSerializablesJUnitTestBase {
+public abstract class AnalyzeSerializablesTestBase
+    extends AnalyzeDataSerializablesTestBase {
 
   private static final String ACTUAL_SERIALIZABLES_DAT = "actualSerializables.dat";
 
@@ -74,6 +76,9 @@ public abstract class AnalyzeSerializablesJUnitTestBase
 
   protected final List<ClassAndVariableDetails> expectedSerializables = new ArrayList<>();
 
+  @Rule
+  public ErrorCollector errorCollector = new ErrorCollector();
+
   @Before
   public void setUp() throws Exception {
     TypeRegistry.init();
@@ -202,12 +207,19 @@ public abstract class AnalyzeSerializablesJUnitTestBase
             isThrowable ? sanctionedClass.getDeclaredConstructor(String.class)
                 : sanctionedClass.getDeclaredConstructor((Class<?>[]) null);
         constructor.setAccessible(true);
-        sanctionedInstance =
-            isThrowable ? constructor.newInstance("test throwable") : constructor.newInstance();
+        if (isThrowable) {
+          sanctionedInstance = constructor.newInstance("test throwable");
+        } else {
+          sanctionedInstance = constructor.newInstance();
+        }
         serializeAndDeserializeSanctionedObject(sanctionedInstance);
         continue;
-      } catch (NoSuchMethodException | InstantiationException | IllegalAccessException e) {
+      } catch (NoSuchMethodException | InstantiationException | IllegalAccessException
+          | NullPointerException | InvocationTargetException e) {
         // fall through
+      } catch (Exception e) {
+        errorCollector.addError(e);
+        continue;
       }
       try {
         Class<?> superClass = sanctionedClass;
@@ -339,22 +351,23 @@ public abstract class AnalyzeSerializablesJUnitTestBase
 
   private void serializeAndDeserializeSanctionedObject(Object object) throws Exception {
     BufferDataOutputStream outputStream = new BufferDataOutputStream(KnownVersion.CURRENT);
+
     try {
       serializeObject(object, outputStream);
     } catch (RemoteException e) {
-      fail(object.getClass().getName() +
-          " is a java.rmi.server.RemoteObject which is not supported by AnalyzeSerializables", e);
-    } catch (IOException e) {
-      // some classes, such as BackupLock, are Serializable because the extend something
-      // like ReentrantLock but we never serialize them & it doesn't work to try to do so
-      throw new AssertionError("Not Serializable: " + object.getClass().getName(), e);
+      // java.rmi.server.RemoteObject which is not supported by AnalyzeSerializables
+    } catch (Exception e) {
+      errorCollector.addError(
+          new AssertionError("I was unable to serialize " + object.getClass().getName(), e));
     }
+
     try {
       deserializeObject(outputStream);
     } catch (CancelException e) {
       // PDX classes fish for a PDXRegistry and find that there is no cache
-    } catch (InvalidClassException e) {
-      fail("I was unable to deserialize " + object.getClass().getName(), e);
+    } catch (Exception e) {
+      errorCollector.addError(
+          new AssertionError("I was unable to deserialize " + object.getClass().getName(), e));
     }
   }
 
diff --git a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesWithClassAnalysisRuleTestBase.java
old mode 100755
new mode 100644
similarity index 63%
copy from geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
copy to geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesWithClassAnalysisRuleTestBase.java
index 7c89c5b..158bd6b
--- a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeRedisSerializablesIntegrationTest.java
+++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/AnalyzeSerializablesWithClassAnalysisRuleTestBase.java
@@ -14,23 +14,30 @@
  */
 package org.apache.geode.codeAnalysis;
 
-import java.util.Optional;
+import java.util.Map;
 
+import org.junit.AfterClass;
+import org.junit.Rule;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.redis.internal.RedisSanctionedSerializablesService;
+import org.apache.geode.codeAnalysis.decode.CompiledClass;
 import org.apache.geode.test.junit.categories.SerializationTest;
+import org.apache.geode.test.junit.rules.ClassAnalysisRule;
 
 @Category(SerializationTest.class)
-public class AnalyzeRedisSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public abstract class AnalyzeSerializablesWithClassAnalysisRuleTestBase
+    extends AnalyzeSerializablesTestBase {
 
-  @Override
-  protected String getModuleName() {
-    return "geode-apis-compatible-with-redis";
+  @Rule
+  public ClassAnalysisRule classProvider = new ClassAnalysisRule(getModuleName());
+
+  @AfterClass
+  public static void afterClass() {
+    ClassAnalysisRule.clearCache();
   }
 
   @Override
-  protected Optional<Class<?>> getModuleClass() {
-    return Optional.of(RedisSanctionedSerializablesService.class);
+  protected Map<String, CompiledClass> loadClasses() {
+    return classProvider.getClasses();
   }
 }
diff --git a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/SanctionedSerializablesServiceIntegrationTestBase.java b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/SanctionedSerializablesServiceIntegrationTestBase.java
index 4a02107..2fd6672 100644
--- a/geode-junit/src/main/java/org/apache/geode/codeAnalysis/SanctionedSerializablesServiceIntegrationTestBase.java
+++ b/geode-junit/src/main/java/org/apache/geode/codeAnalysis/SanctionedSerializablesServiceIntegrationTestBase.java
@@ -38,7 +38,7 @@ public abstract class SanctionedSerializablesServiceIntegrationTestBase {
   }
 
   @Test
-  public final void serviceIsLoaded() {
+  public void serviceIsLoaded() {
     Collection<SanctionedSerializablesService> services = loadSanctionedSerializablesServices();
     SanctionedSerializablesService service = getService();
 
@@ -56,7 +56,7 @@ public abstract class SanctionedSerializablesServiceIntegrationTestBase {
   }
 
   @Test
-  public final void serviceResourceExists() {
+  public void serviceResourceExists() {
     SanctionedSerializablesService service = getService();
 
     URL url = service.getSanctionedSerializablesURL();
@@ -72,7 +72,7 @@ public abstract class SanctionedSerializablesServiceIntegrationTestBase {
   }
 
   @Test
-  public final void serviceResourceIsLoaded() throws IOException {
+  public void serviceResourceIsLoaded() throws IOException {
     SanctionedSerializablesService service = getService();
 
     Collection<String> serializables = service.getSerializationAcceptlist();
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/ClassAnalysisRule.java b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/ClassAnalysisRule.java
index 599edf1..3ee70e7 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/ClassAnalysisRule.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/ClassAnalysisRule.java
@@ -49,13 +49,19 @@ public class ClassAnalysisRule implements TestRule {
       new AtomicReference<>(new HashMap<>());
 
   private final String moduleName;
+  private final String sourceSet;
   private final Map<String, CompiledClass> classes = new HashMap<>();
 
   /**
    * @param moduleName The name of the gradle module in which your test resides
    */
   public ClassAnalysisRule(String moduleName) {
+    this(moduleName, "main");
+  }
+
+  public ClassAnalysisRule(String moduleName, String sourceSet) {
     this.moduleName = moduleName;
+    this.sourceSet = sourceSet;
   }
 
   public Map<String, CompiledClass> getClasses() {
@@ -95,21 +101,18 @@ public class ClassAnalysisRule implements TestRule {
             .map(x -> new File(x))
             .collect(Collectors.toList());
 
+    // check for <module>/build/classes/java/**
     String gradleBuildDirName =
-        Paths.get(getModuleName(), "build", "classes", "java", "main").toString();
-    // System.out.println("gradleBuildDirName is " + gradleBuildDirName);
-    String ideaBuildDirName =
-        Paths.get(getModuleName(), "out", "production", "classes").toString();
-    // System.out.println("ideaBuildDirName is " + ideaBuildDirName);
-    String ideaFQCNBuildDirName =
-        Paths.get("out", "production", "geode." + getModuleName() + ".main").toString();
-    // System.out.println("idea build path with full package names is " + ideaFQCNBuildDirName);
+        Paths.get(getModuleName(), "build", "classes", "java", sourceSet).toString();
+
+    // check for <module>/build/classes/test/**
+    String alternateBuildDirName =
+        Paths.get(getModuleName(), "build", "classes", sourceSet).toString();
 
     String buildDir = null;
     for (File entry : entries) {
       if (entry.toString().endsWith(gradleBuildDirName)
-          || entry.toString().endsWith(ideaBuildDirName)
-          || entry.toString().endsWith(ideaFQCNBuildDirName)) {
+          || entry.toString().endsWith(alternateBuildDirName)) {
         buildDir = entry.toString();
         break;
       }
diff --git a/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java b/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java
index d170cd0..3c77f28 100644
--- a/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java
+++ b/geode-lucene/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeLuceneSerializablesIntegrationTest.java
@@ -23,7 +23,8 @@ import org.apache.geode.test.junit.categories.LuceneTest;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category({LuceneTest.class, SerializationTest.class})
-public class AnalyzeLuceneSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeLuceneSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java b/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java
index aab75d2..75f231f 100644
--- a/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java
+++ b/geode-management/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeManagementSerializablesIntegrationTest.java
@@ -23,7 +23,7 @@ import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
 public class AnalyzeManagementSerializablesIntegrationTest
-    extends AnalyzeSerializablesJUnitTestBase {
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java b/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java
index e473148..407ad6c 100644
--- a/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java
+++ b/geode-membership/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMembershipSerializablesIntegrationTest.java
@@ -36,7 +36,7 @@ import org.apache.geode.test.junit.categories.SerializationTest;
  */
 @Category({MembershipTest.class, SerializationTest.class})
 public class AnalyzeMembershipSerializablesIntegrationTest
-    extends AnalyzeDataSerializablesJUnitTestBase {
+    extends AnalyzeDataSerializablesWithClassAnalysisRuleTestBase {
 
   private final DSFIDSerializer dsfidSerializer = new DSFIDSerializerFactory().create();
 
diff --git a/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java b/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java
index 8959d85..c0850e0 100644
--- a/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java
+++ b/geode-memcached/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeMemcachedSerializablesIntegrationTest.java
@@ -23,7 +23,7 @@ import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
 public class AnalyzeMemcachedSerializablesIntegrationTest
-    extends AnalyzeSerializablesJUnitTestBase {
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java b/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java
index fbf8d52..5efd089 100644
--- a/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java
+++ b/geode-pulse/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzePulseSerializablesIntegrationTest.java
@@ -21,7 +21,8 @@ import org.junit.experimental.categories.Category;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
-public class AnalyzePulseSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzePulseSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java b/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java
index 4aa74ff..175278c 100644
--- a/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java
+++ b/geode-serialization/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeSerializationSerializablesIntegrationTest.java
@@ -23,7 +23,7 @@ import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category(SerializationTest.class)
 public class AnalyzeSerializationSerializablesIntegrationTest
-    extends AnalyzeSerializablesJUnitTestBase {
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java b/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java
index 1438f2f..0f42cb5 100644
--- a/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java
+++ b/geode-wan/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWANSerializablesIntegrationTest.java
@@ -23,7 +23,8 @@ import org.apache.geode.test.junit.categories.SerializationTest;
 import org.apache.geode.test.junit.categories.WanTest;
 
 @Category({WanTest.class, SerializationTest.class})
-public class AnalyzeWANSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeWANSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {
diff --git a/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java b/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java
index 9ed629a..70f31fe 100644
--- a/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java
+++ b/geode-web-api/src/integrationTest/java/org/apache/geode/codeAnalysis/AnalyzeWebApiSerializablesIntegrationTest.java
@@ -23,7 +23,8 @@ import org.apache.geode.test.junit.categories.RestAPITest;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category({RestAPITest.class, SerializationTest.class})
-public class AnalyzeWebApiSerializablesIntegrationTest extends AnalyzeSerializablesJUnitTestBase {
+public class AnalyzeWebApiSerializablesIntegrationTest
+    extends AnalyzeSerializablesWithClassAnalysisRuleTestBase {
 
   @Override
   protected String getModuleName() {