maven打包的那些事

奋斗吧
奋斗吧
擅长邻域:未填写

标签: maven打包的那些事 Python博客 51CTO博客

2023-07-07 18:24:22 132浏览

maven打包的那些事,1.关于Maven打war包《使用Eclipse的Maven2插件开发一个JEE项目》详细介绍了如何在Eclipse使用Maven新


1. 关于 Maven 打 war 包

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

maven打包的那些事_maven



把这个 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打包的那些事_jar_02



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

1. package com.defonds;  
2.   
3. import org.springframework.context.ApplicationContext;  
4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
5.   
6. import com.defonds.service.LinkPayAntharService;  
7.   
8. public class RsaEncryptor {  
9.   
10. public static void main(String[] args) {  
11. new ClassPathXmlApplicationContext("applicationContext.xml");  
12. "linkPayAntharService");  
13.         linkPayAntharService.dealWithYearData();  
14.     }  
15. }

 

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

只要你项目所依赖的配置文件都按照 maven 规范放对位置(src/main/resources),那么打好的 jar 包就会把它们一起打包:

maven打包的那些事_java_03



但是这样打好的 jar 包既没有指定 main 入口类,也没有将依赖包打进来,我们运行它:

maven打包的那些事_jira_04



提示"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 中加入如下代码:

1. <build>  
2. <plugins>  
3. <plugin>  
4. <artifactId>maven-assembly-plugin</artifactId>  
5. <configuration>  
6. <appendAssemblyId>false</appendAssemblyId>  
7. <descriptorRefs>  
8. <descriptorRef>jar-with-dependencies</descriptorRef>  
9. </descriptorRefs>  
10. <archive>  
11. <manifest>  
12. <mainClass>com.defonds.RsaEncryptor</mainClass>  
13. </manifest>  
14. </archive>  
15. </configuration>  
16. <executions>  
17. <execution>  
18. <id>make-assembly</id>  
19. <phase>package</phase>  
20. <goals>  
21. <goal>assembly</goal>  
22. </goals>  
23. </execution>  
24. </executions>  
25. </plugin>  
26. </plugins>  
27. </build>

执行 mvn assembly:assembly,成功构建 swiftonrsa-1.0.0.jar,查看其打包目录,各种配置文件以及第三方依赖包也都有:

maven打包的那些事_maven_05



然后查看 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打包的那些事_jira_06



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 替代:

print     ?             
1. <build>  
2. <plugins>  
3. <plugin>  
4. <groupId>org.apache.maven.plugins</groupId>  
5. <artifactId>maven-shade-plugin</artifactId>  
6. <version>1.4</version>  
7. <executions>  
8. <execution>  
9. <phase>package</phase>  
10. <goals>  
11. <goal>shade</goal>  
12. </goals>  
13. <configuration>  
14. <transformers>  
15. <transformer  
16. implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  
17. <mainClass>com.defonds.RsaEncryptor</mainClass>  
18. </transformer>  
19. <transformer  
20. implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
21. <resource>META-INF/spring.handlers</resource>  
22. </transformer>  
23. <transformer  
24. implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
25. <resource>META-INF/spring.schemas</resource>  
26. </transformer>  
27. </transformers>  
28. </configuration>  
29. </execution>  
30. </executions>  
31. </plugin>  
32. </plugins>  
33. </build>

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

maven打包的那些事_jar_07



错误信息如下:

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 添加:

