1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.catalina.startup;
20
21
22 import java.io.File;
23 import java.lang.reflect.Method;
24 import java.util.ArrayList;
25
26 import org.apache.juli.logging.Log;
27 import org.apache.juli.logging.LogFactory;
28
29
30 /**
31 * <p>General purpose wrapper for command line tools that should execute in an
32 * environment with the common class loader environment set up by Catalina.
33 * This should be executed from a command line script that conforms to
34 * the following requirements:</p>
35 * <ul>
36 * <li>Passes the <code>catalina.home</code> system property configured with
37 * the pathname of the Tomcat installation directory.</li>
38 * <li>Sets the system classpath to include <code>bootstrap.jar</code> and
39 * <code>$JAVA_HOME/lib/tools.jar</code>.</li>
40 * </ul>
41 *
42 * <p>The command line to execute the tool looks like:</p>
43 * <pre>
44 * java -classpath $CLASSPATH org.apache.catalina.startup.Tool \
45 * ${options} ${classname} ${arguments}
46 * </pre>
47 *
48 * <p>with the following replacement contents:
49 * <ul>
50 * <li><strong>${options}</strong> - Command line options for this Tool wrapper.
51 * The following options are supported:
52 * <ul>
53 * <li><em>-ant</em> : Set the <code>ant.home</code> system property
54 * to corresponding to the value of <code>catalina.home</code>
55 * (useful when your command line tool runs Ant).</li>
56 * <li><em>-common</em> : Add <code>common/classes</code> and
57 * <code>common/lib</codE) to the class loader repositories.</li>
58 * <li><em>-server</em> : Add <code>server/classes</code> and
59 * <code>server/lib</code> to the class loader repositories.</li>
60 * <li><em>-shared</em> : Add <code>shared/classes</code> and
61 * <code>shared/lib</code> to the class loader repositories.</li>
62 * </ul>
63 * <li><strong>${classname}</strong> - Fully qualified Java class name of the
64 * application's main class.</li>
65 * <li><strong>${arguments}</strong> - Command line arguments to be passed to
66 * the application's <code>main()</code> method.</li>
67 * </ul>
68 *
69 * @author Craig R. McClanahan
70 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
71 */
72
73 public final class Tool {
74
75
76 private static Log log = LogFactory.getLog(Tool.class);
77
78 // ------------------------------------------------------- Static Variables
79
80
81 /**
82 * Set <code>ant.home</code> system property?
83 */
84 private static boolean ant = false;
85
86
87 /**
88 * The pathname of our installation base directory.
89 */
90 private static String catalinaHome = System.getProperty("catalina.home");
91
92
93 /**
94 * Include common classes in the repositories?
95 */
96 private static boolean common = false;
97
98
99 /**
100 * Include server classes in the repositories?
101 */
102 private static boolean server = false;
103
104
105 /**
106 * Include shared classes in the repositories?
107 */
108 private static boolean shared = false;
109
110
111 // ----------------------------------------------------------- Main Program
112
113
114 /**
115 * The main program for the bootstrap.
116 *
117 * @param args Command line arguments to be processed
118 */
119 public static void main(String args[]) {
120
121 // Verify that "catalina.home" was passed.
122 if (catalinaHome == null) {
123 log.error("Must set 'catalina.home' system property");
124 System.exit(1);
125 }
126
127 // Process command line options
128 int index = 0;
129 while (true) {
130 if (index == args.length) {
131 usage();
132 System.exit(1);
133 }
134 if ("-ant".equals(args[index]))
135 ant = true;
136 else if ("-common".equals(args[index]))
137 common = true;
138 else if ("-server".equals(args[index]))
139 server = true;
140 else if ("-shared".equals(args[index]))
141 shared = true;
142 else
143 break;
144 index++;
145 }
146 if (index > args.length) {
147 usage();
148 System.exit(1);
149 }
150
151 // Set "ant.home" if requested
152 if (ant)
153 System.setProperty("ant.home", catalinaHome);
154
155 // Construct the class loader we will be using
156 ClassLoader classLoader = null;
157 try {
158 ArrayList packed = new ArrayList();
159 ArrayList unpacked = new ArrayList();
160 unpacked.add(new File(catalinaHome, "classes"));
161 packed.add(new File(catalinaHome, "lib"));
162 if (common) {
163 unpacked.add(new File(catalinaHome,
164 "common" + File.separator + "classes"));
165 packed.add(new File(catalinaHome,
166 "common" + File.separator + "lib"));
167 }
168 if (server) {
169 unpacked.add(new File(catalinaHome,
170 "server" + File.separator + "classes"));
171 packed.add(new File(catalinaHome,
172 "server" + File.separator + "lib"));
173 }
174 if (shared) {
175 unpacked.add(new File(catalinaHome,
176 "shared" + File.separator + "classes"));
177 packed.add(new File(catalinaHome,
178 "shared" + File.separator + "lib"));
179 }
180 classLoader =
181 ClassLoaderFactory.createClassLoader
182 ((File[]) unpacked.toArray(new File[0]),
183 (File[]) packed.toArray(new File[0]),
184 null);
185 } catch (Throwable t) {
186 log.error("Class loader creation threw exception", t);
187 System.exit(1);
188 }
189 Thread.currentThread().setContextClassLoader(classLoader);
190
191 // Load our application class
192 Class clazz = null;
193 String className = args[index++];
194 try {
195 if (log.isDebugEnabled())
196 log.debug("Loading application class " + className);
197 clazz = classLoader.loadClass(className);
198 } catch (Throwable t) {
199 log.error("Exception creating instance of " + className, t);
200 System.exit(1);
201 }
202
203 // Locate the static main() method of the application class
204 Method method = null;
205 String params[] = new String[args.length - index];
206 System.arraycopy(args, index, params, 0, params.length);
207 try {
208 if (log.isDebugEnabled())
209 log.debug("Identifying main() method");
210 String methodName = "main";
211 Class paramTypes[] = new Class[1];
212 paramTypes[0] = params.getClass();
213 method = clazz.getMethod(methodName, paramTypes);
214 } catch (Throwable t) {
215 log.error("Exception locating main() method", t);
216 System.exit(1);
217 }
218
219 // Invoke the main method of the application class
220 try {
221 if (log.isDebugEnabled())
222 log.debug("Calling main() method");
223 Object paramValues[] = new Object[1];
224 paramValues[0] = params;
225 method.invoke(null, paramValues);
226 } catch (Throwable t) {
227 log.error("Exception calling main() method", t);
228 System.exit(1);
229 }
230
231 }
232
233
234 /**
235 * Display usage information about this tool.
236 */
237 private static void usage() {
238
239 log.info("Usage: java org.apache.catalina.startup.Tool [<options>] <class> [<arguments>]");
240
241 }
242
243
244 }