开发工具用久了命令行都忘了怎么用了,做个笔记;

先从最简单的例子开始(先装jdk环境,当前我用的jdk11):

Windows编译命令java 命令编译java文件_java命令

一、单个java文件和包结构;

先在电脑E:\Temp\javatest\JavacTest目录创建一个简单的java文件并编写代码;

Windows编译命令java 命令编译java文件_java命令_02

 

Windows编译命令java 命令编译java文件_java命令_03

按住shift右键打开powershell;

Windows编译命令java 命令编译java文件_java_04

将java文件编译成class,输入:javac .\Hello.java

Windows编译命令java 命令编译java文件_jar命令_05

Windows编译命令java 命令编译java文件_javac命令_06

将多个java文件编译的时候可以用@files参数(powershell里@有冲突,标准cmd和linux可以用),files.txt里可以指定多个java文件,多个java文件间空格隔开(每个java用双引号括起来的时候注意反斜杠转义)

Windows编译命令java 命令编译java文件_java_07

Windows编译命令java 命令编译java文件_Windows编译命令java_08

Windows编译命令java 命令编译java文件_javac命令_09

运行class文件,输入:java Hello (不写.class)

Windows编译命令java 命令编译java文件_java_10

打成jar包,输入:jar cvf h.jar .\Hello.class

Windows编译命令java 命令编译java文件_java_11

Windows编译命令java 命令编译java文件_Windows编译命令java_12

执行jar包,输入:java -jar .\h.jar (运行失败,没有主清单属性)

Windows编译命令java 命令编译java文件_java_13

因为自动生成的jar包里的META-INF文件夹下的MANIFEST.MF文件不完全,用压缩软件打开jar包,编辑MANIFEST.MF文件,添加Main-Class: Hello,改动保存到jar包里;

Windows编译命令java 命令编译java文件_Windows编译命令java_14

Windows编译命令java 命令编译java文件_jar命令_15

重新执行jar包

Windows编译命令java 命令编译java文件_javac命令_16

注:MANIFEST.MF文件的格式比较严格,Manifest-Version是MF版本,Created-By通常由编译器生成(也可自定义),Main-Class指定主类(包名.类名完整格式),还有个Class-Path也常用(指定classpath和引用的jar等);

格式上每项“:”后面需要有一个空格,配置中间似乎不可以有空行,每行最多72个字符(应该是包括回车),换行后下一行需要空一个空格,文件最后要空两行(可能是标准,空一行也能运行);

比如写成这样:

Windows编译命令java 命令编译java文件_javac命令_17

是可以运行的。

关于jar命令,jdk11的太长,我查看了一下jdk1.8的说明:

用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
选项:
    -c  创建新档案(创建jar包)
    -t  列出档案目录(查看jar包内容)
    -x  从档案中提取指定的 (或所有) 文件(解压内容)
    -u  更新现有档案(将文件压缩到jar包)
    -v  在标准输出中生成详细输出
    -f  指定档案文件名(指定打成jar包的名字)
    -m  包含指定清单文件中的清单信息(指定mf文件)
    -n  创建新档案后执行 Pack200 规范化
    -e  为捆绑到可执行 jar 文件的独立应用程序
        指定应用程序入口点
    -0  仅存储; 不使用任何 ZIP 压缩(容量换速度)
    -P  保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
    -M  不创建条目的清单文件(-m失效,不会创建MANIFEST.MF)
    -i  为指定的 jar 文件生成索引信息
    -C  更改为指定的目录并包含以下文件(只在c/u参数有效,相当于先cd过去再执行jar,打包该目录下的文件)
如果任何文件为目录, 则对其进行递归处理。
清单文件名, 档案文件名和入口点名称的指定顺序
与 'm', 'f' 和 'e' 标记的指定顺序相同。

避免在jar包里修改MANIFEST.MF文件,打包时指定MANIFEST.MF即可(这个文件可自定义名称比如a.mf或者a.txt、x.abc等等);

先写一个MANIFEST.MF文件:

Windows编译命令java 命令编译java文件_javac命令_18

Windows编译命令java 命令编译java文件_java_19

执行打包命令,指定MF文件:jar cvfm h2.jar .\MANIFEST.MF .\Hello.class (fm位置要跟h2.jar和mf文件对应起来)

