📄 wrappermanager.java
字号:
/*---------------------------------------------------------------
* Class Initializer
*-------------------------------------------------------------*/
/**
* When the WrapperManager class is first loaded, it attempts to load the
* configuration file specified using the 'wrapper.config' system property.
* When the JVM is launched from the Wrapper native code, the
* 'wrapper.config' and 'wrapper.key' parameters are specified.
* The 'wrapper.key' parameter is a password which is used to verify that
* connections are only coming from the native Wrapper which launched the
* current JVM.
*/
static
{
// The wraper.jar must be given AllPermissions if a security manager
// has been configured. This is not a problem if one of the standard
// Wrapper helper classes is used to launch the JVM.
// If however a custom WrapperListener is being implemented then this
// class will most likely be loaded by code that is neither part of
// the system, nor part of the Wrapper code base. To avoid having
// to also give those classes AllPermissions as well, we do all of
// initialization in a Privileged block. This means that the code
// only requires that the wrapper.jar has been given the required
// permissions.
AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
privilegedClassInit();
return null;
}
}
);
}
/**
* The body of the static initializer is moved into a seperate method so
* it can be run as a PrivilegedAction.
*/
private static void privilegedClassInit()
{
// Store references to the original System.out and System.err
// PrintStreams. The WrapperManager will always output to the
// original streams so its output will always end up in the
// wrapper.log file even if the end user code redirects the
// output to another log file.
// This is also important to be protect the Wrapper's functionality
// from the case where the user PrintStream enters a deadlock state.
m_out = System.out;
m_err = System.err;
// Always create an empty properties object in case we are not running
// in the Wrapper or the properties are never sent.
m_properties = new WrapperProperties();
m_properties.lock();
// This must be done before attempting to access any System Properties
// as that could cause a SecurityException if it is too strict.
checkSecurityManager();
// Check for the debug flag
m_debug = WrapperSystemPropertyUtil.getBooleanProperty( "wrapper.debug", false );
if ( m_debug )
{
m_out.println( "WrapperManager class initialized by thread: "
+ Thread.currentThread().getName()
+ " Using classloader: " + WrapperManager.class.getClassLoader() );
}
m_out.println( "Wrapper (Version " + getVersion() + ") http://wrapper.tanukisoftware.org" );
m_out.println();
// Check for the jvmID
m_jvmId = WrapperSystemPropertyUtil.getIntProperty( "wrapper.jvmid", 1 );
if ( m_debug )
{
m_out.println( "Wrapper Manager: JVM #" + m_jvmId );
}
// Decide whether this is a 32 or 64 bit version of Java.
m_jvmBits = Integer.getInteger( "sun.arch.data.model", -1 ).intValue();
if ( m_debug )
{
if ( m_jvmBits > 0 )
{
m_out.println( "Running a " + m_jvmBits + "-bit JVM." );
}
else
{
m_out.println( "The bit depth of this JVM could not be determined." );
}
}
// Initialize the timerTicks to a very high value. This means that we will
// always encounter the first rollover (200 * WRAPPER_MS / 1000) seconds
// after the Wrapper the starts, which means the rollover will be well
// tested.
m_ticks = Integer.MAX_VALUE - 200;
m_useSystemTime = WrapperSystemPropertyUtil.getBooleanProperty(
"wrapper.use_system_time", false );
m_timerFastThreshold = WrapperSystemPropertyUtil.getIntProperty(
"wrapper.timer_fast_threshold", TIMER_FAST_THRESHOLD ) * 1000 / TICK_MS;
m_timerSlowThreshold = WrapperSystemPropertyUtil.getIntProperty(
"wrapper.timer_slow_threshold", TIMER_SLOW_THRESHOLD ) * 1000 / TICK_MS;
// Check to see if we should register a shutdown hook
boolean disableShutdownHook = WrapperSystemPropertyUtil.getBooleanProperty(
"wrapper.disable_shutdown_hook", false );
// Locate the add and remove shutdown hook methods using reflection so
// that this class can be compiled on 1.2.x versions of java.
try
{
m_addShutdownHookMethod =
Runtime.class.getMethod( "addShutdownHook", new Class[] { Thread.class } );
m_removeShutdownHookMethod =
Runtime.class.getMethod( "removeShutdownHook", new Class[] { Thread.class } );
}
catch ( NoSuchMethodException e )
{
if ( m_debug )
{
m_out.println(
"Wrapper Manager: Shutdown hooks not supported by current JVM." );
}
m_addShutdownHookMethod = null;
m_removeShutdownHookMethod = null;
disableShutdownHook = true;
}
// If the shutdown hook is not disabled, then register it.
if ( !disableShutdownHook )
{
if ( m_debug )
{
m_out.println( "Wrapper Manager: Registering shutdown hook" );
}
m_hook = new Thread( "Wrapper-Shutdown-Hook" )
{
/**
* Run the shutdown hook. (Triggered by the JVM when it is about to shutdown)
*/
public void run()
{
// Stop the Wrapper cleanly.
m_hookTriggered = true;
if ( m_debug )
{
m_out.println( "Wrapper Manager: ShutdownHook started" );
}
// Let the startup thread die since the shutdown hook is running.
m_startupRunner = null;
// If we are not already stopping, then do so.
WrapperManager.stop( 0 );
if ( m_debug )
{
m_out.println( "Wrapper Manager: ShutdownHook complete" );
}
}
};
// Actually register the shutdown hook using reflection.
try
{
m_addShutdownHookMethod.invoke( Runtime.getRuntime(), new Object[] { m_hook } );
}
catch ( IllegalAccessException e )
{
m_out.println( "Wrapper Manager: Unable to register shutdown hook: " + e );
}
catch ( InvocationTargetException e )
{
Throwable t = e.getTargetException();
if ( t == null )
{
t = e;
}
m_out.println( "Wrapper Manager: Unable to register shutdown hook: " + t );
}
}
// A key is required for the wrapper to work correctly. If it is not
// present, then assume that we are not being controlled by the native
// wrapper.
if ( ( m_key = System.getProperty( "wrapper.key" ) ) == null )
{
if ( m_debug )
{
m_out.println( "Wrapper Manager: Not using wrapper. (key not specified)" );
}
// The wrapper will not be used, so other values will not be used.
m_port = 0;
m_jvmPort = 0;
m_jvmPortMin = 0;
m_jvmPortMax = 0;
m_service = false;
m_cpuTimeout = 31557600000L; // One Year. Effectively never.
}
else
{
if ( m_debug )
{
m_out.println( "Wrapper Manager: Using wrapper" );
}
// A port must have been specified.
String sPort;
if ( ( sPort = System.getProperty( "wrapper.port" ) ) == null )
{
String msg = m_res.format( "MISSING_PORT" );
m_out.println( msg );
throw new ExceptionInInitializerError( msg );
}
try
{
m_port = Integer.parseInt( sPort );
}
catch ( NumberFormatException e )
{
String msg = m_res.format( "BAD_PORT", sPort );
m_out.println( msg );
throw new ExceptionInInitializerError( msg );
}
m_jvmPort =
WrapperSystemPropertyUtil.getIntProperty( "wrapper.jvm.port", 0 );
m_jvmPortMin =
WrapperSystemPropertyUtil.getIntProperty( "wrapper.jvm.port.min", 31000 );
m_jvmPortMax =
WrapperSystemPropertyUtil.getIntProperty( "wrapper.jvm.port.max", 31999 );
// Check for the ignore signals flag
m_ignoreSignals = WrapperSystemPropertyUtil.getBooleanProperty(
"wrapper.ignore_signals", false );
// If this is being run as a headless server, then a flag would have been set
m_service = WrapperSystemPropertyUtil.getBooleanProperty( "wrapper.service", false );
// Get the cpuTimeout
String sCPUTimeout = System.getProperty( "wrapper.cpu.timeout" );
if ( sCPUTimeout == null )
{
m_cpuTimeout = DEFAULT_CPU_TIMEOUT;
}
else
{
try
{
m_cpuTimeout = Integer.parseInt( sCPUTimeout ) * 1000L;
}
catch ( NumberFormatException e )
{
String msg = m_res.format( "BAD_CPU_TIMEOUT", sCPUTimeout );
m_out.println( msg );
throw new ExceptionInInitializerError( msg );
}
}
}
// Make sure that the version of the Wrapper is correct.
verifyWrapperVersion();
// Register the MBeans if configured to do so.
if ( WrapperSystemPropertyUtil.getBooleanProperty(
WrapperManager.class.getName() + ".mbean", true ) )
{
registerMBean( new org.tanukisoftware.wrapper.jmx.WrapperManager(),
"org.tanukisoftware.wrapper:type=WrapperManager" );
}
if ( WrapperSystemPropertyUtil.getBooleanProperty(
WrapperManager.class.getName() + ".mbean.testing", false ) )
{
registerMBean( new org.tanukisoftware.wrapper.jmx.WrapperManagerTesting(),
"org.tanukisoftware.wrapper:type=WrapperManagerTesting" );
}
// Initialize the native code to trap system signals
initializeNativeLibrary();
if ( m_libraryOK )
{
// Make sure that the native library's version is correct.
verifyNativeLibraryVersion();
// Get the PID of the current JVM from the native library. Be careful as the method
// will not exist if the library is old.
try
{
System.setProperty( "wrapper.java.pid", Integer.toString( nativeGetJavaPID() ) );
}
catch ( Throwable e )
{
if ( m_debug )
{
m_out.println( "Call to nativeGetJavaPID() failed: " + e );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -