class JacksonPlugin {
    private static final AgentLogger LOGGER = AgentLogger.getLogger(JacksonPlugin.class);

    private static final String CLEAR_CACHE_METHOD = "ha$$clearCache";
    public static boolean reloadFlag = false;

    private final Set<Object> needToClearCacheObjects = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
    private final Command reloadJacksonCommand = new Command() {
        public void executeCommand() {
            reloadFlag = true;
            try {
                Set<Object> copy = Collections.newSetFromMap(new WeakHashMap<>());
                synchronized (needToClearCacheObjects) {
                    copy.addAll(needToClearCacheObjects);
                }
                for (Object obj : copy) {
                    invokeClearCacheMethod(obj);
                }
                LOGGER.info("Reloaded Jackson.");
            } catch (Exception e) {
                LOGGER.error("Error reloading Jackson.", e);
            } finally {
                reloadFlag = false;
            }
        }
    };

    @Init
    private Scheduler scheduler;

    @OnClassLoadEvent(classNameRegexp = ".*", events = LoadEvent.REDEFINE)
    public void reload() {
        scheduler.scheduleCommand(reloadJacksonCommand, 500);
    }

    private static void insertRegisterCacheObjectInConstructor(CtClass ctClass) throws CannotCompileException{<FILL_FUNCTION_BODY>}

    @OnClassLoadEvent(classNameRegexp = "com.fasterxml.jackson.databind.ObjectMapper", events = LoadEvent.DEFINE, skipSynthetic = false)
    public static void patchObjectMapper(CtClass ctClass) throws CannotCompileException {
        LOGGER.debug("Patch {}", ctClass);
        insertRegisterCacheObjectInConstructor(ctClass);

        CtMethod clearCacheMethod = CtNewMethod.make("public void " + CLEAR_CACHE_METHOD + "() {_rootDeserializers.clear();}", ctClass);
        ctClass.addMethod(clearCacheMethod);
    }

    @OnClassLoadEvent(classNameRegexp = "com.fasterxml.jackson.databind.ser.SerializerCache", events = LoadEvent.DEFINE, skipSynthetic = false)
    public static void patchSerializerCache(CtClass ctClass) throws CannotCompileException {
        LOGGER.debug("Patch {}", ctClass);
        insertRegisterCacheObjectInConstructor(ctClass);

        CtMethod clearCacheMethod = CtNewMethod.make("public void " + CLEAR_CACHE_METHOD + "() {flush();}", ctClass);
        ctClass.addMethod(clearCacheMethod);
    }

    @OnClassLoadEvent(classNameRegexp = "com.fasterxml.jackson.databind.deser.DeserializerCache", events = LoadEvent.DEFINE, skipSynthetic = false)
    public static void patchDeserializerCache(CtClass ctClass) throws CannotCompileException {
        LOGGER.debug("Patch {}", ctClass);
        insertRegisterCacheObjectInConstructor(ctClass);

        CtMethod clearCacheMethod = CtNewMethod.make("public void " + CLEAR_CACHE_METHOD + "() {flushCachedDeserializers();}", ctClass);
        ctClass.addMethod(clearCacheMethod);
    }

    @OnClassLoadEvent(classNameRegexp = "com.fasterxml.jackson.databind.ser.impl.ReadOnlyClassToSerializerMap", events = LoadEvent.DEFINE, skipSynthetic = false)
    public static void patchReadOnlyClassToSerializerMap(CtClass ctClass) throws CannotCompileException {
        LOGGER.debug("Patch {}", ctClass);
        insertRegisterCacheObjectInConstructor(ctClass);

        CtMethod clearCacheMethod = CtNewMethod.make("public void " + CLEAR_CACHE_METHOD + "() {_buckets = new com.fasterxml.jackson.databind.ser.impl.ReadOnlyClassToSerializerMap.Bucket[_size];}", ctClass);
        ctClass.addMethod(clearCacheMethod);
    }

    @OnClassLoadEvent(classNameRegexp = "com.fasterxml.jackson.databind.type.TypeFactory", events = LoadEvent.DEFINE, skipSynthetic = false)
    public static void patchTypeFactory(CtClass ctClass) throws CannotCompileException {
        LOGGER.debug("Patch {}", ctClass);
        insertRegisterCacheObjectInConstructor(ctClass);

        CtMethod clearCacheMethod = CtNewMethod.make("public void " + CLEAR_CACHE_METHOD + "() { _typeCache.clear();}", ctClass);
        ctClass.addMethod(clearCacheMethod);
    }

    @OnClassLoadEvent(classNameRegexp = "com.fasterxml.jackson.databind.util.LRUMap", events = LoadEvent.DEFINE, skipSynthetic = false)
    public static void patch(CtClass ctClass) throws CannotCompileException {
        LOGGER.debug("Patch {}", ctClass);
        insertRegisterCacheObjectInConstructor(ctClass);

        CtMethod clearCacheMethod = CtNewMethod.make("public void " + CLEAR_CACHE_METHOD + "() { clear();}", ctClass);
        ctClass.addMethod(clearCacheMethod);
    }

    public void registerNeedToClearCacheObjects(Object objectMapper) {
        needToClearCacheObjects.add(objectMapper);
        LOGGER.debug("register {}", objectMapper);
    }

    private static void invokeClearCacheMethod(Object obj) {
        try {
            LOGGER.debug("Reload {}", obj);
            ReflectionHelper.invoke(obj, CLEAR_CACHE_METHOD);
        } catch (Exception e) {
            LOGGER.error("Reload failed {}", obj.getClass(), e);
        }
    }
}

        for (CtConstructor constructor : ctClass.getDeclaredConstructors()) {
            StringBuilder src = new StringBuilder("{");
            src.append(PluginManagerInvoker.buildInitializePlugin(JacksonPlugin.class));
            src.append(PluginManagerInvoker.buildCallPluginMethod(JacksonPlugin.class, "registerNeedToClearCacheObjects",
                    "this", "java.lang.Object"));
            src.append("}");
            constructor.insertAfter(src.toString());
        }
    
<no_super_class>