Windows编译命令java 命令编译java文件_Windows编译命令java_20

Windows编译命令java 命令编译java文件_java命令_21

执行jar包是可以运行的

Windows编译命令java 命令编译java文件_javac命令_22

PS:jar包其实就是一个有点特殊的压缩文件,跟zip一样,只不过里面包括一些java包的文件夹和class文件,外加一些配置,还有一个META-INF文件夹和下面的MANIFEST.MF文件;

可以手动建立jar包:新建个文件夹,将class文件和包文件夹放进去(我这只有个没包的Hello.class),然后再建个META-INF在里面编写MANIFEST.MF文件,然后打成压缩包,改压缩包后缀名为jar:

Windows编译命令java 命令编译java文件_java命令_23

Windows编译命令java 命令编译java文件_java命令_24

Windows编译命令java 命令编译java文件_javac命令_25

Windows编译命令java 命令编译java文件_javac命令_26

Windows编译命令java 命令编译java文件_java命令_27

Windows编译命令java 命令编译java文件_Windows编译命令java_28

Windows编译命令java 命令编译java文件_jar命令_29

将Hello.java修改加上包结构再试:

Windows编译命令java 命令编译java文件_javac命令_30

生成class执行:javac Hello.java

Windows编译命令java 命令编译java文件_Windows编译命令java_31

运行class,输入:java com.test.Hello

Windows编译命令java 命令编译java文件_Windows编译命令java_32

因为没按包结构放class文件,新建com/test/文件夹,将Hello.class放入,然后就可以执行了:

Windows编译命令java 命令编译java文件_javac命令_33

使用javac的-d参数,直接指定生成的class文件输出目录,包结构会自动生成:javac -d classes .\Hello.java (win环境classes文件夹会自动生成,linux需要先创建classes文件夹)

Windows编译命令java 命令编译java文件_java_34

使用java的-classpath或者-cp参数指定classpath参数,执行:java -cp .\classes\ com.test.Hello (-cp参数有多个的时候用英文的“双引号引起来”,中间用分号隔开)

Windows编译命令java 命令编译java文件_jar命令_35

打成jar包:jar cvfm h.jar .\MANIFEST.MF .\classes\com\test\Hello.class (可以打包,但运行是有问题的)

Windows编译命令java 命令编译java文件_Windows编译命令java_36

因为打的jar包默认是执行jar的这个目录:

Windows编译命令java 命令编译java文件_java命令_37

显然classes不是包路径;

解决方法1:修改mf文件,指定Class-Path;(不推荐)

Windows编译命令java 命令编译java文件_Windows编译命令java_38

解决方法2:命令行cd到classes文件夹下,再打包;

Windows编译命令java 命令编译java文件_Windows编译命令java_39

Windows编译命令java 命令编译java文件_javac命令_40

解决方法3:使用jar的-C参数指定打包文件,jar cvfm h.jar .\MANIFEST.MF -C .\classes\ com\test\Hello.class 或者 jar cvfm h.jar .\MANIFEST.MF -C .\classes\ .

Windows编译命令java 命令编译java文件_jar命令_41

Windows编译命令java 命令编译java文件_java_42

二、多个java文件和包结构;

编写Hello和Add两个类,Hello类中使用Add类

Windows编译命令java 命令编译java文件_javac命令_43

Windows编译命令java 命令编译java文件_Windows编译命令java_44

Windows编译命令java 命令编译java文件_Windows编译命令java_45

生成class:javac -d cls .\Hello.java .\A.java

Windows编译命令java 命令编译java文件_jar命令_46

(((此外,javac还有一个-sourcepath参数,可以指定依赖的java文件位置,该依赖文件需要按照包结构放置目录,并且只会编译实际依赖的java文件,其他不会编译,例如:

把Add.java放到ajava\com\add下,并又添加了A.java、B.java、C.java,执行:javac -sourcepath .\ajava\ -d cls .\Hello.java

Windows编译命令java 命令编译java文件_jar命令_47

Windows编译命令java 命令编译java文件_java命令_48

Windows编译命令java 命令编译java文件_jar命令_49

Windows编译命令java 命令编译java文件_Windows编译命令java_50

Windows编译命令java 命令编译java文件_jar命令_51

执行javac后,Add.class也会编译到cls下,其他没用到的ABC不会编译:

Windows编译命令java 命令编译java文件_java命令_52

Windows编译命令java 命令编译java文件_java命令_53

)))

