前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于java打包的那些事

关于java打包的那些事

原创
作者头像
木易三水良
修改2022-03-23 10:06:11
7200
修改2022-03-23 10:06:11
举报
文章被收录于专栏:木易三水良

java命令编译

代码:

代码语言:java
复制
public class Test {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
代码语言:shell
复制
# 编译
javac Test.java
# 运行
java Test
代码语言:java
复制
package com.demo;

public class Test {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
代码语言:shell
复制
# 编译,-d . 生成包名对应的目录
javac .\Test.java -d .
# 运行,一个类的全名应该是包名+类名。类的全名:com.demo.Test
# 运行的目录则是root package所在的目录
java com.demo.Test

java执行class文件是根据CLASSPATH指定的地方来找,不是我们理解当前目录。如果希望它查询当前目录,需要在CLASSPATH中加入 .;,代表当前目录。 java执行class文件对package的路径是强依赖。它在执行的时候会严格以当前用户路径为基础,按照package指定的包路径转化为文件路径去搜索class文件。

jar命令参数详解

jar 用法: jar {ctxui}vfmn0PMe manifest-file -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: 将两个类文件归档到一个名为 test.jar 的档案中: jar cvf test.jar Test1.class Test2.class 示例 2: 使用现有的清单文件 'mymanifest' 并将 foo/ 目录中的所有文件归档到 'test.jar' 中: jar cvfm test.jar mymanifest -C test/ 摘自<jar命令的帮助文档>

MENIFEST.MF文件详解

  • Manifest-Version表示版本号,一般由IDE工具(如eclipse)自动生成
  • Main-Class 是jar文件的主类,程序的入口
  • Class-Path 指定需要的jar,多个jar必须要在一行上,多个jar之间以空格隔开,如果引用的jar在当前目录的子目录下,windows下使用\来分割,linux下用/分割
  • 文件的冒号后面必须要空一个空格,否则会出错
  • 文件的最后一行必须是一个回车换行符,否则也会出错
查看MENIFEST.MF文件内容.png
查看MENIFEST.MF文件内容.png

制作只含字节码文件的jar包(不包含任何路径)

代码

代码语言:java
复制
public class HelloWorld{
  public static void main(String[] args) {
     System.out.println("Hello World!");
  }
}
代码语言:shell
复制
# 编译代码
javac HelloWorld.java

# 打包文件
jar -cvf hello.jar Hello.class 

# 这时运行以下命令,会报如下错误 hello.jar中没有主清单属性
java -jar hello.jar 

添加Main-Class属性,打开META-INF/MANIFEST.MF有如下内容:

代码语言:shell
复制
Manifest-Version: 1.0
Created-By: 1.8.0_271 (Oracle Corporation)

# 以下内容是新添加的:
# 启动类文件名称,格式:Main-class:<空格><启动类class文件名称>
# 再次 java -jar hello.jar 运行成功
# 该行内容可以通过命令指定,自动添加该行内容
# eg: java -cvfe hello.jar HelloWorld HelloWorld.class
Main-class: HelloWorld 

包含多个字节码文件的jar包(不包含任何路径)

代码语言:java
复制
public class HelloWorld{
	public static void main(String[] args) {
		System.out.println("Hello World!");
		Speak.say("muyisanshuiliang");
	}
}

public class Speak{
	public static void say(String name){
		System.out.println("name = " + name);
	}
}
代码语言:shell
复制
# 编译HelloWorld.java 文件的时候会自动自动编译Speak.java
# 如果编译失败,则查看环境变量 CLASSPATH中是否包含".;",意思是否当前位置是否设置为默认加载处
javac HelloWorld.java

# -m 指定MENIFEST文件打包
jar -cvfm hello.jar .\MENIFEST.MF .\HelloWorld.class .\Speak.class

# 执行
java -jar .\hello.jar

包含目录的jar

代码:

代码语言:java
复制
import com.demo.Speak;
public class HelloWorld{
	public static void main(String[] args) {
		System.out.println("Hello World!");
		Speak.say("muyisanshuiliang");
	}
}

package com.demo;
public class Speak{
	public static void say(String name){
		System.out.println("name = " + name);
	}
}
当前目录结构.png
当前目录结构.png

编译:

代码语言:shell
复制
# 将当前文件下下HelloWorld.java编译到指定目录 target下
javac .\HelloWorld.java -d target
编译完成的目录.png
编译完成的目录.png

MENIFEST.MF的内容:

代码语言:shell
复制
Manifest-Version: 1.0
Created-By: 1.8.0_121 (Oracle Corporation)
# 启动类的路径名称要与jar包中的路径名称完全一致,否则在执行的时候会报招不到主启动类的错误。
Main-Class: HelloWorld

打包命令:

代码语言:shell
复制
# 进入到target目录
# 指定MENIFEST.MF文件,将target目录下所有的文件都放入jar包中
jar -cvfm hello.jar MENIFEST.MF *
打包完成的目录结构.png
打包完成的目录结构.png

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • java命令编译
  • jar命令参数详解
  • MENIFEST.MF文件详解
  • 制作只含字节码文件的jar包(不包含任何路径)
    • 代码
    • 包含多个字节码文件的jar包(不包含任何路径)
    • 包含目录的jar
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档