print     ?             
1. <configuration>  
2. <filters>  
3. <filter>  
4. <artifact>*:*</artifact>  
5. <excludes>  
6. <exclude>META-INF/*.SF</exclude>  
7. <exclude>META-INF/*.DSA</exclude>  
8. <exclude>META-INF/*.RSA</exclude>  
9. </excludes>  
10. </filter>  
11. </filters>  
12. </configuration>


于是我们对 maven-shade-plugin 的配置变成这样:


 

print     ?             
1. <build>  
2. <plugins>  
3. <plugin>  
4. <groupId>org.apache.maven.plugins</groupId>  
5. <artifactId>maven-shade-plugin</artifactId>  
6. <version>1.4</version>  
7. <executions>  
8. <execution>  
9. <phase>package</phase>  
10. <goals>  
11. <goal>shade</goal>  
12. </goals>  
13. <configuration>  
14. <filters>  
15. <filter>  
16. <artifact>*:*</artifact>  
17. <excludes>  
18. <exclude>META-INF/*.SF</exclude>  
19. <exclude>META-INF/*.DSA</exclude>  
20. <exclude>META-INF/*.RSA</exclude>  
21. </excludes>  
22. </filter>  
23. </filters>  
24. <transformers>  
25. <transformer  
26. implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  
27. <mainClass>com.defonds.RsaEncryptor</mainClass>  
28. </transformer>  
29. <transformer  
30. implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
31. <resource>META-INF/spring.handlers</resource>  
32. </transformer>  
33. <transformer  
34. implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
35. <resource>META-INF/spring.schemas</resource>  
36. </transformer>  
37. </transformers>  
38. </configuration>  
39. </execution>  
40. </executions>  
41. </plugin>  
42. </plugins>  
43. </build>

再次执行 maven clean package,再次执行成功构建后的 swiftonrsa-1.0.0.jar:

maven打包的那些事_java_08



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

2.4 示例项目


本文示例项目最终 pom.xml 如下:


print     ?             
1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
3. <modelVersion>4.0.0</modelVersion>  
4.   
5. <groupId>settle</groupId>  
6. <artifactId>swiftonrsa</artifactId>  
7. <version>1.0.0</version>  
8. <packaging>jar</packaging>  
9.   
10. <name>swiftonrsa</name>  
11. <url>http://maven.apache.org</url>  
12.   
13. <properties>  
14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
15. </properties>  
16.   
17. <build>  
18. <plugins>  
19. <plugin>  
20. <groupId>org.apache.maven.plugins</groupId>  
21. <artifactId>maven-shade-plugin</artifactId>  
22. <version>1.4</version>  
23. <executions>  
24. <execution>  
25. <phase>package</phase>  
26. <goals>  
27. <goal>shade</goal>  
28. </goals>  
29. <configuration>  
30. <filters>  
31. <filter>  
32. <artifact>*:*</artifact>  
33. <excludes>  
34. <exclude>META-INF/*.SF</exclude>  
35. <exclude>META-INF/*.DSA</exclude>  
36. <exclude>META-INF/*.RSA</exclude>  
37. </excludes>  
38. </filter>  
39. </filters>  
40. <transformers>  
41. <transformer  
42. implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  
43. <mainClass>com.defonds.RsaEncryptor</mainClass>  
44. </transformer>  
45. <transformer  
46. implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
47. <resource>META-INF/spring.handlers</resource>  
48. </transformer>  
49. <transformer  
50. implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
51. <resource>META-INF/spring.schemas</resource>  
52. </transformer>  
53. </transformers>  
54. </configuration>  
55. </execution>  
56. </executions>  
57. </plugin>  
58. </plugins>  
59. </build>  
60.   
61.   
62. <dependencies>  
63.   
64. <!-- logs -->  
65. <dependency>  
66. <groupId>log4j</groupId>  
67. <artifactId>log4j</artifactId>  
68. <version>1.2.17</version>  
69. </dependency>  
70.   
71. <dependency>  
72. <groupId>commons-logging</groupId>  
73. <artifactId>commons-logging</artifactId>  
74. <version>1.2</version>  
75. </dependency>  
76.   
77. <dependency>  
78. <groupId>org.slf4j</groupId>  
79. <artifactId>slf4j-api</artifactId>  
80. <version>1.7.10</version>  
81. </dependency>  
82.   
83. <dependency>  
84. <groupId>org.slf4j</groupId>  
85. <artifactId>slf4j-log4j12</artifactId>  
86. <version>1.7.10</version>  
87. </dependency>  
88.   
89. <!-- spring -->  
90. <dependency>  
91. <groupId>org.springframework</groupId>  
92. <artifactId>spring-core</artifactId>  
93. <version>3.2.3.RELEASE</version>  
94. </dependency>  
95.   
96. <dependency>  
97. <groupId>org.springframework</groupId>  
98. <artifactId>spring-orm</artifactId>  
99. <version>3.2.3.RELEASE</version>  
100. </dependency>  
101.   
102. <dependency>  
103. <groupId>org.springframework</groupId>  
104. <artifactId>spring-context</artifactId>  
105. <version>3.2.3.RELEASE</version>  
106. </dependency>  
107.   
108. <!-- ibatis -->  
109. <dependency>  
110. <groupId>org.apache.ibatis</groupId>  
111. <artifactId>ibatis-sqlmap</artifactId>  
112. <version>2.3.4.726</version>  
113. </dependency>  
114.   
115. <!-- connector -->  
116. <dependency>  
117. <groupId>mysql</groupId>  
118. <artifactId>mysql-connector-java</artifactId>  
119. <version>5.1.19</version>  
120. </dependency>  
121.   
122. <!-- dbcp -->  
123. <dependency>  
124. <groupId>commons-dbcp</groupId>  
125. <artifactId>commons-dbcp</artifactId>  
126. <version>1.4</version>  
127. </dependency>  
128.   
129. <dependency>  
130. <groupId>commons-pool</groupId>  
131. <artifactId>commons-pool</artifactId>  
132. <version>1.6</version>  
133. </dependency>  
134.   
135. <!-- rsa encrypt -->  
136. <dependency>  
137. <groupId>org.bouncycastle</groupId>  
138. <artifactId>bcprov-jdk15on</artifactId>  
139. <version>1.51</version>  
140. </dependency>  
141.   
142. <!-- commons-codec -->  
143. <dependency>  
144. <groupId>commons-codec</groupId>  
145. <artifactId>commons-codec</artifactId>  
146. <version>1.6</version>  
147. </dependency>  
148.   
149. </dependencies>  
150. </project>  
151.

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695