You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确配置Maven项目生成带Classifier的JAR且兼容Javadoc插件

Maven多平台JNI项目打包困境:Classifier与构件生成冲突的解决方案

问题场景

我有一个包含Java源码和JNI C++代码的Maven项目,为适配不同平台,需要生成带平台标识Classifier的JAR文件(将编译后的共享库打包进JAR)。但执行mvn install时触发MINSTALL-151错误:

Failed to execute goal org.apache.maven.plugins:maven-install-plugin:3.1.1:install (default-install) on project <project_name>: NoFileAssignedException:
The packaging plugin for this project did not assign a main file to the project but it has attachments. Change packaging to 'pom'. -> [Help 1]

尝试过两种解决思路,但均存在问题:

  1. 使用allowIncompleteProjects配置:根据Bug评论指引,在maven-install-plugin中开启该参数可绕过错误,但官方文档指出这是“逃生舱”,推荐改用pom打包类型,让我担心这种方式不符合Maven规范。

    默认情况下,此类项目是被禁止的,Mojo将无法处理它们。……大多数情况下,用户真正需要的是一个打包类型为"pom"的项目,并附加一些带分类器的构件(典型示例是打包并附加带分类器的程序集)。

  2. 切换为pom打包类型:按官方建议修改后,需手动配置resources、compiler和surefire插件的执行逻辑,但Javadoc和Source插件完全失效:

    • 生成Javadoc JAR时提示:Not executing Javadoc as the project is not a Java classpath-capable package
    • 执行mvn site时,Javadoc报告看似配置正常,但实际无任何内容生成(对比正常jar打包项目,缺少Javadoc生成的日志步骤)

当前项目提交哈希为f53ab7a8的版本采用pom打包,无法生成Javadoc或Source JAR,可能需暂时切回jar打包以保证基础功能可用。

关于Classifier的说明

项目中JNI C++代码编译生成的共享库依赖特定平台,因此需为每个平台生成带专属Classifier的JAR文件,后续计划构建一个名为uber(或类似)的Classifier JAR,整合多平台共享库内容。

推荐解决方案

方案1:保持Jar打包+优化插件配置(推荐)

核心思路是保留jar打包类型,禁用默认的无Classifier主JAR生成,显式配置带平台Classifier的JAR构建,同时通过allowIncompleteProjects允许安装无主构件的项目。这种方式既能解决MINSTALL-151错误,又能让Javadoc和Source插件正常工作。

示例配置:

<build>
  <plugins>
    <!-- 禁用默认的无Classifier主JAR生成 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>3.3.0</version>
      <executions>
        <execution>
          <id>default-jar</id>
          <phase>none</phase>
        </execution>
        <!-- 构建带平台Classifier的JAR,包含Java类和JNI共享库 -->
        <execution>
          <id>platform-specific-jar</id>
          <phase>package</phase>
          <goals>
            <goal>jar</goal>
          </goals>
          <configuration>
            <classifier>${platform.classifier}</classifier>
            <includes>
              <include>**/*.class</include>
              <include>**/*.so</include>
              <include>**/*.dll</include>
              <include>**/*.dylib</include>
            </includes>
          </configuration>
        </execution>
      </executions>
    </plugin>

    <!-- 允许安装无主构件的项目,绕过MINSTALL-151错误 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-install-plugin</artifactId>
      <version>3.1.1</version>
      <configuration>
        <allowIncompleteProjects>true</allowIncompleteProjects>
      </configuration>
    </plugin>

    <!-- 正常配置Source插件,生成带sources Classifier的JAR -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-source-plugin</artifactId>
      <version>3.3.0</version>
      <executions>
        <execution>
          <id>attach-sources</id>
          <goals>
            <goal>jar-no-fork</goal>
          </goals>
          <configuration>
            <classifier>sources</classifier>
          </configuration>
        </execution>
      </executions>
    </plugin>

    <!-- 正常配置Javadoc插件,生成带javadoc Classifier的JAR -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <version>3.6.0</version>
      <executions>
        <execution>
          <id>attach-javadocs</id>
          <goals>
            <goal>jar</goal>
          </goals>
          <configuration>
            <classifier>javadoc</classifier>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

方案2:拆分多模块项目(更规范)

若追求严格符合Maven项目结构规范,可拆分为三个模块:

  • 父模块(pom打包):统一管理依赖版本、插件配置和子模块聚合
  • 核心Java模块(jar打包):仅包含Java源码,生成不带JNI库的普通JAR
  • 平台专属模块(每个平台一个子模块,pom打包):编译对应平台的JNI库,将核心JAR和JNI库打包成带平台Classifier的构件

这种方式结构更清晰,但会增加项目复杂度,适合大型多平台JNI项目。

为什么Pom打包不可行?

Maven的pom打包类型设计初衷是用于父项目或聚合项目,Java相关插件(compiler、javadoc、source)默认会跳过pom类型项目的执行逻辑,即使手动强制配置插件执行,也会因打包类型限制导致功能失效(比如Javadoc插件会判断项目是否为Java类路径兼容包,直接跳过生成),因此不适合用于需要编译Java源码、生成Javadoc和Source JAR的项目。

内容的提问来源于stack exchange,提问作者Nick Williams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:14:53