You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by up...@apache.org on 2017/09/25 23:12:30 UTC

[geode] branch develop updated: GEODE-3702 Adding a new framework for concurrency testing in geode

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

upthewaterspout pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 13f3c39  GEODE-3702 Adding a new framework for concurrency testing in geode
13f3c39 is described below

commit 13f3c396038fe5e2a8f7fe84d937969976f6dcac
Author: Dan Smith <up...@apache.org>
AuthorDate: Fri Sep 1 15:35:51 2017 -0700

    GEODE-3702 Adding a new framework for concurrency testing in geode
    
    Added a new junit runner, ConcurrentTestRunner, for running a test that
    has parallel threads.
    
    The runner currently runs the test using Java PathFinder, which will
    run the test with all interleavings of the threads.
    
    Added an example test to geode-core for the FilterProfile serialization
    logic.
    
    There are options to configure which concurrent test runner to use, and
    configuration for the JPF runner to pass jpf properties.
---
 build.gradle                                       |    1 +
 geode-concurrency-test/build.gradle                |   28 +
 .../src/main/java/java/net/InetAddress.java        |  156 ++
 .../test/concurrency/ConcurrentTestRunner.java     |  135 ++
 .../geode/test/concurrency/ParallelExecutor.java   |   48 +
 .../test/concurrency/RunnableWithException.java    |   25 +
 .../org/apache/geode/test/concurrency/Runner.java  |   28 +
 .../annotation/ConcurrentTestConfig.java           |   32 +
 .../geode/test/concurrency/jpf/JpfRunner.java      |   98 +
 .../test/concurrency/jpf/JpfRunnerConfig.java      |   34 +
 .../test/concurrency/jpf/ParallelExecutorImpl.java |   87 +
 .../test/concurrency/jpf/logging/EmptyLogger.java  | 1975 ++++++++++++++++++++
 ...il_concurrent_locks_ReentrantReadWriteLock.java |   42 +
 ...ributed_internal_InternalDistributedSystem.java |   28 +
 ...g_apache_geode_internal_logging_LogService.java |   42 +
 ...che_geode_internal_logging_log4j_LogMarker.java |   27 +
 .../JPF_org_apache_logging_log4j_LogManager.java   |   29 +
 .../geode/test/concurrency/loop/LoopRunner.java    |   90 +
 .../test/concurrency/loop/LoopRunnerConfig.java    |   22 +
 geode-core/build.gradle                            |   14 +
 .../cache/FilterProfileConcurrencyTest.java        |   86 +
 .../apache/geode/internal/cache/FilterProfile.java |   17 +-
 .../codeAnalysis/sanctionedDataSerializables.txt   |    4 +-
 gradle/rat.gradle                                  |    1 +
 settings.gradle                                    |    1 +
 25 files changed, 3043 insertions(+), 7 deletions(-)

diff --git a/build.gradle b/build.gradle
index e413366..e12c878 100755
--- a/build.gradle
+++ b/build.gradle
@@ -27,6 +27,7 @@ buildscript {
     classpath "com.diffplug.gradle.spotless:spotless:2.2.0"
     classpath "me.champeau.gradle:jmh-gradle-plugin:0.3.1"
     classpath "com.pedjak.gradle.plugins:dockerized-test:0.5.4"
+    classpath "gradle.plugin.com.github.upthewaterspout.jpfgradle:jpfgradle:0.3"
   }
 }
 
