1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.launcher;
12
13 import org.mule.MuleCoreExtension;
14 import org.mule.api.DefaultMuleException;
15 import org.mule.api.MuleException;
16 import org.mule.config.ExceptionHelper;
17 import org.mule.config.StartupContext;
18 import org.mule.config.i18n.CoreMessages;
19 import org.mule.config.i18n.Message;
20 import org.mule.module.launcher.log4j.ApplicationAwareRepositorySelector;
21 import org.mule.util.ClassUtils;
22 import org.mule.util.MuleUrlStreamHandlerFactory;
23 import org.mule.util.StringMessageUtils;
24 import org.mule.util.SystemUtils;
25
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Properties;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.log4j.LogManager;
38
39
40
41
42 public class MuleContainer
43 {
44 public static final String CLI_OPTIONS[][] = {
45 {"builder", "true", "Configuration Builder Type"},
46 {"config", "true", "Configuration File"},
47 {"idle", "false", "Whether to run in idle (unconfigured) mode"},
48 {"main", "true", "Main Class"},
49 {"mode", "true", "Run Mode"},
50 {"props", "true", "Startup Properties"},
51 {"production", "false", "Production Mode"},
52 {"debug", "false", "Configure Mule for JPDA remote debugging."},
53 {"app", "true", "Application to start"}
54 };
55
56 public static final String SERVICE_PATH = "META-INF/services/org/mule/config/";
57
58 public static final String CORE_EXTENSION_PROPERTIES = "core-extensions.properties";
59
60
61
62
63 private static Log logger;
64
65
66
67
68
69 private static String startupPropertiesFile = null;
70
71
72
73
74 private static MuleShutdownHook muleShutdownHook;
75
76 protected DeploymentService deploymentService;
77
78 protected Map<Class<? extends MuleCoreExtension>, MuleCoreExtension> coreExtensions = new HashMap<Class<? extends MuleCoreExtension>, MuleCoreExtension>();
79
80 static
81 {
82 if (System.getProperty("mule.simpleLog") == null)
83 {
84
85 LogManager.setRepositorySelector(new ApplicationAwareRepositorySelector(), new Object());
86 }
87 logger = LogFactory.getLog(MuleContainer.class);
88 }
89
90
91
92
93
94
95 public static void main(String[] args) throws Exception
96 {
97 MuleContainer container = new MuleContainer(args);
98 container.start(true);
99 }
100
101 public MuleContainer()
102 {
103 init(new String[0]);
104 }
105
106
107
108
109 public MuleContainer(String[] args) throws IllegalArgumentException
110 {
111 init(args);
112 }
113
114 protected void init(String[] args) throws IllegalArgumentException
115 {
116 Map<String, Object> commandlineOptions;
117
118 try
119 {
120 commandlineOptions = SystemUtils.getCommandLineOptions(args, CLI_OPTIONS);
121 }
122 catch (DefaultMuleException me)
123 {
124 throw new IllegalArgumentException(me.toString());
125 }
126
127
128
129 MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
130
131
132 String propertiesFile = (String) commandlineOptions.get("props");
133 if (propertiesFile != null)
134 {
135 setStartupPropertiesFile(propertiesFile);
136 }
137 StartupContext.get().setStartupOptions(commandlineOptions);
138 }
139
140 public void start(boolean registerShutdownHook)
141 {
142 if (registerShutdownHook)
143 {
144 registerShutdownHook();
145 }
146
147 final MuleContainerStartupSplashScreen splashScreen = new MuleContainerStartupSplashScreen();
148 splashScreen.doBody();
149 logger.info(splashScreen.toString());
150
151 try
152 {
153 loadCoreExtensions();
154
155
156 deploymentService = new DeploymentService(coreExtensions);
157 deploymentService.start();
158 }
159 catch (Throwable e)
160 {
161 shutdown(e);
162 }
163 }
164
165
166
167
168 private void loadCoreExtensions() throws MuleException
169 {
170 Enumeration<?> e = ClassUtils.getResources(SERVICE_PATH + CORE_EXTENSION_PROPERTIES, getClass());
171 List<Properties> extensions = new LinkedList<Properties>();
172
173
174 while (e.hasMoreElements())
175 {
176 try
177 {
178 URL url = (URL) e.nextElement();
179 if (logger.isDebugEnabled())
180 {
181 logger.debug("Reading extension file: " + url.toString());
182 }
183 Properties p = new Properties();
184 p.load(url.openStream());
185 extensions.add(p);
186 }
187 catch (Exception ex)
188 {
189 throw new DefaultMuleException("Error loading Mule core extensions", ex);
190 }
191 }
192
193 for (Properties extProps : extensions)
194 {
195 for (Map.Entry entry : extProps.entrySet())
196 {
197 String extName = (String) entry.getKey();
198 String extClass = (String) entry.getValue();
199 try
200 {
201 MuleCoreExtension extension = (MuleCoreExtension) ClassUtils.instanciateClass(extClass);
202 extension.initialise();
203 coreExtensions.put(extension.getClass(), extension);
204 }
205 catch (Exception ex)
206 {
207 throw new DefaultMuleException("Error starting Mule core extension " + extName, ex);
208 }
209 }
210 }
211 }
212
213
214
215
216
217
218 public void shutdown(Throwable e)
219 {
220 Message msg = CoreMessages.fatalErrorWhileRunning();
221 MuleException muleException = ExceptionHelper.getRootMuleException(e);
222 if (muleException != null)
223 {
224 logger.fatal(muleException.getDetailedMessage());
225 }
226 else
227 {
228 logger.fatal(msg.toString() + " " + e.getMessage(), e);
229 }
230 List<String> msgs = new ArrayList<String>();
231 msgs.add(msg.getMessage());
232 Throwable root = ExceptionHelper.getRootException(e);
233 msgs.add(root.getMessage() + " (" + root.getClass().getName() + ")");
234 msgs.add(" ");
235 msgs.add(CoreMessages.fatalErrorInShutdown().getMessage());
236 String shutdownMessage = StringMessageUtils.getBoilerPlate(msgs, '*', 80);
237 logger.fatal(shutdownMessage);
238
239 unregisterShutdownHook();
240 doShutdown();
241 }
242
243
244
245
246 public void shutdown()
247 {
248 logger.info("Mule container shutting down due to normal shutdown request");
249
250 unregisterShutdownHook();
251 doShutdown();
252 }
253
254 protected void doShutdown()
255 {
256 if (deploymentService != null)
257 {
258 deploymentService.stop();
259 }
260
261 for (MuleCoreExtension extension : coreExtensions.values())
262 {
263 try
264 {
265 extension.dispose();
266 }
267 catch (Exception ex)
268 {
269 logger.fatal("Error shutting down core extension " + extension.getName());
270 }
271 }
272
273 System.exit(0);
274 }
275
276 public Log getLogger()
277 {
278 return logger;
279 }
280
281 public void registerShutdownHook()
282 {
283 if (muleShutdownHook == null)
284 {
285 muleShutdownHook = new MuleShutdownHook();
286 }
287 else
288 {
289 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
290 }
291 Runtime.getRuntime().addShutdownHook(muleShutdownHook);
292 }
293
294 public void unregisterShutdownHook()
295 {
296 if (muleShutdownHook != null)
297 {
298 Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
299 }
300 }
301
302
303
304
305
306
307 public static String getStartupPropertiesFile()
308 {
309 return startupPropertiesFile;
310 }
311
312 public static void setStartupPropertiesFile(String startupPropertiesFile)
313 {
314 MuleContainer.startupPropertiesFile = startupPropertiesFile;
315 }
316
317
318
319
320
321
322 private class MuleShutdownHook extends Thread
323 {
324 public MuleShutdownHook()
325 {
326 super("Mule.shutdown.hook");
327 }
328
329 @Override
330 public void run()
331 {
332 doShutdown();
333 }
334 }
335 }
336