Maven practice (9)-packaging skills

Source: Internet
Author: User
Tags maven central

The term "package" sounds quite plain. The official saying should be "build a project package". Specifically, it refers to the various files in the project, for example, source code, compiled bytecode, configuration files, and documents are generated and archived according to the standard format. The most common ones are the jar package and war package, the complex example is the distribution package on the maven official download page. It has a custom format, so that you can directly decompress the package and use it on the command line. As a "Packaging tool", Maven naturally has the obligation to help users create a variety of packages. The standard jar packages and war packages are naturally no longer mentioned, A slightly complicated custom packaging format must also be supported. This article introduces some common packaging cases and related implementation methods, in addition to some of the packages mentioned above, you can also see how to generate the source code package, javadoc package, and CLI package that can be directly run from the command line.

Meaning of Packaging

Any Maven project must define the POM element packaging (if not written, the default value is jar ). As the name suggests, this element determines the packaging method of the project. In actual situations, if you do not declare this element, MAVEN will generate a jar package for you; if you define the value of this element as war, you will get a war package; if its value is defined as pom (for example, a parent module), no package will be generated. Maven also supports some other popular packaging formats by default, such as ejb3 and ear. You don't need to know the specific packaging details. All you need to do is tell Maven, "What type of project is I?", that isConvention is better than Configuration.

To better understand the default packaging method of Maven, let's take a look at what happened behind the simple declaration. To execute the MVN package operation on a jar project, we will see the following output:

