由GlassFish V3的启动脚本说起,分析CLI

一直想写点内容,一来话太白,写不好,二来肚子里没东西。 :oops:
思来想去,每天少写点也会有进步的,写点吧。 8) 开始!


[img]http://dl.iteye.com/upload/attachment/0077/8356/e0fb6992-ed9a-3080-9cb9-8cc9ccc1383c.png[/img]
以上是tomcat的启动脚本内容,看惯了这类的脚本,你再看看下面这个:

[img]http://dl.iteye.com/upload/attachment/0077/8358/fd31e4cd-a880-34f2-9001-302f4297d14c.png[/img]
会不有会有点时下流行的“小清新”的感觉。要想知道这么短小的内容就可以启动server,就不得不了解下CLI (Command Line Interface) ,正是cli,才使得启动变得如此简单。

1.[b]CLI[/b]

CLI是一系列可以在GlassFish的asadmin工具中执行的命令,以完成各类操作的。下面以启动server的start-domain命令为例来分析GlassFish V3 的CLI。

Java –jar 执行admin-cli.jar,必然会执行这个jar包下的一个带有main方法的类,这个类是:AsadminMain
那万一有多个类包含main方法呢?
当然,可以在jar文件admin-cli.jar\META-INF\MANIFEST.MF文件下指定执行的主类,有如下内容:
Main-Class: com.sun.enterprise.admin.cli.AsadminMain


AsadminMain的main方法:
 public static void main(String[] args) {
long startTime = System.currentTimeMillis();
AsadminMain asadminMain = new AsadminMain();
int code = asadminMain.doMain(args);
System.exit(code);
}

同样的短小,再看下主要的doMain方法
protected int doMain(String[] args) {
int minor = JDK.getMinor();

if (minor < 6) {
System.err.println(strings.get("OldJdk", "" + minor));
return ERROR;
}

command = args[0];
int exitCode = executeCommand(args);

public int executeCommand(String[] argv) {
CLICommand cmd = null;


cmd = CLICommand.getCommand(habitat, command);
return cmd.execute(argv);

一系列的小方法,读起来也比较好理解。
其中
CLICommand.getCommand(habitat, command);
,是根据用户要执行的command,查询方法定义,方便下面的执行。
/**
* Get a CLICommand object representing the named command.
*/
public static CLICommand getCommand(ServiceLocator habitat, String name)
throws CommandException {

// first, check if it's a known unsupported command
checkUnsupportedLegacyCommand(name);

// next, try to load our own implementation of the command
CLICommand cmd = habitat.getService(CLICommand.class, name);
if (cmd != null)
return cmd;

// nope, must be a remote command
logger.finer("Assuming it's a remote command: " + name);
Environment environment = habitat.getService(Environment.class);
if (environment != null && environment.getBooleanOption("USE_REST")) {
logger.finest("AS_ADMIN_USE_REST environment variable is on.");
return new RemoteCLICommand(name,
habitat.<ProgramOptions>getService(ProgramOptions.class),
environment);
} else {
return new RemoteCommand(name,
habitat.<ProgramOptions>getService(ProgramOptions.class),
environment);
}
}

以上是用ServiceLocator来定位相应的Command,接着执行CLICommand的execute方法
public int execute(String... argv) throws CommandException {
this.argv = argv;
initializePasswords();
logger.finer("Prepare");
prepare();
logger.finer("Process program options");
processProgramOptions();
logger.finer("Parse command options");
parse();
if (checkHelp())
return 0;
logger.finer("Prevalidate command options");
prevalidate();
logger.finer("Inject command options");
inject();
logger.finer("Validate command options");
validate();
if (programOpts.isEcho()) {
logger.info(echoCommand());
// In order to avoid echoing commands used intenally to the
// implementation of *this* command, we turn off echo after
// having echoed this command.
programOpts.setEcho(false);
} else if (logger.isLoggable(Level.FINER))
logger.finer(echoCommand());
logger.finer("Execute command");
return executeCommand();
}

protected abstract int executeCommand() throws CommandException;

在该方法中的executeCommand方法会执行子类实现的executeCommand方法。
终于到了具体的方法实现了:
@Service(name = "start-domain")
@PerLookup
public class StartDomainCommand extends LocalDomainCommand implements StartServerCommand

正是由于@Service的name和用户输入的command一致,ServiceLocator才会找到这个Command并执行,接着执行其executeCommand
@Override
protected int executeCommand() throws CommandException {
try {
// createLauncher needs to go before the helper is created!!
createLauncher();
final String mpv = getMasterPassword();
...
launcher.launch();

以上是整个start-domain的过程,也简要分析了cli的执行过程。

2012-12-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值