001: package com.caucho.boot;
002:
003: import com.caucho.Version;
004: import com.caucho.config.ConfigException;
005: import com.caucho.server.resin.ResinELContext;
006: import com.caucho.util.L10N;
007: import com.caucho.vfs.Path;
008: import com.caucho.vfs.Vfs;
009:
010: import javax.management.MBeanServer;
011: import javax.management.ObjectName;
012: import java.io.File;
013: import java.io.IOException;
014: import java.lang.management.ManagementFactory;
015: import java.net.URL;
016: import java.util.ArrayList;
017: import java.util.logging.Level;
018: import java.util.logging.Logger;
019:
020: class WatchdogArgs {
021: private static L10N _L;
022:
023: private Path _javaHome;
024: private Path _resinHome;
025: private Path _rootDirectory;
026: private String[] _argv;
027: private Path _resinConf;
028: private Path _logDirectory;
029: private String _serverId = "";
030: private int _watchdogPort;
031: private boolean _isVerbose;
032: private StartMode _startMode = StartMode.DIRECT;
033:
034: WatchdogArgs(String[] argv) {
035: super ();
036:
037: _resinHome = calculateResinHome();
038: _rootDirectory = calculateResinRoot(_resinHome);
039:
040: _javaHome = Vfs.lookup(System.getProperty("java.home"));
041:
042: _argv = fillArgv(argv);
043:
044: _resinConf = _resinHome.lookup("conf/resin.conf");
045:
046: parseCommandLine(argv);
047: }
048:
049: Path getJavaHome() {
050: return _javaHome;
051: }
052:
053: Path getResinHome() {
054: return _resinHome;
055: }
056:
057: Path getRootDirectory() {
058: return _rootDirectory;
059: }
060:
061: Path getLogDirectory() {
062: return _logDirectory;
063: }
064:
065: Path getResinConf() {
066: return _resinConf;
067: }
068:
069: String getServerId() {
070: return _serverId;
071: }
072:
073: String[] getArgv() {
074: return _argv;
075: }
076:
077: boolean isVerbose() {
078: return _isVerbose;
079: }
080:
081: void setWatchdogPort(int port) {
082: _watchdogPort = port;
083: }
084:
085: int getWatchdogPort() {
086: return _watchdogPort;
087: }
088:
089: void setResinHome(Path resinHome) {
090: _resinHome = resinHome;
091: }
092:
093: boolean isStatus() {
094: return _startMode == StartMode.STATUS;
095: }
096:
097: boolean isStart() {
098: return _startMode == StartMode.START;
099: }
100:
101: boolean isStop() {
102: return _startMode == StartMode.STOP;
103: }
104:
105: boolean isRestart() {
106: return _startMode == StartMode.RESTART;
107: }
108:
109: boolean isKill() {
110: return _startMode == StartMode.KILL;
111: }
112:
113: boolean isShutdown() {
114: return _startMode == StartMode.SHUTDOWN;
115: }
116:
117: boolean isSingle() {
118: return _startMode == StartMode.DIRECT;
119: }
120:
121: public ResinELContext getELContext() {
122: return new ResinBootELContext();
123: }
124:
125: private void parseCommandLine(String[] argv) {
126: String resinConf = null;
127:
128: for (int i = 0; i < argv.length; i++) {
129: String arg = argv[i];
130:
131: if ("-conf".equals(arg) || "--conf".equals(arg)) {
132: resinConf = argv[i + 1];
133: i++;
134: } else if ("-fine".equals(arg) || "--fine".equals(arg)) {
135: _isVerbose = true;
136: Logger.getLogger("").setLevel(Level.FINE);
137: } else if ("-finer".equals(arg) || "--finer".equals(arg)) {
138: _isVerbose = true;
139: Logger.getLogger("").setLevel(Level.FINER);
140: } else if ("-log-directory".equals(arg)
141: || "--log-directory".equals(arg)) {
142: _logDirectory = _rootDirectory.lookup(argv[i + 1]);
143: i++;
144: } else if ("-resin-home".equals(arg)
145: || "--resin-home".equals(arg)) {
146: _resinHome = Vfs.lookup(argv[i + 1]);
147: i++;
148: } else if ("-root-directory".equals(arg)
149: || "--root-directory".equals(arg)) {
150: _rootDirectory = Vfs.lookup(argv[i + 1]);
151: i++;
152: } else if ("-server".equals(arg) || "--server".equals(arg)) {
153: _serverId = argv[i + 1];
154: i++;
155: } else if ("-server-root".equals(arg)
156: || "--server-root".equals(arg)) {
157: _rootDirectory = Vfs.lookup(argv[i + 1]);
158: i++;
159: } else if ("-watchdog-port".equals(arg)
160: || "--watchdog-port".equals(arg)) {
161: _watchdogPort = Integer.parseInt(argv[i + 1]);
162: i++;
163: } else if (arg.startsWith("-J") || arg.startsWith("-D")
164: || arg.startsWith("-X")) {
165: } else if ("-verbose".equals(arg)
166: || "--verbose".equals(arg)) {
167: _isVerbose = true;
168: Logger.getLogger("").setLevel(Level.CONFIG);
169: } else if ("status".equals(arg)) {
170: _startMode = StartMode.STATUS;
171: } else if ("start".equals(arg)) {
172: _startMode = StartMode.START;
173: } else if ("stop".equals(arg)) {
174: _startMode = StartMode.STOP;
175: } else if ("kill".equals(arg)) {
176: _startMode = StartMode.KILL;
177: } else if ("restart".equals(arg)) {
178: _startMode = StartMode.RESTART;
179: } else if ("shutdown".equals(arg)) {
180: _startMode = StartMode.SHUTDOWN;
181: } else {
182: System.out.println(L().l("unknown argument '{0}'",
183: argv[i]));
184: System.out.println();
185: usage();
186: System.exit(1);
187: }
188: }
189:
190: if (resinConf != null) {
191: _resinConf = Vfs.getPwd().lookup(resinConf);
192:
193: if (!_resinConf.exists() && _rootDirectory != null)
194: _resinConf = _rootDirectory.lookup(resinConf);
195:
196: if (!_resinConf.exists() && _resinHome != null)
197: _resinConf = _resinHome.lookup(resinConf);
198:
199: if (!_resinConf.exists())
200: throw new ConfigException(
201: L()
202: .l(
203: "Resin/{0} can't find configuration file '{1}'",
204: Version.VERSION,
205: _resinConf.getNativePath()));
206: }
207: }
208:
209: private static void usage() {
210: System.err
211: .println(L()
212: .l(
213: "usage: java -jar resin.jar [-options] [status | start | stop | restart | kill | shutdown]"));
214: System.err.println(L().l(""));
215: System.err.println(L().l("where options include:"));
216: System.err
217: .println(L()
218: .l(
219: " -conf <file> : select a configuration file"));
220: System.err
221: .println(L()
222: .l(
223: " -log-directory <dir> : select a logging directory"));
224: System.err
225: .println(L()
226: .l(
227: " -resin-home <dir> : select a resin home directory"));
228: System.err.println(L().l(
229: " -root-directory <dir> : select a root directory"));
230: System.err.println(L().l(
231: " -server <id> : select a <server> to run"));
232: System.err
233: .println(L()
234: .l(
235: " -watchdog-port <port> : override the watchdog-port"));
236: System.err
237: .println(L()
238: .l(
239: " -verbose : print verbose starting information"));
240: }
241:
242: private String[] fillArgv(String[] argv) {
243: ArrayList<String> args = new ArrayList<String>();
244:
245: try {
246: MBeanServer mbeanServer = ManagementFactory
247: .getPlatformMBeanServer();
248: ObjectName name = new ObjectName("java.lang:type=Runtime");
249:
250: String[] jvmArgs = (String[]) mbeanServer.getAttribute(
251: name, "InputArguments");
252:
253: if (jvmArgs != null) {
254: for (int i = 0; i < jvmArgs.length; i++) {
255: String arg = jvmArgs[i];
256:
257: if (args.contains(arg))
258: continue;
259:
260: if (arg.startsWith("-Djava.class.path=")) {
261: // IBM JDK
262: } else if (arg.startsWith("-D"))
263: args.add("-J" + arg);
264: }
265: }
266: } catch (Exception e) {
267: e.printStackTrace();
268: }
269:
270: for (int i = 0; i < argv.length; i++)
271: args.add(argv[i]);
272:
273: argv = new String[args.size()];
274:
275: args.toArray(argv);
276:
277: return argv;
278: }
279:
280: private static L10N L() {
281: if (_L == null)
282: _L = new L10N(WatchdogArgs.class);
283:
284: return _L;
285: }
286:
287: //
288: // Utility static methods
289: //
290:
291: static Path calculateResinHome() {
292: String resinHome = System.getProperty("resin.home");
293:
294: if (resinHome != null) {
295: return Vfs.lookup(resinHome);
296: }
297:
298: // find the resin.jar as described by the classpath
299: // this may differ from the value given by getURL() because of
300: // symbolic links
301: String classPath = System.getProperty("java.class.path");
302:
303: if (classPath.indexOf("resin.jar") >= 0) {
304: int q = classPath.indexOf("resin.jar")
305: + "resin.jar".length();
306: int p = classPath
307: .lastIndexOf(File.pathSeparatorChar, q - 1);
308:
309: String resinJar;
310:
311: if (p >= 0)
312: resinJar = classPath.substring(p + 1, q);
313: else
314: resinJar = classPath.substring(0, q);
315:
316: return Vfs.lookup(resinJar).lookup("../..");
317: }
318:
319: ClassLoader loader = ClassLoader.getSystemClassLoader();
320:
321: URL url = loader.getResource("com/caucho/boot/ResinBoot.class");
322:
323: String path = url.toString();
324:
325: if (!path.startsWith("jar:"))
326: throw new RuntimeException(L().l(
327: "Resin/{0}: can't find jar for ResinBoot in {1}",
328: Version.VERSION, path));
329:
330: int p = path.indexOf(':');
331: int q = path.indexOf('!');
332:
333: path = path.substring(p + 1, q);
334:
335: Path pwd = Vfs.lookup(path).getParent().getParent();
336:
337: return pwd;
338: }
339:
340: static Path calculateResinRoot(Path resinHome) {
341: String serverRoot = System.getProperty("server.root");
342:
343: if (serverRoot != null)
344: return Vfs.lookup(serverRoot);
345:
346: return resinHome;
347: }
348:
349: static String calculateClassPath(Path resinHome) throws IOException {
350: ArrayList<String> classPath = new ArrayList<String>();
351:
352: Path javaHome = Vfs.lookup(System.getProperty("java.home"));
353:
354: if (javaHome.lookup("lib/tools.jar").canRead())
355: classPath.add(javaHome.lookup("lib/tools.jar")
356: .getNativePath());
357: else if (javaHome.getTail().startsWith("jre")) {
358: String tail = javaHome.getTail();
359: tail = "jdk" + tail.substring(3);
360: Path jdkHome = javaHome.getParent().lookup(tail);
361:
362: if (jdkHome.lookup("lib/tools.jar").canRead())
363: classPath.add(jdkHome.lookup("lib/tools.jar")
364: .getNativePath());
365: }
366:
367: if (javaHome.lookup("../lib/tools.jar").canRead())
368: classPath.add(javaHome.lookup("../lib/tools.jar")
369: .getNativePath());
370:
371: Path resinLib = resinHome.lookup("lib");
372:
373: if (resinLib.lookup("pro.jar").canRead())
374: classPath.add(resinLib.lookup("pro.jar").getNativePath());
375: classPath.add(resinLib.lookup("resin.jar").getNativePath());
376: classPath.add(resinLib.lookup("jaxrpc-15.jar").getNativePath());
377:
378: String[] list = resinLib.list();
379:
380: for (int i = 0; i < list.length; i++) {
381: if (!list[i].endsWith(".jar"))
382: continue;
383:
384: Path item = resinLib.lookup(list[i]);
385:
386: String pathName = item.getNativePath();
387:
388: if (!classPath.contains(pathName))
389: classPath.add(pathName);
390: }
391:
392: String cp = "";
393:
394: for (int i = 0; i < classPath.size(); i++) {
395: if (!"".equals(cp))
396: cp += File.pathSeparatorChar;
397:
398: cp += classPath.get(i);
399: }
400:
401: return cp;
402: }
403:
404: public class ResinBootELContext extends ResinELContext {
405: public Path getResinHome() {
406: return WatchdogArgs.this .getResinHome();
407: }
408:
409: public Path getRootDirectory() {
410: return WatchdogArgs.this .getRootDirectory();
411: }
412:
413: public Path getResinConf() {
414: return WatchdogArgs.this .getResinConf();
415: }
416:
417: public String getServerId() {
418: return WatchdogArgs.this .getServerId();
419: }
420:
421: public boolean isResinProfessional() {
422: return false;
423: }
424: }
425:
426: enum StartMode {
427: STATUS, DIRECT, START, STOP, KILL, RESTART, SHUTDOWN
428: };
429: }
|