I need to list the hooks registered with java.lang.ApplicationShutdownHooks

Viewed 4444

I have a 3rd party application that has a bug which causes it to register multiple shutdown hooks when it only needs 1.

My question is how do I see what the registered shutdown hooks are? I want to iterate them and then call the remove method. The collection holding the hooks is private static and doesn't contain an accessor. We've tried reflection but since the class is package private we have to make our cracker part of java.lang which is a prohibited package.

Any ideas?

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