2011-07-28 26 views
9

我有了,導致其註冊多個關閉掛鉤時,只需要1我要列出與java.lang.ApplicationShutdownHooks

我的問題是怎麼做我的錯誤第三方應用註冊的掛鉤看看註冊的關機掛鉤是什麼?我想迭代它們,然後調用remove方法。持有鉤子的集合是私有靜態的,不包含訪問器。我們已經嘗試了反射,但由於該類是封裝私有的,我們必須使我們的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) { } 
} 
} 
} 

回答

10

包私人不應該減慢你,這是反射!允許各種伏都教魔法。

在這種情況下,您需要獲取該類,然後將該字段設置爲可訪問,然後讀取其值。

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

+0

這是MAT讓我在這裏。 http://stackoverflow.com/questions/6847580/i-need-help-finding-my-memory-leak-using-mat – Preston

+0

啊,好的。那麼上述應該適合你。 –