1 /*------------------------------------------------------------------------------
2 Name: Main.java
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Main class to invoke the xmlBlaster server
6 ------------------------------------------------------------------------------*/
7 package org.xmlBlaster;
8
9 import java.io.BufferedReader;
10 import java.io.IOException;
11 import java.io.InputStreamReader;
12 import java.util.logging.Level;
13 import java.util.logging.Logger;
14
15 import org.xmlBlaster.engine.ServerScope;
16 import org.xmlBlaster.engine.runlevel.I_RunlevelListener;
17 import org.xmlBlaster.engine.runlevel.RunlevelManager;
18 import org.xmlBlaster.protocol.I_Authenticate;
19 import org.xmlBlaster.protocol.I_Driver;
20 import org.xmlBlaster.protocol.I_XmlBlaster;
21 import org.xmlBlaster.util.FileLocator;
22 import org.xmlBlaster.util.Global;
23 import org.xmlBlaster.util.I_SignalListener;
24 import org.xmlBlaster.util.I_XmlBlasterExceptionHandler;
25 import org.xmlBlaster.util.ReplaceVariable;
26 import org.xmlBlaster.util.SignalCatcher;
27 import org.xmlBlaster.util.ThreadLister;
28 import org.xmlBlaster.util.Timestamp;
29 import org.xmlBlaster.util.XmlBlasterException;
30 import org.xmlBlaster.util.admin.extern.JmxWrapper;
31 import org.xmlBlaster.util.def.ErrorCode;
32 import org.xmlBlaster.util.log.StdoutStderrRedirector;
33 import org.xmlBlaster.util.log.XbFormatter;
34 import org.xmlBlaster.util.property.Property;
35
36 /**
37 * Main class to invoke the xmlBlaster server.
38 * <p />
39 * There are many command line parameters supported
40 * please invoke with "-?" to get a complete list of the supported parameters.
41 * <br />
42 * Every parameter may be set in the xmlBlaster.property file as a system property or at the command line,
43 * the command line is strongest, xmlBlaster.properties weakest. The leading "-" from the command line key
44 * parameters are stripped (see Property.java).
45 * <p />
46 * Examples how to start the xmlBlaster server:
47 * <p />
48 * <code> java org.xmlBlaster.Main -bootstrapPort 3412</code>
49 * <p />
50 * <code> java org.xmlBlaster.Main -plugin/ior/iorFile /tmp/XmlBlaster_Ref</code>
51 * <p />
52 * <code> java org.xmlBlaster.Main -logging FINEST</code>
53 * <p />
54 * <code> java org.xmlBlaster.Main -plugin/xmlrpc/hostname 102.24.64.60 -plugin/xmlrpc/port 8081</code>
55 * <p />
56 * <code> java org.xmlBlaster.Main -?</code>
57 *
58 * @author <a href="mailto:xmlBlaster@marcelruff.info">Marcel Ruff</a>.
59 * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/admin.telnet.html" target="others">admin.telnet</a>
60 * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/util.property.html" target="others">util.property</a>
61 */
62 public class Main implements I_RunlevelListener, I_Main, I_SignalListener, I_XmlBlasterExceptionHandler
63 {
64 private String ME = "Main";
65
66 private ServerScope glob = null;
67
68 private static Logger log = Logger.getLogger(Main.class.getName());
69
70 /** Starts/stops xmlBlaster */
71 private RunlevelManager runlevelManager = null;
72
73 private boolean showUsage = false;
74
75 /** Incarnation time of this object instance in millis */
76 private long startupTime;
77
78 private boolean inShutdownProcess = false;
79 private SignalCatcher signalCatcher;
80 /**
81 * Comma separate list of errorCodes which to an immediate System.exit(1);
82 * Used by our default implementation of I_XmlBlasterExceptionHandler
83 * TODO: If you use JdbcManagerCommonTableDelegate.java you may NOT
84 * use ErrorCode.RESOURCE_DB_UNKNOWN as this will retry one time the operation!
85 * How to assure this if configured different???
86 */
87 //private String panicErrorCodes = ErrorCode.RESOURCE_DB_UNAVAILABLE.getErrorCode();
88 private String panicErrorCodes = ErrorCode.RESOURCE_DB_UNKNOWN.getErrorCode()+","+ErrorCode.RESOURCE_DB_UNAVAILABLE.getErrorCode();
89
90 /**
91 * true: If instance created by control panel<br />
92 * false: running without GUI
93 */
94 static MainGUI controlPanel = null;
95
96 private StdoutStderrRedirector stdoutStderrRedirector;
97
98 /**
99 * You need to call init() after construction.
100 * Currently used by XmlBlasterClassLoader
101 */
102 public Main() {
103 //System.out.println("Default constructor called ...");
104 }
105
106
107 public Main(ServerScope glob, MainGUI controlPanel_) {
108 controlPanel = controlPanel_;
109 controlPanel.xmlBlasterMain = this;
110 init(glob);
111 }
112
113
114 /**
115 * Start xmlBlaster using the properties from utilGlob
116 * without loading xmlBlaster.properties again
117 * @param utilGlob The environment for this server instance
118 */
119 public Main(Global utilGlob) {
120 if (utilGlob instanceof ServerScope)
121 init(utilGlob);
122 else
123 init(new ServerScope(Property.propsToArgs(utilGlob.getProperty().getProperties())));
124 }
125
126 /**
127 * Start xmlBlaster using the given properties
128 * and load xmlBlaster.properties.
129 * @param args The command line parameters
130 */
131 public Main(String[] args) {
132 // The setting 'java -DxmlBlaster/initClassName=mypackage.MyClass ...' allows to load an initial class instance
133 String initClass = System.getProperty("xmlBlaster/initClassName", "");
134 if (initClass.length() > 0) {
135 try {
136 this.getClass().getClassLoader().loadClass(initClass).newInstance();
137 } catch (Exception e) {
138 e.printStackTrace();
139 }
140 }
141 init(new ServerScope(args));
142 }
143
144 public ServerScope getGlobal() {
145 return this.glob;
146 }
147
148 /*
149 * Start xmlBlaster using the properties from utilGlob
150 * without loading <tt>xmlBlaster.properties</tt> again
151 * @param utilGlob The environment for this server instance
152 */
153 public void init(org.xmlBlaster.util.Global utilGlob) {
154 org.xmlBlaster.engine.ServerScope gg =
155 new org.xmlBlaster.engine.ServerScope(utilGlob.getProperty().getProperties(), false);
156 utilGlob.setId(gg.getId()); // Inherit backwards the cluster node id
157 init(gg);
158 }
159
160 /*
161 * Start xmlBlaster using the given properties
162 * and load <tt>xmlBlaster.properties</tt>.
163 * @param props The environment for this server instance
164 */
165 public void init(java.util.Properties props) {
166 this.init(new org.xmlBlaster.engine.ServerScope(props, true));
167 }
168
169 public final void init(ServerScope glob)
170 {
171 this.startupTime = System.currentTimeMillis();
172
173 this.glob = glob;
174
175 this.ME = "Main" + glob.getLogPrefixDashed();
176 //try { log.info(ME, glob.getDump()); } catch (Throwable e) { System.out.println(ME + ": " + e.toString()); e.printStackTrace(); }
177
178 showUsage = glob.wantsHelp();
179 Thread.currentThread().setName("XmlBlaster.MainThread");
180
181 if (glob.wantsHelp())
182 showUsage = true;
183 else if (glob.getErrorText() != null) {
184 usage();
185 log.severe(glob.getErrorText());
186 if (glob.isEmbedded())
187 throw new IllegalArgumentException(glob.getErrorText());
188 else
189 System.exit(0);
190 }
191
192 boolean redirect = glob.getProperty().get("xmlBlaster/stdoutStderrToLogging", false);
193 if (redirect) {
194 String filterSetOut = glob.getProperty().get("xmlBlaster/stdoutSuppressSet", (String)null);
195 String filterSetErr = glob.getProperty().get("xmlBlaster/stderrSuppressSet", (String)null);
196 log.info("Redirecting stdout and stderr to java.util.logging as -xmlBlaster/stdoutStderrToLogging=" + redirect + " -xmlBlaster/stdoutSuppressSet=" + filterSetOut + " -xmlBlaster/stderrSuppressSet=" + filterSetErr);
197 this.stdoutStderrRedirector = new StdoutStderrRedirector(filterSetOut, filterSetErr, ";");
198 this.stdoutStderrRedirector.redirect();
199 //System.out.println("First stdout redirect test");
200 //System.err.println("First stderr redirect test");
201 //Exception e = new Exception("First stderr exception redirect test");
202 //e.printStackTrace();
203 }
204
205 long sleepOnStartup = glob.getProperty().get("xmlBlaster/sleepOnStartup", 0L);
206 if (sleepOnStartup > 0L) {
207 log.info("Going to sleep as configured xmlBlaster/sleepOnStartup=" + sleepOnStartup);
208 try { Thread.sleep(sleepOnStartup);
209 } catch(InterruptedException e) { log.warning("Caught exception during xmlBlaster/sleepOnStartup=" + sleepOnStartup + ": " + e.toString()); }
210 }
211
212 boolean useJdbcManagerDelegate = glob.getProperty().get("xmlBlaster/useJdbcManagerDelegate", true);
213 if (useJdbcManagerDelegate) {
214 this.panicErrorCodes = ErrorCode.RESOURCE_DB_UNAVAILABLE.getErrorCode();
215 }
216 else {
217 this.panicErrorCodes = ErrorCode.RESOURCE_DB_UNKNOWN.getErrorCode()+","+ErrorCode.RESOURCE_DB_UNAVAILABLE.getErrorCode();
218 }
219
220 this.panicErrorCodes = glob.getProperty().get("xmlBlaster/panicErrorCodes", this.panicErrorCodes);
221 log.fine("Following errorCodes do an immediate exit: " + this.panicErrorCodes);
222 if (useJdbcManagerDelegate && this.panicErrorCodes.indexOf(ErrorCode.RESOURCE_DB_UNKNOWN.toString()) != -1)
223 log.severe("You can not use 'xmlBlaster/panicErrorCodes' " +
224 ErrorCode.RESOURCE_DB_UNKNOWN.toString() +
225 " with xmlBlaster/useJdbcManagerDelegate=true. This could result in DB-less operation with persistent entries handled as transient entries which are lost on restart");
226 // Add us as an I_XmlBlasterExceptionHandler ... (done again in changeRunlevel() below, but this is too late as first JDBC access can be in RL0
227 if (XmlBlasterException.getExceptionHandler() == null)
228 XmlBlasterException.setExceptionHandler(this); // see public void newException(XmlBlasterException e);
229
230 int runlevel = glob.getProperty().get("runlevel", RunlevelManager.RUNLEVEL_RUNNING);
231 try {
232 runlevelManager = glob.getRunlevelManager();
233 runlevelManager.addRunlevelListener(this);
234 runlevelManager.initPluginManagers();
235 runlevelManager.changeRunlevel(runlevel, false);
236 } catch (Throwable e) {
237 if (e instanceof XmlBlasterException) {
238 log.severe(e.getMessage());
239 }
240 else {
241 e.printStackTrace();
242 log.severe(e.toString());
243 }
244 if (glob.isEmbedded()) {
245 throw new IllegalArgumentException(e.toString());
246 }
247 else {
248 log.severe("Changing runlevel to '" + RunlevelManager.toRunlevelStr(runlevel) + "' failed, good bye");
249 System.exit(1);
250 }
251 }
252
253 boolean useKeyboard = glob.getProperty().get("useKeyboard", true);
254 if (!useKeyboard) {
255 blockThread();
256 }
257
258 // Used by testsuite to switch off blocking, this Main method is by default never returning:
259 boolean doBlocking = glob.getProperty().get("doBlocking", true);
260
261 if (doBlocking) {
262 checkForKeyboardInput();
263 }
264 }
265
266 public void blockThread() {
267 while (true) {
268 try { Thread.sleep(100000000L);
269 } catch(InterruptedException e) { log.warning("Caught exception: " + e.toString()); }
270 }
271 /*
272 // Exception in thread "main" java.lang.IllegalMonitorStateException:
273 try { Thread.currentThread().wait();
274 } catch(InterruptedException e) { log.warn(ME, "Caught exception: " + e.toString()); }
275 */
276 //orb.run();
277 }
278
279 /** Same as shutdown() but does additionally an engine.global.shutdown() */
280 public synchronized void destroy() {
281 shutdown();
282 if (this.glob != null) {
283 this.glob.shutdown();
284 this.glob = null;
285 }
286 }
287
288 /**
289 * Instructs the RunlevelManager to shut down, which causes all object adapters to shut down.
290 * <p />
291 * The drivers are removed.
292 */
293 public synchronized void shutdown()
294 {
295 if (inShutdownProcess)
296 return;
297
298 inShutdownProcess = true;
299
300 int errors = 0;
301 try {
302 errors = runlevelManager.changeRunlevel(RunlevelManager.RUNLEVEL_HALTED, true);
303 }
304 catch(XmlBlasterException e) {
305 log.severe("Problem during shutdown: " + e.toString());
306 }
307 if (errors > 0) {
308 log.warning("There were " + errors + " errors during shutdown.");
309 }
310 else {
311 if (log.isLoggable(Level.FINE)) log.fine("shutdown() done");
312 }
313 }
314
315 /**
316 * Access the authentication singleton.
317 */
318 public I_Authenticate getAuthenticate() {
319 return glob.getAuthenticate();
320 }
321
322 /**
323 * Access the xmlBlaster singleton.
324 */
325 public I_XmlBlaster getXmlBlaster() {
326 return getAuthenticate().getXmlBlaster();
327 }
328
329 /**
330 * Check for keyboard entries from console.
331 * <p />
332 * Supported input is:
333 * <ul>
334 * <li>'g' to pop up the control panel GUI</li>
335 * <li>'d' to dump the internal state of xmlBlaster</li>
336 * <li>'q' to quit xmlBlaster</li>
337 * </ul>
338 * <p />
339 * NOTE: This method never returns, only on exit for 'q'
340 */
341 private void checkForKeyboardInput() {
342 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
343 while (true) {
344 // orbacus needs this !!! Michele?
345 // if (orb.work_pending()) orb.perform_work();
346 try {
347 String line = in.readLine(); // Blocking in I/O
348 if (line == null) continue;
349 line = line.trim();
350 if (line.toLowerCase().equals("g")) {
351 if (controlPanel == null) {
352 log.info("Invoking control panel GUI ...");
353 controlPanel = new MainGUI(glob, this); // the constructor sets the variable controlPanel
354 controlPanel.run();
355 }
356 else
357 controlPanel.showWindow();
358 }
359 else if (line.toLowerCase().equals("gc")) {
360 long totalMem = Runtime.getRuntime().totalMemory();
361 long freeMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
362 System.gc();
363 log.info("Garbage collector has run, total/free bytes before="+totalMem+"/"+freeMem+", after="+Runtime.getRuntime().totalMemory()+"/"+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
364 }
365 else if (line.toLowerCase().startsWith("r")) {
366 if (line.length() > 1) {
367 String tmp = line.substring(1).trim();
368 int runlevel = -10;
369 try { runlevel = Integer.parseInt(tmp.trim()); } catch(NumberFormatException e) { log.severe("Invalid run level '" + tmp + "', it should be a number."); };
370 try { runlevelManager.changeRunlevel(runlevel, true); } catch(XmlBlasterException e) { log.severe(e.toString()); }
371 }
372 else
373 log.info("Current runlevel is " + RunlevelManager.toRunlevelStr(runlevelManager.getCurrentRunlevel()) + "=" + runlevelManager.getCurrentRunlevel() + "");
374 }
375 else if (line.toLowerCase().startsWith("j")) {
376 if (line.length() > 1) {
377 // ObjectName = org.xmlBlaster:nodeClass=node,node="heron"
378 // j org.xmlBlaster:nodeClass=node,node="heron"/action=getFreeMemStr
379 // j org.xmlBlaster:nodeClass=node,node="heron"/action=usage?action=usage
380
381 // java -Djmx.invoke.getters=set ... org.xmlBlaster.Main
382 // j org.xmlBlaster:nodeClass=node,node="heron"/action=getLastWarning?action=getLastWarning
383 // j org.xmlBlaster:nodeClass=node,node="heron"/action=getLastWarning
384 // j org.xmlBlaster:nodeClass=node,node="avalon_mycomp_com",clientClass=client,client="heron.mycomp.com",sessionClass=session,session="1"/action=getConnectionState
385 String tmp = line.substring(1).trim();
386 try {
387 System.out.println("Invoking: " + tmp);
388 Object obj = JmxWrapper.getInstance(this.glob).invokeCommand(tmp);
389 if (obj instanceof String[]) {
390 String[] str = (String[])obj;
391 for(int i=0; i<str.length; i++)
392 System.out.println(str[i]);
393 }
394 else {
395 System.out.println(obj);
396 }
397 } catch(XmlBlasterException e) { log.severe(e.toString()); }
398 }
399 else
400 log.info("Please pass a JMX object name to query");
401 }
402 else if (line.toLowerCase().startsWith("d")) {
403 try {
404 String fileName = null;
405 if (line.length() > 1) fileName = line.substring(1).trim();
406
407 if (fileName == null) {
408 System.out.println(glob.getDump());
409 log.info("Dump done");
410 }
411 else {
412 FileLocator.writeFile(fileName, glob.getDump());
413 log.info("Dumped internal state to '" + fileName + "'");
414 }
415 }
416 catch(XmlBlasterException e) {
417 log.severe("Sorry, dump failed: " + e.getMessage());
418 }
419 catch(Throwable e) {
420 log.severe("Sorry, dump failed: " + e.toString());
421 }
422 }
423 else if (line.toLowerCase().equals("q")) {
424 shutdown();
425 if (glob == null || !glob.isEmbedded())
426 System.exit(0);
427 }
428 else // if (keyChar == '?' || Character.isLetter(keyChar) || Character.isDigit(keyChar))
429 keyboardUsage();
430 }
431 catch (IOException e) {
432 log.warning(e.toString() + " Keyboard input is disabled, we block this thread now");
433 break;
434 }
435 }
436 blockThread();
437 }
438
439 public boolean isHalted() {
440 if( runlevelManager != null )
441 return runlevelManager.isHalted();
442 else return true;
443 }
444
445 /**
446 * A human readable name of the listener for logging.
447 * <p />
448 * Enforced by I_RunlevelListener
449 */
450 public String getName() {
451 return ME;
452 }
453
454 /**
455 * Invoked on run level change, see RunlevelManager.RUNLEVEL_HALTED and RunlevelManager.RUNLEVEL_RUNNING
456 * <p />
457 * Enforced by I_RunlevelListener
458 * @see org.xmlBlaster.engine.runlevel.I_RunlevelListener#runlevelChange(int, int, boolean)
459 */
460 public void runlevelChange(int from, int to, boolean force) throws XmlBlasterException {
461 //if (log.isLoggable(Level.FINER)) log.call(ME, "Changing from run level=" + from + " to level=" + to + " with force=" + force);
462 if (to == from)
463 return;
464
465 if (to > from) { // startup
466 //if (to == RunlevelManager.RUNLEVEL_HALTED) {
467 // log.error(ME, "DEBUG ONLY ........");
468 // if (glob.getNodeId() == null)
469 // glob.setUniqueNodeIdName(createNodeId());
470 //}
471 if (to == RunlevelManager.RUNLEVEL_HALTED_POST) {
472 this.startupTime = System.currentTimeMillis();
473 boolean useSignalCatcher = glob.getProperty().get("useSignalCatcher", true);
474 if (useSignalCatcher) {
475 try {
476 this.signalCatcher = SignalCatcher.instance();
477 this.signalCatcher.register(this);
478 this.signalCatcher.catchSignals();
479 }
480 catch (Throwable e) {
481 log.warning("Can't register signal catcher: " + e.toString());
482 }
483 }
484 // Add us as an I_XmlBlasterExceptionHandler ...
485 if (XmlBlasterException.getExceptionHandler() == null)
486 XmlBlasterException.setExceptionHandler(this); // see public void newException(XmlBlasterException e);
487 }
488 if (to == RunlevelManager.RUNLEVEL_STANDBY) {
489 }
490 if (to == RunlevelManager.RUNLEVEL_STANDBY_POST) {
491 if (showUsage) {
492 usage(); // Now we can display the complete usage of all loaded drivers
493 shutdown();
494 if (!glob.isEmbedded())
495 System.exit(0);
496 }
497 }
498 if (to == RunlevelManager.RUNLEVEL_CLEANUP) {
499 }
500 if (to == RunlevelManager.RUNLEVEL_RUNNING) {
501 }
502 if (to == RunlevelManager.RUNLEVEL_RUNNING_POST) {
503 log.info(Global.getMemoryStatistic());
504 String duration = Timestamp.millisToNice(System.currentTimeMillis() - this.startupTime);
505 // TEST
506 //new XmlBlasterException(this.glob, ErrorCode.RESOURCE_DB_UNAVAILABLE, ME + ".getXBStore", "", null);
507 if (controlPanel == null) {
508 if (XbFormatter.withXtermColors()) System.out.println(XbFormatter.BLACK_GREEN);
509 final String bound = "|";
510 String ver = bound + " XmlBlaster cluster node <" + glob.getId() + "> v" + glob.getReleaseId() + " " + glob.getBuildTimestamp();
511 int width = ver.length() + 6;
512 if (width < 48) width = 48;
513 ReplaceVariable sh = new ReplaceVariable();
514 String line = sh.charChain('-', width-2);
515 System.out.println("");
516 System.out.println(" "+line+" ");
517 System.out.println(ver + sh.charChain(' ', width-ver.length()-1) + bound);
518 boolean useKeyboard = glob.getProperty().get("useKeyboard", true);
519 if (useKeyboard) {
520 String help = bound + " READY " + duration + " - press <enter> for options";
521 System.out.println(help + sh.charChain(' ', width-help.length()-1) + bound);
522 } else {
523 String help = bound + " READY " + duration + " - no keyboard input available";
524 System.out.println(help + sh.charChain(' ', width-help.length()-1) + bound);
525 }
526 System.out.println(" "+line+" ");
527 if (XbFormatter.withXtermColors()) System.out.println(XbFormatter.ESC);
528 }
529 else
530 log.info("xmlBlaster is ready for requests " + duration);
531 }
532 }
533 if (to <= from) { // shutdown
534 if (to == RunlevelManager.RUNLEVEL_RUNNING_PRE) {
535 if (log.isLoggable(Level.FINE)) log.fine("Shutting down xmlBlaster to runlevel " + RunlevelManager.toRunlevelStr(to) + " ...");
536 }
537 if (to == RunlevelManager.RUNLEVEL_HALTED_PRE) {
538 synchronized (this) {
539 if (this.glob != null) {
540 this.glob.shutdown();
541 }
542 }
543 log.info("XmlBlaster halted.");
544 }
545
546 if (to == RunlevelManager.RUNLEVEL_HALTED) {
547 synchronized (this) {
548 if (this.signalCatcher != null) {
549 this.signalCatcher.removeSignalCatcher();
550 this.signalCatcher = null;
551 }
552 }
553 }
554 }
555 }
556
557 public void newException(XmlBlasterException e) {
558 boolean serverScope = (e.getGlobal() != null && e.getGlobal().getObjectEntry("org.xmlBlaster.engine.Global") != null);
559 if (!e.isServerSide() && !serverScope) // isServerSide checks if we are ServerScope implementation, serverScope checks if we are a util.Global in the context of a server
560 return;
561 // Typically if the DB is lost: ErrorCode.RESOURCE_DB_UNKNOWN
562 if (this.panicErrorCodes.indexOf(e.getErrorCodeStr()) != -1) {
563 log.severe("PANIC: Doing immediate shutdown caused by exception: " + e.getMessage());
564 e.printStackTrace();
565 log.severe(Global.getStackTraceAsString(e));
566 log.severe("Complete stack trace (all threads at the time of shutdown: " + ThreadLister.getAllStackTraces());
567 SignalCatcher sc = this.signalCatcher;
568 if (sc != null) {
569 sc.removeSignalCatcher();
570 }
571 System.exit(1);
572 }
573 }
574
575 /**
576 * You will be notified when the runtime exits.
577 * @see I_SignalListener#shutdownHook()
578 */
579 public void shutdownHook() {
580 destroy();
581 }
582
583 /**
584 * Keyboard input usage.
585 */
586 private void keyboardUsage() {
587 if (XbFormatter.withXtermColors()) System.out.println(XbFormatter.BLACK_LTGREEN);
588 System.out.println("");
589 System.out.println("----------------------------------------------------------");
590 System.out.println("XmlBlaster " + ((glob != null) ? glob.getVersion() : "") +
591 ((glob != null) ? (" build " + glob.getBuildTimestamp()) : ""));
592 System.out.println("Following interactive keyboard input is recognized:");
593 System.out.println("Key:");
594 System.out.println(" g Popup the control panel GUI.");
595 System.out.println(" r <run level> Change to run level (0,3,6,9).");
596 try {
597 if (JmxWrapper.getInstance(this.glob).isActivated())
598 System.out.println(" j <JMX call> For example 'j org.xmlBlaster:nodeClass=node,node=\""+this.glob.getStrippedId()+"\"/action=getFreeMemStr'");
599 } catch (XmlBlasterException e) {
600 e.printStackTrace();
601 }
602 System.out.println(" d <file name> Dump internal state of xmlBlaster to file.");
603 System.out.println(" q Quit xmlBlaster.");
604 System.out.println("----------------------------------------------------------");
605 if (XbFormatter.withXtermColors()) System.out.println(XbFormatter.ESC);
606 }
607
608 /**
609 * Command line usage.
610 */
611 private void usage() {
612 System.out.println("-----------------------" + glob.getVersion() + "-------------------------------");
613 System.out.println("java org.xmlBlaster.Main <options>");
614 System.out.println("----------------------------------------------------------");
615 System.out.println(" -h Show the complete usage.");
616 System.out.println("");
617 // try { System.out.println(glob.getProtocolManager().usage()); } catch (XmlBlasterException e) { log.warn(ME, "No usage: " + e.toString()); }
618 // Depending on the current run level not all drivers may be visible:
619 I_Driver[] drivers = glob.getPluginRegistry().getPluginsOfInterfaceI_Driver(); // getPluginsOfGroup("protocol");
620 for (int i=0; i < drivers.length; i++)
621 System.out.println(drivers[i].usage());
622
623 System.out.println("");
624 System.out.println(org.xmlBlaster.engine.cluster.ClusterManager.staticUsage());
625 System.out.println("");
626 System.out.println(glob.usage());
627 System.out.println("");
628 System.out.println("Other stuff:");
629 System.out.println(" -xmlBlaster/acceptWrongSenderAddress/<subjectId> <subjectId> is for example 'joe' [false]");
630 System.out.println(" true: Allows user 'joe' to send wrong sender address in PublishQos");
631 System.out.println(" -xmlBlaster/sleepOnStartup Number of milli seconds to sleep before startup [0]");
632 System.out.println(" -useKeyboard false Switch off keyboard input, to allow xmlBlaster running in background [true]");
633 System.out.println(" -doBlocking false Switch off blocking, the main method is by default never returning [true]");
634 System.out.println(" -admin.remoteconsole.port If port > 1000 a server is started which is available with telnet [2702]");
635 System.out.println(" -xmlBlaster.isEmbedded If set to true no System.exit() is possible [false]");
636 System.out.println(" -wipeOutJdbcDB true Destroy the complete JDBC persistence store entries of prefix=XMLBLASTER (DANGER)");
637 System.out.println(" -xmlBlaster/jmx/HtmlAdaptor Set to true to enable JMX HTTP access on 'http://localhost:8082' [false]");
638 System.out.println(" -xmlBlaster/jmx/XmlBlasterAdaptor Set to true to enable JMX xmlBlaster adaptor access for swing GUI 'org.xmlBlaster.jmxgui.Main' [false].");
639 System.out.println(" java -Dcom.sun.management.jmxremote ... Switch on JMX support with jconsole (JDK >= 1.5).");
640 System.out.println(" -xmlBlaster/jmx/observeLowMemory Write a log error when 90% of the JVM memory is used (JDK >= 1.5) [true]");
641 System.out.println(" -xmlBlaster/jmx/memoryThresholdFactor Configure the log error memory threshhold (defaults to 90%) (JDK >= 1.5) [0.9]");
642 System.out.println(" -xmlBlaster/jmx/exitOnMemoryThreshold If true xmlBlaster stops if the memoryThresholdFactor is reached (JDK >= 1.5) [false]");
643 System.out.println("----------------------------------------------------------");
644 System.out.println("Example:");
645 System.out.println(" java org.xmlBlaster.Main -cluster false");
646 System.out.println(" java org.xmlBlaster.Main -cluster.node.id heron");
647 System.out.println(" java org.xmlBlaster.Main -propertyFile somewhere/xmlBlaster.properties -pluginsFile somewhere/plugins.xml");
648 System.out.println(" java org.xmlBlaster.Main -bootstrapPort 3412");
649 System.out.println(" java org.xmlBlaster.Main -plugin/ior/iorFile /tmp/XmlBlaster_Ref.ior");
650 System.out.println(" java org.xmlBlaster.Main -logging/org.xmlBlaster.engine FINE");
651 System.out.println(" java org.xmlBlaster.Main -logging/org.xmlBlaster.util.protocol.RequestReplyExecutor FINEST (dumps SOCKET messages)");
652 System.out.println(" java org.xmlBlaster.Main -plugin/xmlrpc/hostname 102.24.64.60 -plugin/xmlrpc/port 8081");
653 System.out.println(" java -Dcom.sun.management.jmxremote org.xmlBlaster.Main");
654 System.out.println(" java -Djava.util.logging.config.file=config/logging.properties org.xmlBlaster.Main");
655 System.out.println(" java org.xmlBlaster.Main -?");
656 System.out.println("See xmlBlaster.properties for more options");
657 System.out.println("");
658 }
659
660
661 /**
662 * Invoke: java org.xmlBlaster.Main
663 */
664 public static void main( String[] args )
665 {
666 new Main(args);
667 }
668 }
syntax highlighted by Code2HTML, v. 0.9.1