java - 我需要列出使用 java.lang.ApplicationShutdownHooks 注册的钩子(Hook)

标签 java reflection

我有一个第 3 方应用程序有一个错误,导致它在只需要 1 个时注册多个关闭 Hook 。

我的问题是如何查看注册的关闭 Hook 是什么?我想迭代它们然后调用 remove 方法。持有 Hook 的集合是私有(private)静态的,不包含访问器。我们已经尝试过反射,但由于该类是包私有(private)的,我们必须让我们的 cracker 成为 java.lang 的一部分,这是一个被禁止的包。

有什么想法吗?

/*
 * %W% %E%
 *
 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
class ApplicationShutdownHooks {
static {
    Shutdown.add(1 /* shutdown hook invocation order */,
        new Runnable() {
            public void run() {
                runHooks();
            }
        });
}

/* The set of registered hooks */
private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();

private void ApplicationShutdownHooks() {}

/* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
 * but does not do any security checks.
 */
static synchronized void add(Thread hook) {
if(hooks == null)
    throw new IllegalStateException("Shutdown in progress");

if (hook.isAlive())
    throw new IllegalArgumentException("Hook already running");

if (hooks.containsKey(hook))
    throw new IllegalArgumentException("Hook previously registered");

    hooks.put(hook, hook);
}

/* Remove a previously-registered hook.  Like the add method, this method
 * does not do any security checks.
 */
static synchronized boolean remove(Thread hook) {
if(hooks == null)
    throw new IllegalStateException("Shutdown in progress");

if (hook == null) 
    throw new NullPointerException();

return hooks.remove(hook) != null;
}

/* Iterates over all application hooks creating a new thread for each
 * to run in. Hooks are run concurrently and this method waits for 
 * them to finish.
 */
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
    threads = hooks.keySet();
    hooks = null;
}

for (Thread hook : threads) {
    hook.start();
}
for (Thread hook : threads) {
    try {
    hook.join();
    } catch (InterruptedException x) { }
}
}
}

最佳答案

私有(private)包不应该让你慢下来,这就是反射!允许使用各种巫毒魔法。

在这种情况下,您需要获取类,然后是字段,然后将其设置为可访问,然后读取其值。

    Class clazz = Class.forName("java.lang.ApplicationShutdownHooks");
    Field field = clazz.getDeclaredField("hooks");
    field.setAccessible(true);
    Object hooks = field.get(null);
    System.out.println(hooks); //hooks is a Map<Thread, Thread>

查看此类信息的更简单方法可能只是访问 take a heap dump应用程序并在内存分析器中分析它 MAT (对于 Eclipse)或 JProfiler .

关于java - 我需要列出使用 java.lang.ApplicationShutdownHooks 注册的钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6865408/

相关文章:

java - shutdown 和 awaitTermination 哪个第一次调用有什么区别?

java - 在JSP代码中使用下拉框

c# - 使用 PropertyInfo 作为字典键

c# - 反射 : can't get List "ElementAt" MethodInfo

.net - 泛型类型和泛型类型定义之间有什么区别?

java - 提交表单并得到 404 空响应

java - 可变长度参数列表将泛型和泛型数组作为参数传递 - Java

java - 有没有办法检测 java 中的用户不活动?

java - 如何使用 Java Reflection 将协议(protocol)字符串转换为 Spymemcached 协议(protocol)枚举?

java 字段变化监听器