Maven packages custom MANIFEST.MF key-value pairs

After writing java, it is usually packaged to generate jar and war packages for use. Generally, the MANIFEST.MF file will be generated in the jar package after packaging

Write a simple java file.

package cn.kanyun;

public class Hello {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Hello World");
	}

}

Then use the command to package:

#1.编译源文件
javac Hello.java
#2.打包
jar -cvf hello.jar Hello.class

At this point, the hello.jar file is generated in the current directory.

Let's run this jar file and try it out!

java -jar hello.jar

It was found that an error was reported. It suggested that the main list did not have the corresponding attribute. So what is the master list?

 

We decompress hello.jar using decompression software.

Through the hierarchical relationship of the directory, we found the MANIFEST.MF file. This is the main manifest file we are looking for. Let's open it with a text editor to see what is inside.

After opening, there is only one line of content in it, so it means that when the jar -cvf hello.jar Hello.class command was used just now. A MANIFEST.MF file is created and this line is written to it.

So can this file write other content? The answer is yes.

The following uses eclipse for packaging!

We use eclipse to open the executable jar package! Link

Then open its MANIFEST.MF file and view its contents

It is found that its content has changed. At this time, I can also run the java -jar hello.jar command directly.

So what else is in the MANIFEST.MF file? Can I customize the content inside?

The answer is yes:

First, we customize a MANIFEST.MF file and store it in the META-INF folder

 

At this time, the command to open the jar package is as follows

#该命令表示用第一个文件当做MENIFEST.MF文件,hello.jar作为名称,将Hello.class打成jar包。其中多了一个参数m,表示要定义MANIFEST.MF文件
jar -cvfm hello.jar META-INF\MANIFEST.MF Hello.class

The result was a packaging error

You can see the error message. There is a problem with the custom MANIFEST.MF file.

re-edit

Packed again and found success!

So why did the packaging fail just now? Because there is no space between the key and value in the MANIFEST.MF file that you customized just now, the packaging failed. This point must be paid attention to!

Then we unzip the jar package to see if the content of MANIFEST.MF is our custom content..

It is found that there are two more content than what we defined, so we can know that our custom manifest file is ok.

It seems perfect at present, but in actual work, we don't just write a simple class, then package it, and run it! Usually you have to write a lot of classes. At this time, just packaging is very laborious, so you will use some construction tools such as Maven, Gradle, and Ant.

Maven's packaging command is

mvn clean package -Dmaven.test.skip=true

Let's look at an example of the simplest maven packaging, pom.xml does not add any configuration!

<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>

After the packaging is complete, let's look at the MANIFEST.MF file in the generated jar package.

We found that in the process of using maven to package, maven will also carry private goods. For example, Created-By in the file indicates the packaged maven version and so on.

So can maven package add other content in MANIFEST.MF? Of course it is possible, it is mainly configured in pom.xml. Link

 

The above link mentioned using Maven to package other content in MANIFEST.MF, but it still cannot be customized, so how can it be customized?

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>

Run the packaging command, and unzip the packaged jar package to view the MANIFEST.MF file.

Found that the custom content appeared in the manifest file!

So what is the use of a custom MANIFEST.MF file?

In fact, it is conducive to modularization. By reading the MANIFEST.MF file under Jar, we can know whether the jar package is the jar package we need, and can read some custom configuration information, etc.!

Read MANIFEST.MF under the Jar package

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

 

Guess you like

Origin blog.csdn.net/kanyun123/article/details/113057783