本文原文出处: http://blog.csdn.net/bluishglc/article/details/50380880 严禁任何形式的转载,否则将委托CSDN官方维护权益!

看这样一个非常有趣的问题:

某个项目需要这样进行package操作:

  • 通过maven-jar-plugin率先得到本项目的jar包,之所以显式地配置jar插件是因为要排除掉一些不必要的文件
  • 紧接着,使用maven-shade-plugin,把项目的jar包和其依赖的jar打成一个all-in-one的大jar包。这并不是一种优雅的处理方式,但是限于某些环境的特殊需求,你可能必须这样选择
  • 最后,使用maven-assembly-plugin把最终得到的all-in-one的jar包和一些shell文件以及配置文件按照通常的组织方式(比如bin,lib,conf等文件夹)打包成一个分发包

插一句题外话,有人可能会在看到项目中同时使用jar,shade,assembly这三个package插件时感到惶恐,实际上从我的实践经验来看,这三个插件有各自的侧重点和擅长的问题域,不存在谁替代谁的问题,而是要根据项目需要组合使用。jar是狭义的jar文件打包工具,最终交付的就是一个单一的包含了项目classes的jar包,shade则是侧重于合并依赖jar包生成一个all-in-one的jar包方面,而assembly虽然具有一定的合并依赖jar包的打包能力,但是它在这方面不如shade强大,它的主要强项在于构建一个具有特定目录结构和资源文件的分发包。