[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ git-demo --- [INFO] Building jar: /home/juven/git_juven/git-demo/target/git-demo-1.2-SNAPSHOT.jar 

In contrast, when you perform the MVN package operation on a war project, the output is as follows:

[INFO] --- maven-war-plugin:2.1:war (default-war) @ webapp-demo --- [INFO] Packaging webapp [INFO] Assembling webapp [webapp-demo] in [/home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT] [INFO] Processing war project [INFO] Copying webapp resources [/home/juven/git_juven/webapp-demo/src/main/webapp] [INFO] Webapp assembled in [90 msecs] [INFO] Building war: /home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT.war 

For the same package lifecycle stage, Maven calls Maven-jar-plugin for the jar project and Maven-war-plugin for the War Project. In other words,Packaging directly affects the maven build Lifecycle. It is very important to understand this, especially when you need to customize the packaging behavior, you must know which plug-in to configure. A common example is to exclude some web resource files when packaging a war project. Configure Maven-war-plugin as follows:

<plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-war-plugin</artifactId>     <version>2.1.1</version>     <configuration>       <webResources>         <resource>           <directory>src/main/webapp</directory>           <excludes>             <exclude>**/*.jpg</exclude>           </excludes>         </resource>       </webResources>     </configuration>   </plugin> 
Source code package and javadoc package

In this column, coordinate planning has explained that a Maven project only generates one main component. When other ancillary components need to be generated, classifier is used. The source code package and the javadoc package are excellent examples of ancillary components. They are widely used, especially for source code packages. When you use a third-party dependency, you sometimes want to directly access the dependency source code in the IDE to view its implementation details, if the dependency is released to the maven repository, It is very convenient for eclipse to parse and download the source package through the m2eclipse plug-in and associate it with your project. As it is extremely common to generate source code packages, Maven provides an official plug-in to help you complete this task:

  <plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-source-plugin</artifactId>     <version>2.1.2</version>     <executions>       <execution>         <id>attach-sources</id>         <phase>verify</phase>         <goals>           <goal>jar-no-fork</goal>         </goals>       </execution>     </executions>   </plugin> 

Similarly, to generate a javadoc package, you only need to configure the following plug-in:

  <plugin>               <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-javadoc-plugin</artifactId>     <version>2.7</version>     <executions>       <execution>         <id>attach-javadocs</id>           <goals>             <goal>jar</goal>           </goals>       </execution>     </executions>   </plugin>    

To help all Maven users more easily use the massive resources in the maven central repository, the maintainers of the central repository forcibly require both the source and javadoc packages to be provided when open-source projects submit components. This is a good practice. Readers can also try to implement it within their own company to promote communication between different projects.

Executable CLI package

In addition to the conventional jar package, war package, source code package, and javadoc package, the other commonly used package is the CLI (command line) package that can be run directly on the command line. By default, the jar package generated by Maven only contains the compiled jar package. to obtain a jar file that can be run directly through the Java command in the command line, the following conditions must be met:

  • The/META-INF/manifest. MF metadata file in the jar package must contain the main-class information.
  • All dependencies of the project must be in classpath.

Maven has several plug-ins that can help you complete the preceding tasks, but Maven-shade-plugin is the most convenient to use. It allows you to configure the value of main-class, then enter the value in/META-INF/manifest during packaging. mf file. For project dependencies, it is smart to decompress all dependent jar files, and then obtain. the class file, together with. the class file is merged into the final CLI package. In this way, all required classes are included in the classpath when the cli jar file is executed. The following is a configuration example:

  <plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-shade-plugin</artifactId>     <version>1.4</version>     <executions>       <execution>         <phase>package</phase>         <goals>           <goal>shade</goal>         </goals>         <configuration>           <transformers>             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">               <mainClass>com.juvenxu.mavenbook.HelloWorldCli</mainClass>             </transformer>           </transformers>         </configuration>       </execution>     </executions>   </plugin> 

In the above example, my main-class is com. juvenxu. mavenbook. helloworldcli, after the build is complete, corresponding to a regular hello-world-1.0.jar file, I still got a hello-world-1.0-cli.jar file. Careful readers may have noticed that the classifier CLI is used here. Finally, I can useJava-jar hello-world-1.0-cli.jarCommand to run the program.

Custom format package

Actual software projects often have more complex packaging requirements. For example, we may need to provide customers with a product distribution package, which not only contains the project's bytecode file, the dependency and related script files must be included to facilitate the operation after the customer decompress the files. In addition, the distribution package must contain some necessary documents. The source code directory structure of the project is roughly as follows:

pom.xml src/main/java/ src/main/resources/ src/test/java/ src/test/resources/ src/main/scripts/ src/main/assembly/ README.txt 

In addition to the basic pom. in addition to the XML and general Maven directories, there is also a src/main/scripts/directory, which contains some script files such as run. SH and run. bat, src/main/ASSEMBLY/will contain an assembly.xml. this is a summary file. Later, we will introduce it. The last readme.txt is a simple document.

We want to generate a zip distribution package, which contains the following structure:

bin/ lib/ README.txt 

The bin/directory contains executable scripts run. SH and run. bat. The LIB/directory contains the project jarpackage and all dependent jars. readme.txt is the document mentioned above.

After the requirements are clearly described, we need to move out of Maven's most powerful packaging plug-in: Maven-assembly-plugin. Fill supports various packaging formats, such as zip、tar.gz?tar.bz2, and so on. Use a package description file (src/main/assembly in this example. XML), which helps you select which file sets, dependencies, modules, and even local repository files to package. You can control the specific packaging path of each item. The following is the packaging description file src/main/assembly. xml corresponding to the preceding requirements:

<assembly>   <id>bin</id>   <formats>     <format>zip</format>   </formats>   <dependencySets>     <dependencySet>       <useProjectArtifact>true</useProjectArtifact>       <outputDirectory>lib</outputDirectory>     </dependencySet>   </dependencySets>   <fileSets>     <fileSet>       <outputDirectory>/</outputDirectory>       <includes>         <include>README.txt</include>       </includes>     </fileSet>     <fileSet>       <directory>src/main/scripts</directory>       <outputDirectory>/bin</outputDirectory>       <includes>         <include>run.sh</include>         <include>run.bat</include>       </includes>     </fileSet>   </fileSets> </assembly>
  • First, the ID of the Assembly. xml file corresponds to the classifier of the final generated file.
  • Second, formats defines the format of the file generated by the package. Here is zip. For this reason, we will get a file named hello-world-1.0-bin.zip. (Assume that artifactid is hello-world and version is 1.0)
  • Dependencysets is used to define the selection dependency and define the directory to which the dependency is finally packaged. The depenencyset we declare here contains all Dependencies by default, while useprojectartifact indicates that the components generated by the project are also included, package the package to the Lib path in the output package (specified by outputdirectory ).
  • Filesets allows you to control packaging through the granularity of files or directories. The first filesetpack the readme.txt file to the root directory of the package, and the second fileset pack the run. SH and run. BAT files under src/main/scripts to the bin directory of the output package.

The configuration supported by the packaged description file is far beyond the scope of this article. In order to avoid too many details disturbing your thinking, you can refer to this document if necessary.

Finally, we need to configure Maven-assembly-plugin to use the package description file and bind it to the lifecycle stage so that it can automatically perform the packaging operation:

  <plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-assembly-plugin</artifactId>     <version>2.2.1</version>     <configuration>       <descriptors>         <descriptor>src/main/assembly/assembly.xml</descriptor>       </descriptors>     </configuration>     <executions>       <execution>         <id>make-assembly</id>         <phase>package</phase>         <goals>           <goal>single</goal>         </goals>       </execution>     </executions>   </plugin>

RunMVN clean packageThen, we can get the distribution package named hello-world-1.0-bin.zip under the target/directory.

Summary

Packaging is one of the most important components of project construction. This article introduces mainstream Maven packaging techniques, including the principle of the default packaging method, how to make the source code package and javadoc package, how to make CLI packages that can run on the command line, and how to customize the packaging format based on Personalized Requirements. This involves a lot of Maven plug-ins, of course, the most important, and the most complex and powerful packaging plug-ins are Maven-assembly-plugin. In fact, Maven's distribution package is made through Maven-assembly-plugin. Interested readers can directly view the source code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.