由GlassFish V3的启动脚本说起,分析CLI
一直想写点内容,一来话太白,写不好,二来肚子里没东西。
思来想去,每天少写点也会有进步的,写点吧。 开始!
以上是tomcat的启动脚本内容,看惯了这类的脚本,你再看看下面这个:
会不有会有点时下流行的“小清新”的感觉。要想知道这么短小的内容就可以启动server,就不得不了解下CLI (Command Line Interface) ,正是cli,才使得启动变得如此简单。
1.CLI
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
public static void main(String[] args) { long startTime = System.currentTimeMillis(); AsadminMain asadminMain = new AsadminMain(); int code = asadminMain.doMain(args); System.exit(code);}
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); } }
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;
@Service(name = "start-domain")@PerLookuppublic class StartDomainCommand extends LocalDomainCommand implements StartServerCommand
@Override protected int executeCommand() throws CommandException { try { // createLauncher needs to go before the helper is created!! createLauncher(); final String mpv = getMasterPassword();... launcher.launch();