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