📄 wrappermanager.java
字号:
// Requested restarts no longer reset the restart count.
// Add new wrapper.ignore_signals property.
//
// Revision 1.12 2003/08/28 07:21:54 mortenson
// Remove output to System.out in the WrapperManager.requestThreadDump()
// method to avoid hang problems if the JVM is already hung while accessing
// the System.out object.
//
// Revision 1.11 2003/08/14 09:31:34 mortenson
// Fix a problem where the native library was missing from the release of OSX
//
// Revision 1.10 2003/07/01 14:49:45 mortenson
// Fix a problem where the JVM would sometimes hang when trying to shutdown if
// the wrapper.key parameter was passed to the JVM while not being controlled
// by the Wrapper.
//
// Revision 1.9 2003/06/07 05:18:32 mortenson
// Add a new method WrapperManager.stopImmediate which will cause the JVM to
// exit immediately without calling any stop methods or shutdown hooks.
//
// Revision 1.8 2003/05/29 09:27:14 mortenson
// Improve the debug output so that packet codes are now shown using a name
// rather than a raw number.
//
// Revision 1.7 2003/04/15 15:32:06 mortenson
// Fix a typo in a warning message.
//
// Revision 1.6 2003/04/09 06:26:14 mortenson
// Add some extra checks in the event where the native library can not be loaded
// so that the WrapperManager can differentiate between the library missing and
// not being readable due to permission problems.
//
// Revision 1.5 2003/04/03 04:05:23 mortenson
// Fix several typos in the docs. Thanks to Mike Castle.
//
// Revision 1.4 2003/04/02 10:05:53 mortenson
// Modified the wrapper.ping.timeout property so it also controls the ping
// timeout within the JVM. Before the timeout on responses to the Wrapper
// could be controlled, but the ping timeout within the JVM was hardcoded to
// 30 seconds.
//
// Revision 1.3 2003/03/07 02:11:18 mortenson
// Fix a problem with the wrapper.disable_shutdown_hook. Due to a typo in the
// source, the property was being ignored. This was broken in the 3.0.0 release.
//
// Revision 1.2 2003/03/02 04:23:31 mortenson
// Add a little more javadocs.
//
// Revision 1.1 2003/02/03 06:55:28 mortenson
// License transfer to TanukiSoftware.org
//
import java.io.DataInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.BindException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import org.tanukisoftware.wrapper.event.WrapperControlEvent;
import org.tanukisoftware.wrapper.event.WrapperEvent;
import org.tanukisoftware.wrapper.event.WrapperEventListener;
import org.tanukisoftware.wrapper.event.WrapperPingEvent;
import org.tanukisoftware.wrapper.event.WrapperServiceControlEvent;
import org.tanukisoftware.wrapper.event.WrapperTickEvent;
import org.tanukisoftware.wrapper.resources.ResourceManager;
import org.tanukisoftware.wrapper.security.WrapperEventPermission;
import org.tanukisoftware.wrapper.security.WrapperPermission;
import org.tanukisoftware.wrapper.security.WrapperServicePermission;
/**
* Handles all communication with the native portion of the Wrapper code.
* The native wrapper code will launch Java in a separate process and set
* up a server socket which the Java code is expected to open a socket to
* on startup. When the server socket is created, a port will be chosen
* depending on what is available to the system. This port will then be
* passed to the Java process as property named "wrapper.port".
*
* For security reasons, the native code will only allow connections from
* localhost and will expect to receive the key specified in a property
* named "wrapper.key".
*
* This class is implemented as a singleton class.
*
* Generate JNI Headers with the following command in the build/classes
* directory:
* javah -jni -classpath ./ org.tanukisoftware.wrapper.WrapperManager
*
* @author Leif Mortenson <leif@tanukisoftware.com>
* @version $Revision: 1.78 $
*/
public final class WrapperManager
implements Runnable
{
private static final String WRAPPER_CONNECTION_THREAD_NAME = "Wrapper-Connection";
private static final int DEFAULT_PORT = 15003;
private static final int DEFAULT_SO_TIMEOUT = 10000;
private static final int DEFAULT_CPU_TIMEOUT = 10000;
/** The number of milliseconds in one tick. Used for internal system
* time independent time keeping. */
private static final int TICK_MS = 100;
private static final int TIMER_FAST_THRESHOLD = 2 * 24 * 3600 * 1000 / TICK_MS; // 2 days.
private static final int TIMER_SLOW_THRESHOLD = 2 * 24 * 3600 * 1000 / TICK_MS; // 2 days.
private static final byte WRAPPER_MSG_START = (byte)100;
private static final byte WRAPPER_MSG_STOP = (byte)101;
private static final byte WRAPPER_MSG_RESTART = (byte)102;
private static final byte WRAPPER_MSG_PING = (byte)103;
private static final byte WRAPPER_MSG_STOP_PENDING = (byte)104;
private static final byte WRAPPER_MSG_START_PENDING = (byte)105;
private static final byte WRAPPER_MSG_STARTED = (byte)106;
private static final byte WRAPPER_MSG_STOPPED = (byte)107;
private static final byte WRAPPER_MSG_KEY = (byte)110;
private static final byte WRAPPER_MSG_BADKEY = (byte)111;
private static final byte WRAPPER_MSG_LOW_LOG_LEVEL = (byte)112;
private static final byte WRAPPER_MSG_PING_TIMEOUT = (byte)113;
private static final byte WRAPPER_MSG_SERVICE_CONTROL_CODE = (byte)114;
private static final byte WRAPPER_MSG_PROPERTIES = (byte)115;
/** Log commands are actually 116 + the LOG LEVEL. */
private static final byte WRAPPER_MSG_LOG = (byte)116;
/** Received when the user presses CTRL-C in the console on Windows or UNIX platforms. */
public static final int WRAPPER_CTRL_C_EVENT = 200;
/** Received when the user clicks on the close button of a Console on Windows. */
public static final int WRAPPER_CTRL_CLOSE_EVENT = 201;
/** Received when the user logs off of a Windows system. */
public static final int WRAPPER_CTRL_LOGOFF_EVENT = 202;
/** Received when a Windows system is shutting down. */
public static final int WRAPPER_CTRL_SHUTDOWN_EVENT = 203;
/** Received when a SIG TERM is received on a UNIX system. */
public static final int WRAPPER_CTRL_TERM_EVENT = 204;
/** Log message at debug log level. */
public static final int WRAPPER_LOG_LEVEL_DEBUG = 1;
/** Log message at info log level. */
public static final int WRAPPER_LOG_LEVEL_INFO = 2;
/** Log message at status log level. */
public static final int WRAPPER_LOG_LEVEL_STATUS = 3;
/** Log message at warn log level. */
public static final int WRAPPER_LOG_LEVEL_WARN = 4;
/** Log message at error log level. */
public static final int WRAPPER_LOG_LEVEL_ERROR = 5;
/** Log message at fatal log level. */
public static final int WRAPPER_LOG_LEVEL_FATAL = 6;
/** Log message at advice log level. */
public static final int WRAPPER_LOG_LEVEL_ADVICE = 7;
/** Service Control code which can be sent to start a service. */
public static final int SERVICE_CONTROL_CODE_START = 0x10000;
/** Service Control code which can be sent or received to stop a service. */
public static final int SERVICE_CONTROL_CODE_STOP = 1;
/** Service Control code which can be sent to pause a service. */
public static final int SERVICE_CONTROL_CODE_PAUSE = 2;
/** Service Control code which can be sent to resume a paused service. */
public static final int SERVICE_CONTROL_CODE_CONTINUE = 3;
/** Service Control code which can be sent to or received interrogate the status of a service. */
public static final int SERVICE_CONTROL_CODE_INTERROGATE = 4;
/** Service Control code which can be received when the system is shutting down. */
public static final int SERVICE_CONTROL_CODE_SHUTDOWN = 5;
/** Reference to the original value of System.out. */
private static PrintStream m_out;
/** Reference to the original value of System.err. */
private static PrintStream m_err;
/** Flag that will be set to true once a SecurityManager has been detected and tested. */
private static boolean m_securityManagerChecked = false;
private static boolean m_disposed = false;
private static boolean m_started = false;
private static WrapperManager m_instance = null;
private static Thread m_hook = null;
private static boolean m_hookTriggered = false;
/* Flag which records when the shutdownJVM method has completed. */
private static boolean m_shutdownJVMComplete = false;
private static String[] m_args;
private static int m_port = DEFAULT_PORT;
private static int m_jvmPort;
private static int m_jvmPortMin;
private static int m_jvmPortMax;
private static String m_key;
private static int m_soTimeout = DEFAULT_SO_TIMEOUT;
private static long m_cpuTimeout = DEFAULT_CPU_TIMEOUT;
/** Tick count when the start method completed. */
private static int m_startedTicks;
/** The lowest configured log level in the Wrapper's configuration. This
* is set to a high value by default to disable all logging if the
* Wrapper does not register its low level or is not present. */
private static int m_lowLogLevel = WRAPPER_LOG_LEVEL_ADVICE + 1;
/** The maximum amount of time in ms to allow to pass without the JVM
* pinging the server before the JVM is terminated to allow a resynch. */
private static int m_pingTimeout = 30000;
/** Flag, set when the JVM is launched that is used to remember whether
* or not system signals are supposed to be ignored. */
private static boolean m_ignoreSignals = false;
/** Thread which processes all communications with the native code. */
private static Thread m_commRunner;
private static boolean m_commRunnerStarted = false;
private static Thread m_eventRunner;
private static int m_eventRunnerTicks;
private static Thread m_startupRunner;
/** True if the system time should be used for internal timeouts. */
private static boolean m_useSystemTime;
/** The threashold of how many ticks the timer can be fast before a
* warning is displayed. */
private static int m_timerFastThreshold;
/** The threashold of how many ticks the timer can be slow before a
* warning is displayed. */
private static int m_timerSlowThreshold;
/**
* Bit depth of the currently running JVM. Will be 32 or 64.
* A 64-bit JVM means that the system is also 64-bit, but a 32-bit JVM
* can be run either on a 32 or 64-bit system.
*/
private static int m_jvmBits;
/** An integer which stores the number of ticks since the
* JVM was launched. Using an int rather than a long allows the value
* to be used without requiring any synchronization. This is only
* used if the m_useSystemTime flag is false. */
private static volatile int m_ticks;
private static WrapperListener m_listener;
private static int m_lastPingTicks;
private static ServerSocket m_serverSocket;
private static Socket m_socket;
private static boolean m_shuttingDown = false;
private static boolean m_appearHung = false;
private static Method m_addShutdownHookMethod = null;
private static Method m_removeShutdownHookMethod = null;
private static boolean m_service = false;
private static boolean m_debug = false;
private static int m_jvmId = 0;
private static boolean m_stopping = false;
private static Thread m_stoppingThread;
private static int m_exitCode;
private static boolean m_libraryOK = false;
private static byte[] m_commandBuffer = new byte[512];
/** The contents of the wrapper configuration. */
private static WrapperProperties m_properties;
/** List of registered WrapperEventListeners and their registered masks. */
private static List m_wrapperEventListenerMaskList = new ArrayList();
/** Array of registered WrapperEventListeners and their registered masks.
* Should not be referenced directly. Access by calling
* getWrapperEventListenerMasks(). */
private static WrapperEventListenerMask[] m_wrapperEventListenerMasks = null;
/** Flag used to tell whether or not WrapperCoreEvents should be produced. */
private static boolean m_produceCoreEvents = false;
// message resources: eventually these will be split up
private static ResourceManager m_res = ResourceManager.getResourceManager();
private static ResourceManager m_error = m_res;
private static ResourceManager m_warning = m_res;
private static ResourceManager m_info = m_res;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -