tkobayas opened a new issue, #6876:
URL: https://github.com/apache/incubator-kie/issues/6876
# NPE in maven-artifact-plugin:compare with `-pl` builds
## Symptom
CI build fails with:
```
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-artifact-plugin:3.5.1:compare (compare)
on project kie-parent: Execution compare of goal
org.apache.maven.plugins:maven-artifact-plugin:3.5.1:compare failed:
Cannot invoke "org.apache.maven.project.MavenProject.getBuild()" because
"root" is null
```
Reproducible with 3.5.2. **Fixed in 3.6.1** (see Solution below).
## Root Cause
The CI workflow (`.github/workflows/ci.yaml`, line 195) runs:
```bash
mvn ... -Dfull -Dreproducible -pl "$pl" install
```
where `$pl` is the list of affected modules (e.g. `kie-parent,kie-api,...`).
The root pom (`drools-parent`) is **not** included in `$pl`.
The `-Dreproducible` property activates the `reproducible-build` profile
(root `pom.xml`, line 275), which binds `maven-artifact-plugin:compare` to the
`install` phase.
In a multi-module reactor, the `compare` goal aggregates results. For the
**last** module in the reactor, `CompareMojo.execute()` calls:
```java
checkAgainstReference(artifacts, session.getProjects().size() == 1);
```
Since there are multiple modules, `mono = false`, which leads to:
```java
// CompareMojo.java line 126 (3.5.2)
MavenProject root = mono ? project : getExecutionRoot();
File referenceDir = new File(root.getBuild().getDirectory(), "reference");
// NPE here
```
`getExecutionRoot()` iterates over `session.getProjects()` looking for a
project where `isExecutionRoot() == true`. With `-pl`, the root pom
(`drools-parent`) is excluded from the reactor, so no project has
`isExecutionRoot() == true`, and the method returns `null`.
In 3.6.x the code changed to `session.getTopLevelProject()`, which returns
the first project in the reactor (e.g. `kie-parent`) rather than null when the
root pom is excluded via `-pl`. This resolves the NPE.
### Code path (3.5.x — broken)
```
AbstractBuildinfoMojo.execute()
→ mono = session.getProjects().size() == 1 // false (multiple -pl
modules)
→ last module: calls checkAgainstReference(artifacts, false)
→ CompareMojo.checkAgainstReference()
→ root = getExecutionRoot() // returns null
→ root.getBuild() // NPE
```
```java
// AbstractBuildinfoMojo.java line 342
protected MavenProject getExecutionRoot() {
for (MavenProject p : session.getProjects()) {
if (p.isExecutionRoot()) {
return p;
}
}
return null; // ← no guard against null
}
```
## Version comparison
| Version | Root resolution method | NPE with `-pl`? |
|---------|--------------------------------|-----------------|
| 3.5.1 | `getExecutionRoot()` | Yes |
| 3.5.2 | `getExecutionRoot()` | Yes (confirmed) |
| 3.6.1 | `session.getTopLevelProject()` | **No** (confirmed) |
In 3.5.x, `getExecutionRoot()` returns `null` when the root pom is not in
the reactor.
In 3.6.x, `session.getTopLevelProject()` returns the first project in the
reactor, avoiding the NPE.
## Affected CI step
```yaml
# .github/workflows/ci.yaml line 189-195
- name: "PR CHECK :: BUILD :: Changed and affected modules"
if: github.event_name == 'pull_request'
shell: bash
run: |
pl=$(paste -sd, "$MAVEN_PL_AFFECTED_FILE")
[ -z "$pl" ] && echo "No affected modules. Skipping." && exit 0
mvn --batch-mode --no-transfer-progress -fae
-Dsurefire.redirectTestOutputToFile=true -Dfull -Dreproducible -pl "$pl" install
```
Note: the full CI build on `push` (line 200) runs **without** `-pl` and
works correctly:
```yaml
- name: "CI :: BUILD :: Full"
if: github.event_name == 'push'
run: mvn ... -Dfull -Dreproducible install
```
## Solution
Upgrade `maven-artifact-plugin` to **3.6.1**. No CI workflow changes needed.
In root `pom.xml`:
```xml
<version.maven.artifact.plugin>3.6.1</version.maven.artifact.plugin>
```
### Additional required change
Version 3.6.1's `check-buildplan` goal has an updated plugin database that
correctly detects `maven-remote-resources-plugin:3.2.0` as non-reproducible
(inherited from the Apache parent POM). Upgrade it to 3.3.0:
```xml
<version.maven-remote-resources-plugin>3.3.0</version.maven-remote-resources-plugin>
```
Without this, the build fails with:
```
[ERROR] plugin with non-reproducible output:
org.apache.maven.plugins:maven-remote-resources-plugin:3.2.0, require minimum
3.3.0
```
### Alternative: Add the root pom to `-pl`
If upgrading the plugin is not feasible, adding `.` (the root pom) to `-pl`
in the CI workflow also fixes the NPE with 3.5.x:
```bash
mvn ... -Dfull -Dreproducible -pl ".,$pl" install
```
This ensures `drools-parent` is in the reactor so `getExecutionRoot()` finds
it. The root pom is `pom`-packaging only, so build overhead is negligible.
### Confirmed
`mvn -Dreproducible -pl kie-parent,kie-api install` succeeds with 3.6.1
**without** adding `.` to `-pl`:
```
[INFO] [Reproducible Builds] rebuild comparison result: 6 files match
[INFO] BUILD SUCCESS
```
--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]