You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "Christoph Kunze (JIRA)" <ji...@apache.org> on 2018/05/07 08:19:00 UTC
[jira] [Commented] (MNG-6383) ProjectBuilder unnecessarily rebuilds
modules with ci-friendly versions
[ https://issues.apache.org/jira/browse/MNG-6383?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16465617#comment-16465617 ]
Christoph Kunze commented on MNG-6383:
--------------------------------------
I've attached a simple project with two modules: sample-parent -> sample-child.
To reproduce the problem, build the attached project and put a breakpoint on lines 436 and 639 of {{DefaultProjectBuilder.java}}:
{code:java}
private boolean build( /* ... */, Map<String, MavenProject> projectIndex, /* ... */ ) {
// some lines omitted
/* 432 */ ModelBuildingResult result = modelBuilder.build( request );
/* 434 */ Model model = result.getEffectiveModel();
/* 436 */ projectIndex.put( result.getModelIds().get( 0 ), project );
private void initProject( MavenProject project, Map<String, MavenProject> projects, /* ... */) {
// some lines omitted
/* 636 */ String parentModelId = result.getModelIds().get( 1 );
/* 638 */ MavenProject parent = projects.get( parentModelId );
/* 639 */ if ( parent == null )
{code}
The debugger first stops on line 436.
- {{result.modelIds}} contains
{code:java}
org.example:sample-parent:1.0-SNAPSHOT
""
{code}
- an entry for {{org.example:sample-parent:1.0-SNAPSHOT}} is added to {{projectIndex}}
Then the debugger stops again on line 436
- this time {{result.modelIds}} contains
{code:java}
org.example:sample-child:1.0-SNAPSHOT
org.example:sample-parent:${revision}
""
{code}
- An entry for {{org.example:sample-child:1.0-SNAPSHOT}} is added to {{projectIndex}}
- Note that the {{$\{revision}}} placeholder has only been resolved for the first entry.
The next time the debugger stops is during the second phase, in line 639
- {{result.modelIds}} contains
{code:java}
org.example:sample-child:1.0-SNAPSHOT
org.example:sample-parent:${revision}
""
{code}
- The second entry is read as {{parentModelId}}: {{org.example:sample-parent:$\{revision}}} and is used to query the {{projects}} map which contains
{code}
org.example:sample-child:1.0-SNAPSHOT => MavenProject: org.example:sample-child:1.0-SNAPSHOT @ sample-parent/sample-child/pom.xml
org.example:sample-parent:1.0-SNAPSHOT => MavenProject: org.example:sample-parent:1.0-SNAPSHOT @ sample-parent/pom.xml
{code}
- Although an entry for the sample-parent module exists in {{projects}} it is not found and {{build()}} is invoked a few lines further down.
> ProjectBuilder unnecessarily rebuilds modules with ci-friendly versions
> -----------------------------------------------------------------------
>
> Key: MNG-6383
> URL: https://issues.apache.org/jira/browse/MNG-6383
> Project: Maven
> Issue Type: Bug
> Components: core
> Affects Versions: 3.5.3
> Reporter: Christoph Kunze
> Assignee: Karl Heinz Marbaise
> Priority: Major
> Fix For: 3.5.4-candidate
>
> Attachments: sample-project.tar.gz
>
>
> Consider a multi-module project that uses ci-friendly versions (i.e. the root pom declares <version>${revision}</version>).
> While "scanning for projects", the DefaultProjectBuilder (build:347) uses a two-phase approach.
> 1) build:390 populates a set of interimResults and a projectIndex. The keys of the projectIndex take the form groupId:artifactId:packaging:version and the version always is the interpolated version (i.e. 1.0-SNAPSHOT rather than ${revision}).
> 2) build:573 calls initProject which in line 638 attempts to retrieve the previously constructed parent project from the projectIndex. However, the key used here still contains the uninterpolated version (i.e. ${revision}) so *the* *parent project is never found*. In line 652, the parent project is therefore constructed anew:
> {code:java}
> parent = build( parentPomFile, projectBuildingRequest ).getProject();
> {code}
> This is not only ineffective but also causes problems, e.g. if the parent imports a bom module from the same reactor, this leads to a warning "Failed to build parent project" and potential follow-up problems. Also, the maven assembly plugin seems to fail on such projects.
> *Details*
> - The ModelBuildingResult created in the first phase contains a list of modelIds. They key used to add an entry to the project index always corresponds to the *first* item in this list:
> {code:java}
> // DefaultProjectBuilder:436
> projectIndex.put( result.getModelIds().get( 0 ), project )
> {code}
> However, the key used to retrieve the entry during the processing of its child is the *second* element from the modelIds list:
> {code:java}
> // DefaultProjectBuilder:636
> String parentModelId = result.getModelIds().get( 1 );
> MavenProject parent = projects.get( parentModelId );
> {code}
> The list items are created by DefaultModelBuilder.build:244. First a "lineage" of the current module is built. Then the first element of the lineage, corresponding to the current module, gets interpolated. The other lineage items *do not get interpolated*, i.e. they still contain the placeholder version.
> The list of modelIds is then constructed from the lineage, leading to the first element having an interpolated version whereas all other elements have a placeholder version.
> {code:java}
> // DefaultModelBuilder:411
> for ( ModelData currentData : lineage )
> {
> String modelId = ( currentData != superData ) ? currentData.getId() : "";
> result.addModelId( modelId );
> {code}
> *Fix*
> One way to fix the issue might be to interpolate all elements of the lineage in DefaultModelBuilder.build:244, or to at least replace their versions.
> The following modification (hacky and probably faulty, for demonstration purpose only) fixed the issue for my project:
> {code:java}
> // model interpolation
> resultModel = interpolateModel( resultModel, request, problems );
> resultData.setModel( resultModel );
> /* new code starts here */
> if ( resultModel.getParent() != null )
> {
> final ModelData parentData = lineage.get( 1 );
> final Model interpolatedParent = interpolateModel( parentData.getModel(), request, problems );
> // parentData.setModel( interpolatedParent );
> parentData.setVersion( interpolatedParent.getVersion() );
> }
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)