执行class并用-cp指定classpath位置:java -cp .\cls\ com.test.Hello

Windows编译命令java 命令编译java文件_java命令_54

打成jar包:jar cvfm h.jar .\MANIFEST.MF -C .\cls\ com\

Windows编译命令java 命令编译java文件_javac命令_55

Windows编译命令java 命令编译java文件_java_56

Windows编译命令java 命令编译java文件_Windows编译命令java_57

单独编译测试,先编译Add.java,再编译Hello.java

先将Add.java编译到addcls文件夹下:javac -d addcls .\Add.java

Windows编译命令java 命令编译java文件_java命令_58

Windows编译命令java 命令编译java文件_javac命令_59

再编译Hello.java,用-cp指定Add.class所在,执行:javac -cp .\addcls\ -d hellocls .\Hello.java

(跟java命令一样用-cp指定classpath,-cp参数有多个的时候用英文的“双引号引起来”,中间用分号隔开,-d指定生成目录)

Windows编译命令java 命令编译java文件_java命令_60

测试运行,输入:java -cp ".\addcls\;.\hellocls" com.test.Hello

Windows编译命令java 命令编译java文件_Windows编译命令java_61

打包,输入:jar cvfm h.jar .\MANIFEST.MF .\addcls\ .\hellocls\

(当前目录会把addcls和hellocls文件夹也打包,所以修改MF文件的Class-Path指定classpath)

Windows编译命令java 命令编译java文件_java命令_62

Windows编译命令java 命令编译java文件_java_63

测试执行jar包:java -jar .\h.jar

Windows编译命令java 命令编译java文件_Windows编译命令java_64

三、依赖jar包的情况

先准备依赖的jar包,先将Add.java编译打包

编译:javac -d addcls .\Add.java (依赖的jar包需要有包结构)

打包:jar cvfM add.jar -C .\addcls\ . (需要按实际包结构打包,依赖时包里MF的cp指定似乎不起作用)

Windows编译命令java 命令编译java文件_jar命令_65

开始编译Hello.java用-cp指定依赖jar包,执行:javac -cp .\add.jar -d classes .\Hello.java (classes下只包含Hello.class)

Windows编译命令java 命令编译java文件_java_66

测试执行:java -cp ".\classes\;.\add.jar" com.test.Hello

Windows编译命令java 命令编译java文件_java命令_67

编写MF文件准备打包,指定依赖的add.jar在libs文件夹下:(指定依赖jar包位置是在所打jar包的外部)

Windows编译命令java 命令编译java文件_jar命令_68

将Hello.class打包:jar cvfm h.jar .\MANIFEST.MF -C .\classes\ . (打jar包就是压缩文件,所以跟依赖的jar无关,只要把class文件和MF打包就行)

Windows编译命令java 命令编译java文件_javac命令_69

Windows编译命令java 命令编译java文件_jar命令_70

可以新建个文件夹,将jar包放进去,add.jar按照MF的配置,要放在libs下:

Windows编译命令java 命令编译java文件_Windows编译命令java_71

Windows编译命令java 命令编译java文件_java_72

测试执行jar包:

Windows编译命令java 命令编译java文件_java_73

如果要把依赖的jar包也放到要打的jar包里,需要先把依赖的jar包放到classpath目录下解压,然后再一起打包:

Windows编译命令java 命令编译java文件_java命令_74

把add.jar复制到classes文件夹下,执行解压:

Windows编译命令java 命令编译java文件_javac命令_75

Windows编译命令java 命令编译java文件_javac命令_76

解压后所有的class文件(包括依赖的)就都在classes下了:

Windows编译命令java 命令编译java文件_java_77

然后把依赖的jar包去掉,统一打包就行:

Windows编译命令java 命令编译java文件_Windows编译命令java_78

Windows编译命令java 命令编译java文件_java命令_79

执行jar包,可以运行:

Windows编译命令java 命令编译java文件_Windows编译命令java_80