- /*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed 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.commons.launcher;
-
- import java.awt.Frame;
- import java.awt.Image;
- import java.awt.Rectangle;
- import java.awt.Toolkit;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- import java.io.FileOutputStream;
- import java.io.PrintStream;
- import java.lang.reflect.Method;
-
- /**
- * A wrapper class that invokes another class'
- * <code>main(String[])</code>. This particular class uses several system
- * properties to control features:
- * <ul>
- * <li>Redirecting System.out and System.err.
- * <li>Displaying a minimized window in the Windows taskbar.
- * </ul>
- * This class is normally not invoked directly. Instead, it is invoked by the
- * {@link LaunchTask} class.
- *
- * @author Patrick Luby
- */
- public class ChildMain extends Thread {
-
- //----------------------------------------------------------- Static Fields
-
- /**
- * The appendOutput system property name.
- */
- public final static String APPEND_OUTPUT_PROP_NAME =
- "org.apache.commons.launcher.appendOutput";
-
- /**
- * The displayMiminizedWindow system property name.
- */
- public final static String DISPLAY_MINIMIZED_WINDOW_PROP_NAME =
- "org.apache.commons.launcher.displayMinimizedWindow";
-
- /**
- * The disposeMiminizedWindow system property name.
- */
- public final static String DISPOSE_MINIMIZED_WINDOW_PROP_NAME =
- "org.apache.commons.launcher.disposeMinimizedWindow";
-
- /**
- * The executableName system property name.
- */
- public final static String EXECUTABLE_PROP_NAME =
- "org.apache.commons.launcher.executableName";
-
- /**
- * The heartbeatFile system property name.
- */
- public final static String HEARTBEAT_FILE_PROP_NAME =
- "org.apache.commons.launcher.heartbeatFile";
-
- /**
- * The miminizedWindowTitle system property name.
- */
- public final static String MINIMIZED_WINDOW_TITLE_PROP_NAME =
- "org.apache.commons.launcher.minimizedWindowTitle";
-
- /**
- * The miminizedWindowIcon system property name.
- */
- public final static String MINIMIZED_WINDOW_ICON_PROP_NAME=
- "org.apache.commons.launcher.minimizedWindowIcon";
-
- /**
- * The outputFile system property name.
- */
- public final static String OUTPUT_FILE_PROP_NAME =
- "org.apache.commons.launcher.outputFile";
-
- /**
- * The waitForChild system property name.
- */
- public final static String WAIT_FOR_CHILD_PROP_NAME =
- "org.apache.commons.launcher.waitForChild";
-
- //------------------------------------------------------------------ Fields
-
- /**
- * Cached command line arguments
- */
- private String[] args = null;
-
- //------------------------------------------------------------ Constructors
-
- /**
- * Construct an instance of this {@link Thread} subclass and cache the
- * args parameter for use by the {@link #run()} method.
- *
- * @param group the ThreadGroup to use for this thread
- * @param args the command line arguments
- */
- private ChildMain(ThreadGroup group, String[] args) {
-
- super(group, ChildMain.class.getName());
- this.args = args;
-
- }
-
- //---------------------------------------------------------- Static Methods
-
- /**
- * Main entry point for the child process. This method should only be
- * invoked by the {@link LaunchTask} class.
- *
- * @param args command line arguments
- */
- public static void main(String[] args) {
-
- // Invoke the target application in a separate thread so that we
- // caught any uncaught errors thrown by the target application
- Thread mainThread = new ChildMain(new ExitOnErrorThreadGroup(ChildMain.class.getName()), args);
- mainThread.start();
-
- }
-
- //----------------------------------------------------------------- Methods
-
- /**
- * Invoke the target application.
- *
- * @param args command line arguments
- */
- public void run() {
-
- // If there are no arguments, do nothing
- if (args == null || args.length == 0)
- return;
-
- // Invoke the target application
- try {
-
- // Start the thread to check if the parent JVM exits.
- boolean waitForChild = false;
- if (System.getProperty(ChildMain.WAIT_FOR_CHILD_PROP_NAME) != null) {
- waitForChild = true;
- String heartbeatFile = System.getProperty(ChildMain.HEARTBEAT_FILE_PROP_NAME);
- ParentListener heartbeat = new ParentListener(heartbeatFile);
- // Make the thread a daemon thread so that it does not
- // prevent this process from exiting when all of the
- // appliation's threads finish.
- heartbeat.setDaemon(true);
- heartbeat.start();
- }
-
- // If applicable, redirect output and error streams
- String outputPath = System.getProperty(ChildMain.OUTPUT_FILE_PROP_NAME);
- if (outputPath != null) {
- boolean appendOutput = false;
- if (System.getProperty(ChildMain.APPEND_OUTPUT_PROP_NAME) != null)
- appendOutput = true;
- PrintStream ps = new PrintStream(new FileOutputStream(outputPath, appendOutput), true);
- System.setOut(ps);
- System.setErr(ps);
- }
-
- // The first argument should be the class that we really want to
- // invoke. Try to load the class and invoke its main(String[])
- // method with the first argument shifted out.
- Class mainClass = Class.forName(args[0]);
- Class[] paramTypes = new Class[1];
- Object[] paramValues = new Object[1];
- String[] params = new String[args.length - 1];
- // Shift args[0] out of the arguments
- for (int i = 0; i < params.length; i++)
- params[i] = args[i + 1];
- paramTypes[0] = params.getClass();
- paramValues[0] = params;
-
- // Create the icon window if this is a waitForChild task
- Frame frame = null;
- boolean displayMinimizedWindow = false;
- if (System.getProperty(ChildMain.DISPLAY_MINIMIZED_WINDOW_PROP_NAME) != null)
- displayMinimizedWindow = true;
- String osname = System.getProperty("os.name").toLowerCase();
- if (displayMinimizedWindow && osname.indexOf("windows") >= 0) {
- try {
- frame = new Frame();
- String title = System.getProperty(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME);
- if (title != null)
- frame.setTitle(title);
- frame.setState(Frame.ICONIFIED);
- String icon = System.getProperty(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME);
- if (icon != null) {
- Image iconImage = Toolkit.getDefaultToolkit().createImage(icon);
- if (iconImage != null)
- frame.setIconImage(iconImage);
- }
-
- // Ensure that window always remains minimized
- frame.addWindowListener(new ChildWindowAdapter());
- Rectangle bounds = frame.getGraphicsConfiguration().getBounds();
- int width = (int)frame.getBounds().getWidth();
- int height = frame.getInsets().top + frame.getInsets().bottom;
- int x = (int)bounds.getWidth() - width;
- int y = (int)bounds.getHeight() - height;
- frame.setBounds(x, y, width, height);
- frame.setResizable(false);
- frame.setVisible(true);
- } catch(Exception fe) {}
- }
-
- // Invoke the main() method
- Method mainMethod = mainClass.getDeclaredMethod("main", paramTypes);
- mainMethod.invoke(null, paramValues);
-
- // Close the frame if it exists
- if (frame != null && System.getProperty(ChildMain.DISPOSE_MINIMIZED_WINDOW_PROP_NAME) != null) {
- // Exit this process. Closing or disposing of the window is not
- // enough to allow the process to exit.
- System.exit(0);
- }
-
- } catch (Throwable t) {
- String message = t.getMessage();
- t.printStackTrace();
- System.exit(1);
- }
-
- }
-
- /**
- * A WindowAdapter subclass that causes the application to exit when its
- * {@link #windowClosing(WindowEvent)} method is invoked.
- */
- private static class ChildWindowAdapter extends WindowAdapter {
-
- /**
- * Invoked when a window is in the process of being closed.
- *
- * @param e the event
- */
- public void windowClosing(WindowEvent e) {
-
- System.exit(0);
-
- }
-
- }
-
- }