
asadmin 是 GlassFish 的命令行工具,它提供了一系列子命令,使用 asadmin 可以让你完成 Glassfish 的所有管理任务。
使用 asadmin 的子命令 start-domain 可以启动 GlassFish。下面将描述 GlassFish启动过程的主要流程。先从 asadmin 命令的执行开始。
asadmin 命令的入口是 org.glassfish.admin.cli.AsadminMain, 包含在 ${AS_INSTALL_LIB}/client/appserver-cli.jar包中。
AsadminMain 执行的主要流程如下:

其中的一些关键点:
CLICommand.getCommand()获得启动服务器的子命令。asadmin 的所有子命令的都继承自com.sun.enterprise.admin.cli.CLICommand ,从下列目录或 Jar 中加载:
CLICommand.execute(String... argv) 。
GlassFish 的子命令实现类为StartDomainCommand,内部调用 GFLauncher.launch()启动服务器。
另外,如果设置了 verbose 或 watchdog 参数,作为父进程的asadmin 不会退出,一直等到 GlassFish 运行结束:
// If verbose, hang around until the domain stops
if (getInfo().isVerboseOrWatchdog()) {
wait(glassFishProcess);
}下面分析 GlassFish 主进程的启动流程。
GlassFish 主进程的入口是 com.sun.enterprise.glassfish.bootstrap.ASMain 的 main方法,启动过程的主要流程如下:

启动过程比较复杂,但主要步骤很清晰:
GlassFish.start() 启动 Glassfish 实例创建 GlassFishRuntime 的主要步骤包括:
在创建 GlassFishRuntime的过程中,OSGiGlassFishRuntimeBuilder 会创建并初始化 OSGi Framework ,然后使用 BundleProvisioner 的 installBundles() 方法向 OSGi 安装 GlassFish 的所有 bundles。
BundleProvisioner从哪里找到要加载的 bundles?config/osgi.properties 文件中的 glassfish.osgi.auto.install 属性定义了 OSGi bundles 的加载路径。BundleProvisioner.discoverJars() 方法会扫描这些路径,发现需要加载的 Jar 包。
在完成 bundles 的加载后,OSGiGlassFishRuntimeBuilder会调用 Framework.start() 启动 OSGi Framework。 Framework 的启动过程中,bundles 中的 BundleActivator 会被启动。其中两个重要的 BundleActivator 是:
GlassFishMainActivator 启动过程中会向 OSGi 中注册 EmbeddedOSGiGlassFishRuntime。
HK2Main 会创建 ModulesRegistry。ModulesRegistry 是 HK2 的关键组件,HK2 中的 modules 都注册在这里。在 OSGi 环境下,ModulesRegistry 的具体实现类是 OSGiModulesRegistryImpl,它会从所有 bundle Jar 的 META-INF/hk2-locator 目录中查找并注册该 bundle 包含的 HK2 modules。
ModulesRegistry 和 HK2Main 都会注册为 OSGi 的 service。
通过GlassFishRuntime.newGlassFish() 创建出 GlassFish 实例,这个过程主要做了两件事:
在 EmbeddedOSGiGlassFishRuntime 中使用 ModulesRegistry.newServiceLocator() 创建出 ServiceLocator,然后从 ServiceLocator 获取 ModuleStartup。在 GlassFish 启动场景获取的是 ModuleStartup 的一个具体实现 AppServerStartup。
ServiceLocator 是 HK2 service 的注册表,它提供了一系列获取 HK2 service 的方法。
HK2 Module 和 Service 的关系可以看作是容器和内容的关系。Module(容器)包含了一组 Service(内容),并且负责将这些 Service 注册到 ServiceLocator 中。当一个 Module 被初始化时,它的所有 Service 都会被注册到 ServiceLocator 中,然后这些 Service 就可以被其他 Service 查找和使用。
最后将 AppServerStartup 和 ServiceLocator 作为构造函数的参数,创建出 GlassFish 实例。
使用 GlassFish.start() 启动 Glassfish 实例。其中最关键的步骤是调用 AppServerStartup.start(),分级启动 HK2 的 service。HK2 的 service 可以指定启动级别,级别越低,越先启动。
AppServerStartup.start() 运行完成,所有 service 启动,Glassfish 完成启动并运行。