JBOSS 啓動過程

JBoss啓動過程跟蹤

JBoss啓動過程


簡介
JBoss 的基本框架是JMX,JBoss的服務基本上是通過註冊到一個MBeanServer來實現的,因此具有很好的擴展性,好像Weblogic和 AdventNet的基本結構也是基於jmx的。JBoss的服務類大都實現了ServiceMBean接口,在管理上也方便了許多。

環境設置
啓動catalina
設置環境變量 JBOSS_CLASSPATH (可以自己加上安全管理器和xml解析器)
a)    %JBOSS_CLASSPATH%;
b)    %JAVA_HOME%/lib/tools.jar;
c)    run.jar
d)    ../lib/crimson.jar;
設置啓動參數JAXP(xml解析器和相應工廠)
e)    -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
f)    -Djavax.xml.parsers.SAXParserFactory=org.apache.crimson.jaxp.SAXParserFactoryImpl
啓動
java %JAXP% -classpath "%JBOSS_CLASSPATH%" org.jboss.Main
org.jboss.Main
設置配置信息
String cn = "default";
String patchDir = null;
…………
final String confName = cn;
final String patchDirName = patchDir;
配置文件放在“/conf/” + confName + “/”下面。對於jboss2.4 + Catalina, 在運行run.bat文件時指定了參數catalina,實際使用的是/conf/catalina目錄下的配置文件。
    
讀取配置文件jboss.properties,保存在系統屬性中(System.properties)
URL jbossProps = Main.class.getClassLoader().getResource (confName+”/jboss.properties”);
    InputStream propertiesIn = Main.class.getClassLoader().getResourceAsStream (confName+”/jboss.properties”);
if ( propertiesIn != null ) {
        System.getProperties().load(propertiesIn);
}

設置缺省屬性jboss.home和java.security.auth.login.config
if( System.getProperty(“jboss.home”) == null ) {
…………
              System.setProperty(“jboss.home”, homeDir.getCanonicalPath());
}

// Set the JAAS login config file if not already set
if( System.getProperty(“java.security.auth.login.config”) == null )
{
          …………
      System.setProperty(“java.security.auth.login.config”, loginConfig.toExternalForm());
}

創建MBeanServer.的實例:
final MBeanServer server = MBeanServerFactory.createMBeanServer();

javax.management.MBeanServerFactory中的這個方法是這樣實現的:
public static MBeanServer createMBeanServer () {
MBeanServer mbeanServer = new MBeanServerImpl() ;
addMBeanServer(mbeanServer) ; //存儲MBeanServer
return mbeanServer ;
}
1.    這個方法根據缺省的域創建了一個符合MBeanServer接口的實例。
2.    在MBeanServerFactory中有一個靜態私有變量 MBeanServerList 用於存儲MBeanServer,這樣以後查找BeanServer時候可以找到已創建的server。

com.sun.management.jmx.MBeanServerImpl時這樣實現的:
public MBeanServerImpl()  {
initialize(new RepositorySupport(), null);
}
private void initialize(RepositorySupport repository, String domain) {
}
MBeanServerImpl有一個私有變量repository用於存儲MBean
initialize函數執行下列動作:
1.    如果domain爲null或者是空字符串,將自己的域設置爲repository的缺省域 (”DefaultDomain”)。否則將自己和repository的域設置爲domain.
2.    設置查詢服務的方式,目前的實現是由MBeanServer負責查詢
3.    創建MetaData實例(在註冊時候檢查MBean的接口)
4.    創建標識MBeanServer的MBean: MBeanServerDelegateObject
5.    註冊MBeanServerDelegateObject
6.    保存類加載器,包括加載MBeanServerImpl類的加載器和系統類加載器。


把配置文件和補丁文件所在的目錄指定給特定的遠程類加載器Mlet
URL[] urls = {confDirectory};
獲得所有補丁文件
…………
MLet mlet = new NullURLsMLet(urls);
NullURLsMLet擴展了Mlet類,並調用父類的構造函數進行初始化。

server.registerMBean(mlet, new ObjectName(server.getDefaultDomain(), “service”, “MLet”));
把mlet設置爲本應用的類加載器
Thread.currentThread().setContextClassLoader(mlet);

加載保存配置文件(mlet會自動在配置文件目錄中查找)
URL mletConf = mlet.getResource("jboss.conf");
Set beans = (Set)mlet.getMBeansFromURL(mletConf);
…………
server.invoke(new ObjectName(":service=Configuration"), "loadConfiguration", new Object[0], new String[0]);
server.invoke(new ObjectName(":service=Configuration"), "saveConfiguration", new Object[0] , new String[0]);

初始化並啓動MBean
server.invoke(new ObjectName(":service=ServiceControl"), "init", new Object[0] , new String[0]);
server.invoke(new ObjectName(":service=ServiceControl"), "start", new Object[0] , new String[0]);
配置服務ConfigurationService



加載配置文件
loadConfiguration方法
用DOM讀取配置文件
         doc = parser.parse(new InputSource(new StringReader(sbufData.toString())));
         //創建相應的MBean
create(doc);
        //設置MBean的屬性並註冊相應的服務
         load(doc);
create方法
//把配置文件中所指明的MBean加載到server中
         NodeList nl = configuration.getElementsByTagName("mbean");
         for (int i = 0; i < nl.getLength(); i++)
         {
                …………
                MBeanInfo info;
                try {
               info = server.getMBeanInfo(objectName);
            } catch (InstanceNotFoundException e)  {
                …………
                //創建MBean
server.createMBean(code,objectName,loader,                constructor.params, constructor.signature);
                info = server.getMBeanInfo(instance.getObjectName());
                …………
}
         }
load方法
設置相應MBean的屬性
Object value = attributeText;
         server.setAttribute(objectName, new Attribute(attributeName, value));
註冊服務
registerService(objectName, info, mbeanElement);
server.invoke(serviceControl, "register", args, signature);
保存配置
saveConfiguration方法
將MBeanServer中註冊的MBean的信息寫入jboss-auto.jcml文件中


服務控制ServiceControl


ServiceControl被用來管理JBoss服務的生命週期
初始化服務程序(init方法)
在 配置服務的時候,ConfigurationService.load方法調用serviceControl.register方法註冊了很多 MBean,這些MBean都是Service的子類,即他們都有自己的init, start, stop, destroy方法。
ServiceControl的init方法簡單的調用所有已註冊的MBean的init方法來完成初始化。

啓動服務程序(start方法)
ServiceControl的start方法簡單的調用所有已註冊的MBean的start方法來完成啓動。

配置過程中所加載的類
DefaultDomain:service=Webserver:org.jboss.web.WebService

JNDI
DefaultDomain:service=Naming:org.jboss.naming.NamingService
DefaultDomain:service=JNDIView:org.jboss.naming.JNDIView
Transactions
DefaultDomain:service=TransactionManager:
org.jboss.tm.TransactionManagerService
org.jboss.tm.plugins.tyrex.TransactionManagerService
DefaultDomain:service=ClientUserTransaction:org.jboss.tm.usertx.server.ClientUserTransactionService
Security
DefaultDomain:service=JaasSecurityManager:org.jboss.security.plugins.JaasSecurityManagerService
JDBC
DefaultDomain:service=JdbcProvider:org.jboss.jdbc.JdbcProvider
DefaultDomain:service=Hypersonic:org.jboss.jdbc.HypersonicDatabase
XADataSource:service=DefaultDS:org.jboss.jdbc.XADataSourceLoader
JBoss Server Management
Management:service=Collector:org.jboss.management.ServerDataCollector
J2EE deployment
:service=ContainerFactory:org.jboss.ejb.ContainerFactory
DefaultDomain:service=EmbeddedTomcat:
org.jboss.web.catalina.EmbeddedCatalinaServiceSX
DefaultDomain:service=Jetty:


JBossMQ
JBossMQ:service=Server: org.jboss.mq.server.JBossMQService
JBossMQ:service=StateManager: org.jboss.mq.server.StateManager
JBossMQ:service=PersistenceManager: org.jboss.mq.pm.rollinglogged.PersistenceManager

JBossMQ:service=InvocationLayer,type=JVM:
                    org.jboss.mq.il.jvm.JVMServerILService
JBossMQ:service=InvocationLayer,type=RMI:
                    org.jboss.mq.il.rmi.RMIServerILService
JBossMQ:service=InvocationLayer,type=OIL:
                    org.jboss.mq.il.oil.OILServerILService

JBossMQ:service=InvocationLayer,type=UIL:
                    org.jboss.mq.il.uil.UILServerILService
JBossMQ:service=Topic,name=testTopic:
                    org.jboss.mq.server.TopicManager
JBossMQ:service=Topic,name=example:
                    org.jboss.mq.server.TopicManager
JBossMQ:service=Topic,name=bob:
                    org.jboss.mq.server.TopicManager

JBossMQ:service=Queue,name=DLQ:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=testQueue:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=controlQueue:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=A:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=B:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=C:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=D:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=E:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=F:
                    org.jboss.mq.server.QueueManager
JBossMQ:service=Queue,name=ex:
                    org.jboss.mq.server.QueueManager
