001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: /* @version $Id: DaemonLoader.java 155409 2005-02-26 12:57:06Z dirkv $ */
018:
019: package org.apache.commons.daemon.support;
020:
021: import org.apache.commons.daemon.Daemon;
022: import org.apache.commons.daemon.DaemonContext;
023: import org.apache.commons.daemon.DaemonController;
024:
025: import java.lang.reflect.Method;
026:
027: public final class DaemonLoader {
028:
029: private static Controller controller = null;
030: private static Context context = null;
031: private static Object daemon = null;
032: /* Methods to call */
033: private static Method init = null;
034: private static Method start = null;
035: private static Method stop = null;
036: private static Method destroy = null;
037:
038: public static void version() {
039: System.err.println("java version \""
040: + System.getProperty("java.version") + "\"");
041: System.err.println(System.getProperty("java.runtime.name")
042: + " (build "
043: + System.getProperty("java.runtime.version") + ")");
044: System.err.println(System.getProperty("java.vm.name")
045: + " (build " + System.getProperty("java.vm.version")
046: + ", " + System.getProperty("java.vm.info") + ")");
047: }
048:
049: public static boolean check(String cn) {
050: try {
051: /* Check the class name */
052: if (cn == null)
053: throw new NullPointerException(
054: "Null class name specified");
055:
056: /* Get the ClassLoader loading this class */
057: ClassLoader cl = DaemonLoader.class.getClassLoader();
058: if (cl == null) {
059: System.err
060: .println("Cannot retrieve ClassLoader instance");
061: return (false);
062: }
063:
064: /* Find the required class */
065: Class c = cl.loadClass(cn);
066:
067: /* This should _never_ happen, but doublechecking doesn't harm */
068: if (c == null)
069: throw new ClassNotFoundException(cn);
070:
071: /* Create a new instance of the daemon */
072: Object s = c.newInstance();
073:
074: } catch (Throwable t) {
075: /* In case we encounter ANY error, we dump the stack trace and
076: return false (load, start and stop won't be called). */
077: t.printStackTrace(System.err);
078: return (false);
079: }
080: /* The class was loaded and instantiated correctly, we can return */
081: return (true);
082: }
083:
084: public static boolean load(String cn, String ar[]) {
085: try {
086: /* Make sure any previous instance is garbage collected */
087: System.gc();
088:
089: /* Check if the underlying libray supplied a valid list of
090: arguments */
091: if (ar == null)
092: ar = new String[0];
093:
094: /* Check the class name */
095: if (cn == null)
096: throw new NullPointerException(
097: "Null class name specified");
098:
099: /* Get the ClassLoader loading this class */
100: ClassLoader cl = DaemonLoader.class.getClassLoader();
101: if (cl == null) {
102: System.err
103: .println("Cannot retrieve ClassLoader instance");
104: return (false);
105: }
106:
107: /* Find the required class */
108: Class c = cl.loadClass(cn);
109:
110: /* This should _never_ happen, but doublechecking doesn't harm */
111: if (c == null)
112: throw new ClassNotFoundException(cn);
113:
114: /* Check interface */
115: boolean isdaemon = false;
116: try {
117: Class dclass = cl
118: .loadClass("org.apache.commons.daemon.Daemon");
119: isdaemon = dclass.isAssignableFrom(c);
120: } catch (Exception cnfex) {
121: // Swallow if Daemon not found.
122: }
123:
124: /* Check methods */
125: Class[] myclass = new Class[1];
126: if (isdaemon) {
127: myclass[0] = DaemonContext.class;
128: } else {
129: myclass[0] = ar.getClass();
130: }
131:
132: init = c.getMethod("init", myclass);
133:
134: myclass = null;
135: start = c.getMethod("start", myclass);
136:
137: stop = c.getMethod("stop", myclass);
138:
139: destroy = c.getMethod("destroy", myclass);
140:
141: /* Create a new instance of the daemon */
142: daemon = c.newInstance();
143:
144: if (isdaemon) {
145: /* Create a new controller instance */
146: controller = new Controller();
147:
148: /* Set the availability flag in the controller */
149: controller.setAvailable(false);
150:
151: /* Create context */
152: context = new Context();
153: context.setArguments(ar);
154: context.setController(controller);
155:
156: /* Now we want to call the init method in the class */
157: Object arg[] = new Object[1];
158: arg[0] = context;
159: init.invoke(daemon, arg);
160: } else {
161: Object arg[] = new Object[1];
162: arg[0] = ar;
163: init.invoke(daemon, arg);
164: }
165:
166: } catch (Throwable t) {
167: /* In case we encounter ANY error, we dump the stack trace and
168: return false (load, start and stop won't be called). */
169: t.printStackTrace(System.err);
170: return (false);
171: }
172: /* The class was loaded and instantiated correctly, we can return */
173: return (true);
174: }
175:
176: public static boolean start() {
177: try {
178: /* Attempt to start the daemon */
179: Object arg[] = null;
180: start.invoke(daemon, arg);
181:
182: /* Set the availability flag in the controller */
183: if (controller != null)
184: controller.setAvailable(true);
185:
186: } catch (Throwable t) {
187: /* In case we encounter ANY error, we dump the stack trace and
188: return false (load, start and stop won't be called). */
189: t.printStackTrace(System.err);
190: return (false);
191: }
192: return (true);
193: }
194:
195: public static boolean stop() {
196: try {
197: /* Set the availability flag in the controller */
198: if (controller != null)
199: controller.setAvailable(false);
200:
201: /* Attempt to stop the daemon */
202: Object arg[] = null;
203: stop.invoke(daemon, arg);
204:
205: /* Run garbage collector */
206: System.gc();
207:
208: } catch (Throwable t) {
209: /* In case we encounter ANY error, we dump the stack trace and
210: return false (load, start and stop won't be called). */
211: t.printStackTrace(System.err);
212: return (false);
213: }
214: return (true);
215: }
216:
217: public static boolean destroy() {
218: try {
219: /* Attempt to stop the daemon */
220: Object arg[] = null;
221: destroy.invoke(daemon, arg);
222:
223: /* Run garbage collector */
224: daemon = null;
225: controller = null;
226: System.gc();
227:
228: } catch (Throwable t) {
229: /* In case we encounter ANY error, we dump the stack trace and
230: return false (load, start and stop won't be called). */
231: t.printStackTrace(System.err);
232: return (false);
233: }
234: return (true);
235: }
236:
237: private static native void shutdown(boolean reload);
238:
239: public static class Controller implements DaemonController {
240:
241: boolean available = false;
242:
243: private Controller() {
244: super ();
245: this .setAvailable(false);
246: }
247:
248: private boolean isAvailable() {
249: synchronized (this ) {
250: return (this .available);
251: }
252: }
253:
254: private void setAvailable(boolean available) {
255: synchronized (this ) {
256: this .available = available;
257: }
258: }
259:
260: public void shutdown() throws IllegalStateException {
261: synchronized (this ) {
262: if (!this .isAvailable()) {
263: throw new IllegalStateException();
264: } else {
265: this .setAvailable(false);
266: DaemonLoader.shutdown(false);
267: }
268: }
269: }
270:
271: public void reload() throws IllegalStateException {
272: synchronized (this ) {
273: if (!this .isAvailable()) {
274: throw new IllegalStateException();
275: } else {
276: this .setAvailable(false);
277: DaemonLoader.shutdown(true);
278: }
279: }
280: }
281:
282: public void fail() throws IllegalStateException {
283: }
284:
285: public void fail(String message) throws IllegalStateException {
286: }
287:
288: public void fail(Exception exception)
289: throws IllegalStateException {
290: }
291:
292: public void fail(String message, Exception exception)
293: throws IllegalStateException {
294: }
295:
296: }
297:
298: public static class Context implements DaemonContext {
299:
300: DaemonController controller = null;
301:
302: String[] args = null;
303:
304: public DaemonController getController() {
305: return controller;
306: }
307:
308: public void setController(DaemonController controller) {
309: this .controller = controller;
310: }
311:
312: public String[] getArguments() {
313: return args;
314: }
315:
316: public void setArguments(String[] args) {
317: this.args = args;
318: }
319:
320: }
321:
322: }
|