Tomcatのソースを読んでみる - Catalinaの開始
前回はCatalinaの初期化処理をみました。
今回はCatalinaの開始処理をみます。
public final class Bootstrap { //----------------------------------------------中略 /** * Start the Catalina daemon. */ public void start() throws Exception { if( catalinaDaemon==null ) init(); Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null); method.invoke(catalinaDaemon, (Object [])null); }
Catalina#start()を呼び出します。
/** * Start a new server instance. */ public void start() { if (getServer() == null) { load(); } if (getServer() == null) { log.fatal("Cannot start server. Server instance is not configured."); return; } long t1 = System.nanoTime(); // Start the new server if (getServer() instanceof Lifecycle) { try { ((Lifecycle) getServer()).start(); } catch (LifecycleException e) { log.error("Catalina.start: ", e); } }
( (Lifecycle) getServer() ).start()でStandardServer#start()を呼び出します。
Lifecycleインターフェースはサーバ開始・サーバ終了のメカニズムを提供するオブジェクトに共通して継承されています。
Lifecycleの継承関連はとても多いので骨が折れます。
関連クラスは以下のようになっています。
Lifecycleのサブインターフェース
Container, Context, Engine, Executor, Host, Server, Service, Wrapper
Lifecycleの継承クラス
AccessLogValve, AuthenticatorBase, BackupManager, BasicAuthenticator, ClusterManagerBase, ClusterSingleSignOn, CombinedRealm, CometConnectionManagerValve, Connector, ContainerBase, CrawlerSessionManagerValve, DataSourceRealm, DeltaManager, DigestAuthenticator, Embedded, ErrorReportValve, ExtendedAccessLogValve, FailedContext, FileStore, FormAuthenticator, JAASMemoryLoginModule, JAASRealm, JDBCAccessLogValve, JDBCRealm, JDBCStore, JNDIRealm, JvmRouteBinderValve, LifecycleBase, LifecycleMBeanBase, LockOutRealm, ManagerBase, MapperListener, MemoryRealm, NamingResources, NonLoginAuthenticator, NullRealm, PersistentManager, PersistentManagerBase, PersistentValve, RealmBase, RemoteAddrValve, RemoteHostValve, RemoteIpValve, ReplicatedContext, ReplicationValve, RequestFilterValve, SemaphoreValve, SimpleTcpCluster, SingleSignOn, SpnegoAuthenticator, SSLAuthenticator, SSLValve, StandardContext, StandardEngine, StandardHost, StandardManager, StandardPipeline, StandardServer, StandardService, StandardThreadExecutor, StandardWrapper, StoreBase, StuckThreadDetectionValve, Tomcat.ExistingStandardWrapper, UserDatabaseRealm, ValveBase, VirtualWebappLoader, WebappClassLoader, WebappLoader
今回は上記のうち、代表的なものやシーケンス図に載っているものだけみてみます。
public final class StandardServer implements Lifecycle, Server, MBeanRegistration { //---------------------------------------------中略 public void start() throws LifecycleException { // Validate and update our current component state if (started) { log.debug(sm.getString("standardServer.start.started")); return; } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start our defined Services synchronized (services) { for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).start(); } }
((Lifecycle) services[i]).start();でStandardService#start()を呼び出します。
public class StandardService implements Lifecycle, Service, MBeanRegistration { //---------------------------------------------中略 public void start() throws LifecycleException { // Validate and update our current component state if (started) { if (log.isInfoEnabled()) { log.info(sm.getString("standardService.start.started")); } return; } if( ! initialized ) init(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); if(log.isInfoEnabled()) log.info(sm.getString("standardService.start.name", this.name)); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start our defined Container first if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).start(); } } }
StandardEngine、StandardHost、ContainerBase、StandardContext、StandardPipelineをみてみます。
public class StandardEngine extends ContainerBase implements Engine { //---------------------------------------------------------中略 public void start() throws LifecycleException { // Standard container startup super.start();
public abstract class ContainerBase implements Container, Lifecycle, Pipeline, MBeanRegistration, Serializable { //---------------------------------------------------------中略 public synchronized void start() throws LifecycleException { // Validate and update our current component state if (started) { if(log.isInfoEnabled()) log.info(sm.getString("containerBase.alreadyStarted", logName())); return; } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); started = true; // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start(); logger = null; getLogger(); if ((logger != null) && (logger instanceof Lifecycle)) ((Lifecycle) logger).start(); if ((manager != null) && (manager instanceof Lifecycle)) ((Lifecycle) manager).start(); if ((cluster != null) && (cluster instanceof Lifecycle)) ((Lifecycle) cluster).start(); if ((realm != null) && (realm instanceof Lifecycle)) ((Lifecycle) realm).start(); if ((resources != null) && (resources instanceof Lifecycle)) ((Lifecycle) resources).start(); // Start our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).start(); } // Start the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(START_EVENT, null); // Start our thread threadStart(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
ContainerBaseは抽象クラスで、継承クラスの開始処理を行っているみたいです。
public class StandardHost extends ContainerBase implements Host { public synchronized void start() throws LifecycleException { if( started ) { return; } if( ! initialized ) init(); // Look for a realm - that may have been configured earlier. // If the realm is added after context - it'll set itself. if( realm == null ) { ObjectName realmName=null; try { realmName=new ObjectName( domain + ":type=Realm,host=" + getName()); if( mserver.isRegistered(realmName ) ) { mserver.invoke(realmName, "init", new Object[] {}, new String[] {} ); } } catch( Throwable t ) { log.debug("No realm for this host " + realmName); } } // Set error report valve if ((errorReportValveClass != null) && (!errorReportValveClass.equals(""))) { try { boolean found = false; if(errorReportValveObjectName != null) { ObjectName[] names = ((StandardPipeline)pipeline).getValveObjectNames(); for (int i=0; !found && i<names.length; i++) if(errorReportValveObjectName.equals(names[i])) found = true ; } if(!found) { Valve valve = (Valve) Class.forName(errorReportValveClass) .newInstance(); addValve(valve); errorReportValveObjectName = ((ValveBase)valve).getObjectName() ; } } catch (Throwable t) { log.error(sm.getString ("standardHost.invalidErrorReportValveClass", errorReportValveClass), t); } } if(log.isDebugEnabled()) { if (xmlValidation) log.debug(sm.getString("standardHost.validationEnabled")); else log.debug(sm.getString("standardHost.validationDisabled")); } super.start(); } }
realm(レルム)の初期化をしています。レルムとは,同一の認証ポリシーを適用する範囲のことみたいです。 また、エラーコード別の適切なHTML出力を行うためにErrorReportValveを設定します。 StandardPipelineでvalveを登録します。
public class StandardPipeline implements Pipeline, Contained, Lifecycle { //----------------------------------------------------中略 public synchronized void start() throws LifecycleException { // Validate and update our current component state if (started) throw new LifecycleException (sm.getString("standardPipeline.alreadyStarted")); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); started = true; // Start the Valves in our pipeline (including the basic), if any Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof Lifecycle) ((Lifecycle) current).start(); registerValve(current); current = current.getNext(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(START_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
public class HostConfig implements LifecycleListener { protected void deployApps() { File appBase = appBase(); File configBase = configBase(); String[] filteredAppPaths = filterAppPaths(appBase.list()); // Deploy XML descriptors from configBase deployDescriptors(configBase, configBase.list()); // Deploy WARs, and loop if additional descriptors are found deployWARs(appBase, filteredAppPaths); // Deploy expanded folders deployDirectories(appBase, filteredAppPaths); } }
HostConfigでアプリをデプロイします。
長くなったので、HTTPリクエストを受け取る処理は次回にみてみます。
- 作者: Jason Brittain,Ian F. Darwin,村上雅章
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/11/21
- メディア: 大型本
- 購入: 8人 クリック: 74回
- この商品を含むブログ (32件) を見る