爲了向後兼容所引入的MBean
DefaultDomain:service=NamingAlias,fromName=QueueConnectionFactory:
                    org.jboss.naming.NamingAlias
DefaultDomain:service=NamingAlias,fromName=TopicConnectionFactory:
org.jboss.naming.NamingAlias
消息驅動MBean
:service=JMSProviderLoader,name=JBossMQProvider
org.jboss.jms.jndi.JMSProviderLoader
:service=ServerSessionPoolMBean,name=StdJMSPool:
                    org.jboss.jms.asf.ServerSessionPoolLoader
J2eeDeployer
J2EE:service=J2eeDeployer:
                    org.jboss.deployment.J2eeDeployer
J2EE:service=J2eeDeployer(optional):
org.jboss.deployment.scope.J2eeGlobalScopeDeployer

JBossCX setup, for J2EE connector architecture support
JCA:service=RARDeployer:
                    org.jboss.resource.RARDeployer
JCA:service=ConnectionManagerFactoryLoader,name=MinervaNoTransCMFactory:
                    org.jboss.resource.ConnectionManagerFactoryLoader
JCA:service=ConnectionManagerFactoryLoader,name=MinervaSharedLocalCMFactory:
                    org.jboss.resource.ConnectionManagerFactoryLoader
JCA:service=ConnectionManagerFactoryLoader,name=MinervaXACMFactory:
                    org.jboss.resource.ConnectionManagerFactoryLoader
JCA:service=ConnectionFactoryLoader,name=MinervaDS:
                    org.jboss.resource.ConnectionFactoryLoader
resource adapter example
DefaultDomain:service=RawXADataSourceLoader,name=MinervaXADS
                    org.jboss.jdbc.RawXADataSourceLoader
JCA:service=ConnectionFactoryLoader,name=XAMinervaDS:
                    org.jboss.resource.ConnectionFactoryLoader
JMS XA Resource adapter
JCA:service=ConnectionFactoryLoader,name=JmsXA:
                    org.jboss.resource.ConnectionFactoryLoader
Auto deployment
EJB:service=AutoDeployer:
                    org.jboss.ejb.AutoDeployer
Adaptor:name=RMI
                    org.jboss.jmx.server.JMXAdaptorService
Connector:name=RMI:
                    org.jboss.jmx.server.RMIConnectorService
Adaptor:name=html:
                    com.sun.jdmk.comm.HtmlAdaptorServer
Mail Connection Factory
:service=Mail
                    org.jboss.mail.MailService
Monitor:name=BeanCacheMonitor:
                    org.jboss.monitor.BeanCacheMonitor
Scheduler Service
:service=Scheduler:
                    org.jboss.util.Scheduler

附錄A com.sun. management.jmx.MBeanServerImpl
registerMBean方法
檢查是否符合MBean規範(參考JMX筆記內省算法)
meta.testCompliance(theClass);
如果對象實現了MBeanRegistration接口,調用其preRegisterInvoker方法
        if (object instanceof MBeanRegistration) {
            res=preRegisterInvoker(object,name);  
        }
把對象加入池中
        internal_addObject(object, logicalName);
如果對象實現了MBeanRegistration接口,調用其postRegisterInvoker方法
if (object instanceof MBeanRegistration)    
postRegisterInvoker(object, true);
如果新註冊的MBean是一個類加載器,把它加在加載器池中
        if (object instanceof ClassLoader) {
            DefaultLoaderRepository.addClassLoader((ClassLoader)object);
        }      
如果是動態MBean,獲取其MBeanInfo和ClassName
        MBeanInfo mbi = ((DynamicMBean)object).getMBeanInfo();
        className = mbi.getClassName();
返回ObjectInstance對象以供使用
return(new ObjectInstance(logicalName, className));

invoke方法
public Object invoke(ObjectName name, String operationName, Object params[],
String signature[])
throws InstanceNotFoundException, MBeanException, ReflectionException;


取得MBean對象的實例
        Object obj = getMBean(name);

取得MBean的接口
Class mbeanClass = meta.getMBeanInterface(instance.getClass());
在註冊時曾經用meta檢查對象的接口,在檢查的時候,meta把對象的MBeanInterface保存在自己的mbeanInterfaceCache中,現在可以從中取回。如果對象是DynamicMBean,則meta不會保存,返回null。

用指定的類裝載器重新裝載參數
Class primCla = meta.findClassForPrim(signature);
        params= transferObject(params, aloader);

查找將要啓動的方法
        Method mth= meta.findMethod(mbeanClass, operationName, tab);

啓動方法
        result=  mth.invoke(instance, params);

 
發佈了13 篇原創文章 · 獲贊 0 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章