命令行工具
Java虚拟机启动时,需要指定类启动应用程序。
但是Java虚拟机规范中并没有明确规定,怎么指定类启动应用程序,也就是主类(包含main
方法的类)。
Oracle的虚拟机实现是通过 java 命令来启动的,主类名由命令函参数指定。
1 2 3 4
| java [-options] class [args] java [-options] -jar jarfile [args] javaw [-options] class [args] javaw [-options] -jar jarfile [args]
|
一、编写命令行工具
目前主要添加几个命令参数:
- -help
- -version
- -classpath
另外,启动程序主类名也是参数之一,并且必须放在所有参数中的第一位。
1 2 3 4
| private boolean helpFlag = false; private boolean versionFlag = false; private String cpOption = null; private String mainClass = null;
|
命令行参数的生成和解析,采用了 Apache 的一个 commons-cli
命令行工具包。
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| public class Cmd {
private final static Options options;
static { options = new Options(); options.addOption(new Option("help", false, "print help message")); options.addOption(new Option("?", false, "print help message")); options.addOption(new Option("version", false, "print version and exit")); options.addOption(Option.builder("classpath") .hasArg().desc("classpath") .type(String.class) .build()); options.addOption(Option.builder("cp") .hasArg().desc("classpath") .type(String.class) .build()); }
private boolean helpFlag = false; private boolean versionFlag = false; private String cpOption = null; private String mainClass = null; private String[] args = null;
public void parse(String[] args) { try { CommandLineParser parser = new DefaultParser(); CommandLine line = parser.parse(options, args); this.args = Arrays.copyOfRange(args, 1, args.length);
if (line.hasOption("help") || line.hasOption("?")) { helpFlag = true; printHelp(); }
if (line.hasOption("version")) { versionFlag = true; System.out.println("version 0.0.1"); }
if (args.length > 0) { mainClass = args[0]; }
if (line.hasOption("classpath")) { cpOption = line.getOptionValue("classpath"); } else if (line.hasOption("cp")) { cpOption = line.getOptionValue("cp"); }
System.out.println("helpFlag = " + helpFlag); System.out.println("versionFlag = " + versionFlag); System.out.println("mainClass = " + mainClass); System.out.println("classpath = " + cpOption); } catch (ParseException e) { e.printStackTrace(); } }
public void printHelp() { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("self-jvm", options); } }
|
二、添加测试类
测试类代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class CmdTest {
@Test public void parse() { String[] args = new String[]{ "com.wjd.cmd.Cmd", "-classpath", "/projects" }; Cmd cmd = new Cmd(); cmd.parse(args); }
@Test public void printHelp() { Cmd cmd = new Cmd(); cmd.printHelp(); } }
|
测试的打印结果大概是这样子的:
1 2 3 4 5 6 7 8 9 10 11 12 13
| # parse helpFlag = false versionFlag = false mainClass = com.wjd.cmd.Cmd classpath = /projects
# printHelp usage: self-jvm -? print help message -classpath <arg> classpath -cp <arg> classpath -help print help message -version print version and exit
|