编写java后,一般都是通过打包生成jar、war包提供使用,一般在打包后都会在jar包中生成MANIFEST.MF文件
编写一个简单的java文件。
package cn.kanyun;
public class Hello {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World");
}
}
然后使用命令进行打包:
#1.编译源文件
javac Hello.java
#2.打包
jar -cvf hello.jar Hello.class
此时在当前目录下生成了hello.jar文件。
我们运行一下这个jar文件试试看!
java -jar hello.jar
发现报错了.提示主清单没有相应属性。那么什么是主清单呢?
我们把hello.jar使用解压软件进行解压。
通过目录的层级关系,我们找到了MANIFEST.MF文件,这就是我们要找的主清单文件,我们使用文本编辑器打开它,看里面都有什么内容吧。
打开之后里面只有一行内容,那么就说明,刚才使用 jar -cvf hello.jar Hello.class 命令时。创建了 MANIFEST.MF文件,并向其中写入了 该行内容。
那么这个文件是否可以写入其他内容呢?答案是可以的。
以下使用eclipse进行打包!
我们使用eclipse打可运行的jar包!链接
然后打开它的MANIFEST.MF文件,并查看其中的内容
发现它的内容变化了,此时我直接使用 java -jar hello.jar 命令也可以运行了。
那么MANIFEST.MF文件中还有哪些内容呢?我是否可以自定义里面的内容呢?
答案是可以的:
首先我们自定义一个MANIFEST.MF 文件 ,并存放在META-INF文件夹下
此时打jar包的命令如下
#该命令表示用第一个文件当做MENIFEST.MF文件,hello.jar作为名称,将Hello.class打成jar包。其中多了一个参数m,表示要定义MANIFEST.MF文件
jar -cvfm hello.jar META-INF\MANIFEST.MF Hello.class
结果打包出错了
可以看到错误信息。自定义的MANIFEST.MF文件有问题。
重新编辑
再次打包,发现成功了!
那么为什么刚才打包不成功呢?因为刚才自定的MANIFEST.MF文件中key和value中间没有空格,所以打包失败了。这一点一定要注意!
然后我们解压打好的jar包看看里面MANIFEST.MF的内容是不是我们自定义的内容.。
发现比我们定义的内容多了两条,那么可以知道我们自定义清单文件是可以的。
目前看起来是完美的,但是实际情况上我们在实际工作中,并不会只写一个简单的类,然后打包,运行!通常要写很多的类,这个时候光是打包就很费劲了,所以通过会借助一些构建工具比如Maven、Gradle、Ant。
Maven的打包命令是
mvn clean package -Dmaven.test.skip=true
我们看一个最简单的maven打包的例子,pom.xml 什么配置都不加!
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.kanyun</groupId>
<artifactId>maven_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>maven_test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
</dependencies>
</project>
打包完成后,我们查看一下生成的jar包中的MANIFEST.MF文件。
我们发现其实在使用maven打包的过程中maven也会夹带私货,比如文件中的Created-By 表示打包的maven版本等等。
那么maven打包是否可以在MANIFEST.MF中添加其他内容呢?当然是可以了,其主要是在pom.xml中进行配置。链接
上面的链接提到了使用Maven打包MANIFEST.MF中的其他内容,但是还是不能自定义,那么怎么才能自定义呢?
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.kanyun</groupId>
<artifactId>maven_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>maven_test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<my.name>kanyun</my.name>
<my.age>30</my.age>
<my.sex>man</my.sex>
</properties>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Name>${my.name}</Name>
<Age>${my.age}</Age>
<Sex>${my.sex}</Sex>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
运行打包命令,并解压打好的jar包查看其中的MANIFEST.MF文件。
发现自定义的内容出现在了清单文件中!
那么自定义MANIFEST.MF文件有什么用呢?
其实是有利于做模块化。通过读取Jar下的MANIFEST.MF文件可以知道这个jar包否是我们需要的jar包,以及可以读取到一些自定义的配置信息等!
读取Jar包下的MANIFEST.MF
public static String readMainClassFromJarFile(final String jarFilePath) {
try {
JarFile jarFile = new JarFile(jarFilePath);
Manifest mf = jarFile.getManifest();
Attributes mainAttributes = mf.getMainAttributes();
for (Map.Entry<Object, Object> entry : mainAttributes.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
System.out.println("key: " + key + " value:" + value);
}
} catch (Exception e) {
throw new IllegalStateException(String.format("Find Main-Class Exception %s", e.getMessage()));
}
return null;
}