1
2
3
4
5
6
7
8
9
10
11 package org.mule;
12
13 import org.mule.api.DefaultMuleException;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.config.ConfigurationBuilder;
17 import org.mule.api.config.ConfigurationException;
18 import org.mule.config.ExceptionHelper;
19 import org.mule.config.StartupContext;
20 import org.mule.config.builders.SimpleConfigurationBuilder;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.config.i18n.Message;
23 import org.mule.context.DefaultMuleContextBuilder;
24 import org.mule.context.DefaultMuleContextFactory;
25 import org.mule.util.ClassUtils;
26 import org.mule.util.IOUtils;
27 import org.mule.util.MuleUrlStreamHandlerFactory;
28 import org.mule.util.PropertiesUtils;
29 import org.mule.util.StringMessageUtils;
30 import org.mule.util.SystemUtils;
31
32 import java.net.URL;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Properties;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41
42
43
44
45 public class MuleServer implements Runnable
46 {
47 public static final String CLI_OPTIONS[][] = {
48 {"builder", "true", "Configuration Builder Type"},
49 {"config", "true", "Configuration File"},
50 {"idle", "false", "Whether to run in idle (unconfigured) mode"},
51 {"main", "true", "Main Class"},
52 {"mode", "true", "Run Mode"},
53 {"props", "true", "Startup Properties"},
54 {"production", "false", "Production Mode"},
55 {"debug", "false", "Configure Mule for JPDA remote debugging."}
56 };
57
58
59
60
61 protected static final String CLASSNAME_DEFAULT_CONFIG_BUILDER = "org.mule.config.builders.AutoConfigurationBuilder";
62
63
64
65
66
67 protected static final String CLASSNAME_DEFAULT_IDLE_CONFIG_BUILDER = "org.mule.config.builders.MuleIdleConfigurationBuilder";
68
69
70
71
72
73
74 protected static final String CLASSNAME_SPRING_CONFIG_BUILDER = "org.mule.config.spring.SpringXmlConfigurationBuilder";
75
76
77
78
79 public static final String CLASSNAME_ANNOTATIONS_CONFIG_BUILDER = "org.mule.config.AnnotationsConfigurationBuilder";
80
81
82
83
84 private static final Log logger = LogFactory.getLog(MuleServer.class);
85
86 public static final String DEFAULT_CONFIGURATION = "mule-config.xml";
87
88
89
90
91 private String configurationResources = null;
92
93
94
95
96
97 private static String configBuilderClassName = null;
98
99
100
101
102
103 private static String startupPropertiesFile = null;
104
105
106
107
108 private static MuleShutdownHook muleShutdownHook;
109
110
111
112
113
114
115
116 protected static MuleContext muleContext = null;
117
118
119
120
121
122
123
124 public static void main(String[] args) throws Exception
125 {
126 MuleServer server = new MuleServer(args);
127 server.start(false, true);
128
129 }
130
131 public MuleServer()
132 {
133 init(new String[]{});
134 }
135
136 public MuleServer(String configResources)
137 {
138
139 init(new String[]{"-config", configResources});
140 }
141
142
143
144
145
146
147 public MuleServer(String[] args) throws IllegalArgumentException
148 {
149 init(args);
150 }
151
152 protected void init(String[] args) throws IllegalArgumentException
153 {
154 Map<String, Object> commandlineOptions;
155
156 try
157 {
158 commandlineOptions = SystemUtils.getCommandLineOptions(args, CLI_OPTIONS);
159 }
160 catch (DefaultMuleException me)
161 {
162 throw new IllegalArgumentException(me.toString());
163 }
164
165
166
167 MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
168
169 String config = (String) commandlineOptions.get("config");
170
171 if (config == null && !commandlineOptions.containsKey("idle"))
172 {
173 logger.warn("A configuration file was not set, using default: " + DEFAULT_CONFIGURATION);
174
175 URL configUrl = IOUtils.getResourceAsUrl(DEFAULT_CONFIGURATION, MuleServer.class, true, false);
176 if (configUrl != null)
177 {
178 config = configUrl.toExternalForm();
179 }
180 else
181 {
182 System.out.println(CoreMessages.configNotFoundUsage());
183 System.exit(-1);
184 }
185 }
186
187 if (config != null)
188 {
189 setConfigurationResources(config);
190 }
191
192
193 String cfgBuilderClassName = (String) commandlineOptions.get("builder");
194
195 if (commandlineOptions.containsKey("idle"))
196 {
197 setConfigurationResources("IDLE");
198 cfgBuilderClassName = CLASSNAME_DEFAULT_IDLE_CONFIG_BUILDER;
199 }
200
201
202 if (cfgBuilderClassName != null)
203 {
204 try
205 {
206
207 if (cfgBuilderClassName.equalsIgnoreCase("spring"))
208 {
209 cfgBuilderClassName = CLASSNAME_SPRING_CONFIG_BUILDER;
210 }
211 setConfigBuilderClassName(cfgBuilderClassName);
212 }
213 catch (Exception e)
214 {
215 logger.fatal(e);
216 final Message message = CoreMessages.failedToLoad("Builder: " + cfgBuilderClassName);
217 System.err.println(StringMessageUtils.getBoilerPlate("FATAL: " + message.toString()));
218 System.exit(1);
219 }
220 }
221
222
223 String propertiesFile = (String) commandlineOptions.get("props");
224 if (propertiesFile != null)
225 {
226 setStartupPropertiesFile(propertiesFile);
227 }
228
229 StartupContext.get().setStartupOptions(commandlineOptions);
230 }
231
232
233
234
235
236
237
238
239
240 public void start(boolean ownThread, boolean registerShutdownHook)
241 {
242 if (registerShutdownHook)
243 {
244 registerShutdownHook();
245 }
246 if (ownThread)
247 {
248 Thread serverThread = new Thread(this, "MuleServer");
249 serverThread.setDaemon(true);
250 serverThread.start();
251 }
252 else
253 {
254 run();
255 }
256 }
257
258
259
260
261
262 public void run()
263 {
264 try
265 {
266 logger.info("Mule Server initializing...");
267 initialize();
268 logger.info("Mule Server starting...");
269 muleContext.start();
270 }
271 catch (Throwable e)
272 {
273 shutdown(e);
274 }
275 }
276
277
278
279
280
281
282
283
284
285
286 public static void setConfigBuilderClassName(String builderClassName) throws ClassNotFoundException
287 {
288 if (builderClassName != null)
289 {
290 Class cls = ClassUtils.loadClass(builderClassName, MuleServer.class);
291 if (ConfigurationBuilder.class.isAssignableFrom(cls))
292 {
293 MuleServer.configBuilderClassName = builderClassName;
294 }
295 else
296 {
297 throw new IllegalArgumentException("Not a usable ConfigurationBuilder class: "
298 + builderClassName);
299 }
300 }
301 else
302 {
303 MuleServer.configBuilderClassName = null;
304 }
305 }
306
307
308
309
310
311
312
313 public static String getConfigBuilderClassName()
314 {
315 if (configBuilderClassName != null)
316 {
317 return configBuilderClassName;
318 }
319 else
320 {
321 return CLASSNAME_DEFAULT_CONFIG_BUILDER;
322 }
323 }
324
325
326
327
328
329
330
331 public void initialize() throws Exception
332 {
333 if (configurationResources == null)
334 {
335 logger.warn("A configuration file was not set, using default: " + DEFAULT_CONFIGURATION);
336 configurationResources = DEFAULT_CONFIGURATION;
337 }
338
339 ConfigurationBuilder cfgBuilder;
340
341 try
342 {
343
344 cfgBuilder = (ConfigurationBuilder) ClassUtils.instanciateClass(getConfigBuilderClassName(),
345 new Object[]{configurationResources}, MuleServer.class);
346 }
347 catch (Exception e)
348 {
349 throw new ConfigurationException(CoreMessages.failedToLoad(getConfigBuilderClassName()), e);
350 }
351
352 if (!cfgBuilder.isConfigured())
353 {
354 List<ConfigurationBuilder> builders = new ArrayList<ConfigurationBuilder>(2);
355
356
357
358
359 if (ClassUtils.isClassOnPath(CLASSNAME_ANNOTATIONS_CONFIG_BUILDER, getClass()))
360 {
361 Object configBuilder = ClassUtils.instanciateClass(
362 CLASSNAME_ANNOTATIONS_CONFIG_BUILDER, ClassUtils.NO_ARGS, getClass());
363 builders.add((ConfigurationBuilder) configBuilder);
364 }
365
366
367 Properties startupProperties = null;
368 if (getStartupPropertiesFile() != null)
369 {
370 startupProperties = PropertiesUtils.loadProperties(getStartupPropertiesFile(), getClass());
371 }
372 builders.add(new SimpleConfigurationBuilder(startupProperties));
373
374 builders.add(cfgBuilder);
375
376 DefaultMuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
377 muleContext = muleContextFactory.createMuleContext(builders, new DefaultMuleContextBuilder());
378 }
379 }
380
381
382
383
384
385
386 public void shutdown(Throwable e)
387 {
388 doShutdown();
389 unregisterShutdownHook();
390
391 Message msg = CoreMessages.fatalErrorWhileRunning();
392 MuleException muleException = ExceptionHelper.getRootMuleException(e);
393 int exitCode = 1;
394 if (muleException != null)
395 {
396 logger.fatal(muleException.getDetailedMessage());
397 exitCode = muleException.getExceptionCode();
398 }
399 else
400 {
401 logger.fatal(msg.toString() + " " + e.getMessage(), e);
402 }
403 List<String> msgs = new ArrayList<String>();
404 msgs.add(msg.getMessage());
405 Throwable root = ExceptionHelper.getRootException(e);
406 msgs.add(root.getMessage() + " (" + root.getClass().getName() + ")");
407 msgs.add(" ");
408 msgs.add(CoreMessages.fatalErrorInShutdown().getMessage());
409 String shutdownMessage = StringMessageUtils.getBoilerPlate(msgs, '*', 80);
410 logger.fatal(shutdownMessage);
411
412 System.exit(exitCode);
413
414
415 }
416
417
418
419
420 public void shutdown()
421 {
422 logger.info("Mule server shutting down due to normal shutdown request");
423
424 unregisterShutdownHook();
425 doShutdown();
426 System.exit(0);
427 }
428
429 protected void doShutdown()
430 {
431 if (muleContext != null)
432 {
433 muleContext.dispose();
434 muleContext = null;
435 }
436 }
437
438 public Log getLogger()
439 {
440 return logger;
441 }
442
443 public void registerShutdownHook()
444 {
445 if (muleShutdownHook == null)
446 {
447 muleShutdownHook = new MuleShutdownHook();
448 }
449 else
450 {
451 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
452 }
453 Runtime.getRuntime().addShutdownHook(muleShutdownHook);
454 }
455
456 public void unregisterShutdownHook()
457 {
458 if (muleShutdownHook != null)
459 {
460 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
461 }
462 }
463
464
465
466
467
468
469
470
471
472
473 public String getConfigurationResources()
474 {
475 return configurationResources;
476 }
477
478
479
480
481
482
483 public void setConfigurationResources(String configurationResources)
484 {
485 this.configurationResources = configurationResources;
486 }
487
488 public static String getStartupPropertiesFile()
489 {
490 return startupPropertiesFile;
491 }
492
493 public static void setStartupPropertiesFile(String startupPropertiesFile)
494 {
495 MuleServer.startupPropertiesFile = startupPropertiesFile;
496 }
497
498 public MuleContext getMuleContext()
499 {
500 return muleContext;
501 }
502
503
504
505
506
507
508 private class MuleShutdownHook extends Thread
509 {
510 public MuleShutdownHook()
511 {
512 super();
513 }
514
515 @Override
516 public void run()
517 {
518 doShutdown();
519 System.exit(0);
520 }
521 }
522 }