Maven pom.xml licenses license 开源协议配置

1次阅读

license 标签必须嵌套在 licenses 容器内才生效,单独使用会被 maven 忽略;一个项目可声明多个 license,建议用 spdx id(如 apache-2.0)并配可访问的完整 url;第三方依赖许可证由其自身 pom.xml 提供,不继承自当前项目;license-maven-plugin 默认只校验不生成文件,需配置 add-third-party goal 并设 phase 为 generate-resources。

Maven pom.xml licenses license 开源协议配置

license 标签必须嵌套在 licenses 容器里,单独写会失效

很多人直接在 pom.xml 里加 <license></license>,以为能声明项目用的协议,结果 mvn verify 或生成的 notice.txt 里完全没出现——因为 Maven 要求它必须作为 <licenses><license>...</license></licenses> 的子元素存在。不套这层容器,解析时直接忽略。

常见错误写法:
<license><name>Apache License, Version 2.0</name><url>https://www.apache.org/licenses/LICENSE-2.0</url></license>
正确位置:必须放在 <project></project> 下的 <licenses></licenses> 块内。

  • <name></name> 值建议用 SPDX ID(如 Apache-2.0),比自由文本更易被工具识别
  • <url></url> 必须是可访问的完整 URL,不能是相对路径或本地文件
  • 一个项目可声明多个 <license></license>,比如双协议发布时同时写 MITApache-2.0

第三方依赖的 license 不会自动继承到你的 pom.xml

你在自己的 pom.xml 里配了 <licenses></licenses>,只是声明「你自己发布的这个构件」遵循什么协议。它对依赖的 JAR 包毫无影响——那些依赖的许可证信息来自它们各自的 pom.xml,Maven 在构建时通过依赖传递链收集,不是靠你手动抄一遍。

想检查实际打包时包含了哪些许可证?得用插件:
maven-license-pluginlicense-maven-plugin 可生成 THIRD-PARTY-LICENSES.txtsyft + grype 这类 SBOM 工具也能提取依赖许可证树。

  • 别在 <licenses></licenses> 里罗列所有依赖的协议,那是冗余且易过期的
  • 如果你发布的是库(非应用),要确保你选的协议和所用依赖的协议兼容(比如 AGPL 依赖不能放进 MIT 库)
  • 某些 CI 流程会校验 compile 范围依赖是否含禁用协议(如 SSPL),这时靠的是插件扫描,不是你 pom 里的声明

license-maven-plugin 默认不生成 LICENSE 文件,要显式配置 goal

装了 license-maven-plugin,跑 mvn clean compile 却没见 LICENSE 文件生成?默认它只做校验(check goal),不生成(add-third-partyaggregate-add-third-party 才负责写文件)。

典型配置漏掉 <executions></executions> 或写错 goal 名,导致“配了等于没配”:

<plugin>   <groupId>org.codehaus.mojo</groupId>   <artifactId>license-maven-plugin</artifactId>   <version>2.2.0</version>   <executions>     <execution>       <id>add-third-party</id>       <goals><goal>add-third-party</goal></goals>       <phase>generate-resources</phase>     </execution>   </executions> </plugin>
  • 注意 <phase></phase> 设为 generate-resources,太早(如 initialize)可能读不到依赖元数据
  • 生成路径默认是 ${project.basedir}/target/generated-sources/license/,不是 src/main/resources,需配合 resources 插件复制过去
  • 若项目含 provided 依赖,插件默认不扫描,得加 <includeprovidedscope>true</includeprovidedscope>

SPDX 表达式支持有限,复杂组合协议要拆开声明

Maven 原生只认单个 SPDX ID(如 Apache-2.0),不支持表达式语法(如 Apache-2.0 OR MIT)。你硬写进去,部分插件会解析失败或静默忽略。

真实场景中,双协议发布很常见(比如允许用户自选),但 Maven 没有标准字段存 OR/AND 关系。折中做法是:

  • <licenses></licenses> 里并列两个 <license></license>,各自填一个 SPDX ID
  • <comments></comments> 字段补充说明选择关系(如 <comments>You may choose either Apache-2.0 or MIT.</comments>
  • 如果必须机器可读,考虑在 NOTICE 文件里手写 SPDX 表达式,或用 about-code-tool 等外部工具管理

别指望 IDE 或 Nexus ui 自动理解你写的注释——它们只扫 <name></name><url></url><comments></comments> 是给人看的。

text=ZqhQzanResources