001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.startup;
018:
019: import java.io.File;
020: import java.lang.reflect.Method;
021: import java.util.ArrayList;
022:
023: /**
024: * <p>General purpose wrapper for command line tools that should execute in an
025: * environment with the common class loader environment set up by Catalina.
026: * This should be executed from a command line script that conforms to
027: * the following requirements:</p>
028: * <ul>
029: * <li>Passes the <code>catalina.home</code> system property configured with
030: * the pathname of the Tomcat installation directory.</li>
031: * <li>Sets the system classpath to include <code>bootstrap.jar</code> and
032: * <code>$JAVA_HOME/lib/tools.jar</code>.</li>
033: * </ul>
034: *
035: * <p>The command line to execute the tool looks like:</p>
036: * <pre>
037: * java -classpath $CLASSPATH org.apache.catalina.startup.Tool \
038: * ${options} ${classname} ${arguments}
039: * </pre>
040: *
041: * <p>with the following replacement contents:
042: * <ul>
043: * <li><strong>${options}</strong> - Command line options for this Tool wrapper.
044: * The following options are supported:
045: * <ul>
046: * <li><em>-ant</em> : Set the <code>ant.home</code> system property
047: * to corresponding to the value of <code>catalina.home</code>
048: * (useful when your command line tool runs Ant).</li>
049: * <li><em>-common</em> : Add <code>common/classes</code> and
050: * <code>common/lib</codE) to the class loader repositories.</li>
051: * <li><em>-debug</em> : Enable debugging messages from this wrapper.</li>
052: * <li><em>-server</em> : Add <code>server/classes</code> and
053: * <code>server/lib</code> to the class loader repositories.</li>
054: * <li><em>-shared</em> : Add <code>shared/classes</code> and
055: * <code>shared/lib</code> to the class loader repositories.</li>
056: * </ul>
057: * <li><strong>${classname}</strong> - Fully qualified Java class name of the
058: * application's main class.</li>
059: * <li><strong>${arguments}</strong> - Command line arguments to be passed to
060: * the application's <code>main()</code> method.</li>
061: * </ul>
062: *
063: * @author Craig R. McClanahan
064: * @version $Revision: 1.4 $ $Date: 2004/02/27 14:58:49 $
065: */
066:
067: public final class Tool {
068:
069: // ------------------------------------------------------- Static Variables
070:
071: /**
072: * Set <code>ant.home</code> system property?
073: */
074: private static boolean ant = false;
075:
076: /**
077: * The pathname of our installation base directory.
078: */
079: private static String catalinaHome = System
080: .getProperty("catalina.home");
081:
082: /**
083: * Include common classes in the repositories?
084: */
085: private static boolean common = false;
086:
087: /**
088: * Enable debugging detail messages?
089: */
090: private static boolean debug = false;
091:
092: /**
093: * Include server classes in the repositories?
094: */
095: private static boolean server = false;
096:
097: /**
098: * Include shared classes in the repositories?
099: */
100: private static boolean shared = false;
101:
102: // ----------------------------------------------------------- Main Program
103:
104: /**
105: * The main program for the bootstrap.
106: *
107: * @param args Command line arguments to be processed
108: */
109: public static void main(String args[]) {
110:
111: // Verify that "catalina.home" was passed.
112: if (catalinaHome == null) {
113: log("Must set 'catalina.home' system property");
114: System.exit(1);
115: }
116:
117: // Process command line options
118: int index = 0;
119: while (true) {
120: if (index == args.length) {
121: usage();
122: System.exit(1);
123: }
124: if ("-ant".equals(args[index]))
125: ant = true;
126: else if ("-common".equals(args[index]))
127: common = true;
128: else if ("-debug".equals(args[index]))
129: debug = true;
130: else if ("-server".equals(args[index]))
131: server = true;
132: else if ("-shared".equals(args[index]))
133: shared = true;
134: else
135: break;
136: index++;
137: }
138: if (index > args.length) {
139: usage();
140: System.exit(1);
141: }
142:
143: // Set "ant.home" if requested
144: if (ant)
145: System.setProperty("ant.home", catalinaHome);
146:
147: // Construct the class loader we will be using
148: ClassLoader classLoader = null;
149: try {
150: if (debug) {
151: log("Constructing class loader");
152: ClassLoaderFactory.setDebug(1);
153: }
154: ArrayList packed = new ArrayList();
155: ArrayList unpacked = new ArrayList();
156: unpacked.add(new File(catalinaHome, "classes"));
157: packed.add(new File(catalinaHome, "lib"));
158: if (common) {
159: unpacked.add(new File(catalinaHome, "common"
160: + File.separator + "classes"));
161: packed.add(new File(catalinaHome, "common"
162: + File.separator + "lib"));
163: }
164: if (server) {
165: unpacked.add(new File(catalinaHome, "server"
166: + File.separator + "classes"));
167: packed.add(new File(catalinaHome, "server"
168: + File.separator + "lib"));
169: }
170: if (shared) {
171: unpacked.add(new File(catalinaHome, "shared"
172: + File.separator + "classes"));
173: packed.add(new File(catalinaHome, "shared"
174: + File.separator + "lib"));
175: }
176: classLoader = ClassLoaderFactory.createClassLoader(
177: (File[]) unpacked.toArray(new File[0]),
178: (File[]) packed.toArray(new File[0]), null);
179: } catch (Throwable t) {
180: log("Class loader creation threw exception", t);
181: System.exit(1);
182: }
183: Thread.currentThread().setContextClassLoader(classLoader);
184:
185: // Load our application class
186: Class clazz = null;
187: String className = args[index++];
188: try {
189: if (debug)
190: log("Loading application class " + className);
191: clazz = classLoader.loadClass(className);
192: } catch (Throwable t) {
193: log("Exception creating instance of " + className, t);
194: System.exit(1);
195: }
196:
197: // Locate the static main() method of the application class
198: Method method = null;
199: String params[] = new String[args.length - index];
200: System.arraycopy(args, index, params, 0, params.length);
201: try {
202: if (debug)
203: log("Identifying main() method");
204: String methodName = "main";
205: Class paramTypes[] = new Class[1];
206: paramTypes[0] = params.getClass();
207: method = clazz.getMethod(methodName, paramTypes);
208: } catch (Throwable t) {
209: log("Exception locating main() method", t);
210: System.exit(1);
211: }
212:
213: // Invoke the main method of the application class
214: try {
215: if (debug)
216: log("Calling main() method");
217: Object paramValues[] = new Object[1];
218: paramValues[0] = params;
219: method.invoke(null, paramValues);
220: } catch (Throwable t) {
221: log("Exception calling main() method", t);
222: System.exit(1);
223: }
224:
225: }
226:
227: /**
228: * Log a debugging detail message.
229: *
230: * @param message The message to be logged
231: */
232: private static void log(String message) {
233:
234: System.out.print("Tool: ");
235: System.out.println(message);
236:
237: }
238:
239: /**
240: * Log a debugging detail message with an exception.
241: *
242: * @param message The message to be logged
243: * @param exception The exception to be logged
244: */
245: private static void log(String message, Throwable exception) {
246:
247: log(message);
248: exception.printStackTrace(System.out);
249:
250: }
251:
252: /**
253: * Display usage information about this tool.
254: */
255: private static void usage() {
256:
257: log("Usage: java org.apache.catalina.startup.Tool [<options>] <class> [<arguments>]");
258:
259: }
260:
261: }
|