2011-07-28 27 views
9

Tôi có một ứng dụng của bên thứ 3 mà có lỗi gây ra nó để đăng ký nhiều móc tắt máy khi nó chỉ cần 1.tôi cần phải liệt kê các móc đăng ký với java.lang.ApplicationShutdownHooks

Câu hỏi của tôi là làm thế nào để tôi xem những gì các móc tắt máy đã đăng ký là gì? Tôi muốn lặp lại chúng và sau đó gọi phương thức remove. Bộ sưu tập giữ móc là tư nhân tĩnh và không chứa một accessor. Chúng tôi đã cố gắng phản ánh nhưng kể từ khi lớp là gói riêng tư, chúng tôi phải làm cho một phần cracker của chúng tôi java.lang đó là một gói bị cấm.

Bất kỳ ý tưởng nào?

/* 
* %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) { } 
} 
} 
} 

Trả lời

10

Gói riêng tư không làm chậm bạn, đây là Phản ánh! Tất cả các loại ma thuật voodoo đều được phép.

Trong trường hợp này, bạn cần phải có được lớp, sau đó là trường, sau đó đặt nó thành có thể truy cập, sau đó đọc giá trị của nó.

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> 

Một cách đơn giản hơn để xem loại thông tin này chỉ có thể là để take a heap dump của ứng dụng và phân tích nó trong một máy phân tích bộ nhớ như MAT (cho Eclipse) hoặc JProfiler.

+0

Đó là MAT dẫn tôi đến đây. http://stackoverflow.com/questions/6847580/i-need-help-finding-my-memory-leak-using-mat – Preston

+0

Ah, OK. Vâng ở trên nên làm việc cho bạn sau đó. –

Các vấn đề liên quan