package org.apache.markt.leaks.rmi;

import java.lang.ref.WeakReference;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class BindingLeak {

    public static void main(String[] args) {

        BindingLeak bindingLeak = new BindingLeak();

        // Registry creation has a known leak (see RegistryLeak) so create it
        // under what is effectively the container class loader
        try {
            LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Use this to demonstrate that the problem lies with bind/unbind
        // When true, there is a memory leak
        // When false, there is no memory leak
        boolean register = true;

        // Switch TCCL
        bindingLeak.start();

        // Register new object in RMI
        bindingLeak.register(register);

        // Deregister object
        bindingLeak.deregister(register);

        // Restore TCCL
        bindingLeak.stop();

        // Trigger GC
        System.gc();

        // Check for leak
        bindingLeak.leakCheck();
    }


    private static final ClassLoader ORIGINAL_CLASS_LOADER =
            Thread.currentThread().getContextClassLoader();
    private static final String NAME = "Chat";

    private WeakReference<ClassLoader> moduleClassLoaderRef;
    private Remote remoteObject;

    private void start() {
        ClassLoader moduleClassLoader = new URLClassLoader(new URL[] {}, ORIGINAL_CLASS_LOADER);

        Thread.currentThread().setContextClassLoader(moduleClassLoader);
        moduleClassLoaderRef = new WeakReference<>(moduleClassLoader);
    }


    private void register(boolean register) {
        remoteObject = new ChatImpl();
        try {
            Chat stub = (Chat) UnicastRemoteObject.exportObject(remoteObject, 10180);
            if (register) {
                LocateRegistry.getRegistry().bind(NAME, stub);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void deregister(boolean register) {
        try {
            if (register) {
                LocateRegistry.getRegistry().unbind(NAME);
            }
            UnicastRemoteObject.unexportObject(remoteObject, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        remoteObject = null;
    }


    private void stop() {
        Thread.currentThread().setContextClassLoader(ORIGINAL_CLASS_LOADER);
    }


    private void leakCheck() {
        if (moduleClassLoaderRef.get() == null) {
            System.out.println("No leak");
        } else {
            System.out.println("Leak");
        }
    }
}
@@ -695,208 +695,8 @@
  %7D%0A%0A
-        // Use this to demonstrate that the problem lies with bind/unbind%0A        // When true, there is a memory leak%0A        // When false, there is no memory leak%0A        boolean register = true;%0A%0A
     
@@ -807,32 +807,24 @@
 ak.register(
-register
 );%0A%0A        
@@ -875,24 +875,16 @@
 egister(
-register
 );%0A%0A    
@@ -928,24 +928,134 @@
 ak.stop();%0A%0A
+        // Check for leaks%0A        int count = 0;%0A        while (count %3C 10 && bindingLeak.leakCheck()) %7B%0A    
         // T
@@ -1068,24 +1068,28 @@
  GC%0A        
+    
 System.gc();
@@ -1093,34 +1093,258 @@
 ();%0A
-%0A        // Check for leak
+            try %7B%0A                Thread.sleep(200);%0A            %7D catch (InterruptedException e) %7B%0A                e.printStackTrace();%0A            %7D%0A            count++;%0A        %7D%0A        System.out.println(%22There were %22 + count + %22 calls to GC%22);%0A
 %0A   
@@ -1340,32 +1340,36 @@
  GC%22);%0A%0A        
+if (
 bindingLeak.leak
@@ -1375,17 +1375,129 @@
 kCheck()
-;
+) %7B%0A            System.out.println(%22Leak%22);%0A        %7D else %7B%0A            System.out.println(%22No leak%22);%0A        %7D
 %0A    %7D%0A%0A
@@ -2064,32 +2064,16 @@
 egister(
-boolean register
 ) %7B%0A    
@@ -2211,40 +2211,8 @@
 0);%0A
-            if (register) %7B%0A    
     
@@ -2266,30 +2266,16 @@
  stub);%0A
-            %7D%0A
         
@@ -2381,24 +2381,8 @@
 ter(
-boolean register
 ) %7B%0A
@@ -2399,40 +2399,8 @@
 y %7B%0A
-            if (register) %7B%0A    
     
@@ -2450,30 +2450,16 @@
 (NAME);%0A
-            %7D%0A
         
@@ -2753,20 +2753,23 @@
 private 
-void
+boolean
  leakChe
@@ -2783,20 +2783,23 @@
         
-if (
+return 
 moduleCl
@@ -2821,128 +2821,16 @@
 t() 
-=
+!
 = null
-) %7B%0A            System.out.println(%22No leak%22);%0A        %7D else %7B%0A            System.out.println(%22Leak%22);%0A        %7D
+;
 %0A   

Make the leak test more robust which demonstrates that there is no leak.