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/ .)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)