|
Ant example source code file (ProcessDestroyer.java)
The ProcessDestroyer.java source code/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.Vector; /** * Destroys all registered <code>Processes when the VM exits. * * @since Ant 1.5 */ class ProcessDestroyer implements Runnable { private Vector processes = new Vector(); // methods to register and unregister shutdown hooks private Method addShutdownHookMethod; private Method removeShutdownHookMethod; private ProcessDestroyerImpl destroyProcessThread = null; // whether or not this ProcessDestroyer has been registered as a // shutdown hook private boolean added = false; // whether or not this ProcessDestroyer is currently running as // shutdown hook private boolean running = false; private class ProcessDestroyerImpl extends Thread { private boolean shouldDestroy = true; public ProcessDestroyerImpl() { super("ProcessDestroyer Shutdown Hook"); } public void run() { if (shouldDestroy) { ProcessDestroyer.this.run(); } } public void setShouldDestroy(boolean shouldDestroy) { this.shouldDestroy = shouldDestroy; } } /** * Constructs a <code>ProcessDestroyer and obtains * <code>Runtime.addShutdownHook() and * <code>Runtime.removeShutdownHook() through reflection. The * ProcessDestroyer manages a list of processes to be destroyed when the * VM exits. If a process is added when the list is empty, * this <code>ProcessDestroyer is registered as a shutdown hook. If * removing a process results in an empty list, the * <code>ProcessDestroyer is removed as a shutdown hook. */ public ProcessDestroyer() { try { // check to see if the shutdown hook methods exists // (support pre-JDK 1.3 VMs) Class[] paramTypes = {Thread.class}; addShutdownHookMethod = Runtime.class.getMethod("addShutdownHook", paramTypes); removeShutdownHookMethod = Runtime.class.getMethod("removeShutdownHook", paramTypes); // wait to add shutdown hook as needed } catch (NoSuchMethodException e) { // it just won't be added as a shutdown hook... :( } catch (Exception e) { e.printStackTrace(); } } /** * Registers this <code>ProcessDestroyer as a shutdown hook, * uses reflection to ensure pre-JDK 1.3 compatibility. */ private void addShutdownHook() { if (addShutdownHookMethod != null && !running) { destroyProcessThread = new ProcessDestroyerImpl(); Object[] args = {destroyProcessThread}; try { addShutdownHookMethod.invoke(Runtime.getRuntime(), args); added = true; } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t != null && t.getClass() == IllegalStateException.class) { // shutdown already is in progress running = true; } else { e.printStackTrace(); } } } } /** * Removes this <code>ProcessDestroyer as a shutdown hook, * uses reflection to ensure pre-JDK 1.3 compatibility */ private void removeShutdownHook() { if (removeShutdownHookMethod != null && added && !running) { Object[] args = {destroyProcessThread}; try { Boolean removed = (Boolean) removeShutdownHookMethod.invoke( Runtime.getRuntime(), args); if (!removed.booleanValue()) { System.err.println("Could not remove shutdown hook"); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t != null && t.getClass() == IllegalStateException.class) { // shutdown already is in progress running = true; } else { e.printStackTrace(); } } // start the hook thread, a unstarted thread may not be // eligible for garbage collection // Cf.: http://developer.java.sun.com/developer/bugParade/bugs/4533087.html destroyProcessThread.setShouldDestroy(false); if (!destroyProcessThread.getThreadGroup().isDestroyed()) { // start() would throw IllegalThreadStateException from // ThreadGroup.add if it were destroyed destroyProcessThread.start(); } // this should return quickly, since it basically is a NO-OP. try { destroyProcessThread.join(20000); } catch (InterruptedException ie) { // the thread didn't die in time // it should not kill any processes unexpectedly } destroyProcessThread = null; added = false; } } /** * Returns whether or not the ProcessDestroyer is registered as * as shutdown hook * @return true if this is currently added as shutdown hook */ public boolean isAddedAsShutdownHook() { return added; } /** * Returns <code>true if the specified Other Ant examples (source code examples)Here is a short list of links related to this Ant ProcessDestroyer.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.