Java虚拟机之自己编写命令行工具(上)

本篇主要涉及如何用Java编写命令行工具(此命令行工具用来加载.class文件)。

准备工作

在Java中本人使用Apache Commons CLI这款开源的工具,这里是官方主页:Commons CLI

工具包下载地址为Apache Commons CLI,也可以通过在maven中配置依赖的方式使用。

定义 & 解析

为了编写一个命令行工具,首先需要完成定义(Definition Stage)和解析(Parsing Stage)。新建一个Cmd.java文件,创建一个Cmd类,用一个静态方法进行封装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Cmd {
public static CommandLine cmd(String[] args) throws ParseException {
//定义
Options options = new Options();
options.addOption("help", false, "print help message");
options.addOption("?", false, "print help message");
options.addOption("version", false, "print version and exit");
//解析
CommandLineParser paraer = new DefaultParser();
CommandLine cmd = paraer.parse(options, args);
return cmd;
}
public static void printUsage(String classMainName) {
System.out.println("Usage: java " + classMainName + " [-options] class [args...]");
}
}

注意:

  • options.addOption()的第二参数表示whether the option requires an argument or not
  • 在命令行没有输入参数的时候,Java代码读取args[0]会抛出异常,这和Go中args[0]为命令文件名是不一样的;

询问

询问(Interrogation Stage)阶段放在主类Main.java中,具体代码如下:

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
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws ParseException {
String className = getMainName();
CommandLine cmd = Cmd.cmd(args);
if (cmd.hasOption("version")) {
System.out.println("version 0.0.1");
} else if (cmd.hasOption("help") || cmd.hasOption("?") || args.length == 0)) {
Cmd.printUsage(className);
} else {
startJVM();
}
}
private static void startJVM() {
System.out.println("Hello JVM!");
}
// 该方法用来返回静态方法main所属的类的类名
public static String getMainName() {
return new Object() {
String getClassName() {
String clazzName = this.getClass().getName();
return clazzName.substring(0, clazzName.lastIndexOf('$'));
}
}.getClassName();
}
}

注意:

  • 当参数输入为-help?或者没有输入参数的时候,将会返回printUsage方法返回的打印语句,提示正确的输入格式;

  • 如果程序强制要求传入Option参数,则需要使用cmd.getOptions().length != 0而非判断null的方式;

  • getMainName方法是通过匿名类让静态方法main能得到主类名,不直接采用类名字符串带入也是为了避免硬编码;

关于Apache Commons CLI更详细的使用见本文最后列出的官方手册等资料。

小结

通过使用Apache Commons CLI这款开源的工具,可以很方便的用Java实现一个命令行工具,访问路径和读取文件的功能将在下一篇释出,源代码见GitHub

参考

《自己动手写Java虚拟机》的作者用Go语言写了一个简易的Java虚拟机

HotSpot和OpenJDK入门:一篇虚拟机的入门文章

Apache Commons CLI官方手册