You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by "lizhimins (via GitHub)" <gi...@apache.org> on 2026/10/12 10:16:42 UTC

[PR] build(server): make the license gate satisfiable and record every determination [rocketmq-dashboard]

lizhimins opened a new pull request, #6349:
URL: https://github.com/apache/rocketmq-dashboard/pull/6349

   ## Why this is not "turn the gate off"
   
   `binary-license-gate` required every bundled dependency JAR to carry its own upstream LICENSE text inside itself. That is not satisfiable in principle: of the 277 dependencies in the fat JAR, **163 carry no license file at all** — `jtokkit`, `mcp`, `antlr4-runtime`, `protobuf-java`, `logback-classic`, `dom4j`, `curvesapi`, `reflections`, every `netty-*-native-*` classifier JAR, and so on (`bcprov-jdk18on` has an `org/bouncycastle/LICENSE.class`, which is code, not text). So `mvn package` has not succeeded on trunk since the gate landed, and the 3.0.0 release build could not run.
   
   What ASF asks of a binary distribution is that the **terms travel with the distribution**, not that each dependency embeds them. The gate now accepts three recorded outcomes per artifact, keyed by artifactId in `server/scripts/legal-determinations.json`:
   
   | determination | count | what ships |
   |:--|--:|:--|
   | Apache-2.0 | 143 | covered by the distribution's own `META-INF/LICENSE`, which *is* that text — ASF does not ask for 143 copies of it. A dependency's own NOTICE is still merged into ours when its JAR carries one (unchanged). |
   | other Category A (MIT / BSD-2 / BSD-3 / MIT-0 / Bouncy Castle / EDL / WTFPL / Plexus) | 18 | upstream text collected under `server/legal/licenses/` and **embedded into the JAR** as that component's material, so the terms still ship |
   | ASF Category B | 2 | `logback-classic` / `logback-core`, EPL-2.0. Allowed only with a recorded `review` decision; printed as a `WARNING` on every build and listed in the manifest's `categoryB` field. |
   
   An artifact with neither internal text nor a determination **still fails**, so adding a dependency forces an explicit license decision instead of slipping through. GPL-family text inside a JAR is still a hard error, unchanged.
   
   ## Determinations that needed actual verification
   
   - `javassist` declares **MPL-1.1 / LGPL-2.1 / Apache-2.0**; Apache-2.0 is elected and the election is recorded. The old code read only the first `<license>` element, which is how a triple-licensed artifact ended up looking LGPL. `reflections` (WTFPL / New BSD) is the same shape.
   - The five `com.aliyun:*:0.3.5-beta` artifacts (`aliyun-java-core`, `aliyun-java-auth`, `aliyun-gateway-pop`, `aliyun-http-apache`, `darabonba-java-core`) have no `<licenses>` of their own; it is in their **parent POM** `com.aliyun:core-service:0.3.5-beta` (`The Apache License, Version 2.0`).
   - `listenablefuture-9999.0-empty-to-avoid-conflict-with-guava` is an **empty placeholder JAR with zero classes**, covered by `com.google.guava:guava`'s Apache-2.0.
   - `zstd-jni` = BSD-2-Clause, `opentelemetry-exporter-prometheus` = Apache-2.0, both straight from their POMs.
   - artifactId extraction has to strip **classifiers**: `netty-transport-native-epoll-4.2.15.Final-linux-x86_64` → `netty-transport-native-epoll`. Taking the leftmost digit-leading segment is what makes `zstd-jni-1.5.2-2` come out as `zstd-jni` rather than `zstd-jni-1.5.2`; `artifact_id()` is self-tested against 12 such names.
   
   ## Second stale assumption fixed: the Spring Boot loader
   
   The gate also required `META-INF/LICENSE.txt` and `META-INF/NOTICE.txt` at the fat JAR root for the loader classes. Boot 4.x no longer copies them there, and the loader is not a dependency JAR at all — its classes are laid into the JAR root from `spring-boot-loader-tools` (`BOOT-INF/lib` contains no `spring-boot-loader`). There is nothing left in the archive to read, so the check could never pass.
   
   Both files are now collected from `spring-boot-loader-tools-4.1.0.jar` itself (`META-INF/LICENSE.txt` 11359 bytes, `META-INF/NOTICE.txt` 210 bytes) into `server/legal/licenses/spring-boot-loader.{LICENSE,NOTICE}.txt`, and the gate **rejects them if the collected NOTICE is not for the JAR's own `Spring-Boot-Version`** — that is exactly how a stale NOTICE would otherwise survive a Boot upgrade.
   
   ## Verification
   
   ```
   $ mvn -B -ntp package -DskipTests          # gate ON, no -Dmaven.antrun.skip
   [exec] WARNING logback-classic-1.5.34.jar: ASF Category B (EPL-2.0) bundled — …
   [exec] WARNING logback-core-1.5.34.jar: ASF Category B (EPL-2.0) bundled — …
   [exec] JAR license check passed: 278 actual components (143 Apache-2.0 covered by the distribution LICENSE, 20 from collected text, 2 Category B)
   [INFO] BUILD SUCCESS
   ```
   
   Four mutations, each of which turns the gate red — i.e. the narrowing did not disable it:
   
   | mutation | result |
   |:--|:--|
   | delete `jtokkit` from the determinations | `missing complete upstream LICENSE/COPYING and no determination in scripts/legal-determinations.json` |
   | delete `server/legal/licenses/zstd-jni.txt` | `collected license text is unusable` |
   | rewrite the collected loader NOTICE to say 3.5.3 | `the collected NOTICE is not for 4.1.0; re-collect it from spring-boot-loader-tools 4.1.0` |
   | blank logback's `review` field | `ASF Category B (EPL-2.0) is bundled without a recorded review decision` |
   
   ## Still open, deliberately
   
   - The two Category B entries are recorded with a rationale (file-scoped weak copyleft, no linking obligation on our code, Spring Boot's default logging backend) but **need PMC/legal confirmation before 3.0.0 GA**. They are a build WARNING and a manifest field, not a silent pass.
   - `.github/workflows/ci.yml` still has no `actions/setup-python`, so `Backend Build (Java 21)` will now fail on "python3 not found" instead of on the gate. That is a CI change and is left out of this PR.
   - `bcprov-jdk18on.txt` is upstream's own HTML-formatted licence text (that is how Bouncy Castle publishes it); it is kept verbatim rather than reformatted.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] build(server): make the license gate satisfiable and record every determination [rocketmq-dashboard]

Posted by "lizhimins (via GitHub)" <gi...@apache.org>.
lizhimins merged PR #6349:
URL: https://github.com/apache/rocketmq-dashboard/pull/6349


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org