/* * com.yellowpig.rod.app.watchdog.ProcessLauncher.java * * Version 1.0 [1999.03.22] Rodney Waldhoff * * Copyright (c) 1999 Rodney Waldhoff * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software wihtout restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABLITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABLITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * (Note that this license is the same as MIT X Consortium license, which * can be found at http://www.opensource.org/mit-license.html, and constitutes * Open Source software, according to the Open Source Defintion, version 1.0 * (http://www.opensource.org/osd.html).) * * Open Source is a trademark of the Open Source Initiative. * * Open source promotes software reliability and quality by supporting * independent peer review and rapid evolution of source code. To be certified * as open source, the license of a program must guarantee the right to read, * redistribute, modify, and use it freely. For more information, visit the web * site, http://www.opensource.org. */ package com.yellowpig.rod.app.watchdog; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.FileInputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; /** * A utility for launching and monitoring processes. A launched process * can be automatically restarted when it goes down. *
* See the documentation for the {@link #main(java.lang.String[]) main} * method for information on how to use the ProcessLauncher. *
* You can also view * the source for this class. *
* This program and its documentation are copyright © 1999 Rodney Waldhoff. * You must agree to the licensing terms * in order to read, use, distribute or deploy this software or its documentation. * (Don't worry, it's Open Source.) *
* @see com.yellowpig.rod.app.watchdog.RunnableLauncher * @author Rodney Waldhoff <rwald@hotmail.com> * @version 1.0 [1999.03.23] */ public class ProcessLauncher { /** * The delimiter that separates the "restart flag" from the command to execute. *
* @see #main(java.lang.String[]) */ private static final int DELIM_CHAR = (int)';'; /** * The string that starts a comment line. *
* Lines beginning with this string will be ignored. *
* @see #main(java.lang.String[]) */ private static final String COMMENT_STR = "#"; /** * The application's main method. Launches and optionally monitors/restarts * a set of processes, as specified by a parameter file. *
* Usage: *
* From the command line: *** Within your Java code: *java com.yellowpig.rod.app.watchdog.ProcessLauncher <paramfile>* where <paramfile> is the platform-specific path to a parameter file. *com.yellowpig.rod.app.watchdog.ProcessLauncher.main((String[]){"paramfile"})* Parameter files are composed of lines with the following format: *
* where *<restartflag>{@link #DELIM_CHAR DELIM_CHAR}<command>* Blank lines and lines beginning with {@link #COMMENT_STR COMMENT_STR} * are ignored. **
- <restartflag> *
- indicates whether or not to restart the process when it closes. * (The case-insenstive string TRUE indicates that the process should * be restarted, all other strings cause the process to be forgetten * about once started.) *
- <command> *
- is a platform-dependent command that launches the process to be * monitored. (see {@link java.lang.Runtime#exec java.lang.Runtime.exec(String)}) *
* @param args The command-line arguments.
*/
public static void main(String[] args) {
printBanner();
if(args.length < 1) {
printUsage();
} else {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(args[0])));
} catch (Exception e) {
System.err.println();
System.err.println("ERROR OPENING FILE \"" + args[0] + "\"");
System.err.println(e.toString());
System.err.println();
try { in.close(); } catch(Exception ignored) { }
return;
}
int linecount = 1;
try {
for(;;linecount++) {
String line = in.readLine();
if(null == line) {
break;
} else {
line = line.trim();
if(line.startsWith(COMMENT_STR) || line.length() == 0 ) {
continue; // skip this line
} else {
int delim = line.indexOf(DELIM_CHAR);
if(-1 == delim) { throw new IllegalArgumentException("Expected '" + ((char)DELIM_CHAR) + "' character in non-comment line " + linecount + "."); }
boolean restart = Boolean.valueOf(line.substring(0,delim)).booleanValue();
Thread t = new Thread(new RunnableLauncher(restart,line.substring(delim+1)));
t.start();
}
}
}
} catch (Exception e) {
System.err.println();
System.err.println("ERROR READING FILE \"" + args[0] + "\" (LINE " + linecount + ")");
System.err.println(e.toString());
System.err.println();
return;
} finally {
try { in.close(); } catch(Exception ignored) { }
}
}
}
/**
* Outputs the application's "banner" to System.out.
*/
protected static void printBanner() {
System.out.println();
System.out.println(" com.yellowpig.rod.app.watchdog.ProcessLauncher");
System.out.println(" (a process monitoring utility)");
System.out.println();
System.out.println(" Version 1.0 - 1999.03.22");
System.out.println(" Copyright (c) 1999 Rodney Waldhoff");
System.out.println();
}
/**
* Outputs the application's "help" to System.out.
*/
protected static void printUsage() {
System.out.println("Use:");
System.out.println(" java com.yellowpig.rod.app.watchdog.ProcessLauncher
* You can also view
* the source for this class.
*
* This program and its documentation are copyright © 1999 Rodney Waldhoff.
* You must agree to the licensing terms
* in order to read, use, distribute or deploy this software or its documentation.
* (Don't worry, it's Open Source.)
*
* @see com.yellowpig.rod.app.watchdog.ProcessLauncher
* @author Rodney Waldhoff <rwald@hotmail.com>
* @version 1.0 [1999.03.23]
*/
class RunnableLauncher implements Runnable {
/**
* A data/time format used when reporting start/restart times.
*/
private static final SimpleDateFormat DT_FORMATTER = new SimpleDateFormat("yyyy.MM.dd kk:mm:ss:SSS zzz");
/**
* A flag indicating whether or not to restart the process when it closes.
* @see #run
*/
protected boolean _restart = false;
/**
* The command to execute (via {@link java.lang.Runtime#exec java.lang.Runtime.exec(String)}).
* @see #run
*/
protected String _cmnd = null;
/**
* My constructor.
* @param restart A flag indicating whether or not to restart the process when it closes.
* @param execCmnd The command to execute (via {@link java.lang.Runtime#exec java.lang.Runtime.exec(String)})
*/
RunnableLauncher(boolean restart, String execCmnd) {
_restart = restart;
_cmnd = execCmnd;
System.out.println(DT_FORMATTER.format(new Date()) + " | Launcher started, restart=" + _restart + ", command = \"" + execCmnd + "\".");
}
/**
* My threaded method.
*
* Start the process, and optionally restart it when it exits.
*/
public void run() {
for(;;) {
try {
System.out.println(DT_FORMATTER.format(new Date()) + " | starting process \"" + _cmnd + "\".");
Process p = Runtime.getRuntime().exec(_cmnd);
if(!_restart) {
break;;
} else {
p.waitFor();
}
} catch(IOException ioe) {
System.err.println();
System.err.println("ERROR LAUNCHING PROCESS \"" + _cmnd + "\"");
System.err.println(ioe.toString());
System.err.println("This launcher is exiting.");
break;
} catch(InterruptedException ignored) {
continue;
}
}
}
}