Maven package错误:You have to use a classifier to attach supplemental artifacts to the project instead...

在pom.xml中配置maven-jar-plugin时,为避免打包时生成两个同名jar包导致错误,需要使用classifier属性来区分不同jar。classifier是一个标识符,用于在jar包名称后添加区分的标签。例如,原本的jar名为deploy-0.0.1-SNAPSHOT.jar,加上classifier后,额外生成的jar变为deploy-0.0.1-SNAPSHOT-bak.jar。正确配置classifier可以避免覆盖原有jar,并确保maven执行正确的打包操作。

我在pom.xml文件中添加了一个maven-jar-plugin的插件,目的是想多打一个jar包,如下:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.0.2</version>
  <executions>
    <execution>
      <id>service-jar</id>
      <phase>package</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <classesDirectory>${project.build.directory}/webservice/</classesDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>


目的是将webservice目录打包成jar包,运行mvn package之后,却报错了:

...
[INFO] --- maven-jar-plugin:3.0.2:jar (make-a-jar) @ deploy ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.035 s
[INFO] Finished at: 2017-11-17T09:25:22+08:00
[INFO] Final Memory: 18M/167M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-jar-plugin:3.0.2:jar (make-a-jar) on project deploy: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them. -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException


原来如果在plugin中添加maven-jar-plugin插件之后,maven会运行两次maven-jar-plugin插件,第一次运行是打包当前工程的jar,第二次运行是执行在plugin中设置的jar,这样的话会生成两个jar包,这里就要用到classifier这个属性了。classifier是用来标识不同的jar包的名称的一个分类符,这个属性的值会添加到工程jar包的名称后面。
例如当前工程的坐标:

<groupId>deploy</groupId>
<artifactId>deploy</artifactId>
<version>0.0.1-SNAPSHOT</version>


那就是意味着打包之后的jar包名称为deploy-0.0.1-SNAPSHOT.jar,而在plugin中设置要打的jar包是额外的jar包,classifier的值设置为bak:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.0.2</version>
  <executions>
    <execution>
      <id>service-jar</id>
      <phase>package</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <classifier>bak</classifier> <!-- 生成deploy-0.0.1-SNAPSHOT-bak.jar -->
        <classesDirectory>${project.build.directory}/webservice/</classesDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>


那最后在build目录下会有两个jar包,一个是deploy-0.0.1-SNAPSHOT.jar,另外一个则是deploy-0.0.1-SNAPSHOT-bak.jar
这个deploy-0.0.1-SNAPSHOT-bak.jar是根据${project.build.directory}/webservice/这个目录下的文件来生成的jar包。
总之,打出的jar包名称一定要区分,maven默认打多个jar包时不能覆盖掉原来的jar包,所以classifier就做了这个事情,可以从控制台打印的信息看到,maven执行了两次maven-jar-plugin的打包操作:

[INFO] 
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ vbap3-webservice ---
[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: /deploy/target/deploy-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-jar-plugin:3.0.2:jar (vbap-jar) @ vbap3-webservice ---
[INFO] Building jar: /deploy/target/deploy-0.0.1-SNAPSHOT-bak.jar
[INFO] 

如果是只想要使用plugin生成的jar包,那么可以直接把execution的id改为default-jar,因为默认本身会调用一个maven-jar-plugin并且执行一个default-jar的操作,这里如果命名了一个default-jar的操作,那么就会按照这个操作进行打包,但是这个时候不能添加classifier分类符,因为这时只有一个jar包。
 

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.0.2</version>
  <executions>
    <execution>
      <id>default-jar</id>
      <phase>package</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>  <!-- 没有classifier -->
        <classesDirectory>${project.build.directory}/webservice/</classesDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

 

转载于:https://my.oschina.net/clyy/blog/2960592

### 解决方案 当 Maven 执行 `package` 阶段时,可能会因为配置不当而触发错误:“You have to use a classifier to attach supplemental artifacts to the project instead of replacing them.” 此类问题通常发生在多个插件尝试生成相同类型的工件(如 JAR 文件)时。 为了防止冲突并区分不同版本的工件,可以使用 **classifier** 属性。以下是具体实现方法: #### 使用 Classifier 的解决方案 在 Maven 中,Classifier 是一种用于区分同一构件的不同变体的方式。它会被附加到最终构建产物的名字中,从而允许在同一项目中创建多个具有不同用途的工件[^2]。 以下是一个典型的 `pom.xml` 配置示例,展示如何通过设置 `classifier` 来解决上述问题: ```xml <build> <plugins> <!-- 默认的 maven-jar-plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <!-- 自定义 jar 插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>custom-jar</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> <configuration> <classifier>custom</classifier> <!-- 设置分类器 --> <includes> <include>com/example/custom/**</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> ``` 在这个例子中,我们为自定义的 JAR 工件设置了 `classifier="custom"`。这使得该工件不会覆盖默认的主 JAR 文件,而是作为独立文件存在。假设项目的坐标如下所示,则生成的工件名将是这样的形式: - 主 JAR:`deploy-deploy-0.0.1-SNAPSHOT.jar` - 自定义 JAR:`deploy-deploy-0.0.1-SNAPSHOT-custom.jar` 这样就成功避免了重复命名引发的冲突问题。 #### 关键点说明 - 如果在一个 POM 文件里多次声明相同的插件目标 (Goal),则需要利用额外参数比如 `classifier` 或者完全不同的路径来区别这些输出物。 - 对于仅提供依赖管理功能而不含业务逻辑代码的基础库模块来说,也可以考虑将其类型设成 pom 类型而非 jar ,即 `<packaging>pom</packaging>` 。如此一来就不会涉及任何二进制文件的实际编译过程[^3]。 ### 结论 通过合理运用 Maven 构建工具中的 `classifier` 参数,能够有效应对多工件场景下的命名冲突难题,保障各阶段任务顺利完成的同时维持良好的可维护性和扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值