View Javadoc

1   /*
2    * $Id: MuleContainerWrapper.java 20208 2010-11-17 14:33:40Z dirk.olmes $
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.reboot;
12  
13  import java.io.File;
14  import java.lang.reflect.Constructor;
15  import java.lang.reflect.Method;
16  
17  import org.tanukisoftware.wrapper.WrapperListener;
18  import org.tanukisoftware.wrapper.WrapperManager;
19  
20  public class MuleContainerWrapper implements WrapperListener
21  {
22      protected static final String CLASSNAME_MULE_CONTAINER = "org.mule.module.launcher.MuleContainer";
23  
24      /**
25       * We can't reference MuleContainer class literal here, as it will fail to resolve at runtime.
26       * Instead, make all calls anonymous through reflection, so we can safely pump up our new
27       * classloader and make it the default one for downstream applications.
28       */
29      private Object mule;
30  
31      /*---------------------------------------------------------------
32       * WrapperListener Methods
33       *-------------------------------------------------------------*/
34      /**
35       * The start method is called when the WrapperManager is signaled by the native
36       * wrapper code that it can start its application. This method call is expected
37       * to return, so a new thread should be launched if necessary.
38       *
39       * @param args List of arguments used to initialize the application.
40       * @return Any error code if the application should exit on completion of the
41       *         start method. If there were no problems then this method should return
42       *         null.
43       */
44      public Integer start(String[] args)
45      {
46          try
47          {
48              ClassLoader muleSystemCl = createContainerSystemClassLoader();
49  
50              Thread.currentThread().setContextClassLoader(muleSystemCl);
51  
52              Class<?> muleClass = Thread.currentThread().getContextClassLoader().loadClass(CLASSNAME_MULE_CONTAINER);
53              Constructor<?> c = muleClass.getConstructor(String[].class);
54              mule = c.newInstance(new Object[] {args});
55              Method startMethod = muleClass.getMethod("start", boolean.class);
56              startMethod.invoke(mule, true);
57              return null;
58          }
59          catch (Exception e)
60          {
61              e.printStackTrace();
62              return 1;
63          }
64      }
65  
66      protected ClassLoader createContainerSystemClassLoader() throws Exception
67      {
68          File muleHome = MuleContainerBootstrap.lookupMuleHome();
69          File muleBase = MuleContainerBootstrap.lookupMuleBase();
70          DefaultMuleClassPathConfig config = new DefaultMuleClassPathConfig(muleHome, muleBase);
71  
72          return new MuleContainerSystemClassLoader(config);
73      }
74  
75      /**
76       * Called when the application is shutting down. The Wrapper assumes that this
77       * method will return fairly quickly. If the shutdown code code could potentially
78       * take a long time, then WrapperManager.signalStopping() should be called to
79       * extend the timeout period. If for some reason, the stop method can not return,
80       * then it must call WrapperManager.stopped() to avoid warning messages from the
81       * Wrapper.
82       *
83       * @param exitCode The suggested exit code that will be returned to the OS when
84       *            the JVM exits.
85       * @return The exit code to actually return to the OS. In most cases, this should
86       *         just be the value of exitCode, however the user code has the option of
87       *         changing the exit code if there are any problems during shutdown.
88       */
89      public int stop(int exitCode)
90      {
91          try
92          {
93              Method shutdownMethod = mule.getClass().getMethod("shutdown");
94              shutdownMethod.invoke(mule);
95          }
96          catch (Throwable t)
97          {
98              // ignore
99          }
100 
101         return exitCode;
102     }
103 
104     /**
105      * Called whenever the native wrapper code traps a system control signal against
106      * the Java process. It is up to the callback to take any actions necessary.
107      * Possible values are: WrapperManager.WRAPPER_CTRL_C_EVENT,
108      * WRAPPER_CTRL_CLOSE_EVENT, WRAPPER_CTRL_LOGOFF_EVENT, or
109      * WRAPPER_CTRL_SHUTDOWN_EVENT
110      *
111      * @param event The system control signal.
112      */
113     public void controlEvent(int event)
114     {
115         if (WrapperManager.isControlledByNativeWrapper())
116         {
117             // The Wrapper will take care of this event
118         }
119         else
120         {
121             // We are not being controlled by the Wrapper, so
122             // handle the event ourselves.
123             if ((event == WrapperManager.WRAPPER_CTRL_C_EVENT)
124                 || (event == WrapperManager.WRAPPER_CTRL_CLOSE_EVENT)
125                 || (event == WrapperManager.WRAPPER_CTRL_SHUTDOWN_EVENT))
126             {
127                 WrapperManager.stop(0);
128             }
129         }
130     }
131 }