最初的配置是这样的:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>${jar.version}</version>
    <configuration>
        <excludes>
            <exclude>bin/**</exclude>
            <exclude>deploy.bat</exclude>
        </excludes>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>${assembly.version}</version>
    <inherited>false</inherited>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <descriptors>
            <descriptor>src/main/assembly/bin.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>${shade.version}</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>

在生成的target目录下,得到类似如下的几个重要文件:

xxx.jar (大约15M )
original-xxx.jar (大约10K )
xxx-bin.zip ~10K (大约10K )

解释一下这三个文件的来历:
original-xxx.jar最初是由jar插件生成的只包含项目自身classes的jar包,所以它很小,它被创建之初时名字是xxx.jar,是后续的shade插件在工作时,将其重命名的, shade将xxx.jar及其依赖的jar打包在一起,为了避免重名而将原来的xxx.jar更名为了original-xxx.jar,新的xxx.jar是所有依赖jar的合集,所以体积很大。xxx-bin.zip就是包含了xxx.jar的一个最后的发行包。

然而这份配置却有一个重大的bug:

我们可以看到xxx-bin.zip文件是很小的,它里面的xxx.jar并不是经过shade处理后的all-in-one的大jar包,而是在jar打包阶段生成的那个原始的较小的xxx.jar。虽然上述三个插件无一例外地都绑定到了package这个phase上,但三者之间还是有一个“先来后到”的顺序,这个bug在暗示我们,根据上面的这份配置中,maven率先执行的jar插件,然后执行了assembly,这是为什么zip包中包含的是经过jar插件生成的那个原始xxx.jar而不是经过shadee插件生成的那个all-in-one大jar包的原因,因为shade插件放在了最后面执行了,所以是最后生成的all-in-one的大jar包,也就错过zip打包的过程。所以说,maven对于绑定到同一phase上的多个插件的执行顺序是按照它们在pom.xml声明的顺序来的

所以修改这个bug的方案也就清楚了,我们只需要调整一下这三个插件的声明顺序就可以了,把之前的maven-jar-plugin -> maven-assembly-plugin -> maven-shade-plugin 修改为maven-jar-plugin -> maven-shade-plugin -> maven-assembly-plugin 即可

以下是修改后的版本:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>${jar.version}</version>
    <configuration>
        <excludes>
            <exclude>bin/**</exclude>
            <exclude>deploy.bat</exclude>
        </excludes>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>${shade.version}</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>${assembly.version}</version>
    <inherited>false</inherited>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <descriptors>
            <descriptor>src/main/assembly/bin.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>
                    看这样一个非常有趣的问题:某个项目需要这样进行package操作:通过maven-jar-plugin率先得到本项目的jar包,之所以显式地配置jar插件是因为要排除掉一些不必要的文件紧接着,使用maven-shade-plugin,把项目的jar包和其依赖的jar打成一个all-in-one的大jar包。这并不是一种优雅的处理方式,但是限于某些环境的特殊需求,你可能必须这样选择最后,使用ma
				
对于maven进行项目构建时,我们会使用到插件,对构建过程进行一些控制,加工,加密,重写,依赖打包等工作,一般我们打包时会把phase定为package,意思是说,当进行package动作后,处理你的插件。 多个相同phase的顺序 当我们有多个plugin,并且相同phase时,有时需要考虑到顺序问题,因为你的plugin可能会有某个其它plugin的结果的依赖,所以我们需要控制 <plugins> <plugin> <artifactId>maven-sha
maven多模块打包一般相互之间都有互相的依赖关系,如果没有按照正确的依赖关系顺序进行打包就会报错。 例如有三个模块web、service、common。其中web依赖service。web和service都依赖common,那么正确的打包顺序就是: common->service->web。 否则就会报错。 如果用一个父目录包含他们三个模块的话,可以用 maven-ass...
Maven中,您可以使用构建生命周期或阶段来控制插件执行的顺序。 在某些情况下,您必须将几个插件绑定到同一个阶段,但是仍然想控制插件执行的顺序。 但是,该命令的执行顺序与POM中列出的顺序不同,请参见此MNG-2258和MNG-3719 。 此错误已在Maven 3.0.3中修复, 绑定到同一阶段的Maven插件将按照pom.xml中列出的顺序执行 例如,在“ prepar...
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors>   本博文不会长篇大论的讨论生命周期的概念,而是从各种plugin的实际功能和应用出发,来讨论maven的实际应用,说得通透一点,生命周期(lifecycle)可以理解成由各种plugin按照一定的顺序执行来完成java项目清理、编译、打包、测试、布署等整个项目的流程的一个过程。   生命周期(lifecycle)由各个阶段组成,每个阶段由maven插件plugin来执行完成。生命周期...
我们使用maven做一些日常的工作开发的时候,无非是想利用这个工具带来的一些便利。比如它带来的依赖管理,方便我们打包和部署运行。这里几个常见的插件就是和这些工程中常用的步骤相关。 maven-compile-plugin     这个插件就如同名字所显示的这样,用来编译源代码的。最开始碰到这个插件是在于有的时候我们下载了一些工程需要编译的时候,比如我们输入命令:mvn install ,
您可以使用 `org.mybatis.generator:mybatis-generator-maven-plugin` Maven 插件以编程方式配置和使用 MyBatis Generator。以下是一些简单的步骤: 1.在 Maven pom.xml 文件中,添加 MyBatis Generator Maven 插件的依赖项: ```xml <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>{mybatis-generator-version}</version> </dependency> 2.在 Maven pom.xml 文件中,添加 MyBatis Generator 的配置和生成器的目标: ```xml <build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>{mybatis-generator-version}</version> <executions> <execution> <id>Generate MyBatis Artifacts</id> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <configurationFile>src/main/resources/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin> </plugins> </build> 3.在 Maven pom.xml 文件中,创建 MyBatis Generator 的配置文件 `generatorConfig.xml`。 4.使用以下命令运行插件来生成 MyBatis 代码: ```bash mvn mybatis-generator:generate 以上是一些基本步骤,您可以根据需要进行进一步的配置和调整,如在配置文件中添加数据库连接等信息,以生成您需要的 MyBatis 代码。
Java应用/JDBC/Squirrel在Kerberos认证时报Unable to obtain Principal Name for authentication的解决方法 _a_0_: 你好 如果想要使用不同的keytab连接impala 通过配置能实现吗 用代码可是做到 但是我们这边是个可视化的平台驱动二次开发也不方便 移除Office 365快捷键 UnknownKaze: 感谢,哈哈哈,做个ppt快被这个弹出烦死了 算法效果评估:均方根误差(RMSE)/ 标准误差 weixin_45073642: 这也没有RMSE,MSE的代码啊,公式虽然和方差标准差很像,但参与运算的是两组数据。。。 Python PIP 配置文件的存放位置与加载顺序 cnn_xiaobai: # This file has been autogenerated or modified by NVIDIA PyIndex. # In case you need to modify your PIP configuration, please be aware that # some configuration files may have a priority order. Here are the following # files that may exists in your machine by order of priority: # [Priority 1] Site level configuration files # 1. `/opt/conda/pip.conf` # [Priority 2] User level configuration files # 1. `/root/.config/pip/pip.conf` # 2. `/root/.pip/pip.conf` # [Priority 3] Global level configuration files # 1. `/etc/pip.conf` # 2. `/etc/xdg/pip/pip.conf` 探索Apache Hudi核心概念 (1) - File Layouts Knight丶: DNS lookup for realm name failed, SRV record for LDAP / Kerberos does not exist for IP … 解决方法 探索Apache Hudi核心概念 (3) - Compaction 移除Office 365快捷键