KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > loom > launcher > DaemonLauncher


1 /* ====================================================================
2  * Loom Software License, version 1.1
3  *
4  * Copyright (c) 2003, Loom Group. All rights reserved.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * 3. Neither the name of the Loom Group nor the name "Loom" nor
18  * the names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior
20  * written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * ====================================================================
36  *
37  * Loom includes code from the Apache Software Foundation
38  *
39  * ====================================================================
40  * The Apache Software License, Version 1.1
41  *
42  * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
43  * reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  *
49  * 1. Redistributions of source code must retain the above copyright
50  * notice, this list of conditions and the following disclaimer.
51  *
52  * 2. Redistributions in binary form must reproduce the above copyright
53  * notice, this list of conditions and the following disclaimer in
54  * the documentation and/or other materials provided with the
55  * distribution.
56  *
57  * 3. The end-user documentation included with the redistribution,
58  * if any, must include the following acknowledgment:
59  * "This product includes software developed by the
60  * Apache Software Foundation (http://www.apache.org/)."
61  * Alternately, this acknowledgment may appear in the software
62  * itself, if and wherever such third-party acknowledgments
63  * normally appear.
64  *
65  * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
66  * must not be used to endorse or promote products derived from this
67  * software without prior written permission. For written
68  * permission, please contact apache@apache.org.
69  *
70  * 5. Products derived from this software may not be called "Apache",
71  * nor may "Apache" appear in their name, without prior written
72  * permission of the Apache Software Foundation.
73  *
74  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
75  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
76  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
78  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
79  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
80  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
81  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
82  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
83  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
84  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85  * SUCH DAMAGE.
86  */

87 package org.codehaus.loom.launcher;
88
89 import java.util.Hashtable JavaDoc;
90 import java.util.Observable JavaDoc;
91 import java.util.Observer JavaDoc;
92 import org.tanukisoftware.wrapper.WrapperListener;
93 import org.tanukisoftware.wrapper.WrapperManager;
94
95 /**
96  * A frontend for Phoenix that starts it as a native service using the Java
97  * Service Wrapper at http://wrapper.tanukisoftware.org
98  *
99  * @author Peter Donald
100  * @author <a HREF="mailto:leif@tanukisoftware.com">Leif Mortenson</a>
101  */

