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]

Reply via email to