Maven 项目打包需要注意到的那点事儿

1. 关于 Maven 打 war 包

《 使用 Eclipse 的 Maven 2 插件开发一个 JEE 项目》详细介绍了如何在 Eclipse 使用 Maven 新建一个 JEE 项目并对其进行断点跟踪调试,但是没有介绍如何对 JEE 项目打 war 包。其实很简单,你只需要把 pom.xml 中的 jar 换成 war 就可以使用 mvn package 命令对其打 war 包了,而不需要添加任何 maven 插件。只要你遵循了 maven 规范(比如照着《 使用 Eclipse 的 Maven 2 插件开发一个 JEE 项目》所述做了),那你打成的 war 包就肯定包含了第三方依赖包:
Maven 项目打包需要注意到的那点事儿_第1张图片

把这个 war 包丢进 tomcat 的 webapps 目录,重启 tomcat 即可完成了该项目的部署。你唯一需要注意的是,在重启 tomcat 之前把你的 war 重命名为 项目访问路径.war。比如作者打成的 war 包是为 swifton-1.0.0.war,对该项目定义的访问路径是 /swifton,那么我在重启 tomcat 之前需要将其重命名为 swifton.war。

2. 可执行程序打 jar 包

关于可执行程序(需要指定一个 main 类)打 jar 包就没这么方便了,我们需要考虑以下几个问题:
  • 配置文件需要打进 jar 包;
  • 需要指定 main 入口类;
  • 所依赖的第三方库也要打进 jar 包;
只有同时满足以上三点,我们才可以直接使用 java -jar swiftonrsa-1.0.0.jar 命令成功执行该程序。
为了让讨论不那么抽象,我们在 Eclipse 下新建一个 maven 项目 swiftonrsa:
Maven 项目打包需要注意到的那点事儿_第2张图片

其中,com.defonds.RsaEncryptor 是入口 main 类,其源码如下:
package com.defonds;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.defonds.service.LinkPayAntharService;

public class RsaEncryptor {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		LinkPayAntharService linkPayAntharService = (LinkPayAntharService) context.getBean("linkPayAntharService");
		linkPayAntharService.dealWithYearData();
	}
}

2.1 配置文件打包不需要额外关注

只要你项目所依赖的配置文件都按照 maven 规范放对位置(src/main/resources),那么打好的 jar 包就会把它们一起打包:
Maven 项目打包需要注意到的那点事儿_第3张图片

但是这样打好的 jar 包既没有指定 main 入口类,也没有将依赖包打进来,我们运行它:
swiftonrsa-1.0.0.jar中没有清单属性

提示"swiftonrsa-1.0.0.jar中没有主清单属性",我们查看打好 jar 包下 META-INF 目录中的 MANIFEST.MF,其内容如下:
Manifest-Version: 1.0
Built-By: Defonds
Build-Jdk: 1.7.0_67
Created-By: Apache Maven 3.2.3
Archiver-Version: Plexus Archiver

确实没有指出 main 入口类。

2.2 maven-assembly-plugin 插件

于是我们引入了 maven-assembly-plugin 插件,pom.xml 中加入如下代码:
	
		
			
				maven-assembly-plugin
				
					false
					
						jar-with-dependencies
					
					
						
							com.defonds.RsaEncryptor
						
					
				
				
					
						make-assembly
						package
						
							assembly
						
					
				
			
		
	

执行 mvn assembly:assembly,成功构建 swiftonrsa-1.0.0.jar,查看其打包目录,各种配置文件以及第三方依赖包也都有:
Maven 项目打包需要注意到的那点事儿_第4张图片

然后查看 META-INF 目录中的 MANIFEST.MF,内容如下:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Defonds
Build-Jdk: 1.7.0_67
Main-Class: com.defonds.RsaEncryptor

怀着兴奋的心情执行之:
Maven 项目打包需要注意到的那点事儿_第5张图片

maven-assembly-plugin 插件没有给我们带来惊喜。错误信息如下:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]
原来这是 assembly 插件的一个 bug: http://jira.codehaus.org/browse/MASSEMBLY-360,它在对第三方打包时,对于 META-INF 下的 spring.handlers,spring.schemas 等多个同名文件进行了覆盖,遗漏掉了一些版本的 xsd 本地映射。

