Christoph Kunze created MNG-6383:
------------------------------------
Summary: 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
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:java}
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:java}
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)