public DistributedReference<V> autoClose(boolean value) {
    autoClose.set(value);
    return this;
  }
DistributedReference is a JUnit Rule that provides automated tearDown for a static
reference in every distributed test {@code VM}s including the main JUnit controller {@code VM}.
If the referenced value is an {@code AutoCloseable} or {@code Closeable} then it will be
auto-closed and set to null in every {@code VM} during tear down.

<p>
If the referenced value is not an {@code AutoCloseable} or {@code Closeable}, the
{@code DistributedReference} will use reflection to invoke any method named
{@code close}, {@code disconnect}, or {@code stop} regardless of what interfaces are implemented
unless {@code autoClose} is set to false.

<p>
If the referenced value is null in any {@code VM} then it will be ignored in that {@code VM}
during tear down.

<p>
In the following example, every {@code VM} has a {@code ServerLauncher} which will be
auto-stopped and set to null during tear down:

<pre>
{@literal @}Rule
public DistributedReference&lt;ServerLauncher&gt; server = new DistributedReference&lt;&gt;();

{@literal @}Before
public void setUp() throws IOException {
  Properties configProperties = new Properties();
  configProperties.setProperty(LOCATORS, DistributedRule.getLocators());

  for (VM vm : toArray(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
    vm.invoke(() -&gt; {
      server.set(new ServerLauncher.Builder()
          .setMemberName("server" + getVMId())
          .setDisableDefaultServer(true)
          .reinitializeWithWorkingDirectory(temporaryFolder.newFolder("server" + getVMId()).getAbsolutePath())
          .build());

      server.get().start();
    });
  }
}

{@literal @}Test
public void eachVmHasItsOwnServerCache() {
  for (VM vm : toArray(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
    vm.invoke(() -&gt; {
      assertThat(server.get().getCache()).isNotNull();
    });
}
</pre>

<p>
In the following example, every {@code VM} has a {@code Cache} which will be auto-closed and set
to null during tear down:

<pre>
{@literal @}Rule
public DistributedReference&lt;Cache&gt; cache = new DistributedReference&lt;&gt;();

{@literal @}Before
public void setUp() {
  Properties configProperties = new Properties();
  configProperties.setProperty(LOCATORS, DistributedRule.getLocators());

  for (VM vm : toArray(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
    vm.invoke(() -&gt; {
      cache.set(new CacheFactory(configProperties).create());
    });
  }
}

{@literal @}Test
public void eachVmHasItsOwnCache() {
  for (VM vm : toArray(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
    vm.invoke(() -&gt; {
      assertThat(cache.get()).isNotNull();
    });
  }
}
</pre>

<p>
In the following example, every {@code VM} has a {@code DistributedSystem} which will be
auto-disconnected and set to null during tear down:

<pre>
{@literal @}Rule
public DistributedReference&lt;DistributedSystem&gt; system = new DistributedReference&lt;&gt;();

{@literal @}Before
public void setUp() {
  Properties configProperties = new Properties();
  configProperties.setProperty(LOCATORS, DistributedRule.getLocators());

  for (VM vm : toArray(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
    vm.invoke(() -&gt; {
      system.set(DistributedSystem.connect(configProperties));
    });
  }
}

{@literal @}Test
public void eachVmHasItsOwnDistributedSystemConnection() {
  for (VM vm : toArray(getVM(0), getVM(1), getVM(2), getVM(3), getController())) {
    vm.invoke(() -&gt; {
      assertThat(system.get()).isNotNull();
    });
  }
}
</pre>

<p>
To disable auto-closing in a test, specify {@code autoClose(false)}:

<pre>
{@literal @}Rule
public DistributedReference&lt;ServerLauncher&gt; serverLauncher =
    new DistributedReference&lt;&gt;().autoClose(false);
</pre>

<p>
The {@code DistributedReference} value will still be set to null during tear down even
if auto-closing is disabled.
geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedReference.java