我有一个第三方应用程序,它有一个bug,导致它注册多个关闭钩子,而它只需要一个。
我的问题是,我如何查看已注册的关闭挂钩是什么?我想迭代它们,然后调用remove方法。持有钩子的集合是私有静态的,并且不包含访问器。我们已经尝试过反射,但是因为类是包私有的,所以我们必须使我们的破解器成为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) { }
}
}
}发布于 2011-07-29 04:52:39
软件包私有不应该减慢你的速度,这是反射!所有的巫毒魔法都是允许的。
在这种情况下,您需要获取类,然后获取字段,然后将其设置为accessible,然后读取它的值。
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等内存分析器中分析它。
https://stackoverflow.com/questions/6865408
复制相似问题