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

import java.lang.reflect.Method;

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

/**
 * Clear Jackson TypeFactory cache as per https://github.com/FasterXML/jackson-databind/issues/1363
 * @author Mattias Jiderhamn
 */
public class JacksonCleanUp implements ClassLoaderPreMortemCleanUp {
  @Override
  public void cleanUp(ClassLoaderLeakPreventor preventor) {
    final Class<?> typeFactoryClass = preventor.findClass("com.fasterxml.jackson.databind.type.TypeFactory");
    if(typeFactoryClass != null && ! preventor.isLoadedInClassLoader(typeFactoryClass)) {
      try {
        final Method defaultInstance = preventor.findMethod(typeFactoryClass, "defaultInstance");
        final Method clearCache = preventor.findMethod(typeFactoryClass, "clearCache");
        if(defaultInstance != null && clearCache != null) {
          final Object defaultTypeFactory = defaultInstance.invoke(null);
          if(defaultTypeFactory != null) {
            clearCache.invoke(defaultTypeFactory);
          }
        }
      }
      catch (Exception e) {
        preventor.error(e);
      }
    }
  }
}
@@ -84,16 +84,38 @@
 .Method;
+%0Aimport java.util.Map;
 %0A%0Aimport
@@ -860,222 +860,492 @@
     
-final Method clearCache = preventor.findMethod(typeFactoryClass, %22clearCache%22);%0A        if(defaultInstance != null && clearCache != null) %7B%0A          final Object defaultTypeFactory = defaultInstance.invoke(null);%0A
+if(defaultInstance != null) %7B%0A          final Object defaultTypeFactory = defaultInstance.invoke(null);%0A          if(defaultTypeFactory != null) %7B%0A            final Method clearCache = preventor.findMethod(typeFactoryClass, %22clearCache%22);%0A            if(clearCache != null) %7B %0A              clearCache.invoke(defaultTypeFactory);%0A            %7D%0A            else %7B // Version %3C 2.4.1%0A              final Object typeCache = preventor.getFieldValue(defaultTypeFactory, %22_typeCache%22);%0A    
     
@@ -1357,88 +1357,250 @@
  if(
-defaultTypeFactory != null) %7B%0A            clearCache.invoke(defaultTypeFactory);
+typeCache instanceof Map) %7B%0A                //noinspection SynchronizationOnLocalVariableOrMethodParameter%0A                synchronized (typeCache) %7B%0A                  ((Map) typeCache).clear();%0A                %7D%0A              %7D%0A            %7D
 %0A   

Make Jackson TypeFactory cache clean up compatible with Jackson version < 2.4.1. #75