一、编写java文件
Test1.java
package com.test1;
public class Test1{
public void display(){
System.out.println("This is test1");
}
}
Test2.java
package com.test2;
public class Test2{
public void display(){
System.out.println("This is Test2");
}
}
Test.java
package com.test;
import com.test1.Test1;
import com.test2.Test2;
public class Test{
public static void main(String[] args){
for(String s : args){
System.out.println("arg:"+s);
}
Test1 t1 = new Test1();
t1.display();
Test2 t2 = new Test2();
t2.display();
}
}
三个java文件放在 /home/zxm/testjar
下,再新建 foo1
目录,用于存放编译生成的 class
文件
目录结构:
foo1/
Test.java
Test1.java
Test2.java
二、编译文件
java版本:
zxm@zxm-pc:~/testjar$ java -version
java version "1.8.0_341"
Java(TM) SE Runtime Environment (build 1.8.0_341-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)
java命令使用:
zxm@zxm-pc:~/testjar$ java -help
用法: java [-options] class [args...]
(执行类)
或 java [-options] -jar jarfile [args...]
(执行 jar 文件)
其中选项包括:
-d32 使用 32 位数据模型 (如果可用)
-d64 使用 64 位数据模型 (如果可用)
-server 选择 "server" VM
默认 VM 是 server,
因为您是在服务器类计算机上运行。
-cp <目录和 zip/jar 文件的类搜索路径>
-classpath <目录和 zip/jar 文件的类搜索路径>
用 : 分隔的目录, JAR 档案
和 ZIP 档案列表, 用于搜索类文件。
-D<名称>=<值>
设置系统属性
-verbose:[class|gc|jni]
启用详细输出
-version 输出产品版本并退出
-version:<值>
警告: 此功能已过时, 将在
未来发行版中删除。
需要指定的版本才能运行
-showversion 输出产品版本并继续
-jre-restrict-search | -no-jre-restrict-search
警告: 此功能已过时, 将在
未来发行版中删除。
在版本搜索中包括/排除用户专用 JRE
-? -help 输出此帮助消息
-X 输出非标准选项的帮助
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
按指定的粒度启用断言
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
禁用具有指定粒度的断言
-esa | -enablesystemassertions
启用系统断言
-dsa | -disablesystemassertions
禁用系统断言
-agentlib:<libname>[=<选项>]
加载本机代理库 <libname>, 例如 -agentlib:hprof
另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
-agentpath:<pathname>[=<选项>]
按完整路径名加载本机代理库
-javaagent:<jarpath>[=<选项>]
加载 Java 编程语言代理, 请参阅 java.lang.instrument
-splash:<imagepath>
使用指定的图像显示启动屏幕
javac命令使用:
zxm@zxm-pc:~/testjar$ javac -help
用法: javac <options> <source files>
其中, 可能的选项包括:
-g 生成所有调试信息
-g:none 不生成任何调试信息
-g:{lines,vars,source} 只生成某些调试信息
-nowarn 不生成任何警告
-verbose 输出有关编译器正在执行的操作的消息
-deprecation 输出使用已过时的 API 的源位置
-classpath <路径> 指定查找用户类文件和注释处理程序的位置
-cp <路径> 指定查找用户类文件和注释处理程序的位置
-sourcepath <路径> 指定查找输入源文件的位置
-bootclasspath <路径> 覆盖引导类文件的位置
-extdirs <目录> 覆盖所安装扩展的位置
-endorseddirs <目录> 覆盖签名的标准路径的位置
-proc:{none,only} 控制是否执行注释处理和/或编译。
-processor <class1>[,<class2>,<class3>...] 要运行的注释处理程序的名称; 绕过默认的搜索进程
-processorpath <路径> 指定查找注释处理程序的位置
-parameters 生成元数据以用于方法参数的反射
-d <目录> 指定放置生成的类文件的位置
-s <目录> 指定放置生成的源文件的位置
-h <目录> 指定放置生成的本机标头文件的位置
-implicit:{none,class} 指定是否为隐式引用文件生成类文件
-encoding <编码> 指定源文件使用的字符编码
-source <发行版> 提供与指定发行版的源兼容性
-target <发行版> 生成特定 VM 版本的类文件
-profile <配置文件> 请确保使用的 API 在指定的配置文件中可用
-version 版本信息
-help 输出标准选项的提要
-A关键字[=值] 传递给注释处理程序的选项
-X 输出非标准选项的提要
-J<标记> 直接将 <标记> 传递给运行时系统
-Werror 出现警告时终止编译
@<文件名> 从文件读取选项和文件名
另:
可以向低版本编译,例,javac -d foo1/ Test1.java Test2.java Test.java -encoding UTF-8 -source 7 -target 7
编译的文件放在 foo1
目录下,使用 javac
命令编译,-d
指定 class
文件存放目录
使用 java
命令运行程序
zxm@zxm-pc:~/testjar$ mkdir foo1/
zxm@zxm-pc:~/testjar$ javac -d foo1/ Test1.java Test2.java Test.java
zxm@zxm-pc:~/testjar$ java -cp foo1/ com.test.Test
This is test1
This is Test2
zxm@zxm-pc:~/testjar/foo1$ java com.test.Test
This is test1
This is Test2
目录结构:
foo1
com
test
Test.class
test1
Test1.class
test2
Test2.class
Test.java
Test1.java
Test2.java
三、编写清单文件(MANIFEST.MF)
在 /home/zxm/testjar
目录下,新建文件 MANIFEST.MF
(可以自定义名,jar
会把清单文件里的内容放到,生成 jar
文件的 META-INF
目录下 MANIFEST.MF
文件中,用解压文件解压 jar
可以看到)。Manifest-Version
指定版本号;Main-Class
指定程序入口,实现直接执行jar文件
也可以不编写 MANIFEST.MF 文件,使用 jar 打包时候指定主类
MANIFEST.MF
Manifest-Version: 1.0
Main-Class: com.test.Test
注意:在每行冒号后有空格;文件最后一行为空行
四、打jar包
jar命令使用:
zxm@zxm-pc:~/testjar$ jar
用法: `jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...`
选项:
-c 创建新档案
-t 列出档案目录
-x 从档案中提取指定的 (或所有) 文件
-u 更新现有档案
-v 在标准输出中生成详细输出
-f 指定档案文件名
-m 包含指定清单文件中的清单信息
-n 创建新档案后执行 Pack200 规范化
-e 为捆绑到可执行 jar 文件的独立应用程序
指定应用程序入口点
-0 仅存储; 不使用任何 ZIP 压缩
-P 保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
-M 不创建条目的清单文件
-i 为指定的 jar 文件生成索引信息
-C 更改为指定的目录并包含以下文件
如果任何文件为目录, 则对其进行递归处理。
清单文件名, 档案文件名和入口点名称的指定顺序
与 'm', 'f' 和 'e' 标记的指定顺序相同。
示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中:
`jar cvf classes.jar Foo.class Bar.class`
示例 2: 使用现有的清单文件 'mymanifest' 并
将 foo/ 目录中的所有文件归档到 'classes.jar' 中:
`jar cvfm classes.jar mymanifest -C foo/ .`
1.指定主类:使用 jar cvfe
命令打包
2.指定清单文件:使用 jar cvfm
命令打包,t.jar
为打的包名;MANIFEST.MF
为清单文件;-C
更改为指定的目录并包含其中的文件,如果文件为目录,则递归处理;.
表示当前路径
3.不指定清单文件:使用 jar cvf t.jar -C foo1/ .
,也能打包成功,但是自动生成的清单里没有指定 Main-Class
# zxm@zxm-pc:~/testjar$ jar cvfe t.jar com.test.Test -C foo1/ .
# 已添加清单
# 正在添加: com/(输入 = 0) (输出 = 0)(存储了 0%)
# 正在添加: com/test/(输入 = 0) (输出 = 0)(存储了 0%)
# 正在添加: com/test/Test.class(输入 = 786) (输出 = 503)(压缩了 36%)
# 正在添加: com/test2/(输入 = 0) (输出 = 0)(存储了 0%)
# 正在添加: com/test2/Test2.class(输入 = 405) (输出 = 285)(压缩了 29%)
# 正在添加: com/test1/(输入 = 0) (输出 = 0)(存储了 0%)
# 正在添加: com/test1/Test1.class(输入 = 405) (输出 = 285)(压缩了 29%)
zxm@zxm-pc:~/testjar$ jar cvfm t.jar MANIFEST.MF -C foo1/ .
已添加清单
正在添加: com/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/test/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/test/Test.class(输入 = 786) (输出 = 503)(压缩了 36%)
正在添加: com/test2/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/test2/Test2.class(输入 = 405) (输出 = 285)(压缩了 29%)
正在添加: com/test1/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/test1/Test1.class(输入 = 405) (输出 = 285)(压缩了 29%)
此时目录结构:
foo1
com
test
Test.class
test1
Test1.class
test2
Test2.class
MANIFEST.MF
t.jar
Test.java
Test1.java
Test2.java
五、运行jar包
使用 java -jar <jar_name>
命令运行 jar
包
zxm@zxm-pc:~/testjar$ java -cp foo1/ com.test.Test
This is test1
This is Test2
zxm@zxm-pc:~/testjar/foo1$ java com.test.Test
This is test1
This is Test2
zxm@zxm-pc:~/testjar$ java -jar t.jar
This is test1
This is Test2
zxm@zxm-pc:~/testjar$ java -jar t.jar a b c
arg:a
arg:b
arg:c
This is test1
This is Test2
六、使用jar包
在 /home/zxm/testjar
下新建 MyMain.java
文件,MyMain.java
使用到 Test1
类
package main;
import com.test1.Test1;
public class MyMain{
public static void main(String[] args){
Test1 t1 = new Test1();
t1.display();
}
}
javac
编译 MyMain.java
文件。
-d .
指定编译的文件放在当前目录下,对于 MyMain.java
写了 package main
,MyMain.java
的 class
文件会放在当前文件 main/MyMain.class
-cp(-classpath)
指定 classpath
,如果不指定默认,classpath
是当前目录,MyMain.java
使用到 com.test1.Test1
类文件,编译 MyMain.java
时,编译器会找当前目录下 comtest1Test1.class
,此时是找不到的,会提示程序包 com.test1
不存在编译失败,-cp
指定类加载器去 t.jar
里找 comtest1Test1.class
java
命令运行 MyMain
-cp
指定 classpath
是 foo1/
,则可以找到 Test1.class
文件,或者指定 classpath
是 t.jar
,则从 jar 包中,找到 Test1.class
文件
zxm@zxm-pc:~/testjar$ mkdir foo2/
# zxm@zxm-pc:~/testjar$ javac -d foo2/ -cp foo1/ MyMain.java
zxm@zxm-pc:~/testjar$ javac -d foo2/ -cp t.jar MyMain.java
zxm@zxm-pc:~/testjar$ java -cp foo1/:foo2/ main.MyMain
This is test1
zxm@zxm-pc:~/testjar$ java -cp t.jar:foo2/ main.MyMain
This is test1
七、jar打jar包
在 /home/zxm/testjar
新建清单文件 my.mf
(自定义名,jar会把清单文件里的内容放到,生成 jar
文件的 META-INF
目录下 MANIFEST.MF
文件中,用解压文件解压 jar
可以看到)
Class-Path指定包含的jar,如果包含多个,用空格隔开
Manifest-Version: 1.0
Class-Path: t.jar
Main-Class: main.MyMain
jar命令打包,直接执行java -jar jar包就可成功运行
zxm@zxm-pc:~/testjar$ jar cvfm main.jar my.mf -C foo2/ .
已添加清单
正在添加: main/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: main/MyMain.class(输入 = 328) (输出 = 250)(压缩了 23%)
zxm@zxm-pc:~/testjar$ java -jar main.jar
This is test1
查看 jar 包内容
zxm@zxm-pc:~/testjar$ jar -tf main.jar
META-INF/
META-INF/MANIFEST.MF
main/
main/MyMain.class
解压 jar 包
jar -xvf <jar_name>
解压到当前目录,使用 unzip
可解压到指定目录
# zxm@zxm-pc:~/testjar/t$ jar -xvf main.jar
zxm@zxm-pc:~/testjar/t$ unzip main.jar -d temp/
Archive: main.jar
creating: temp/META-INF/
inflating: temp/META-INF/MANIFEST.MF
creating: temp/main/
inflating: temp/main/MyMain.class
zxm@zxm-pc:~/testjar$ cat temp/META-INF/MANIFEST.MF
Manifest-Version: 1.0
Class-Path: t.jar
Created-By: 1.8.0_341 (Oracle Corporation)
Main-Class: main.MyMain