javac编译java后缀编成class,打包成jar-
前言全局说明
测试环境:
Windows 11
JAVA 1.8.0_301
示例,源码本站下载:java_test_build_jar.zip (约3.81KB)
一、编译独立.java后缀文件
1.1.1 编译单个.java后缀文件
此java文件,没有依赖外部任何jar包。
文件名:test_print.java
public class test_print {
public static void main(String[] args) {
if (args.length == 1) {
System.out.println("[ INFO ]User args:" + args[0]);
} else {
System.out.println("[ INFO ] no args!!!");
}
}
}
注意:在网页内容复制到.java文件里时,中文可能会导致编译报错,删除或手动输入中文内容即可。
1.1.2 编译命令:
javac test_print.java
编译出 .class 文件
1.1.3 运行命令:
java test_print
1.2.1 包里的.java后缀文件
文件名:test_print.java
package com;
public class test_print {
public static void main(String[] args) {
if (args.length == 1) {
System.out.println("[ INFO ]User args:" + args[0]);
} else {
System.out.println("[ INFO ] no args!!!");
}
}
}
java的包概念,在系统里就是文件夹。
假设:java_test 是某个项目文件夹。
在 java_test 文件夹下,新建 com 文件夹,把 test_print.java 放到 com 文件夹里。
资源管理器,显示目录结构::
tree命令,显示目录结构:
1.2.2 编译命令:
javac com\test_print.java
1.2.3 运行命令:
java -cp .;com test_print
-cp 给解释器指定到哪里找到你的.class文件
这里 -cp .;com/ 指定了当前目录.和子目录 com 作为类(包)路径。
-cp <目录和 zip/jar 文件的类搜索路径>
注意: Windows系统使用分号 ; 作为路径分隔符,而在Linux或Mac系统中使用冒号 :
二、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/ .
-C 指定了要添加到jar中内容所在目录和内容(这里是所有内容)
-C compiled/ . compiled,指定要添加文件的目录。后面的.代表添加目录下所有东西
三、jar 打包
3.1 使用清单文件,打包单个文件
3.1.1 源码文件
创建 MANIFEST.MF 清单文件
文件名:MANIFEST.MF
Manifest-Version: 1.0
Created-By: 1.8.0_301 (Oracle Corporation)
Main-Class: test_print
注意:
- MANIFEST.MF 清单文件, 最后一行一定要有空行
- Manifest-Version 和 Created-By 不写,系统会自动生成
- MANIFEST.MF 清单文件名可以是任意文件名和后缀,也可以没有后缀
文件名:test_print.java
public class test_print {
public static void main(String[] args) {
if (args.length == 1) {
System.out.println("[ INFO ]User args:" + args[0]);
} else {
System.out.println("[ INFO ] no args!!!");
}
}
}
3.1.3 编译
javac test_print.java
3.1.2 打包:
jar -cvfm my.jar MANIFEST.MF test_print.class
只写 -cf 不指定 清单文件,打包
3.1.4 运行jar包:
java -jar my.jar
java -jar my.jar 你好
3.1.5 jar 目录结构
3.2 指定目录打包
3.2.1 源码文件
创建 MANIFEST.MF 清单文件
文件名:MANIFEST.MF
Main-Class: com.test_print
文件名:test_print.java
package com;
public class test_print {
public static void main(String[] args) {
if (args.length == 1) {
System.out.println("[ INFO ]User args:" + args[0]);
} else {
System.out.println("[ INFO ] no args!!!");
}
}
}
3.2.2 编译
javac com\test_print.java
3.2.3 执行打包:
示例 1: 将当前目录下面的所有文件归档到一个名为 my.jar 的档案中:
jar cvfm my.jar MANIFEST.MF com\
另:jar 不只是打包 class 文件,还可以将其他jar文件也打包了
3.2.4 运行jar包&效果:
(效果同 3.1.4)
3.2.5 jar 目录结构
3.3 用.方式打包
3.3.1 源码文件
文件名:MANIFEST.MF
(同3.1.1)
文件名:test_print.java
(同1.1.1)
3.3.2 编译
cd com\
javac test_print.java
3.3.3 执行打包:
使用现有的清单文件 'MANIFEST.MF' 并将 com/ 目录下的所有文件归档到 'my.jar' 中。
jar -cvfm ..\my.jar ..\MANIFEST.MF .
注意:这次执行时,要进入到 D:\java_test\com 目录下
3.3.4 运行jar包:
(效果同 3.1.4)
3.3.5 jar 目录结构
3.4 用.方式打包
3.4.1 源码文件
文件名:MANIFEST.MF
(同3.1.1)
文件名:test_print.java
(同1.1.1)
3.4.2 编译
javac test_print.java
3.4.3 执行打包:
使用现有的清单文件 'MANIFEST.MF' 并将 com/ 目录下的所有文件归档到 'my.jar' 中。
jar cvfm my.jar MANIFEST.MF -C com/ .
3.4.4 运行jar包:
(效果同 3.1.4)
3.4.5 jar 目录结构
3.5 用-cp 引入依赖包编译
-cp指明了.java文件里import的类的位置
3.5.1 源码文件
(略)
3.5.2 编译
javac -cp lib\jsch-0.1.54.jar test_print.java
3.5.3 执行打包:
(略)
3.5.4 运行jar包:
(略)
3.5.5 jar 目录结构
(略)
3.6 用 uvf 更新 jar 包
3.6.1 源码文件
(略)
3.6.2 编译
jar -uvf my.jar com/
3.6.3 执行打包:
(略)
3.6.4 运行jar包:
(略)
3.6.5 jar 目录结构
(略)
3.7 用 -e 参数,指定程序的入口类
用-e参数,就不用写 MANIFEST.MF 清单文件
3.7.1 源码文件
(略)
3.7.2 编译
jar cfe my.jar test_print test_print.class
3.7.3 执行打包:
(略)
3.7.4 运行jar包:
(略)
3.7.5 jar 目录结构
(略)
四、错误:
4.1 "jar中没有主清单属性"t
4.1.1 原因
jar文件的Manifest.mf文件中缺少主类声明引起的。
在Java程序中,主类是程序的入口点,当其他类引用主类时,
JVM(Java虚拟机)可以找到并执行主类中的main方法。
如果jar文件的Manifest.mf文件中没有声明主类,
那么其他类就无法正确引用主类,从而导致程序无法运行。
4.1.2 解决方法:(百度AI)
1. 使用jar命令或者jar工具打开jar文件。
2. 找到或者创建一个名为Manifest.mf的文件。
3. 在Manifest.mf文件中添加以下内容:
Main-Class: YourMainClassName
将"YourMainClassName"替换为你的主类的全名,包括包名。
4. 保存并关闭Manifest.mf文件。
5. 使用jar命令或者jar工具重新打包jar文件。
4.2 "错误: 找不到或无法加载主类 test_print"
4.2.1 原因
1.源码里缺少 package com; 指定包路径。
2.运行时没有指定包路径
4.1.2 解决方法:(百度AI)
1.源码里缺少 package com; 指定包路径。(详见1.2.1源码)
2.(详见 1.1.3 命令)
免责声明:本号所涉及内容仅供安全研究与教学使用,如出现其他风险,后果自负。
参考、来源:
https://blog.csdn.net/xiamaocheng/article/details/129229336 (-cp 即 -classpath 指定 jar 路径)
https://blog.51cto.com/u_16099298/6473404 (-cp 参数后面是类路径,是指定给解释器到哪里找到你的.class文件, )
https://blog.csdn.net/lvjingWn/article/details/73605638 (-cp 指明了.java文件里import的类的位置)
https://blog.51cto.com/u_39029/6504810 (-cp 或 -classpath 指定 jar 路径)
https://blog.csdn.net/weixin_48033662/article/details/134311219 (MANIFEST.MF文件,最后一行必须是空行)
https://blog.51cto.com/u_16213440/7117526 (-e参数用于指定程序的入口类为)
https://blog.csdn.net/tiansyun/article/details/137785780 (-C compiled/ .)