View Javadoc

1   /*
2    * $Id: MuleContainer.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.module.launcher;
12  
13  import org.mule.api.DefaultMuleException;
14  import org.mule.api.MuleException;
15  import org.mule.config.ExceptionHelper;
16  import org.mule.config.StartupContext;
17  import org.mule.config.i18n.CoreMessages;
18  import org.mule.config.i18n.Message;
19  import org.mule.util.MuleUrlStreamHandlerFactory;
20  import org.mule.util.StringMessageUtils;
21  import org.mule.util.SystemUtils;
22  
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  /**
31   *
32   */
33  public class MuleContainer
34  {
35      public static final String CLI_OPTIONS[][] = {
36          {"builder", "true", "Configuration Builder Type"},
37          {"config", "true", "Configuration File"},
38          {"idle", "false", "Whether to run in idle (unconfigured) mode"},
39          {"main", "true", "Main Class"},
40          {"mode", "true", "Run Mode"},
41          {"props", "true", "Startup Properties"},
42          {"production", "false", "Production Mode"},
43          {"debug", "false", "Configure Mule for JPDA remote debugging."},
44          {"app", "true", "Application to start"}
45      };
46  
47      /**
48       * logger used by this class
49       */
50      private static final Log logger = LogFactory.getLog(MuleContainer.class);
51  
52      /**
53       * A properties file to be read at startup. This can be useful for setting
54       * properties which depend on the run-time environment (dev, test, production).
55       */
56      private static String startupPropertiesFile = null;
57  
58      /**
59       * The Runtime shutdown thread used to undeploy this server
60       */
61      private static MuleShutdownHook muleShutdownHook;
62  
63      protected DeploymentService deploymentService;
64  
65      /**
66       * Application entry point.
67       *
68       * @param args command-line args
69       */
70      public static void main(String[] args) throws Exception
71      {
72          MuleContainer container = new MuleContainer(args);
73          container.start(true);
74      }
75  
76      public MuleContainer()
77      {
78          init(new String[0]);
79      }
80  
81      /**
82       * Configure the server with command-line arguments.
83       */
84      public MuleContainer(String[] args) throws IllegalArgumentException
85      {                                                                                                                                                           
86          init(args);
87      }
88  
89      protected void init(String[] args) throws IllegalArgumentException
90      {
91          Map<String, Object> commandlineOptions;
92  
93          try
94          {
95              commandlineOptions = SystemUtils.getCommandLineOptions(args, CLI_OPTIONS);
96          }
97          catch (DefaultMuleException me)
98          {
99              throw new IllegalArgumentException(me.toString());
100         }
101 
102         // set our own UrlStreamHandlerFactory to become more independent of system
103         // properties
104         MuleUrlStreamHandlerFactory.installUrlStreamHandlerFactory();
105 
106         // Startup properties
107         String propertiesFile = (String) commandlineOptions.get("props");
108         if (propertiesFile != null)
109         {
110             setStartupPropertiesFile(propertiesFile);
111         }
112         StartupContext.get().setStartupOptions(commandlineOptions);
113     }
114 
115     public void start(boolean registerShutdownHook)
116     {
117         if (registerShutdownHook)
118         {
119             registerShutdownHook();
120         }
121 
122         final MuleContainerStartupSplashScreen splashScreen = new MuleContainerStartupSplashScreen();
123         splashScreen.doBody();
124         logger.info(splashScreen.toString());
125 
126         try
127         {
128             // TODO pluggable deployer
129             deploymentService = new DeploymentService();
130             deploymentService.start();
131         }
132         catch (Throwable e)
133         {
134             shutdown(e);
135         }
136     }
137 
138     /**
139      * Will shut down the server displaying the cause and time of the shutdown
140      *
141      * @param e the exception that caused the shutdown
142      */
143     public void shutdown(Throwable e)
144     {
145         Message msg = CoreMessages.fatalErrorWhileRunning();
146         MuleException muleException = ExceptionHelper.getRootMuleException(e);
147         if (muleException != null)
148         {
149             logger.fatal(muleException.getDetailedMessage());
150         }
151         else
152         {
153             logger.fatal(msg.toString() + " " + e.getMessage(), e);
154         }
155         List<String> msgs = new ArrayList<String>();
156         msgs.add(msg.getMessage());
157         Throwable root = ExceptionHelper.getRootException(e);
158         msgs.add(root.getMessage() + " (" + root.getClass().getName() + ")");
159         msgs.add(" ");
160         msgs.add(CoreMessages.fatalErrorInShutdown().getMessage());
161         String shutdownMessage = StringMessageUtils.getBoilerPlate(msgs, '*', 80);
162         logger.fatal(shutdownMessage);
163 
164         unregisterShutdownHook();
165         doShutdown();
166     }
167 
168     /**
169      * shutdown the server. This just displays the time the server shut down
170      */
171     public void shutdown()
172     {
173         logger.info("Mule container shutting down due to normal shutdown request");
174 
175         unregisterShutdownHook();
176         doShutdown();
177     }
178 
179     protected void doShutdown()
180     {
181         if (deploymentService != null)
182         {
183             deploymentService.stop();
184         }
185 
186         System.exit(0);
187     }
188 
189     public Log getLogger()
190     {
191         return logger;
192     }
193 
194     public void registerShutdownHook()
195     {
196         if (muleShutdownHook == null)
197         {
198             muleShutdownHook = new MuleShutdownHook();
199         }
200         else
201         {
202             Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
203         }
204         Runtime.getRuntime().addShutdownHook(muleShutdownHook);
205     }
206 
207     public void unregisterShutdownHook()
208     {
209         if (muleShutdownHook != null)
210         {
211             Runtime.getRuntime().removeShutdownHook(muleShutdownHook);
212         }
213     }
214 
215     // /////////////////////////////////////////////////////////////////
216     // Getters and setters
217     // /////////////////////////////////////////////////////////////////
218 
219 
220     public static String getStartupPropertiesFile()
221     {
222         return startupPropertiesFile;
223     }
224 
225     public static void setStartupPropertiesFile(String startupPropertiesFile)
226     {
227         MuleContainer.startupPropertiesFile = startupPropertiesFile;
228     }
229 
230     /**
231      * This class is installed only for MuleContainer running as commandline app. A
232      * clean Mule shutdown can be achieved by disposing the
233      * {@link org.mule.DefaultMuleContext}.
234      */
235     private class MuleShutdownHook extends Thread
236     {
237         public MuleShutdownHook()
238         {
239             super();
240         }
241 
242         @Override
243         public void run()
244         {
245             doShutdown();
246         }
247     }
248 }
249