See:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=1975
This change offers a reduction of 6% in startup time on my MacBook
Pro Core 2 Duo 2.33GHz. It works by running the onInitialization work
in a separate thread. No change in load order or initialization is
made with respect to modules.
I also need a volunteer to run QuickLook enterprise on Linux. I will
run it on Mac OS X and Solaris.
The modified file is attached, and diffs are found below.
---------------
-----------------
cvs server: Diffing src/java/com/sun/appserv/server
Index: src/java/com/sun/appserv/server/LifecycleModuleService.java
===================================================================
RCS file: /cvs/glassfish/appserv-core/src/java/com/sun/appserv/server/
LifecycleModuleService.java,v
retrieving revision 1.7
diff -u -w -r1.7 LifecycleModuleService.java
--- src/java/com/sun/appserv/server/LifecycleModuleService.java 1 Dec
2006 09:55:32 -0000 1.7
+++ src/java/com/sun/appserv/server/LifecycleModuleService.java 16
Jan 2007 19:49:06 -0000
@@ -25,6 +25,7 @@
import java.util.HashSet;
import java.util.Set;
+import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
@@ -47,6 +48,10 @@
import com.sun.enterprise.server.ServerContext;
+import com.sun.appserv.management.util.misc.TimingDelta;
+import com.sun.appserv.management.util.misc.RunnableBase;
+import com.sun.appserv.management.helper.AMXDebugHelper;
+
/**
* Support class to assist in firing LifecycleEvent notifications to
* registered LifecycleListeners.
@@ -57,30 +62,38 @@
public class LifecycleModuleService implements ServerLifecycle {
+ private OneTimeIniter mOneTimeIniter;
+
+ private final AMXDebugHelper mDebug = new AMXDebugHelper
( "LifecycleModuleService" );
+ private void debug( final Object...args ) { mDebug.println
( args ); }
+
/**
* The set of registered LifecycleListeners for event
notifications.
*/
- private ArrayList listeners = new ArrayList();
+ private final List<ServerLifecycleModule> listeners = new
ArrayList<ServerLifecycleModule>();
+ private final class OneTimeIniter extends RunnableBase {
+ private final ServerContext mServerContext;
- public synchronized void onInitialization(ServerContext context)
- throws
ServerLifecycleException {
+ public OneTimeIniter( final ServerContext serverContext ) {
+ mServerContext = serverContext;
+ }
- try {
+ protected void doRun() throws ConfigException,
ServerLifecycleException {
//ROB: config changes
//Applications apps =
- //ServerBeansFactory.getServerBean
(context.getConfigContext()).getApplications();
- Applications apps =
ServerBeansFactory.getApplicationsBean(context.getConfigContext());
+ //ServerBeansFactory.getServerBean
(mServerContext.getConfigContext()).getApplications();
+ final Applications apps =
ServerBeansFactory.getApplicationsBean(mServerContext.getConfigContext
());
if (apps == null) return;
- LifecycleModule[] lcms = apps.getLifecycleModule();
+ final LifecycleModule[] lcms = apps.getLifecycleModule();
if(lcms == null) return;
- HashSet listenerSet = new HashSet();
+ final HashSet listenerSet = new HashSet();
for(int i=0;i<lcms.length;i++) {
- LifecycleModule next = lcms[i];
+ final LifecycleModule next = lcms[i];
- if ( isEnabled(next, context.getConfigContext()) ) {
+ if ( isEnabled(next, mServerContext.getConfigContext
()) ) {
int order = Integer.MAX_VALUE;
String strOrder = next.getLoadOrder();
if (strOrder != null) {
@@ -90,14 +103,13 @@
nfe.printStackTrace();
}
}
- ServerLifecycleModule slcm =
- new ServerLifecycleModule(context,
- next.getName(), next.getClassName
());
+ final ServerLifecycleModule slcm =
+ new ServerLifecycleModule(mServerContext,
next.getName(), next.getClassName());
slcm.setLoadOrder(order);
slcm.setClasspath(next.getClasspath());
slcm.setIsFatal(next.isIsFailureFatal());
- ElementProperty[] s = next.getElementProperty();
+ final ElementProperty[] s =
next.getElementProperty();
if(s != null) {
for(int j=0;j< s.length;j++) {
ElementProperty next1 = s[j];
@@ -105,17 +117,57 @@
}
}
- LifecycleListener listener =
slcm.loadServerLifecycle();
+ final LifecycleListener listener =
slcm.loadServerLifecycle();
listenerSet.add(slcm);
}
}
sortModules(listenerSet);
- } catch(Exception ce1) {
- // FIXME eat it?
- ce1.printStackTrace();
+
+ initialize(mServerContext);
+ }
+ };
+
+
+ private void sortModules( final HashSet listenerSet) {
+ // FIXME: use a better sorting algo
+ for( final Iterator iter = listenerSet.iterator();
iter.hasNext();) {
+ final ServerLifecycleModule next =
(ServerLifecycleModule) iter.next();
+ final int order = next.getLoadOrder();
+ int i=0;
+ for(;i<this.listeners.size();i++) {
+ if( listeners.get(i).getLoadOrder() > order) {
+ break;
+ }
+ }
+ this.listeners.add(i,next);
}
+ }
+
+ private void initialize( final ServerContext context)
+ throws ServerLifecycleException {
+ if (listeners.isEmpty())
+ return;
- initialize(context);
+ final ClassLoader cl = Thread.currentThread
().getContextClassLoader();
+ for( final ServerLifecycleModule next : listeners ) {
+ next.onInitialization(context);
+ }
+ // set it back
+ resetClassLoader(cl);
+ }
+
+
+
+ public LifecycleModuleService() {
+ }
+
+
+ public synchronized void onInitialization( final ServerContext
context)
+ throws
ServerLifecycleException {
+ mOneTimeIniter = new OneTimeIniter( context );
+
+ mOneTimeIniter.submit( RunnableBase.SUBMIT_ASYNC );
+ // leave it running; we'll sync up with it in start()
}
/**
@@ -128,7 +180,6 @@
* @return true if life cycle module is enabled
*/
private boolean isEnabled(LifecycleModule lcm, ConfigContext
config) {
-
try {
// return false if arguments are null
if (lcm == null || config == null) {
@@ -136,8 +187,8 @@
}
// find the ref to the life cycle module
- Server server = ServerBeansFactory.getServerBean(config);
- ApplicationRef appRef=server.getApplicationRefByRef
(lcm.getName());
+ final Server server = ServerBeansFactory.getServerBean
(config);
+ final ApplicationRef appRef=server.getApplicationRefByRef
(lcm.getName());
// true if enabled in both lifecyle module and in the ref
return ((lcm.isEnabled()) &&
@@ -159,46 +210,18 @@
}
);
}
-
- private void sortModules(HashSet listenerSet) {
- // FIXME: use a better sorting algo
- for(Iterator iter = listenerSet.iterator(); iter.hasNext();) {
- ServerLifecycleModule next = (ServerLifecycleModule)
iter.next();
- int order = next.getLoadOrder();
- int i=0;
- for(;i<this.listeners.size();i++) {
- if(((ServerLifecycleModule)listeners.get
(i)).getLoadOrder() > order) {
- break;
- }
- }
- this.listeners.add(i,next);
- }
- }
-
- private void initialize(ServerContext context)
- throws ServerLifecycleException {
-
- if (listeners.isEmpty())
- return;
-
- final ClassLoader cl = Thread.currentThread
().getContextClassLoader();
- for(Iterator iter = listeners.iterator(); iter.hasNext();) {
- ServerLifecycleModule next = (ServerLifecycleModule)
iter.next();
- next.onInitialization(context);
- }
- // set it back
- resetClassLoader(cl);
- }
-
public void onStartup(ServerContext context) throws
ServerLifecycleException {
+ final TimingDelta delta = new TimingDelta();
+ // wait for initialization to finish
+ mOneTimeIniter.waitDoneThrow();
+ debug( "Millis for initer to run: ",
(mOneTimeIniter.getNanosFromSubmit() / (1000*1000)), ", wait time =
", delta.elapsedMillis() );
+ mOneTimeIniter = null;
if (listeners.isEmpty())
return;
final ClassLoader cl = Thread.currentThread
().getContextClassLoader();
- for(Iterator iter = listeners.iterator(); iter.hasNext();) {
- ServerLifecycleModule next = (ServerLifecycleModule)
iter.next();
-
+ for( final ServerLifecycleModule next : listeners ) {
// the SERVLET invocation context so J2EE invocations from
// lifecycle modules get a legal ComponentInvocation.
@@ -222,8 +245,7 @@
return;
final ClassLoader cl = Thread.currentThread
().getContextClassLoader();
- for(Iterator iter = listeners.iterator(); iter.hasNext();) {
- ServerLifecycleModule next = (ServerLifecycleModule)
iter.next();
+ for( final ServerLifecycleModule next : listeners ) {
next.onReady(context);
}
// set it back
@@ -236,8 +258,7 @@
return;
final ClassLoader cl = Thread.currentThread
().getContextClassLoader();
- for(Iterator iter = listeners.iterator(); iter.hasNext();) {
- ServerLifecycleModule next = (ServerLifecycleModule)
iter.next();
+ for( final ServerLifecycleModule next : listeners ) {
next.onShutdown();
}
// set it back
@@ -249,12 +270,16 @@
if (listeners.isEmpty())
return;
- ClassLoader cl = Thread.currentThread().getContextClassLoader
();
- for(Iterator iter = listeners.iterator(); iter.hasNext();) {
- ServerLifecycleModule next = (ServerLifecycleModule)
iter.next();
+ final ClassLoader cl = Thread.currentThread
().getContextClassLoader();
+ for( final ServerLifecycleModule next : listeners ) {
next.onTermination();
}
// set it back
resetClassLoader(cl);
}
}
+