DavidTavoularis opened a new issue, #11798:
URL: https://github.com/apache/maven/issues/11798

   ### Affected version
   
   4.0.0-rc5
   
   ### Bug description
   
   Note that I asked Claude Code to help with the analysis and the fix.
   
   This is a different bug from #11767, discovered while testing the fixes from 
that ticket. The #11767 fix (PR #11768) correctly passes repositories and 
profiles to the consumer POM builder, but a separate code path still causes 
failures when parent POMs define properties inside profiles with property-based 
activation.
   
    ```
    $ mvn clean install
   [...]
   [INFO] --- install:3.1.3:install (default-install) @ xxx ---
   [INFO] 
--------------------------------------------------------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] 
--------------------------------------------------------------------------------------------------------------------------
    [...]
    [ERROR] Failed to execute goal 
org.apache.maven.plugins:maven-install-plugin:3.1.3:install (default-install) 
on project xxx: Execution default-install of goal 
org.apache.maven.plugins:maven-install-plugin:3.1.3:install failed: Invalid 
Version Range Request: 
org.springframework:spring-framework-bom:pom:${spring.version} [...]
   ```
   The property ${spring.version} is defined in a great-grandparent POM 
(lineup) inside a profile with property-based activation:
   ```
   <!-- lineup pom.xml -->
     <profiles>
         <profile>
             <id>spring-old</id>
             <activation>
                 <property>
                     <name>!explicitelyDeactivated</name>
                 </property>
             </activation>
             <properties>
                 <spring.version>5.3.39</spring.version>
             </properties>
         </profile>
     </profiles>
   ```
   
   A grandparent POM uses this property in a BOM import:
   ```
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-framework-bom</artifactId>
                 <version>${spring.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>
   ```
   
   During BUILD_PROJECT, profiles are properly activated and the property 
resolves to 5.3.39. During BUILD_CONSUMER (install phase), the property is null 
and the BOM import fails with Invalid Version Range Request.
   
   **Root cause**
   The bug is in DefaultModelBuilder.readParentLocally() (line ~1151 in 
DefaultModelBuilder.java).
   When the consumer POM is built (BUILD_CONSUMER), readParentLocally() finds 
the parent POM via resolveReactorModel() (because the parent was loaded into 
mappedSources during the earlier BUILD_PROJECT phase). It then calls:
   ```
     // Line ~1151 - DefaultModelBuilder.java - readParentLocally()
     ModelBuilderSessionState derived = derive(candidateSource);
   ```
   derive(candidateSource) calls derive(ModelBuilderRequest.build(request, 
source)) which preserves the BUILD_CONSUMER request type. Since 
isBuildRequestWithActivation() returns false for BUILD_CONSUMER, POM profile 
activation is skipped for all parent POMs in the chain:
   
   ```
     boolean isBuildRequestWithActivation() {
         return request.getRequestType() != 
ModelBuilderRequest.RequestType.BUILD_CONSUMER;
     }
   ```
   In contrast, resolveAndReadParentExternally() (used when the parent is NOT 
in the reactor) explicitly creates a CONSUMER_PARENT request:
   ```
     // Line ~1284 - DefaultModelBuilder.java - resolveAndReadParentExternally()
     ModelBuilderRequest lenientRequest = ModelBuilderRequest.builder(request)
             .requestType(ModelBuilderRequest.RequestType.CONSUMER_PARENT)
             .source(modelSource)
             .build();
   ```
   CONSUMER_PARENT allows profile activation, so parent POMs resolved 
externally work correctly. Only parent POMs resolved locally (via 
reactor/mappedSources) are affected.
   
   **Fix**
   In readParentLocally(), when the current request is BUILD_CONSUMER, derive 
the parent session with CONSUMER_PARENT type — consistent with how 
resolveAndReadParentExternally() handles it:
   
   ```
     ModelBuilderSessionState derived;
     if (request.getRequestType() == 
ModelBuilderRequest.RequestType.BUILD_CONSUMER) {
         ModelBuilderRequest parentRequest = 
ModelBuilderRequest.builder(request)
                 .requestType(ModelBuilderRequest.RequestType.CONSUMER_PARENT)
                 .source(candidateSource)
                 .build();
         derived = derive(parentRequest);
     } else {
         derived = derive(candidateSource);
     }
   ```
   Claude Code created the following unit test (which fails without the fix):
   Test: 
DefaultModelBuilderTest.testBuildConsumerResolvesParentProfileProperties 
(maven-impl)
     - Builds a parent POM with BUILD_PROJECT to populate the reactor 
(mappedSources) — the parent defines managed.version=1.2.3 inside a profile 
with property-based activation (!skipDefaultVersions)
     - Builds the child POM with BUILD_CONSUMER on the same session — the 
parent is found via resolveReactorModel() in readParentLocally()
     - Asserts the effective model has managed.version=1.2.3 (from the parent's 
profile)
     - Asserts the managed dependency version is interpolated to 1.2.3, not 
${managed.version}
   Without the fix: `AssertionFailedError: expected: <1.2.3> but was: <null>`
   
   I was also able to confirm that when implementing the fix on top of 4.0-rc5, 
my mvn clean install passed.
   
   I am now preparing a Pull Request.


-- 
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]

Reply via email to