2.3 maven-shade-plugin 插件

有破必有立。 http://jira.codehaus.org/browse/MASSEMBLY-360 跟帖中有网友推荐了 maven-shade-plugin 插件。于是我们使用 maven-shade-plugin 将 maven-assembly-plugin 替代:
	
		
			
				org.apache.maven.plugins
				maven-shade-plugin
				1.4
				
					
						package
						
							shade
						
						
							
								
									com.defonds.RsaEncryptor
								
								
									META-INF/spring.handlers
								
								
									META-INF/spring.schemas
								
							
						
					
				
			
		
	

对于多个第三方包 META-INF 下的同名的 spring.handlers 文件它采取的态度是追加而不是覆盖。执行 maven clean package,成功构建 swiftonrsa-1.0.0.jar,查看其打包目录,各种配置文件以及第三方依赖包也都有,以及 META-INF 目录中的 MANIFEST.MF 的内容,基本如 maven-assembly-plugin 打包后的样子,执行之:
Maven 项目打包需要注意到的那点事儿_第6张图片

错误信息如下:
java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
这是由于一些包重复引用,打包后的 META-INF 目录多出了一些 *.SF 等文件所致。
有破必有立。博客 http://zhentao-li.blogspot.com/2012/06/maven-shade-plugin-invalid-signature.html 给出了解决方案,pom.xml 添加:
        
          
            
              *:*
              
                META-INF/*.SF
                META-INF/*.DSA
                META-INF/*.RSA
              
            
          
        

于是我们对 maven-shade-plugin 的配置变成这样:
	
		
			
				org.apache.maven.plugins
				maven-shade-plugin
				1.4
				
					
						package
						
							shade
						
						
							
								
									*:*
									
										META-INF/*.SF
										META-INF/*.DSA
										META-INF/*.RSA
									
								
							
							
								
									com.defonds.RsaEncryptor
								
								
									META-INF/spring.handlers
								
								
									META-INF/spring.schemas
								
							
						
					
				
			
		
	

再次执行 maven clean package,再次执行成功构建后的 swiftonrsa-1.0.0.jar:
Maven 项目打包需要注意到的那点事儿_第7张图片

最后两行是具体业务实现类 com.defonds.service.LinkPayAntharServiceImpl 成功执行打印出的 log 日志。

2.4 示例项目

本文示例项目 swiftonrsa 已上传至 CSDN 资源,有兴趣的朋友可以下载下来参考实验,下载地址: http://download.csdn.net/detail/defonds/8404739。
本文示例项目最终 pom.xml 如下:

	4.0.0

	settle
	swiftonrsa
	1.0.0
	jar

	swiftonrsa
	http://maven.apache.org

	
		UTF-8
	

	
		
			
				org.apache.maven.plugins
				maven-shade-plugin
				1.4
				
					
						package
						
							shade
						
						
							
								
									*:*
									
										META-INF/*.SF
										META-INF/*.DSA
										META-INF/*.RSA
									
								
							
							
								
									com.defonds.RsaEncryptor
								
								
									META-INF/spring.handlers
								
								
									META-INF/spring.schemas
								
							
						
					
				
			
		
	


	

		
		
			log4j
			log4j
			1.2.17
		

		
			commons-logging
			commons-logging
			1.2
		

		
			org.slf4j
			slf4j-api
			1.7.10
		

		
			org.slf4j
			slf4j-log4j12
			1.7.10
		

		
		
			org.springframework
			spring-core
			3.2.3.RELEASE
		

		
			org.springframework
			spring-orm
			3.2.3.RELEASE
		

		
			org.springframework
			spring-context
			3.2.3.RELEASE
		

		
		
			org.apache.ibatis
			ibatis-sqlmap
			2.3.4.726
		

		
		
			mysql
			mysql-connector-java
			5.1.19
		

		
		
			commons-dbcp
			commons-dbcp
			1.4
		

		
			commons-pool
			commons-pool
			1.6
		

		
		
			org.bouncycastle
			bcprov-jdk15on
			1.51
		

		
		
			commons-codec
			commons-codec
			1.6
		

	


你可能感兴趣的:(项目管理)