Maven打包自定义MANIFEST.MF键值对

编写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;
	}

猜你喜欢

转载自blog.csdn.net/kanyun123/article/details/113057783