102 public class DaemonLauncher
103     implements WrapperListener, Observer JavaDoc
104 {
105     /**
106      * In order to avoid calling the Wrapper stop method recursively, we need to
107      * keep track of whether or not the Wrapper already knows we are stopping.
108      * Necessary because of the way the shutdown process in Phoenix works.
109      * Ideally, we would unregister this Observer with CLIMain but we can't do
110      * that for security reasons.
111      */

112     private boolean m_ignoreUpdates = false;
113
114     /*---------------------------------------------------------------
115      * WrapperListener Methods
116      *-------------------------------------------------------------*/

117     /**
118      * The start method is called when the WrapperManager is signaled by the
119      * native wrapper code that it can start its application. This method call
120      * is expected to return, so a new thread should be launched if necessary.
121      *
122      * @param args List of arguments used to initialize the application.
123      * @return Any error code if the application should exit on completion of
124      * the start method. If there were no problems then this method
125      * should return null.
126      */

127     public Integer JavaDoc start( final String JavaDoc[] args )
128     {
129         Integer JavaDoc exitCodeInteger = null;
130
131         // This startup could take a while, so tell the wrapper to be patient.
132
WrapperManager.signalStarting( 45000 );
133
134         final Hashtable JavaDoc data = new Hashtable JavaDoc();
135         data.put( Observer JavaDoc.class.getName(), this );
136
137         if( WrapperManager.isDebugEnabled() )
138         {
139             System.out.println( "DaemonLauncher: starting up." );
140         }
141
142         try
143         {
144             int exitCode = Main.startup( args, data, false );
145             if( exitCode != 0 )
146             {
147                 exitCodeInteger = new Integer JavaDoc( exitCode );
148             }
149
150             if( WrapperManager.isDebugEnabled() )
151             {
152                 System.out.println( "DaemonLauncher: startup completed." );
153             }
154         }
155         catch( final Exception JavaDoc e )
156         {
157             e.printStackTrace();
158             exitCodeInteger = new Integer JavaDoc( 1 );
159         }
160
161         // We are almost up now, so reset the wait time
162
WrapperManager.signalStarting( 2000 );
163
164         return exitCodeInteger;
165     }
166
167     /**
168      * Called when the application is shutting down. The Wrapper assumes that
169      * this method will return fairly quickly. If the shutdown code code could
170      * potentially take a long time, then WrapperManager.stopping() should be
171      * called to extend the timeout period. If for some reason, the stop method
172      * can not return, then it must call WrapperManager.stopped() to avoid
173      * warning messages from the Wrapper.
174      *
175      * @param exitCode The suggested exit code that will be returned to the OS
176      * when the JVM exits.
177      * @return The exit code to actually return to the OS. In most cases, this
178      * should just be the value of exitCode, however the user code has
179      * the option of changing the exit code if there are any problems
180      * during shutdown.
181      */

182     public int stop( final int exitCode )
183     {
184         // To avoid recursive calls, start ignoring updates.
185
m_ignoreUpdates = true;
186
187         Main.shutdown();
188         return exitCode;
189     }
190
191     /**
192      * Called whenever the native wrapper code traps a system control signal
193      * against the Java process. It is up to the callback to take any actions
194      * necessary. Possible values are: WrapperManager.WRAPPER_CTRL_C_EVENT,
195      * WRAPPER_CTRL_CLOSE_EVENT, WRAPPER_CTRL_LOGOFF_EVENT, or
196      * WRAPPER_CTRL_SHUTDOWN_EVENT
197      *
198      * @param event The system control signal.
199      */

200     public void controlEvent( final int event )
201     {
202         if( WrapperManager.isControlledByNativeWrapper() )
203         {
204             if( WrapperManager.isDebugEnabled() )
205             {
206                 System.out.println(
207                     "DaemonLauncher: controlEvent(" + event + ") - Ignored." );
208             }
209
210             // This application ignores all incoming control events.
211
// It relies on the wrapper code to handle them.
212
}
213         else
214         {
215             if( WrapperManager.isDebugEnabled() )
216             {
217                 System.out.println(
218                     "DaemonLauncher: controlEvent(" + event + ") - Stopping." );
219             }
220
221             // Not being run under a wrapper, so this isn't an NT service and should always exit.
222
// Handle the event here.
223
WrapperManager.stop( 0 );
224             // Will not get here.
225
}
226     }
227
228     /*---------------------------------------------------------------
229      * Methods
230      *-------------------------------------------------------------*/

231     /**
232      * We use an Observer rather than operating on some more meaningful event
233      * system as Observer and friends can be loaded from system ClassLoader and
234      * thus the Embeddor does not have to share a common classloader ancestor
235      * with invoker
236      */

237     public void update( final Observable JavaDoc observable, final Object JavaDoc arg )
238     {
239         if( m_ignoreUpdates )
240         {
241             // Ignore this update
242
if( WrapperManager.isDebugEnabled() )
243             {
244                 System.out.println(
245                     "DaemonLauncher: " +
246                     arg
247                     + " request ignored because stop already called." );
248                 System.out.flush();
249             }
250         }
251         else
252         {
253             final String JavaDoc command = ( null != arg ) ? arg.toString() : "";
254             if( command.equals( "restart" ) )
255             {
256                 if( WrapperManager.isDebugEnabled() )
257                 {
258                     System.out.println( "DaemonLauncher: restart requested." );
259                     System.out.flush();
260                 }
261
262                 WrapperManager.restart();
263
264                 if( WrapperManager.isDebugEnabled() )
265                 {
266                     //Should never get here???
267
System.out.println( "DaemonLauncher: restart completed." );
268                     System.out.flush();
269                 }
270             }
271             else if( command.equals( "shutdown" ) )
272             {
273                 if( WrapperManager.isDebugEnabled() )
274                 {
275                     System.out.println( "DaemonLauncher: shutdown requested." );
276                     System.out.flush();
277                 }
278
279                 WrapperManager.stop( 0 );
280
281                 if( WrapperManager.isDebugEnabled() )
282                 {
283                     //Should never get here???
284
System.out.println( "DaemonLauncher: shutdown completed." );
285                     System.out.flush();
286                 }
287             }
288             else
289             {
290                 throw new IllegalArgumentException JavaDoc(
291                     "Unknown action " + command );
292             }
293         }
294     }
295
296     /*---------------------------------------------------------------
297      * Main Method
298      *-------------------------------------------------------------*/

299     public static void main( final String JavaDoc[] args )
300     {
301         // Start the application. If the JVM was launched from the native
302
// Wrapper then the application will wait for the native Wrapper to
303
// call the application's start method. Otherwise the start method
304
// will be called immediately.
305
WrapperManager.start( new DaemonLauncher(), args );
306     }
307 }
308
Popular Tags