001: package org.tanukisoftware.wrapper.test;
002:
003: /*
004: * Copyright (c) 1999, 2006 Tanuki Software Inc.
005: *
006: * Permission is hereby granted, free of charge, to any person
007: * obtaining a copy of the Java Service Wrapper and associated
008: * documentation files (the "Software"), to deal in the Software
009: * without restriction, including without limitation the rights
010: * to use, copy, modify, merge, publish, distribute, sub-license,
011: * and/or sell copies of the Software, and to permit persons to
012: * whom the Software is furnished to do so, subject to the
013: * following conditions:
014: *
015: * The above copyright notice and this permission notice shall be
016: * included in all copies or substantial portions of the Software.
017: *
018: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
019: * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
020: * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
021: * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
022: * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
023: * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
024: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
025: * OTHER DEALINGS IN THE SOFTWARE.
026: *
027: *
028: * Portions of the Software have been derived from source code
029: * developed by Silver Egg Technology under the following license:
030: *
031: * Copyright (c) 2001 Silver Egg Technology
032: *
033: * Permission is hereby granted, free of charge, to any person
034: * obtaining a copy of this software and associated documentation
035: * files (the "Software"), to deal in the Software without
036: * restriction, including without limitation the rights to use,
037: * copy, modify, merge, publish, distribute, sub-license, and/or
038: * sell copies of the Software, and to permit persons to whom the
039: * Software is furnished to do so, subject to the following
040: * conditions:
041: *
042: * The above copyright notice and this permission notice shall be
043: * included in all copies or substantial portions of the Software.
044: */
045:
046: import java.awt.BorderLayout;
047: import java.awt.Button;
048: import java.awt.Component;
049: import java.awt.Container;
050: import java.awt.Frame;
051: import java.awt.GridBagConstraints;
052: import java.awt.GridBagLayout;
053: import java.awt.Label;
054: import java.awt.List;
055: import java.awt.Panel;
056: import java.awt.ScrollPane;
057: import java.awt.TextField;
058: import java.awt.event.ActionEvent;
059: import java.awt.event.ActionListener;
060:
061: import org.tanukisoftware.wrapper.WrapperActionServer;
062: import org.tanukisoftware.wrapper.WrapperManager;
063: import org.tanukisoftware.wrapper.WrapperListener;
064: import org.tanukisoftware.wrapper.event.WrapperEventListener;
065:
066: /**
067: * This is a Test / Example program which can be used to test the
068: * main features of the Wrapper.
069: * <p>
070: * It is also an example of Integration Method #3, where you implement
071: * the WrapperListener interface manually.
072: * <p>
073: * <b>NOTE</b> that in most cases you will want to use Method #1, using the
074: * WrapperSimpleApp helper class to integrate your application. Please
075: * see the <a href="http://wrapper.tanukisoftware.org/doc/english/integrate.html">integration</a>
076: * section of the documentation for more details.
077: *
078: * @author Leif Mortenson <leif@tanukisoftware.com>
079: */
080: public class Main extends AbstractActionApp implements WrapperListener {
081: private MainFrame m_frame;
082:
083: private DeadlockPrintStream m_out;
084: private DeadlockPrintStream m_err;
085:
086: private Thread m_userRunner;
087:
088: private List m_listenerFlags;
089: private TextField m_serviceName;
090:
091: /**************************************************************************
092: * Constructors
093: *************************************************************************/
094: private Main() {
095: }
096:
097: private class MainFrame extends Frame implements ActionListener {
098: MainFrame() {
099: super ("Wrapper Test Application");
100:
101: init();
102:
103: setLocation(10, 10);
104: setSize(750, 480);
105:
106: setResizable(true);
107: }
108:
109: private void init() {
110: GridBagLayout gridBag = new GridBagLayout();
111: GridBagConstraints c = new GridBagConstraints();
112:
113: Panel panel = new Panel();
114: panel.setLayout(gridBag);
115:
116: ScrollPane scrollPane = new ScrollPane();
117: scrollPane.add(panel);
118: scrollPane.getHAdjustable().setUnitIncrement(20);
119: scrollPane.getVAdjustable().setUnitIncrement(20);
120:
121: setLayout(new BorderLayout());
122: add(scrollPane, BorderLayout.CENTER);
123:
124: buildCommand(
125: panel,
126: gridBag,
127: c,
128: "Stop(0)",
129: "stop0",
130: "Calls WrapperManager.stop( 0 ) to shutdown the JVM and Wrapper with a success exit code.");
131:
132: buildCommand(
133: panel,
134: gridBag,
135: c,
136: "Stop(1)",
137: "stop1",
138: "Calls WrapperManager.stop( 1 ) to shutdown the JVM and Wrapper with a failure exit code.");
139:
140: buildCommand(
141: panel,
142: gridBag,
143: c,
144: "Exit(0)",
145: "exit0",
146: "Calls System.exit( 0 ) to shutdown the JVM and Wrapper with a success exit code.");
147:
148: buildCommand(
149: panel,
150: gridBag,
151: c,
152: "Exit(1)",
153: "exit1",
154: "Calls System.exit( 1 ) to shutdown the JVM and Wrapper with a failure exit code.");
155:
156: buildCommand(
157: panel,
158: gridBag,
159: c,
160: "StopImmediate(0)",
161: "stopimmediate0",
162: "Calls WrapperManager.stopImmediate( 0 ) to immediately shutdown the JVM and Wrapper with a success exit code.");
163:
164: buildCommand(
165: panel,
166: gridBag,
167: c,
168: "StopImmediate(1)",
169: "stopimmediate1",
170: "Calls WrapperManager.stopImmediate( 1 ) to immediately shutdown the JVM and Wrapper with a failure exir code.");
171:
172: buildCommand(
173: panel,
174: gridBag,
175: c,
176: "StopAndReturn(0)",
177: "stopandreturn0",
178: "Calls WrapperManager.stopAndReturn( 0 ) to shutdown the JVM and Wrapper with a success exit code.");
179:
180: buildCommand(panel, gridBag, c, "Nested Exit(1)",
181: "nestedexit1",
182: "Calls System.exit(1) within WrapperListener.stop(1) callback.");
183:
184: buildCommand(
185: panel,
186: gridBag,
187: c,
188: "Halt(0)",
189: "halt0",
190: "Calls Runtime.getRuntime().halt(0) to kill the JVM, the Wrapper will restart it.");
191:
192: buildCommand(
193: panel,
194: gridBag,
195: c,
196: "Halt(1)",
197: "halt1",
198: "Calls Runtime.getRuntime().halt(1) to kill the JVM, the Wrapper will restart it.");
199:
200: buildCommand(
201: panel,
202: gridBag,
203: c,
204: "Restart()",
205: "restart",
206: "Calls WrapperManager.restart() to shutdown the current JVM and start a new one.");
207:
208: buildCommand(
209: panel,
210: gridBag,
211: c,
212: "RestartAndReturn()",
213: "restartandreturn",
214: "Calls WrapperManager.restartAndReturn() to shutdown the current JVM and start a new one.");
215:
216: buildCommand(
217: panel,
218: gridBag,
219: c,
220: "Access Violation",
221: "access_violation",
222: "Attempts to cause an access violation within the JVM, relies on a JVM bug and may not work.");
223:
224: buildCommand(
225: panel,
226: gridBag,
227: c,
228: "Native Access Violation",
229: "access_violation_native",
230: "Causes an access violation using native code, the JVM will crash and be restarted.");
231:
232: buildCommand(
233: panel,
234: gridBag,
235: c,
236: "Simulate JVM Hang",
237: "appear_hung",
238: "Makes the JVM appear to be hung as viewed from the Wrapper, it will be killed and restarted.");
239:
240: buildCommand(
241: panel,
242: gridBag,
243: c,
244: "Request Thread Dump",
245: "dump",
246: "Calls WrapperManager.requestThreadDump() to cause the JVM to dump its current thread state.");
247:
248: buildCommand(panel, gridBag, c, "System.out Deadlock",
249: "deadlock_out",
250: "Simulates a failure mode where the System.out object has become deadlocked.");
251:
252: buildCommand(
253: panel,
254: gridBag,
255: c,
256: "Poll Users",
257: "users",
258: "Begins calling WrapperManager.getUser() and getInteractiveUser() to monitor the current and interactive users.");
259:
260: buildCommand(panel, gridBag, c, "Poll Users with Groups",
261: "groups",
262: "Same as above, but includes information about the user's groups.");
263:
264: buildCommand(panel, gridBag, c, "Console", "console",
265: "Prompt for Actions in the console.");
266:
267: buildCommand(panel, gridBag, c, "Idle", "idle", "Run idly.");
268:
269: buildCommand(panel, gridBag, c, "Dump Properties",
270: "properties",
271: "Dumps all System Properties to the console.");
272:
273: buildCommand(panel, gridBag, c, "Dump Configuration",
274: "configuration",
275: "Dumps all Wrapper Configuration Properties to the console.");
276:
277: m_listenerFlags = new List(2, true);
278: m_listenerFlags.add("Service");
279: m_listenerFlags.add("Control");
280: m_listenerFlags.add("Core");
281:
282: Panel flagPanel = new Panel();
283: flagPanel.setLayout(new BorderLayout());
284: flagPanel
285: .add(new Label("Event Flags: "), BorderLayout.WEST);
286: flagPanel.add(m_listenerFlags, BorderLayout.CENTER);
287: flagPanel.setSize(100, 10);
288:
289: Panel flagPanel2 = new Panel();
290: flagPanel2.setLayout(new BorderLayout());
291: flagPanel2.add(flagPanel, BorderLayout.WEST);
292:
293: buildCommand(panel, gridBag, c, "Update Event Listener",
294: "listener", flagPanel2);
295:
296: buildCommand(panel, gridBag, c, "Service List",
297: "service_list",
298: "Displays a list of registered services on Windows.");
299:
300: m_serviceName = new TextField("testwrapper");
301:
302: Panel servicePanel = new Panel();
303: servicePanel.setLayout(new BorderLayout());
304: servicePanel.add(new Label(
305: "Interrogate Service. Service name: "),
306: BorderLayout.WEST);
307: servicePanel.add(m_serviceName, BorderLayout.CENTER);
308:
309: Panel servicePanel2 = new Panel();
310: servicePanel2.setLayout(new BorderLayout());
311: servicePanel2.add(servicePanel, BorderLayout.WEST);
312:
313: buildCommand(panel, gridBag, c, "Service Interrogate",
314: "service_interrogate", servicePanel2);
315:
316: buildCommand(panel, gridBag, c, "Service Start",
317: "service_start", "Starts the above service.");
318:
319: buildCommand(panel, gridBag, c, "Service Stop",
320: "service_stop", "Stops the above service.");
321:
322: buildCommand(panel, gridBag, c, "Service User Code",
323: "service_user",
324: "Sends a series of user codes to the above service.");
325: }
326:
327: private void buildCommand(Container container,
328: GridBagLayout gridBag, GridBagConstraints c,
329: String label, String command, Object description) {
330: Button button = new Button(label);
331: button.setActionCommand(command);
332:
333: c.fill = GridBagConstraints.BOTH;
334: c.gridwidth = 1;
335: gridBag.setConstraints(button, c);
336: container.add(button);
337: button.addActionListener(this );
338:
339: c.gridwidth = GridBagConstraints.REMAINDER;
340: Component desc;
341: if (description instanceof String) {
342: desc = new Label((String) description);
343: } else if (description instanceof Component) {
344: desc = (Component) description;
345: } else {
346: desc = new Label(description.toString());
347: }
348:
349: gridBag.setConstraints(desc, c);
350: container.add(desc);
351: }
352:
353: public void actionPerformed(ActionEvent event) {
354: String action = event.getActionCommand();
355: if (action.equals("listener")) {
356: // Create the mask.
357: long mask = 0;
358: String[] flags = m_listenerFlags.getSelectedItems();
359: for (int i = 0; i < flags.length; i++) {
360: String flag = flags[i];
361: if (flag.equals("Service")) {
362: mask |= WrapperEventListener.EVENT_FLAG_SERVICE;
363: } else if (flag.equals("Control")) {
364: mask |= WrapperEventListener.EVENT_FLAG_CONTROL;
365: } else if (flag.equals("Core")) {
366: mask |= WrapperEventListener.EVENT_FLAG_CORE;
367: }
368: }
369:
370: setEventMask(mask);
371: }
372:
373: setServiceName(m_serviceName.getText());
374:
375: Main.this .doAction(action);
376: }
377: }
378:
379: /**************************************************************************
380: * WrapperListener Methods
381: *************************************************************************/
382: public Integer start(String[] args) {
383: System.out.println("start()");
384:
385: prepareSystemOutErr();
386:
387: try {
388: m_frame = new MainFrame();
389: m_frame.setVisible(true);
390: } catch (java.lang.InternalError e) {
391: System.out.println();
392: System.out
393: .println("ERROR - Unable to display the Swing GUI:");
394: System.out.println(" " + e.toString());
395: System.out.println("Exiting");
396: System.out.println();
397: return new Integer(1);
398: }
399:
400: try {
401: int port = 9999;
402: WrapperActionServer server = new WrapperActionServer(port);
403: server.enableShutdownAction(true);
404: server.enableHaltExpectedAction(true);
405: server.enableRestartAction(true);
406: server.enableThreadDumpAction(true);
407: server.enableHaltUnexpectedAction(true);
408: server.enableAccessViolationAction(true);
409: server.enableAppearHungAction(true);
410: server.start();
411:
412: System.out.println("ActionServer Enabled. ");
413: System.out.println(" Telnet localhost 9999");
414: System.out.println(" Commands: ");
415: System.out.println(" S: Shutdown");
416: System.out.println(" H: Expected Halt");
417: System.out.println(" R: Restart");
418: System.out.println(" D: Thread Dump");
419: System.out
420: .println(" U: Unexpected Halt (Simulate crash)");
421: System.out
422: .println(" V: Access Violation (Actual crash)");
423: System.out
424: .println(" G: Make the JVM appear to be hung.");
425: } catch (java.io.IOException e) {
426: System.out
427: .println("Unable to open the action server socket: "
428: + e.getMessage());
429: }
430:
431: return null;
432: }
433:
434: public int stop(int exitCode) {
435: System.out.println("stop(" + exitCode + ")");
436:
437: if (m_frame != null) {
438: if (!WrapperManager.hasShutdownHookBeenTriggered()) {
439: m_frame.setVisible(false);
440: m_frame.dispose();
441: }
442: m_frame = null;
443: }
444:
445: if (isNestedExit()) {
446: System.out.println("calling System.exit(" + exitCode
447: + ") within stop.");
448: System.exit(exitCode);
449: }
450:
451: return exitCode;
452: }
453:
454: public void controlEvent(int event) {
455: System.out.println("controlEvent(" + event + ")");
456:
457: if ((event == WrapperManager.WRAPPER_CTRL_LOGOFF_EVENT)
458: && WrapperManager.isLaunchedAsService()) {
459: System.out.println(" Ignoring logoff event");
460: // Ignore
461: } else {
462: WrapperManager.stop(0);
463: }
464: }
465:
466: /**************************************************************************
467: * Main Method
468: *************************************************************************/
469: /**
470: * IMPORTANT: Please read the Javadocs for this class at the top of the
471: * page before you start to use this class as a template for integrating
472: * your own application. This will save you a lot of time.
473: */
474: public static void main(String[] args) {
475: System.out.println("Initializing...");
476:
477: // Start the application. If the JVM was launched from the native
478: // Wrapper then the application will wait for the native Wrapper to
479: // call the application's start method. Otherwise the start method
480: // will be called immediately.
481: WrapperManager.start(new Main(), args);
482: }
483: }
|