diff --git a/geode-concurrency-test/build.gradle b/geode-concurrency-test/build.gradle
new file mode 100644
index 0000000..8c475e4
--- /dev/null
+++ b/geode-concurrency-test/build.gradle
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+apply plugin: "com.github.upthewaterspout.jpf"
+
+jpf {
+  sourceSet='main'
+  downloadUrl='https://bitbucket.org/upthewaterspout/jpf-core/downloads/jpf-core-r34.zip'
+  installDir=System.getProperty('user.home') + '/.jpf'
+}
+
+dependencies {
+  compile 'junit:junit:' + project.'junit.version'
+  compile 'org.apache.logging.log4j:log4j-api:' + project.'log4j.version'
+}
diff --git a/geode-concurrency-test/src/main/java/java/net/InetAddress.java b/geode-concurrency-test/src/main/java/java/net/InetAddress.java
new file mode 100644
index 0000000..0416664
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/java/net/InetAddress.java
@@ -0,0 +1,156 @@
+/*
+ * 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 java.net;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+/**
+ * Replace the JDK's InetAddress with a mock implementation that uses no native calls or IO.
+ *
+ * This implementation is simply a holder for a hostname, no DNS lookups are done. The address
+ * returned from getAddress is simply the hostname converted to bytes in UTF-8
+ */
+public class InetAddress implements java.io.Serializable {
+
+  public String hostname;
+
+  public InetAddress(String host) {
+    this.hostname = host;
+  }
+
+  public boolean isMulticastAddress() {
+    return false;
+  }
+
+  public boolean isAnyLocalAddress() {
+    return false;
+  }
+
+  public boolean isLoopbackAddress() {
+    return false;
+  }
+
+  public boolean isLinkLocalAddress() {
+    return false;
+  }
+
+  public boolean isSiteLocalAddress() {
+    return false;
+  }
+
+  public boolean isMCGlobal() {
+    return false;
+  }
+
+  public boolean isMCNodeLocal() {
+    return false;
+  }
+
+  public boolean isMCLinkLocal() {
+    return false;
+  }
+
+  public boolean isMCSiteLocal() {
+    return false;
+  }
+
+  public boolean isMCOrgLocal() {
+    return false;
+  }
+
+
+  public boolean isReachable(int timeout) throws IOException {
+    return false;
+  }
+
+  public boolean isReachable(NetworkInterface netif, int ttl, int timeout) throws IOException {
+    return false;
+  }
+
+  public String getHostName() {
+    return hostname;
+  }
+
+  public String getCanonicalHostName() {
+    return hostname;
+  }
+
+
+  public byte[] getAddress() {
+    return hostname.getBytes(Charset.forName("UTF-8"));
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    InetAddress that = (InetAddress) o;
+
+    return hostname != null ? hostname.equals(that.hostname) : that.hostname == null;
+  }
+
+  @Override
+  public int hashCode() {
+    return hostname != null ? hostname.hashCode() : 0;
+  }
+
+  /**
+   * Converts this IP address to a {@code String}. The string returned is of the form: hostname /
+   * literal IP address.
+   *
+   * If the host name is unresolved, no reverse name service lookup is performed. The hostname part
+   * will be represented by an empty string.
+   *
+   * @return a string representation of this IP address.
+   */
+  public String toString() {
+    return hostname;
+  }
+
+
+  public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException {
+    return new InetAddress(host);
+  }
+
+
+  public static InetAddress getByName(String host) throws UnknownHostException {
+    return new InetAddress(host);
+  }
+
+  public static InetAddress[] getAllByName(String host) throws UnknownHostException {
+    return new InetAddress[] {new InetAddress("localhost")};
+  }
+
+  public static InetAddress getLoopbackAddress() {
+    return new InetAddress("localhost");
+  }
+
+
+  public static InetAddress getByAddress(byte[] addr) throws UnknownHostException {
+    String host = new String(addr, Charset.forName("UTF-8"));
+    return getByName(host);
+  }
+
+  public static InetAddress getLocalHost() throws UnknownHostException {
+    return getLoopbackAddress();
+  }
+}
+
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/ConcurrentTestRunner.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/ConcurrentTestRunner.java
new file mode 100644
index 0000000..0839bfa
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/ConcurrentTestRunner.java
@@ -0,0 +1,135 @@
+/*
+ * 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.test.concurrency;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import gov.nasa.jpf.Config;
+import gov.nasa.jpf.JPF;
+import gov.nasa.jpf.JPFListener;
+import junit.framework.AssertionFailedError;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.simple.SimpleLoggerContextFactory;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+
+import org.apache.geode.test.concurrency.annotation.ConcurrentTestConfig;
+import org.apache.geode.test.concurrency.jpf.JpfRunner;
+
+
+/**
+ * Test runner for tests that involve multiple threads.
+ *
+ * All methods annotated with @Test must take a {@link ParallelExecutor} as a parameter, which the
+ * test can use to invoke code in parallel.
+ *
+ * This test run will try to exercise the test method to flush out any concurrent bugs in the
+ * parallel execution. Currently this runner is using Java PathFinder to run the test with *all*
+ * possible thread interleavings, but other methods such as invoking the method multiple times in a
+ * normal JVM may be supported in the feature.
+ *
+ * All test logic and state *must* be encapsulated in the individual test methods. This is because
+ * the concurrency testing logic may need to invoke the test body multiple times, possibly in
+ * parallel.
+ *
+ * No guarantees are currently made about logic in methods annotated with @Before, @BeforeClass or
+ * about the behavior of {@link Rule} for concurrent tests.
+ *
+ * Example
+ *
+ * <code>
+ * &#64;RunWith(ConcurrentTestRunner.class)
+ * public void MyTest {
+ *   &#64;Test
+ *   public void someTestMethod(ParallelExecutor executor) {
+ *     AtomicInteger atomicInteger = new AtomicInteger();
+ *     executor.inParallel(() -> atomicInteger.incrementAndGet());
+ *     executor.inParallel(() -> atomicInteger.incrementAndGet());
+ *     executor.execute();
+ *     assertEquals(2, atomicInteger.get());
+ *   }
+ * }
+ * </code>
+ *
+ * ConcurrentTestRunner currently executes tests using Java Pathfinder, which will run the test with
+ * all thread interleavings.
+ */
+public class ConcurrentTestRunner extends ParentRunner<FrameworkMethod> {
+  /**
+   * Delegate to actually run the test.
+   */
+  private final Runner runner;
+
+  public ConcurrentTestRunner(Class testClass) throws InitializationError {
+    super(testClass);
+    ConcurrentTestConfig configuration = getTestClass().getAnnotation(ConcurrentTestConfig.class);
+    if (configuration == null) {
+      runner = new JpfRunner();
+      return;
+    }
+
+    try {
+      runner = configuration.runner().newInstance();
+    } catch (InstantiationException | IllegalAccessException e) {
+      throw new InitializationError(e);
+    }
+  }
+
+  @Override
+  protected List<FrameworkMethod> getChildren() {
+    return getTestClass().getAnnotatedMethods(Test.class);
+  }
+
+  @Override
+  protected void collectInitializationErrors(List<Throwable> errors) {
+    super.collectInitializationErrors(errors);
+    validateTestMethods(getChildren(), errors);
+  }
+
+  private void validateTestMethods(List<FrameworkMethod> methods, List<Throwable> errors) {
+    for (FrameworkMethod method : methods) {
+      if (!Arrays.equals(method.getMethod().getParameterTypes(),
+          new Class[] {ParallelExecutor.class})) {
+        errors.add(new AssertionFailedError("Incorrect signature on method: " + method
+            + ". For a concurrent test, all test methods should take a ParallelExector parameter."));
+      }
+    }
+  }
+
+  @Override
+  protected Description describeChild(FrameworkMethod child) {
+    return Description.createTestDescription(child.getDeclaringClass(), child.getName());
+  }
+
+  @Override
+  protected void runChild(FrameworkMethod child, RunNotifier notifier) {
+    notifier.fireTestStarted(describeChild(child));
+    try {
+      List<Throwable> failures = runner.runTestMethod(child.getMethod());
+      failures.stream()
+          .forEach(failure -> notifier.fireTestFailure(new Failure(describeChild(child), failure)));
+    } finally {
+      notifier.fireTestFinished(describeChild(child));
+    }
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/ParallelExecutor.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/ParallelExecutor.java
new file mode 100644
index 0000000..ee46ed8
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/ParallelExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * 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.test.concurrency;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * Executor that executes multiple tasks in parallel as part of the main body of concurrent test.
+ *
+ * See {@link ConcurrentTestRunner}
+ */
+public interface ParallelExecutor {
+
+  /**
+   * Add a task to run in parallel
+   */
+  <T> Future<T> inParallel(Callable<T> callable);
+
+  /**
+   * Add a task to run in parallel
+   */
+  default <T> Future<T> inParallel(RunnableWithException runnable) {
+    return inParallel(() -> {
+      runnable.run();
+      return null;
+    });
+  }
+
+  /**
+   * Execute all tasks in parallel, wait for them to complete and throw an exception if any of the
+   * tasks throw an exception.
+   */
+  void execute() throws ExecutionException, InterruptedException;
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/RunnableWithException.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/RunnableWithException.java
new file mode 100644
index 0000000..a55a9b3
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/RunnableWithException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.test.concurrency;
+
+import java.io.Serializable;
+
+/**
+ * Like Runnable, but allows the run method to throw an exception
+ */
+public interface RunnableWithException extends Serializable {
+
+  void run() throws Exception;
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/Runner.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/Runner.java
new file mode 100644
index 0000000..a2e073d
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/Runner.java
@@ -0,0 +1,28 @@
+/*
+ * 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.test.concurrency;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * Code that actually runs a single concurrent test method.
+ */
+public interface Runner {
+  /**
+   * Run a test method in a concurrency testing framework and return a list of errors encountered.
+   */
+  List<Throwable> runTestMethod(Method child);
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/annotation/ConcurrentTestConfig.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/annotation/ConcurrentTestConfig.java
new file mode 100644
index 0000000..324b071
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/annotation/ConcurrentTestConfig.java
@@ -0,0 +1,32 @@
+/*
+ * 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.test.concurrency.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.geode.test.concurrency.Runner;
+import org.apache.geode.test.concurrency.jpf.JpfRunner;
+
+/**
+ * Configuration options for the ConcurrentTestRunner
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ConcurrentTestConfig {
+  Class<? extends Runner> runner() default JpfRunner.class;
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/JpfRunner.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/JpfRunner.java
new file mode 100644
index 0000000..b2fab1f
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/JpfRunner.java
@@ -0,0 +1,98 @@
+/*
+ * 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.test.concurrency.jpf;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import gov.nasa.jpf.Config;
+import gov.nasa.jpf.JPF;
+import gov.nasa.jpf.JPFListener;
+import gov.nasa.jpf.annotation.JPFConfig;
+import gov.nasa.jpf.search.Search;
+import gov.nasa.jpf.search.SearchListenerAdapter;
+import gov.nasa.jpf.vm.Verify;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.simple.SimpleLoggerContextFactory;
+
+import org.apache.geode.test.concurrency.ParallelExecutor;
+
+/**
+ * Run a concurrent test using Java PathFinder
+ */
+public class JpfRunner implements org.apache.geode.test.concurrency.Runner {
+
+  @Override
+  public List<Throwable> runTestMethod(Method child) {
+    List<Throwable> failures = new ArrayList<>();
+    String[] userConfig = getUserConfiguration(child);
+    Config config = JPF.createConfig(userConfig);
+    config.setTarget(TestMain.class.getName());
+    config.setTargetArgs(new String[] {child.getDeclaringClass().getName(), child.getName()});
+    config.setProperty("report.probe_interval", "5");
+    config.setProperty("peer_packages+", "org.apache.geode.test.concurrency.jpf.peers");
+    config.setProperty("classpath", getClasspath());
+    config.setProperty("vm.shared.skip_static_finals", "true");
+    config.setProperty("vm.shared.skip_constructed_finals", "true");
+    JPF jpf = new JPF(config);
+    try {
+      jpf.run();
+    } catch (Throwable e) {
+      failures.add(new AssertionError("JPF had an internal error", e));
+    }
+
+    jpf.getSearchErrors().stream().forEach(error -> failures
+        .add(new AssertionError("JPF found test failures: " + error.getDescription())));
+
+    return failures;
+  }
+
+  private String[] getUserConfiguration(Method child) {
+    JpfRunnerConfig annotation = child.getDeclaringClass().getAnnotation(JpfRunnerConfig.class);
+    if (annotation != null) {
+      return annotation.value();
+    }
+
+    return new String[] {};
+  }
+
+  private String getClasspath() {
+    Collection<String> classpath = pathElements(System.getProperty("java.class.path"));
+    Collection<String> bootClasspath = pathElements(System.getProperty("sun.boot.class.path"));
+    classpath.removeAll(bootClasspath);
+    return String.join(File.pathSeparator, classpath);
+  }
+
+  private Collection<String> pathElements(String path) {
+    return new LinkedHashSet<String>(Arrays.asList(path.split(File.pathSeparator)));
+  }
+
+  public static class TestMain {
+    public static void main(String[] args) throws Exception {
+      String clazzName = args[0];
+      String methodName = args[1];
+      Class clazz = Class.forName(clazzName);
+      Object instance = clazz.newInstance();
+      Method method = clazz.getMethod(methodName, ParallelExecutor.class);
+      ParallelExecutorImpl parallelExecutor = new ParallelExecutorImpl();
+      method.invoke(instance, parallelExecutor);
+    }
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/JpfRunnerConfig.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/JpfRunnerConfig.java
new file mode 100644
index 0000000..4ca3c18
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/JpfRunnerConfig.java
@@ -0,0 +1,34 @@
+/*
+ * 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.test.concurrency.jpf;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Configuration options for the JPF Runner. This currently takes a list of options that are passed
+ * directly to JPF.
+ *
+ * For example: <code>
+ * {@literal @}JpfRunnerConfig({"+listener+=gov.nasa.jpf.listener.CGMonitor,gov.nasa.jpf.listener.MethodTracker"})
+ * </code>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface JpfRunnerConfig {
+  String[] value();
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/ParallelExecutorImpl.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/ParallelExecutorImpl.java
new file mode 100644
index 0000000..65c4c77
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/ParallelExecutorImpl.java
@@ -0,0 +1,87 @@
+/*
+ * 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.test.concurrency.jpf;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.geode.test.concurrency.ParallelExecutor;
+import org.apache.geode.test.concurrency.RunnableWithException;
+
+class ParallelExecutorImpl implements ParallelExecutor {
+  List<ThreadFuture<?>> futures = new ArrayList<>();
+
+  @Override
+  public <T> Future<T> inParallel(Callable<T> callable) {
+    ThreadFuture<T> future = newThread(callable);
+    futures.add(future);
+    return future;
+  }
+
+  @Override
+  public void execute() throws ExecutionException, InterruptedException {
+    for (ThreadFuture future : futures) {
+      future.start();
+    }
+    for (ThreadFuture future : futures) {
+      future.get();
+    }
+  }
+
+
+  private static <T> ThreadFuture<T> newThread(Callable<T> callable) {
+    ThreadFuture<T> future = new ThreadFuture<T>(callable);
+    Thread thread = new Thread(future);
+    future.setThread(thread);
+    return future;
+  }
+
+  private static class ThreadFuture<T> extends FutureTask<T> {
+
+    private Thread thread;
+
+    public ThreadFuture(Callable<T> callable) {
+      super(callable);
+    }
+
+    public void setThread(Thread thread) {
+      this.thread = thread;
+    }
+
+    @Override
+    public T get() throws InterruptedException, ExecutionException {
+      thread.join();
+      return super.get();
+    }
+
+    @Override
+    public T get(long timeout, TimeUnit unit)
+        throws InterruptedException, ExecutionException, TimeoutException {
+      thread.join(unit.toMillis(timeout));
+      return super.get(0, TimeUnit.MILLISECONDS);
+    }
+
+    public void start() {
+      thread.start();
+    }
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/logging/EmptyLogger.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/logging/EmptyLogger.java
new file mode 100644
index 0000000..a5a7ab2
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/logging/EmptyLogger.java
@@ -0,0 +1,1975 @@
+/*
+ * 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.test.concurrency.jpf.logging;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.message.EntryMessage;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.util.MessageSupplier;
+import org.apache.logging.log4j.util.Supplier;
+
+public class EmptyLogger implements Logger {
+  @Override
+  public void catching(Level level, Throwable t) {
+
+  }
+
+  @Override
+  public void catching(Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Message msg) {
+
+  }
+
+  @Override
+  public void debug(Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void debug(MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(CharSequence message) {
+
+  }
+
+  @Override
+  public void debug(CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Object message) {
+
+  }
+
+  @Override
+  public void debug(Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(String message) {
+
+  }
+
+  @Override
+  public void debug(String message, Object... params) {
+
+  }
+
+  @Override
+  public void debug(String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void debug(String message, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void debug(Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void debug(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void debug(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void entry() {
+
+  }
+
+  @Override
+  public void entry(Object... params) {
+
+  }
+
+  @Override
+  public void error(Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void error(Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void error(Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void error(Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void error(Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void error(Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Message msg) {
+
+  }
+
+  @Override
+  public void error(Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void error(MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void error(MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void error(CharSequence message) {
+
+  }
+
+  @Override
+  public void error(CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Object message) {
+
+  }
+
+  @Override
+  public void error(Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void error(String message) {
+
+  }
+
+  @Override
+  public void error(String message, Object... params) {
+
+  }
+
+  @Override
+  public void error(String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void error(String message, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void error(Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void error(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void error(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void exit() {
+
+  }
+
+  @Override
+  public <R> R exit(R result) {
+    return null;
+  }
+
+  @Override
+  public void fatal(Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Message msg) {
+
+  }
+
+  @Override
+  public void fatal(Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void fatal(MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(CharSequence message) {
+
+  }
+
+  @Override
+  public void fatal(CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Object message) {
+
+  }
+
+  @Override
+  public void fatal(Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(String message) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object... params) {
+
+  }
+
+  @Override
+  public void fatal(String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void fatal(String message, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void fatal(Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void fatal(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void fatal(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public Level getLevel() {
+    return null;
+  }
+
+  @Override
+  public <MF extends MessageFactory> MF getMessageFactory() {
+    return null;
+  }
+
+  @Override
+  public String getName() {
+    return null;
+  }
+
+  @Override
+  public void info(Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void info(Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void info(Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void info(Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void info(Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void info(Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Message msg) {
+
+  }
+
+  @Override
+  public void info(Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void info(MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void info(MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void info(CharSequence message) {
+
+  }
+
+  @Override
+  public void info(CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Object message) {
+
+  }
+
+  @Override
+  public void info(Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void info(String message) {
+
+  }
+
+  @Override
+  public void info(String message, Object... params) {
+
+  }
+
+  @Override
+  public void info(String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void info(String message, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void info(Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void info(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void info(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public boolean isDebugEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isDebugEnabled(Marker marker) {
+    return false;
+  }
+
+  @Override
+  public boolean isEnabled(Level level) {
+    return false;
+  }
+
+  @Override
+  public boolean isEnabled(Level level, Marker marker) {
+    return false;
+  }
+
+  @Override
+  public boolean isErrorEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isErrorEnabled(Marker marker) {
+    return false;
+  }
+
+  @Override
+  public boolean isFatalEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isFatalEnabled(Marker marker) {
+    return false;
+  }
+
+  @Override
+  public boolean isInfoEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isInfoEnabled(Marker marker) {
+    return false;
+  }
+
+  @Override
+  public boolean isTraceEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isTraceEnabled(Marker marker) {
+    return false;
+  }
+
+  @Override
+  public boolean isWarnEnabled() {
+    return false;
+  }
+
+  @Override
+  public boolean isWarnEnabled(Marker marker) {
+    return false;
+  }
+
+  @Override
+  public void log(Level level, Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Message msg) {
+
+  }
+
+  @Override
+  public void log(Level level, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void log(Level level, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, CharSequence message) {
+
+  }
+
+  @Override
+  public void log(Level level, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Object message) {
+
+  }
+
+  @Override
+  public void log(Level level, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, String message) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object... params) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void log(Level level, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3, Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3, Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3, Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3, Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void log(Level level, Marker marker, String message, Object p0, Object p1, Object p2,
+      Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void log(Level level, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void printf(Level level, Marker marker, String format, Object... params) {
+
+  }
+
+  @Override
+  public void printf(Level level, String format, Object... params) {
+
+  }
+
+  @Override
+  public <T extends Throwable> T throwing(Level level, T t) {
+    return null;
+  }
+
+  @Override
+  public <T extends Throwable> T throwing(T t) {
+    return null;
+  }
+
+  @Override
+  public void trace(Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Message msg) {
+
+  }
+
+  @Override
+  public void trace(Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void trace(MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(CharSequence message) {
+
+  }
+
+  @Override
+  public void trace(CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Object message) {
+
+  }
+
+  @Override
+  public void trace(Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(String message) {
+
+  }
+
+  @Override
+  public void trace(String message, Object... params) {
+
+  }
+
+  @Override
+  public void trace(String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void trace(String message, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void trace(Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void trace(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void trace(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public EntryMessage traceEntry() {
+    return null;
+  }
+
+  @Override
+  public EntryMessage traceEntry(String format, Object... params) {
+    return null;
+  }
+
+  @Override
+  public EntryMessage traceEntry(Supplier<?>... paramSuppliers) {
+    return null;
+  }
+
+  @Override
+  public EntryMessage traceEntry(String format, Supplier<?>... paramSuppliers) {
+    return null;
+  }
+
+  @Override
+  public EntryMessage traceEntry(Message message) {
+    return null;
+  }
+
+  @Override
+  public void traceExit() {
+
+  }
+
+  @Override
+  public <R> R traceExit(R result) {
+    return null;
+  }
+
+  @Override
+  public <R> R traceExit(String format, R result) {
+    return null;
+  }
+
+  @Override
+  public void traceExit(EntryMessage message) {
+
+  }
+
+  @Override
+  public <R> R traceExit(EntryMessage message, R result) {
+    return null;
+  }
+
+  @Override
+  public <R> R traceExit(Message message, R result) {
+    return null;
+  }
+
+  @Override
+  public void warn(Marker marker, Message msg) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, CharSequence message) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, Object message) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object... params) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Message msg) {
+
+  }
+
+  @Override
+  public void warn(Message msg, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(MessageSupplier msgSupplier) {
+
+  }
+
+  @Override
+  public void warn(MessageSupplier msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(CharSequence message) {
+
+  }
+
+  @Override
+  public void warn(CharSequence message, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Object message) {
+
+  }
+
+  @Override
+  public void warn(Object message, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(String message) {
+
+  }
+
+  @Override
+  public void warn(String message, Object... params) {
+
+  }
+
+  @Override
+  public void warn(String message, Supplier<?>... paramSuppliers) {
+
+  }
+
+  @Override
+  public void warn(String message, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Supplier<?> msgSupplier) {
+
+  }
+
+  @Override
+  public void warn(Supplier<?> msgSupplier, Throwable t) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void warn(Marker marker, String message, Object p0, Object p1, Object p2, Object p3,
+      Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4,
+      Object p5) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6, Object p7) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6, Object p7, Object p8) {
+
+  }
+
+  @Override
+  public void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+      Object p6, Object p7, Object p8, Object p9) {
+
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_java_util_concurrent_locks_ReentrantReadWriteLock.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_java_util_concurrent_locks_ReentrantReadWriteLock.java
new file mode 100644
index 0000000..9fa8274
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_java_util_concurrent_locks_ReentrantReadWriteLock.java
@@ -0,0 +1,42 @@
+/*
+ * 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.test.concurrency.jpf.peers;
+
+import gov.nasa.jpf.annotation.MJI;
+import gov.nasa.jpf.vm.MJIEnv;
+import gov.nasa.jpf.vm.NativePeer;
+
+/**
+ * MJI class to make ReentrantReadWriteLock work with later versions of Java 8.
+ *
+ * The issue is that ReentrantReadWriteLock uses unsafe find a thread id, but JPF's thread class is
+ * different than the JDK.
+ *
+ * This class allows us to use the JDK's ReentrantReadWriteLock by overriding the behavior to get
+ * the thread id.
+ */
+public class JPF_java_util_concurrent_locks_ReentrantReadWriteLock extends NativePeer {
+
+  @MJI
+  public void $clinit____V(MJIEnv env, int clsObjRef) {
+    // Overriding the JDK's class initialization which looks up the location of
+    // the tid field on Thread.class
+  }
+
+  @MJI
+  public long getThreadId(MJIEnv env, int clsObjRef, int rThread0) {
+    return env.getThreadInfoForObjRef(rThread0).getId();
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_distributed_internal_InternalDistributedSystem.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_distributed_internal_InternalDistributedSystem.java
new file mode 100644
index 0000000..c5ba6ae
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_distributed_internal_InternalDistributedSystem.java
@@ -0,0 +1,28 @@
+/*
+ * 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.test.concurrency.jpf.peers;
+
+import gov.nasa.jpf.annotation.MJI;
+import gov.nasa.jpf.vm.MJIEnv;
+import gov.nasa.jpf.vm.NativePeer;
+
+public class JPF_org_apache_geode_distributed_internal_InternalDistributedSystem
+    extends NativePeer {
+
+  @MJI
+  public void $clinit____V(MJIEnv env, int clsObjRef) {
+    // Override initialization
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_internal_logging_LogService.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_internal_logging_LogService.java
new file mode 100644
index 0000000..4e1d5ce
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_internal_logging_LogService.java
@@ -0,0 +1,42 @@
+/*
+ * 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.test.concurrency.jpf.peers;
+
+import gov.nasa.jpf.annotation.MJI;
+import gov.nasa.jpf.vm.MJIEnv;
+import gov.nasa.jpf.vm.NativePeer;
+
+import org.apache.geode.test.concurrency.jpf.logging.EmptyLogger;
+
+public class JPF_org_apache_geode_internal_logging_LogService extends NativePeer {
+
+  @MJI
+  public void $clinit____V(MJIEnv env, int clsObjRef) {
+    // Override LogService initialization, which tries to load some log4j classes
+    // which in turn will try to read from zip files, etc...
+  }
+
+  @MJI
+  public int getLogger__Ljava_lang_String_2__Lorg_apache_logging_log4j_Logger_2(MJIEnv env,
+      int clsObjRef, int rString0) {
+    return getLogger____Lorg_apache_logging_log4j_Logger_2(env, clsObjRef);
+  }
+
+  @MJI
+  public int getLogger____Lorg_apache_logging_log4j_Logger_2(MJIEnv env, int clsObjRef) {
+    int logger = env.newObject(EmptyLogger.class.getName());
+    return logger;
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_internal_logging_log4j_LogMarker.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_internal_logging_log4j_LogMarker.java
new file mode 100644
index 0000000..683f465
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_geode_internal_logging_log4j_LogMarker.java
@@ -0,0 +1,27 @@
+/*
+ * 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.test.concurrency.jpf.peers;
+
+import gov.nasa.jpf.annotation.MJI;
+import gov.nasa.jpf.vm.MJIEnv;
+import gov.nasa.jpf.vm.NativePeer;
+
+public class JPF_org_apache_geode_internal_logging_log4j_LogMarker extends NativePeer {
+
+  @MJI
+  public void $clinit____V(MJIEnv env, int clsObjRef) {
+    // MarkierManager does a whole bunch of stuff
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_logging_log4j_LogManager.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_logging_log4j_LogManager.java
new file mode 100644
index 0000000..51c06f4
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/jpf/peers/JPF_org_apache_logging_log4j_LogManager.java
@@ -0,0 +1,29 @@
+/*
+ * 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.test.concurrency.jpf.peers;
+
+import gov.nasa.jpf.annotation.MJI;
+import gov.nasa.jpf.vm.MJIEnv;
+import gov.nasa.jpf.vm.NativePeer;
+
+import org.apache.geode.test.concurrency.jpf.logging.EmptyLogger;
+
+public class JPF_org_apache_logging_log4j_LogManager extends NativePeer {
+
+  @MJI
+  public void $clinit____V(MJIEnv env, int clsObjRef) {
+    // Override LogManager initialization, which tries to load a bunch of stuff from jars
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/loop/LoopRunner.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/loop/LoopRunner.java
new file mode 100644
index 0000000..31d87f9
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/loop/LoopRunner.java
@@ -0,0 +1,90 @@
+/*
+ * 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.test.concurrency.loop;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.geode.test.concurrency.ParallelExecutor;
+import org.apache.geode.test.concurrency.Runner;
+
+/**
+ * Simple runner that just runs the test in a loop
+ */
+public class LoopRunner implements Runner {
+  private static final int DEFAULT_COUNT = 1000;
+
+  @Override
+  public List<Throwable> runTestMethod(Method child) {
+    int count = getCount(child);
+
+    ExecutorService executorService = Executors.newCachedThreadPool();
+    try {
+      ParallelExecutor executor = new DelegatingExecutor(executorService);
+      for (int i = 0; i < count; i++) {
+        try {
+          Object test = child.getDeclaringClass().newInstance();
+          child.invoke(test, executor);
+        } catch (Exception e) {
+          return Collections.singletonList(e);
+        }
+      }
+    } finally {
+      executorService.shutdown();
+    }
+
+    return Collections.emptyList();
+  }
+
+  private int getCount(Method child) {
+    LoopRunnerConfig config = child.getDeclaringClass().getAnnotation(LoopRunnerConfig.class);
+    if (config == null) {
+      return DEFAULT_COUNT;
+    }
+
+    return config.count();
+  }
+
+  private static class DelegatingExecutor implements ParallelExecutor {
+    private final ExecutorService executorService;
+    List<Future<?>> futures;
+
+    public DelegatingExecutor(ExecutorService executorService) {
+      this.executorService = executorService;
+      futures = new ArrayList<Future<?>>();
+    }
+
+    @Override
+    public <T> Future<T> inParallel(Callable<T> callable) {
+      Future<T> future = executorService.submit(callable);
+      futures.add(future);
+      return future;
+    }
+
+    @Override
+    public void execute() throws ExecutionException, InterruptedException {
+      for (Future future : futures) {
+        future.get();
+      }
+    }
+  }
+}
diff --git a/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/loop/LoopRunnerConfig.java b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/loop/LoopRunnerConfig.java
new file mode 100644
index 0000000..7e58a4e
--- /dev/null
+++ b/geode-concurrency-test/src/main/java/org/apache/geode/test/concurrency/loop/LoopRunnerConfig.java
@@ -0,0 +1,22 @@
+/*
+ * 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.test.concurrency.loop;
+
+/**
+ * Configuration for the LoopRunner class
+ */
+public @interface LoopRunnerConfig {
+  int count();
+}
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index 9f5a242..1c3daec 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -23,8 +23,16 @@ sourceSets {
     compileClasspath += configurations.compile
     runtimeClasspath += configurations.runtime
   }
+  jpfTest {
+    compileClasspath += configurations.compile
+    compileClasspath += main.output
+    runtimeClasspath += configurations.runtime
+    runtimeClasspath += main.output
+  }
 }
 
+
+
 configurations {
   //declaring new configuration that will be used to associate with artifacts
   archives
@@ -148,6 +156,7 @@ dependencies {
   testCompile 'com.pholser:junit-quickcheck-guava:' + project.'junit-quickcheck.version'
 
   testRuntime 'xerces:xercesImpl:' + project.'xercesImpl.version'
+  jpfTestCompile project(':geode-concurrency-test')
 }
 
 def generatedResources = "$buildDir/generated-resources/main"
@@ -217,6 +226,11 @@ task jcaJar (type: Jar, dependsOn: raJar) {
   from raJar.archivePath
 }
 
+task jpfTest(type: Test) {
+  classpath = sourceSets.jpfTest.runtimeClasspath
+  testClassesDir = sourceSets.jpfTest.output.classesDir
+}
+
 configurations {
   classesOutput {
     extendsFrom compile
diff --git a/geode-core/src/jpfTest/java/org/apache/geode/internal/cache/FilterProfileConcurrencyTest.java b/geode-core/src/jpfTest/java/org/apache/geode/internal/cache/FilterProfileConcurrencyTest.java
new file mode 100644
index 0000000..f3bba25
--- /dev/null
+++ b/geode-core/src/jpfTest/java/org/apache/geode/internal/cache/FilterProfileConcurrencyTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.cache;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
+import org.apache.geode.distributed.internal.membership.MemberAttributes;
+import org.apache.geode.internal.Version;
+import org.apache.geode.internal.cache.tier.InterestType;
+import org.apache.geode.internal.util.BlobHelper;
+import org.apache.geode.test.concurrency.ConcurrentTestRunner;
+import org.apache.geode.test.concurrency.ParallelExecutor;
+import org.apache.geode.test.concurrency.annotation.ConcurrentTestConfig;
+import org.apache.geode.test.concurrency.loop.LoopRunner;
+import org.apache.geode.test.concurrency.loop.LoopRunnerConfig;
+
+@RunWith(ConcurrentTestRunner.class)
+public class FilterProfileConcurrencyTest {
+
+  @Test
+  public void serializationOfFilterProfileWithConcurrentUpdateShouldSucceed(
+      ParallelExecutor executor) throws Exception {
+    // warmUp();
+
+    FilterProfile profile = createFilterProfile();
+
+    // In parallel, serialize the filter profile
+    // and add a new client
+    Future<byte[]> serializer = executor.inParallel(() -> serialize(profile));
+    executor.inParallel(() -> addClient(profile));
+    executor.execute();
+
+    // Make sure we can deserialize the filter profile
+    byte[] bytes = serializer.get();
+    Object deserialized = deserialize(bytes);
+    assertEquals(FilterProfile.class, deserialized.getClass());
+
+  }
+
+  private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
+    return BlobHelper.deserializeBlob(bytes, Version.CURRENT, null);
+  }
+
+  private FilterProfile createFilterProfile() throws UnknownHostException {
+    DistributedMember member = new InternalDistributedMember(InetAddress.getLocalHost(), 0, false,
+        false, MemberAttributes.DEFAULT);
+    return new FilterProfile(null, member, true);
+  }
+
+  private Set addClient(FilterProfile profile) {
+    return profile.registerClientInterest("client", ".*", InterestType.REGULAR_EXPRESSION, false);
+  }
+
+  private byte[] serialize(FilterProfile profile) throws IOException {
+    return BlobHelper.serializeToBlob(profile);
+  }
+
+  private void warmUp() throws IOException {
+    FilterProfile profile = createFilterProfile();
+    byte[] bytes = BlobHelper.serializeToBlob(profile);
+    addClient(profile);
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/FilterProfile.java b/geode-core/src/main/java/org/apache/geode/internal/cache/FilterProfile.java
index a13e616..3ab0a75 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/FilterProfile.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/FilterProfile.java
@@ -72,7 +72,6 @@ import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LocalizedMessage;
 import org.apache.geode.internal.logging.log4j.LogMarker;
-import org.apache.geode.internal.offheap.annotations.Released;
 import org.apache.geode.internal.offheap.annotations.Unretained;
 import org.apache.geode.internal.util.concurrent.CopyOnWriteHashMap;
 
@@ -205,13 +204,22 @@ public class FilterProfile implements DataSerializableFixedID {
    * distribution advisor profiles.
    */
   public FilterProfile(LocalRegion r) {
+    this(r, r.getMyId(), r.getGemFireCache().getCacheServers().size() > 0);
+  }
+
+  /**
+   * used for instantiation of a profile associated with a region and not describing region filters
+   * in a different process. Do not use this method when instantiating profiles to store in
+   * distribution advisor profiles.
+   */
+  public FilterProfile(LocalRegion r, DistributedMember member, boolean hasCacheServer) {
     this.region = r;
     this.isLocalProfile = true;
-    this.memberID = region.getMyId();
+    this.memberID = member;
     this.cqCount = new AtomicInteger();
     this.clientMap = new IDMap();
     this.cqMap = new IDMap();
-    this.localProfile.hasCacheServer = (r.getGemFireCache().getCacheServers().size() > 0);
+    this.localProfile.hasCacheServer = hasCacheServer;
   }
 
   public static boolean isCqOp(operationType opType) {
@@ -1494,13 +1502,12 @@ public class FilterProfile implements DataSerializableFixedID {
 
   }
 
-
   public int getDSFID() {
     return FILTER_PROFILE;
   }
 
   public void toData(DataOutput out) throws IOException {
-    InternalDataSerializer.invokeToData(((InternalDistributedMember) memberID), out);
+    InternalDataSerializer.invokeToData(memberID, out);
     InternalDataSerializer.writeSetOfLongs(this.allKeyClients.getSnapshot(),
         this.clientMap.hasLongID, out);
     DataSerializer.writeHashMap(this.keysOfInterest.getSnapshot(), out);
diff --git a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
index c0cf5ee..3cc48c7 100644
--- a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
+++ b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
@@ -1011,8 +1011,8 @@ fromData,33,2a2bb9001b0100b500072a2bb8001cc0001db500052a2bb8001cc0001eb50003b1
 toData,27,2b2ab40007b9001902002ab400052bb8001a2ab400032bb8001ab1
 
 org/apache/geode/internal/cache/FilterProfile,2
-fromData,192,bb013659b701374d2c2bb801382a2cb500202ab4000d2bb80139b60070572ab400052bb8013ab6013b2ab400072bb8013ab6013b2ab400092bb8013ab6013b2ab4000e2bb80139b60070572ab400062bb8013ab6013b2ab400082bb8013ab6013b2ab4000a2bb8013ab6013b2bb8013c3e1d9e004d05b8013e360403360515051da2002a2bb8013f3a062bb801403a072a1906190703b601412ab4000f19061907b6008957840501a7ffd61504b8013e57a7000e3a081504b8013e571908bfb1
-toData,208,2ab40020c001362bb801432ab4000db6006e2ab40023b4011b2bb801442ab40005b601452bb801462ab40007b601452bb801462ab40009b601452bb801462ab4000eb6006e2ab40023b4011b2bb801442ab40006b601452bb801462ab40008b601452bb801462ab4000ab601452bb801462ab4000fb601454d2cb900bc01003e1d2bb801472cb9011d0100b900b201003a041904b900b301009900361904b900b40100c000b53a051905b9011f0100c0003c3a061905b900b60100c000853a0719062bb8014819072bb80143a7ffc6b1
+fromData,192,bb013759b701384d2c2bb801392a2cb500242ab4000d2bb8013ab60071572ab400052bb8013bb6013c2ab400072bb8013bb6013c2ab400092bb8013bb6013c2ab4000e2bb8013ab60071572ab400062bb8013bb6013c2ab400082bb8013bb6013c2ab4000a2bb8013bb6013c2bb8013d3e1d9e004d05b8013f360403360515051da2002a2bb801403a062bb801413a072a1906190703b601422ab4000f19061907b6008a57840501a7ffd61504b8013f57a7000e3a081504b8013f571908bfb1
+toData,205,2ab400242bb801442ab4000db6006f2ab40027b4011c2bb801452ab40005b601462bb801472ab40007b601462bb801472ab40009b601462bb801472ab4000eb6006f2ab40027b4011c2bb801452ab40006b601462bb801472ab40008b601462bb801472ab4000ab601462bb801472ab4000fb601464d2cb900bd01003e1d2bb801482cb9011e0100b900b301003a041904b900b401009900361904b900b50100c000b63a051905b901200100c0003d3a061905b900b70100c000863a0719062bb8014919072bb80144a7ffc6b1
 
 org/apache/geode/internal/cache/FilterProfile$OperationMessage,2
 fromData,129,2a2bb700522a2bb900530100b500092a2bb900540100b500412ab800552bb90056010032b500232a2bb900570100b500292a2bb900580100b5004a2ab40023b8004c99002c2a2bb900540100b500322ab40023b2004ea5000d2ab40023b2004fa600202a2bb80059b50033a700152a2bb900580100b500252a2bb8005ab50027b1
diff --git a/gradle/rat.gradle b/gradle/rat.gradle
index fc66578..729a283 100644
--- a/gradle/rat.gradle
+++ b/gradle/rat.gradle
@@ -118,6 +118,7 @@ rat {
     'geode-core/src/test/resources/org/apache/geode/management/internal/configuration/utils/*.xml',
 
     '**/META-INF/**',
+    'jpf.properties',
 
     // --- Other Licenses ---
 
diff --git a/settings.gradle b/settings.gradle
index 3d16884..87f4a9c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -39,6 +39,7 @@ include 'extensions/geode-modules-session'
 include 'extensions/geode-modules-assembly'
 include 'geode-protobuf'
 include 'extensions/session-testing-war'
+include 'geode-concurrency-test'
 
 if (GradleVersion.current() < GradleVersion.version(minimumGradleVersion)) {
   throw new GradleException('Running with unsupported Gradle Version. Use Gradle Wrapper or with Gradle version >= ' + minimumGradleVersion)

-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <co...@geode.apache.org>'].