Maven 项目打包需要注意到的那点事儿
发布日期:2025-04-12 18:25:22 浏览次数:17 分类:原创文章

本文共 9114 字,大约阅读时间需要 30 分钟。



1. 关于 Maven 打 war 包

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


maven打的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:


新建maven项目swiftonrsa



其中,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.  



    ApplicationContext context =
    new ClassPathXmlApplicationContext(
    "applicationContext.xml");




  12.  



    LinkPayAntharService linkPayAntharService = (LinkPayAntharService) context.getBean(
    "linkPayAntharService");




  13.  



    linkPayAntharService.dealWithYearData();




  14.  



    }




  15.  



    }





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

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


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



但是这样打好的 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 中加入如下代码:





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


assembly打包后的目录结构



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

怀着兴奋的心情执行之:


assembly打包后的执行情况



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: ,它在对第三方打包时,对于 META-INF 下的 spring.handlers,spring.schemas 等多个同名文件进行了覆盖,遗漏掉了一些版本的 xsd 本地映射。


2.3 maven-shade-plugin 插件

有破必有立。 跟帖中有网友推荐了 maven-shade-plugin 插件。于是我们使用 maven-shade-plugin 将 maven-assembly-plugin 替代:





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


shade插件打包后执行情况



错误信息如下:

java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

这是由于一些包重复引用,打包后的 META-INF 目录多出了一些 *.SF 等文件所致。

有破必有立。博客 给出了解决方案,pom.xml 添加:





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





  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:


再次执行shade插件打包后的swiftonrsa



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


2.4 示例项目

本文示例项目 swiftonrsa 已上传至 CSDN 资源,有兴趣的朋友可以下载下来参考实验,下载地址: 。

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





  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>









转载于:https://www.cnblogs.com/gscq073240/articles/9250243.html

上一篇:Maven 项目用Assembly打包可执行jar包
下一篇:maven 项目依赖自动导入失败(pom.xml 文件爆红),解决--手动导入

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月01日 05时19分16秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章