ApplicationServerpublic class ApplicationServer extends Object ApplicationServer is the main entry point for iAS 7.0 J2EE server instance.
This code implements the server lifecycle state transitions and it relies on
various iAS 7.0 subsystems such as Web/EJB containers throught its lifecycle.
com.sun.enterprise.J2EEServer is the RI counerpart of this code; the evolving
iAS server implementation replaces functionality of RI J2EEServer.
NOTES on services by name:
Default services implementing lifecycle interface for orderly startup
shutdown and hot deployment.
Each service entry is of the form {name, className}.
Note: Make sure LifecycleModuleService is the last subsystem in this list. |
Fields Summary |
---|
protected static final Logger | _loggerserver logger | private static ServerContext | contextServerContext -- server-wide runtime environment context | private final List | servicesservices -- standard runtime service objects | private ClassLoader | commonClassLoadercommon class loader for the server | private ClassLoader | connectorClassLoadershare class loader for the server | private static final int | CLASSNAME_IDXIndex into String[] of the classname for a ServerLifecycle. | private static final RunnableBase.HowToRun | HOW_TO_RUNChanging to RUN_IN_SEPARATE_THREAD achieves some efficiences at
startup, but leaving it as 'RUN_IN_CURRENT_THREAD' until time allows
testing. |
Constructors Summary |
---|
public ApplicationServer()Default constructor.
|
Methods Summary |
---|
public static ServerContext | getServerContext()Get the server runtime context; returns a valid context only
after initialization; a null otherwise.
return context;
| protected static final com.sun.appserv.server.ServerLifecycle | instantiateOneServerLifecycle(ServerContext serverContext, java.lang.String classname)
//final TimingDelta delta = new TimingDelta();
final Class c = Class.forName( classname );
ServerLifecycle item = null;
// call a constructor that takes a ServerContext if it exists, since
// some services might make efficient use of it during construction.
// otherwise use a no-argument constructor
try {
final Constructor constructor = c.getConstructor( ServerContext.class );
item = (ServerLifecycle)constructor.newInstance( serverContext );
}
catch( Exception e ) {
item = (ServerLifecycle)c.newInstance();
}
//System.out.println( "Instantiate " + classname + ": " + delta.elapsedMillis() );
return item;
| protected java.util.List | instantiateRuntimeServices(ServerContext serverContext, java.lang.String[][] servicesByName)
final List<String> classnames = new ArrayList<String>();
for (int i=0; i < servicesByName.length; i++) {
final String[] serviceInfo = servicesByName[i];
final String classname = serviceInfo[ CLASSNAME_IDX ];
classnames.add( classname );
}
return instantiateRuntimeServices( serverContext, classnames );
| protected java.util.List | instantiateRuntimeServices(ServerContext serverContext, java.util.List classnames)Go through the list of built-in runtime services and instantiate them.
final Instantiator[] instantiators = new Instantiator[ classnames.size() ];
// Instantiate service objects
int idx = 0;
for ( final String classname : classnames ) {
instantiators[idx] = new Instantiator( serverContext, classname );
instantiators[idx].submit( );
++idx;
}
// collect the resulting ServerLifecycle
final List<ServerLifecycle> serviceList = new ArrayList<ServerLifecycle>();
for ( int i = 0; i < instantiators.length; ++i ) {
serviceList.add( instantiators[i].getService() );
}
return serviceList;
| private void | logCommonClassLoaderDetails()
Logger _log = LogDomains.getLogger(LogDomains.LOADER_LOGGER);
if (_log.isLoggable( Level.FINE ) ) {
if (commonClassLoader instanceof URLClassLoader) {
URL[] u = ((URLClassLoader)commonClassLoader).getURLs();
StringBuffer sbuf = new StringBuffer();
for (int i = 0; i < u.length; i++) {
sbuf.append(u[i].toExternalForm() + " ,");
}
_log.log(Level.FINE, "Common classloader contents: [ " + sbuf.toString() + " ].") ;
}
}
| public void | onInitialization(ServerContext context)Server is initializing subsystems and setting up the runtime environment.
Prepare for the beginning of active use of the public methods of this
subsystem. This method is called before any of the public methods of
this subsystem are utilized.
// sets the server context
this.context = context;
// NOTE: side effects of reInitializeServerLoggers invoke various MBean related code
// that really ought not to run yet, and that code hits synchronized code being relied
// upon (indirectly via a Logger). The thread initializing the MBeanServer (see PEMain)
// will try to acquire that same synchronized lock and then hang.
// See CR6555027.
com.sun.enterprise.util.FeatureAvailability.getInstance().waitForMBeanServer();
// initialize all server loggers that were not initialized
// Note: reInitializeServerLoggers should be called after
// setting the server context and before performing any
// other server startup activities that needs a logger
ServerLogManager.reInitializeServerLoggers();
// print jvm info
printStartupInfo();
// system class loader
ClassLoader parentOfCommonCL = this.getClass().getClassLoader();
//Shared CL
//In the new CL hierarchy the parent of common classloader
//is the shared chain.
if(Boolean.getBoolean(com.sun.enterprise.server.PELaunch.USE_NEW_CLASSLOADER_PROPERTY))
parentOfCommonCL = PELaunch.getSharedChain();
final InstanceEnvironment env = this.context.getInstanceEnvironment();
try {
final String dir = env.getLibClassesPath();
final String jarDir = env.getLibPath();
// constructs the common class loader. System class loader
// is the parent of common class loader. Common class loader
// includes <instance>/lib/classes dir, <instance>/lib/*.jar
// and <instance>/lib/*.zip
commonClassLoader =
ClassLoaderUtils.getClassLoader(new File[] {new File(dir)},
new File[] {new File(jarDir)},
parentOfCommonCL
);
logCommonClassLoaderDetails();
// ignore if null
if (commonClassLoader == null) {
commonClassLoader = parentOfCommonCL;
}
} catch (IOException ioe) {
_logger.log(Level.WARNING, "server.ioexception", ioe);
commonClassLoader = parentOfCommonCL;
} catch (Throwable th) {
_logger.log(Level.WARNING, "server.exception", th);
commonClassLoader = parentOfCommonCL;
}
// Create the connector class loader. This will be the parent class
// loader for all j2ee components!! Common class loader is the
// parent of connector class loader.
connectorClassLoader =
ConnectorClassLoader.getInstance(commonClassLoader);
// sets the class loaders in the server context
if (this.context instanceof ServerContextImpl) {
final ServerContextImpl contextImpl = (ServerContextImpl) this.context;
// set the common classloader in the server context
contextImpl.setCommonClassLoader(commonClassLoader);
// sets the shared class loader
contextImpl.setSharedClassLoader(connectorClassLoader);
// sets the life cycle parent class loader
contextImpl.setLifecycleParentClassLoader(connectorClassLoader);
}
// final common class loader for the anonymous inner class
final ClassLoader commonCL = commonClassLoader;
// set the common class loader as the thread context class loader
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
Thread.currentThread().setContextClassLoader(commonCL);
return null;
}
}
);
//added the pluggable interface way of getting the list of services
final InternalServicesList servicesList =
context.getPluggableFeatureFactory().getInternalServicesList();
final String[][] servicesByName = servicesList.getServicesByName();
if (servicesByName == null) {
_logger.log(Level.SEVERE, "services.null");
throw new ServerLifecycleException();
}
// security manager is set inside SecurityLifecycle
// Instantiate the built-in runtime services
final List<ServerLifecycle> temp = instantiateRuntimeServices( context, servicesByName );
services.addAll( temp );
// Initialize the built-in runtime services
for ( final ServerLifecycle service : services) {
try {
service.onInitialization(context);
} catch (ServerLifecycleException e) {
_logger.log(Level.SEVERE, "service.notinit",
new Object[] {service, e.toString()});
throw e;
}
}
//add listeners for security dynamic reconfiguration
AdminEventListenerRegistry.addAuditModuleEventListener(
new AuditModuleEventListenerImpl());
AdminEventListenerRegistry.addAuthRealmEventListener(
new AuthRealmEventListenerImpl());
AdminEventListenerRegistry.addSecurityServiceEventListener(
new SecurityServiceEventListenerImpl());
AdminEventListenerRegistry.addUserMgmtEventListener(
new UserMgmtEventListenerImpl());
AdminEventListenerRegistry.addEventListener(
MessageSecurityConfigEvent.eventType,
new MessageSecurityConfigEventListenerImpl());
// Call RI J2EEServer initialization code. Note that all resources
// specified in server.xml will be loaded by the common class loader.
try {
J2EEServer.main(context);
} catch (Exception e) {
throw new ServerLifecycleException(e);
}
// final connector class loader for the anonymous inner class
final ClassLoader connCL = connectorClassLoader;
// set the connector class loader as the thread context class loader
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
Thread.currentThread().
setContextClassLoader(connCL);
return null;
}
}
);
| public void | onReady()Server has complted loading the applications and is ready to
serve requests.
try {
// registers the resource manager as a listener for the
// resource deploy events
AdminEventListenerRegistry.addResourceDeployEventListener(
new ResourceManager(context));
// registers listeners for JmsService and JmsHost changes.
AdminEventListenerRegistry.addEventListener(JmsServiceEvent.eventType,
new JmsServiceEventListener());
AdminEventListenerRegistry.addEventListener(JmsHostEvent.eventType,
new JmsHostEventListener());
// Since onReady is called by a new thread, we have to again set
// the common class loader as the thread context class loader
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
Thread.currentThread().setContextClassLoader
(commonClassLoader);
return null;
}
}
);
/*
* com.sun.enterprise.server.startupHook is an internal
* undocumented property that can be used by iplanet developers
* to invoke some custom code just after server startup happens.
* Currently it is used by the ORB to easily benchmark and profile
* the local invocation path of remote interfaces in the EJB
* without having to deal with servlets or client/server processes
*
* If the property com.sun.enterprise.server.startupHook is
* defined then "main" in that class is executed
* Note: This should always be the last piece of code executed
* in this method
*/
String startupHook = null;
startupHook = System.getProperty(
"com.sun.enterprise.server.startupHook");
if (startupHook != null) {
try {
// Call the custom startup hook specified
Class hookClass = Class.forName(startupHook);
java.lang.reflect.Method hookMethod =
hookClass.getMethod("main",
new Class[] { ServerContext.class });
hookMethod.invoke(null, new Object[] { context });
}
catch (Exception ex) {
if (Debug.enabled) {
_logger.log(Level.FINE, "server.exception", ex);
}
}
}
} catch (Exception ee) {
throw new ServerLifecycleException(ee);
}
// notify the built-in runtime services that we are ready
for ( final ServerLifecycle service : services) {
try {
service.onReady(context);
} catch (ServerLifecycleException e) {
_logger.log(Level.SEVERE, "service.notready",
new Object[] {service, e.toString()});
}
}
| public void | onShutdown()Server is shutting down applications
// shutdown the built-in runtime services (in the reverse order).
for (int i = services.size(); i > 0; i--) {
final ServerLifecycle service = services.get(i-1);
_logger.log(Level.FINE,"service.shutdown", services.get(i-1));
try {
service.onShutdown();
} catch (Exception e) {
//do nothing since we want to continue shutting down other LFC
//modules
_logger.log(Level.WARNING, "server.exception", e);
}
}
| public void | onStartup()Server is starting up applications
// startup the built-in runtime services
for ( final ServerLifecycle service : services) {
try {
service.onStartup(context);
} catch (ServerLifecycleException e) {
_logger.log(Level.SEVERE, "service.notstarted",
new Object[] {service, e.toString()});
throw e;
}
}
// _REVISIT_: Mover AlertConfigurator to configure after onReady()
AlertConfigurator.getAlertConfigurator( ).configure( );
| public void | onTermination()Server is terminating the subsystems and the runtime environment.
Gracefully terminate the active use of the public methods of this
subsystem. This method should be the last one called on a given
instance of this subsystem.
//Kill all connections in the appserver's connection pools
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE, "Killing all pools in the appserver");
}
try {
Switch.getSwitch().getPoolManager().killAllPools();
} catch( Throwable t ) {
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE, "exception : " +t);
}
}
// terminate the built-in runtime services (in the reverse order)
for (int i = services.size(); i > 0; i--) {
final ServerLifecycle service = services.get(i-1);
_logger.log(Level.FINE,"service.shutdown",
services.get(i-1));
try {
service.onTermination();
} catch (Exception e) {
//do nothing since we want to continue shutting down other LFC
//modules
_logger.log(Level.WARNING, "server.exception", e);
}
}
services.clear();
| private void | printStartupInfo()
_logger.log(Level.INFO, "j2eerunner.printstartinfo",
new Object[] {
System.getProperty("java.vm.name"),
System.getProperty("java.version"),
System.getProperty("java.vm.vendor") });
| protected void | setServerContext(ServerContext context)
this.context = context;
|
|