001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.startup;
019:
020: import java.io.File;
021: import java.lang.reflect.Method;
022: import java.util.ArrayList;
023:
024: import org.apache.juli.logging.Log;
025: import org.apache.juli.logging.LogFactory;
026:
027: /**
028: * <p>General purpose wrapper for command line tools that should execute in an
029: * environment with the common class loader environment set up by Catalina.
030: * This should be executed from a command line script that conforms to
031: * the following requirements:</p>
032: * <ul>
033: * <li>Passes the <code>catalina.home</code> system property configured with
034: * the pathname of the Tomcat installation directory.</li>
035: * <li>Sets the system classpath to include <code>bootstrap.jar</code> and
036: * <code>$JAVA_HOME/lib/tools.jar</code>.</li>
037: * </ul>
038: *
039: * <p>The command line to execute the tool looks like:</p>
040: * <pre>
041: * java -classpath $CLASSPATH org.apache.catalina.startup.Tool \
042: * ${options} ${classname} ${arguments}
043: * </pre>
044: *
045: * <p>with the following replacement contents:
046: * <ul>
047: * <li><strong>${options}</strong> - Command line options for this Tool wrapper.
048: * The following options are supported:
049: * <ul>
050: * <li><em>-ant</em> : Set the <code>ant.home</code> system property
051: * to corresponding to the value of <code>catalina.home</code>
052: * (useful when your command line tool runs Ant).</li>
053: * <li><em>-common</em> : Add <code>common/classes</code> and
054: * <code>common/lib</codE) to the class loader repositories.</li>
055: * <li><em>-server</em> : Add <code>server/classes</code> and
056: * <code>server/lib</code> to the class loader repositories.</li>
057: * <li><em>-shared</em> : Add <code>shared/classes</code> and
058: * <code>shared/lib</code> to the class loader repositories.</li>
059: * </ul>
060: * <li><strong>${classname}</strong> - Fully qualified Java class name of the
061: * application's main class.</li>
062: * <li><strong>${arguments}</strong> - Command line arguments to be passed to
063: * the application's <code>main()</code> method.</li>
064: * </ul>
065: *
066: * @author Craig R. McClanahan
067: * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
068: */
069:
070: public final class Tool {
071:
072: private static Log log = LogFactory.getLog(Tool.class);
073:
074: // ------------------------------------------------------- Static Variables
075:
076: /**
077: * Set <code>ant.home</code> system property?
078: */
079: private static boolean ant = false;
080:
081: /**
082: * The pathname of our installation base directory.
083: */
084: private static String catalinaHome = System
085: .getProperty("catalina.home");
086:
087: /**
088: * Include common classes in the repositories?
089: */
090: private static boolean common = 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.error("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 ("-server".equals(args[index]))
129: server = true;
130: else if ("-shared".equals(args[index]))
131: shared = true;
132: else
133: break;
134: index++;
135: }
136: if (index > args.length) {
137: usage();
138: System.exit(1);
139: }
140:
141: // Set "ant.home" if requested
142: if (ant)
143: System.setProperty("ant.home", catalinaHome);
144:
145: // Construct the class loader we will be using
146: ClassLoader classLoader = null;
147: try {
148: ArrayList packed = new ArrayList();
149: ArrayList unpacked = new ArrayList();
150: unpacked.add(new File(catalinaHome, "classes"));
151: packed.add(new File(catalinaHome, "lib"));
152: if (common) {
153: unpacked.add(new File(catalinaHome, "common"
154: + File.separator + "classes"));
155: packed.add(new File(catalinaHome, "common"
156: + File.separator + "lib"));
157: }
158: if (server) {
159: unpacked.add(new File(catalinaHome, "server"
160: + File.separator + "classes"));
161: packed.add(new File(catalinaHome, "server"
162: + File.separator + "lib"));
163: }
164: if (shared) {
165: unpacked.add(new File(catalinaHome, "shared"
166: + File.separator + "classes"));
167: packed.add(new File(catalinaHome, "shared"
168: + File.separator + "lib"));
169: }
170: classLoader = ClassLoaderFactory.createClassLoader(
171: (File[]) unpacked.toArray(new File[0]),
172: (File[]) packed.toArray(new File[0]), null);
173: } catch (Throwable t) {
174: log.error("Class loader creation threw exception", t);
175: System.exit(1);
176: }
177: Thread.currentThread().setContextClassLoader(classLoader);
178:
179: // Load our application class
180: Class clazz = null;
181: String className = args[index++];
182: try {
183: if (log.isDebugEnabled())
184: log.debug("Loading application class " + className);
185: clazz = classLoader.loadClass(className);
186: } catch (Throwable t) {
187: log.error("Exception creating instance of " + className, t);
188: System.exit(1);
189: }
190:
191: // Locate the static main() method of the application class
192: Method method = null;
193: String params[] = new String[args.length - index];
194: System.arraycopy(args, index, params, 0, params.length);
195: try {
196: if (log.isDebugEnabled())
197: log.debug("Identifying main() method");
198: String methodName = "main";
199: Class paramTypes[] = new Class[1];
200: paramTypes[0] = params.getClass();
201: method = clazz.getMethod(methodName, paramTypes);
202: } catch (Throwable t) {
203: log.error("Exception locating main() method", t);
204: System.exit(1);
205: }
206:
207: // Invoke the main method of the application class
208: try {
209: if (log.isDebugEnabled())
210: log.debug("Calling main() method");
211: Object paramValues[] = new Object[1];
212: paramValues[0] = params;
213: method.invoke(null, paramValues);
214: } catch (Throwable t) {
215: log.error("Exception calling main() method", t);
216: System.exit(1);
217: }
218:
219: }
220:
221: /**
222: * Display usage information about this tool.
223: */
224: private static void usage() {
225:
226: log
227: .info("Usage: java org.apache.catalina.startup.Tool [<options>] <class> [<arguments>]");
228:
229: }
230:
231: }
|