View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.boot;
8   
9   import java.lang.reflect.Constructor;
10  import java.lang.reflect.Method;
11  
12  import org.tanukisoftware.wrapper.WrapperListener;
13  import org.tanukisoftware.wrapper.WrapperManager;
14  
15  public class MuleServerWrapper implements WrapperListener
16  {
17  
18      /**
19       * We can't reference MuleServer class literal here, as it will fail to resolve at runtime.
20       * Instead, make all calls anonymous through reflection, so we can safely pump up our new classloader
21       * and make it the default one for downstream applications. 
22       */
23      private Object mule;
24  
25      /*---------------------------------------------------------------
26       * Constructors
27       *-------------------------------------------------------------*/
28      public MuleServerWrapper()
29      {
30          super();
31      }
32  
33      /*---------------------------------------------------------------
34       * WrapperListener Methods
35       *-------------------------------------------------------------*/
36      /**
37       * The start method is called when the WrapperManager is signaled by the native
38       * wrapper code that it can start its application. This method call is expected
39       * to return, so a new thread should be launched if necessary.
40       * 
41       * @param args List of arguments used to initialize the application.
42       * @return Any error code if the application should exit on completion of the
43       *         start method. If there were no problems then this method should return
44       *         null.
45       */
46      public Integer start(String[] args)
47      {
48          try
49          {
50              ClassLoader muleSystemCl = new MuleSystemClassLoader();
51  
52              Thread.currentThread().setContextClassLoader(muleSystemCl);
53  
54              Class muleClass = Thread.currentThread().getContextClassLoader().loadClass("org.mule.MuleServer");
55              Constructor c = muleClass.getConstructor(String[].class);
56              mule = c.newInstance(new Object[] {args});
57              Method startMethod = muleClass.getMethod("start", boolean.class, boolean.class);
58              startMethod.invoke(mule, false, false);
59              return null;
60          }
61          catch (Exception e)
62          {
63              e.printStackTrace();
64              return Integer.valueOf(1);
65          }
66      }
67  
68      /**
69       * Called when the application is shutting down. The Wrapper assumes that this
70       * method will return fairly quickly. If the shutdown code code could potentially
71       * take a long time, then WrapperManager.signalStopping() should be called to
72       * extend the timeout period. If for some reason, the stop method can not return,
73       * then it must call WrapperManager.stopped() to avoid warning messages from the
74       * Wrapper.
75       * 
76       * @param exitCode The suggested exit code that will be returned to the OS when
77       *            the JVM exits.
78       * @return The exit code to actually return to the OS. In most cases, this should
79       *         just be the value of exitCode, however the user code has the option of
80       *         changing the exit code if there are any problems during shutdown.
81       */
82      public int stop(int exitCode)
83      {
84          try
85          {
86              Method shutdownMethod = mule.getClass().getMethod("shutdown");
87              shutdownMethod.invoke(mule);
88          }
89          catch (Throwable t)
90          {
91              // ignore
92          }
93          
94          return exitCode;
95      }
96  
97      /**
98       * Called whenever the native wrapper code traps a system control signal against
99       * the Java process. It is up to the callback to take any actions necessary.
100      * Possible values are: WrapperManager.WRAPPER_CTRL_C_EVENT,
101      * WRAPPER_CTRL_CLOSE_EVENT, WRAPPER_CTRL_LOGOFF_EVENT, or
102      * WRAPPER_CTRL_SHUTDOWN_EVENT
103      * 
104      * @param event The system control signal.
105      */
106     public void controlEvent(int event)
107     {
108         if (WrapperManager.isControlledByNativeWrapper())
109         {
110             // The Wrapper will take care of this event
111         }
112         else
113         {
114             // We are not being controlled by the Wrapper, so
115             // handle the event ourselves.
116             if ((event == WrapperManager.WRAPPER_CTRL_C_EVENT)
117                 || (event == WrapperManager.WRAPPER_CTRL_CLOSE_EVENT)
118                 || (event == WrapperManager.WRAPPER_CTRL_SHUTDOWN_EVENT))
119             {
120                 WrapperManager.stop(0);
121             }
122         }
123     }
124 
125 }