package se.jiderhamn.classloader.leak.prevention.preinit;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor;
import se.jiderhamn.classloader.leak.prevention.PreClassLoaderInitiator;

/**
 * sun.misc.GC.requestLatency(long), which is known to be called from
 * javax.management.remote.rmi.RMIConnectorServer.start(), will cause the current
 * contextClassLoader to be unavailable for garbage collection.
 * 
 * See http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?view=markup#l106 and 
 * http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?view=markup#l296
 * 
 * See http://java.jiderhamn.se/2012/02/26/classloader-leaks-v-common-mistakes-and-known-offenders/
 * 
 * @author Mattias Jiderhamn
 */
public class SunGCInitiator implements PreClassLoaderInitiator {
  @Override
  public void doOutsideClassLoader(ClassLoaderLeakPreventor preventor) {
    try {
      Class<?> gcClass = Class.forName("sun.misc.GC");
      final Method requestLatency = gcClass.getDeclaredMethod("requestLatency", long.class);
      requestLatency.invoke(null, Long.valueOf(Long.MAX_VALUE - 1));
    }
    catch (ClassNotFoundException cnfex) {
      if(preventor.isOracleJRE())
        preventor.error(cnfex);
    }
    catch (NoSuchMethodException nsmex) {
      preventor.error(nsmex);
    }
    catch (IllegalAccessException iaex) {
      preventor.error(iaex);
    }
    catch (InvocationTargetException itex) {
      preventor.error(itex);
    }
    
  }
}
@@ -1107,35 +1107,24 @@
 s = 
-Class.forName(%22sun.misc.GC%22
+this.getGCClass(
 );%0A 
@@ -1215,16 +1215,58 @@
 class);%0A
+      requestLatency.setAccessible(true);%0A
       re
@@ -1684,16 +1684,265 @@
     %7D%0A  
-  
+%7D%0A%0A  private Class%3C?%3E getGCClass() throws ClassNotFoundException %7B%0A    try %7B%0A      return Class.forName(%22sun.misc.GC%22);%0A    %7D catch (ClassNotFoundException cnfex) %7B%0A      // Try Jre 9 classpath%0A      return Class.forName(%22sun.rmi.transport.GC%22);%0A    %7D
 %0A  %7D%0A%7D

Fix Init sun.misc.GC for Java 9