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 包就肯定包含了第三方依赖包:

把这个 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:

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

[java] view
plain
 copy

print?

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

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

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

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

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

[html] view
plain
 copy

print?

  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,查看其打包目录,各种配置文件以及第三方依赖包也都有:

然后查看 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-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 替代:

[html] view
plain
 copy

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
打包后的样子,执行之:

错误信息如下:

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

[html] view
plain
 copy

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 的配置变成这样:

[html] view
plain
 copy

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:

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

5 .注意:如果你出现以下情况

E:\workspace\iccardcore\mis\src\main\java\com\hxsmart\sicard\core\webapp\action\

process\DayEndProcessBean.java:[298,65] 找不到符号

那么解决方法:

project---》clean

然后再执行maven工程----》run as--》maven install

在对应的target文件夹下就出现相应的包,运行包即可!,一切正常

时间: 2024-11-05 21:39:09

Maven 打包的一些事儿的相关文章

maven打包之新手拙见

maven打包一直都困扰着我这种新手,现在我也有点明白这是一个什么东西了.把maven打包问题总结一下. 首先配置好各种东西,能运行打包之后再细细研究一下这个打包的配置文件. pom.xml文件: 添加各种jar包引用不多讲了 下来是配置主类这个东西:pom.xml中添加<bulid> 内容如下: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-

maven 打包 java中的配置文件

转发地址 http://www.cnblogs.com/liuzy2014/p/5981824.html 一般情况下,我们用到的资源文件(各种xml,properites,xsd文件等)都放在src/main/resources下面,利用maven打包时,maven能把这些资源文件打包到相应的jar或者war里. 有时候,比如mybatis的mapper.xml文件,我们习惯把它和Mapper.java放一起,都在src/main/java下面,这样利用maven打包时,就需要修改pom.xml

利用Maven打包时,如何包含更多的资源文件

首先,来看下MAVENx项目标准的目录结构: 一般情况下,我们用到的资源文件(各种xml,properites,xsd文件等)都放在src/main/resources下面,利用maven打包时,maven能把这些资源文件打包到相应的jar或者war里. 有时候,比如mybatis的mapper.xml文件,我们习惯把它和Mapper.java放一起,都在src/main/java下面,这样利用maven打包时,就需要修改pom.xml文件,来把mapper.xml文件一起打包进jar或者war

hive udaf 用maven打包运行create temporary function 时报错

用maven打包写好的jar,在放到hive中作暂时函数时报错. 错误信息例如以下: hive> create temporary function maxvalue as "com.leaf.data.Maximum"; java.lang.SecurityException: Invalid signature file digest for Manifest main attributes at sun.security.util.SignatureFileVerifier

基于spring打包 maven 打包jar项目

J2EE项目开发 一般使用tomcat等servlet容器,有些自动化的任务却不需要放在servlet容器中, 把任务打包成jar会更方便部署 使用Maven打包Spring的jar包

Idea开发环境中搭建Maven并且使用Maven打包部署程序

1.配置Maven的环境变量 a.首先我们去maven官网下载Maven程序,解压到安装目录,如图所示: b.配置M2_HOME的环境变量,然后将该变量添加到Path中 备注:必须要有JAVA_HOME的M2_HOME环境变量,不然Maven会提示错误.配置环境变量如图所示: c.如果想要修改Maven的本地仓库位置,则可以直接在Maven的安装目录下找到conf文件下的setting配置文件中,设置localRepository为本地仓库位置 <localRepository>E:\java

Vcenter数据采集之maven打包可执行jar血历史

技术点:spring加载xsd过程: http://blog.csdn.net/bluishglc/article/details/7596118 案发背景: 1.一个使用maven管理的普通项目(vcenter-collector :关于Vcenter数据采集) 2.项目主要技术: java + mybatis(基于接口形式)+其他 3.项目中有一个非maven仓库的jar包:vijava(做vcenter数据采集的),在项目中以system方式引用 (该jar放在${project.base

maven打包步骤

maven打包1:先在pom文件中添加下面配置<build>        <plugins>            <!-- compiler插件, 设定JDK版本 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plug

maven打包异常:软件包com.sun.org.apache.xml.internal.security.utils.Base64 不存在

maven打包异常:软件包com.sun.org.apache.xml.internal.security.utils.Base64 不存在 将jre/lib/rt.jar添加到maven的compiler里面  编译正常... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <versio