自己手动写Java虚拟机-第1章 命令行工具

Kelvin

目录结构

1
2
3
4
5
6
workspace
|-src
|-jvmgo
|-ch01
|-pkg
|-bin

Java命令启动应用程序

1
2
3
4
5
// javaw命令不显示命令行窗口
java [-options] class [args]
java [-options] -jar jarfile [args]
javaw [-options] class [args]
javaw [-options] -jar jarfile [args]

编写命令行工具

cmd.go

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
package main

import "flag"
import "fmt"
import "os"

type Cmd struct {
helpFlag bool
versionFlag bool
cpOption string //cp:classpath
class string //.class文件
args []string //参数数组
}

func parseCmd() *Cmd {
cmd := &Cmd{} //cmd存放Cmd结构体的地址
flag.Usage = printUsage
//BoolVar(p *bool, name string, value bool, usage string)
//BoolVar defines a bool flag with specified name, default value, and usage string.
//The argument p points to a bool variable in which to store the value of the flag.
//&cmd.helpFlag是存放bool变量的地址
flag.BoolVar(&cmd.helpFlag, "help", false, "print help message")
flag.BoolVar(&cmd.helpFlag, "?", false, "print help message")
flag.BoolVar(&cmd.versionFlag, "version", false, "print version and exit")
flag.StringVar(&cmd.cpOption, "classpath", "", "classpath")
flag.StringVar(&cmd.cpOption, "cp", "", "classpath")
flag.Parse()

args := flag.Args()
if len(args) > 0 {
cmd.class = args[0]
cmd.args = args[1:]
}
return cmd
}

func printUsage() {
//os.Args[0]是要运行的文件名,如ch01.exe
fmt.Printf("Usage: %s [-options] class [args...]\n", os.Args[0])
}

flag用于处理命令行选项,

1
2
3
4
5
ch01.exe -cp foo/bar MyApp arg1 arg2
> cmd.classpath = foo/bar
> flag.Args = [MyApp arg1 arg2]
> cmd.class = MyApp
> cmd.args = [arg1, arg2]

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
cmd := parseCmd()
if cmd.versionFlag {
fmt.Println("version 0.0.1")
} else if cmd.helpFlag || cmd.class == "" {
printUsage()
} else {
startJVM(cmd)
}
}

func startJVM(cmd *Cmd) {
fmt.Printf("Classpath:%s class:%s args:%v\n", cmd.cpOption, cmd.class, cmd.args)
}

编译代码

1
go install jvmgo\ch01

第一次执行该指令报错,需要将go111module设置为false

1
go env -w GO111MODULE=off

关于GO111MODULE

过去源代码存在$GOPATH/src中,Go 1.11引入Go模块(Go Module),Go模块不使用GOPATH存储每个软件包,而是使用go.mod,并跟踪每个软件包的版本

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找.
  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找.
  • GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。当
    1.当前目录在GOPATH/src之外且该目录包含go.mod文件
    2.当前文件在包含go.mod文件的目录下面时
  • 启用module功能.
  • Title: 自己手动写Java虚拟机-第1章 命令行工具
  • Author: Kelvin
  • Created at: 2023-01-16 00:00:00
  • Updated at: 2023-05-11 21:41:59
  • Link: https://yanwc.com/2023/01/16/2023-01-16-jvmgo-ch01/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
自己手动写Java虚拟机-第1章 命令行工具