[!NOTE] 习惯性执行
java -jar xxx.jar来启动一个Java服务,今天手动打一个可执行jar包看看,
先看文档
Oracle文档关于可执行jar的一些描述:link
## JAR Files as Applications
You can run JAR packaged applications with the Java launcher (java command). The basic command is:
java -jar _jar-file_
The -jar flag tells the launcher that the application is packaged in the JAR file format. You can only specify one JAR file, which must contain all of the application-specific code.
Before you execute this command, make sure that the runtime environment has information about which class within the JAR file is the application's entry point.
To indicate which class is the application's entry point, you must add a Main-Class header to the JAR file's manifest. The header takes the form:
Main-Class: _classname_
The header's value, classname, is the name of the class that is the application's entry point.
For more information, see the [Setting an Application's Entry Point](https://docs.oracle.com/javase/tutorial/deployment/jar/appman.html) section.
When the Main-Class is set in the manifest file, you can run the application from the command line:
java -jar app.jar
To run the application from the JAR file that is in another directory, you must specify the path of that directory: `java -jar path/app.jar`
再看下jar文件的结构,可以在Oracle里找到 oracle-jar-spec , 重点看 META-INF/MANIFEST.MF 同样提到了 Main-Class: 这个属性;
开始动手:
新建文件夹 simple-jar 下面所有操作都是在该目录下执行的
新建一个类One.java 代码如下
package org.none;
public class One {
public static void main(String[] args) {
System.out.println("Hello One");
}
}
新建文件 MANIFEST.MF , 文件内容如下
Main-Class: org.none.One
编译java文件
javac org.none/One.java
使用tree命令看下目前的文件及目录
➜ simple-jar tree
.
├── META-INF
│ └── MANIFEST.MF
└── org.none
├── One.class
└── One.java
2 directories, 3 files
使用jar命令打包并运行
jar -c -f simple.jar -m META-INF/MANIFEST.MF org/example/One.class
java -jar simple.jar
输出错误提示: simple.jar中没有主清单属性
解压simple.jar看看
jar包里的META-INF/MANIFEST.MF 文件 内容 确实没有 Main-Class 一项
Manifest-Version: 1.0
Created-By: 17.0.7 (Oracle Corporation)
反复搜索后从文档中看到
A JAR file manifest consists of a main section followed by a list of sections for individual JAR file entries, each separated by a newline. Both the main section and individual sections follow the section syntax specified above. They each have their own specific restrictions and rules.
The main section contains security and configuration information about the JAR file itself, as well as the application. It also defines main attributes that apply to every individual manifest entry. No attribute in this section can have its name equal to "Name". This section is terminated by an empty line.
最后一句是重点 ==This section is terminated by an empty line.==
其中Main-Class就属于 main section 部分,可以到文档里详细查看
在我的MANIFEST.MF追加一个空行试试看
Main-Class: org.none.One
重新打包并执行
➜ simple-jar jar -c -f simple.jar -m META-INF/MANIFEST.MF org/example/One.class && java -jar simple.jar
Hello One
终于输出了 Hello One
最后再看一眼现在的目录结构:
➜ simple-jar tree
.
├── META-INF
│ └── MANIFEST.MF
├── org
│ └── example
│ ├── One.class
│ └── One.java
└── simple.jar
3 directories, 4 files