[MNG-6530] Introduce system property to disable global model cache

The global model cache introduced in MNG-6311 causes severe regressions
in case of POM files changing during application lifetime.
This patch adds a system property
`defaultProjectBuilder.disableGlobalModelCache` that disables this global
model cache when set to true, ensure pom modifications are honored.

This closes #194
This commit is contained in:
Mickael Istria 2018-11-27 22:56:31 +01:00 committed by Michael Osipov
parent 33e4f201d3
commit d9facde3bc
2 changed files with 58 additions and 6 deletions

View File

@ -81,6 +81,9 @@ public class DefaultProjectBuilder
implements ProjectBuilder implements ProjectBuilder
{ {
public static final String DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY =
"maven.defaultProjectBuilder.disableGlobalModelCache";
@Requirement @Requirement
private Logger logger; private Logger logger;
@ -115,14 +118,21 @@ public class DefaultProjectBuilder
public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest request ) public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest request )
throws ProjectBuildingException throws ProjectBuildingException
{ {
return build( pomFile, new FileModelSource( pomFile ), new InternalConfig( request, null ) ); return build( pomFile, new FileModelSource( pomFile ),
new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null ) );
}
private boolean useGlobalModelCache()
{
return !Boolean.getBoolean( DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY );
} }
@Override @Override
public ProjectBuildingResult build( ModelSource modelSource, ProjectBuildingRequest request ) public ProjectBuildingResult build( ModelSource modelSource, ProjectBuildingRequest request )
throws ProjectBuildingException throws ProjectBuildingException
{ {
return build( null, modelSource, new InternalConfig( request, null ) ); return build( null, modelSource,
new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null ) );
} }
private ProjectBuildingResult build( File pomFile, ModelSource modelSource, InternalConfig config ) private ProjectBuildingResult build( File pomFile, ModelSource modelSource, InternalConfig config )
@ -293,7 +303,7 @@ public class DefaultProjectBuilder
org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact ); org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact );
pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact ); pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact );
InternalConfig config = new InternalConfig( request, null ); InternalConfig config = new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null );
boolean localProject; boolean localProject;
@ -355,7 +365,8 @@ public class DefaultProjectBuilder
ReactorModelPool modelPool = new ReactorModelPool(); ReactorModelPool modelPool = new ReactorModelPool();
InternalConfig config = new InternalConfig( request, modelPool ); InternalConfig config = new InternalConfig( request, modelPool,
useGlobalModelCache() ? getModelCache() : new ReactorModelCache() );
Map<String, MavenProject> projectIndex = new HashMap<>( 256 ); Map<String, MavenProject> projectIndex = new HashMap<>( 256 );
@ -951,11 +962,11 @@ public class DefaultProjectBuilder
private final ReactorModelCache modelCache; private final ReactorModelCache modelCache;
InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool ) InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool, ReactorModelCache modelCache )
{ {
this.request = request; this.request = request;
this.modelPool = modelPool; this.modelPool = modelPool;
this.modelCache = getModelCache(); this.modelCache = modelCache;
session = session =
LegacyLocalRepositoryManager.overlay( request.getLocalRepository(), request.getRepositorySession(), LegacyLocalRepositoryManager.overlay( request.getLocalRepository(), request.getRepositorySession(),
repoSystem ); repoSystem );

View File

@ -28,6 +28,9 @@ import org.apache.maven.AbstractCoreMavenComponentTestCase;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.FileModelSource;
import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.building.ModelSource;
import org.apache.maven.shared.utils.io.FileUtils;
import com.google.common.io.Files;
public class ProjectBuilderTest public class ProjectBuilderTest
extends AbstractCoreMavenComponentTestCase extends AbstractCoreMavenComponentTestCase
@ -126,4 +129,42 @@ public class ProjectBuilderTest
assertEquals( 0, mavenProject.getArtifacts().size() ); assertEquals( 0, mavenProject.getArtifacts().size() );
} }
public void testReadModifiedPoms() throws Exception {
String initialValue = System.setProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, Boolean.toString( true ) );
// TODO a similar test should be created to test the dependency management (basically all usages
// of DefaultModelBuilder.getCache() are affected by MNG-6530
File tempDir = Files.createTempDir();
FileUtils.copyDirectoryStructure (new File( "src/test/resources/projects/grandchild-check"), tempDir );
try
{
MavenSession mavenSession = createMavenSession( null );
ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
configuration.setRepositorySession( mavenSession.getRepositorySession() );
org.apache.maven.project.ProjectBuilder projectBuilder = lookup( org.apache.maven.project.ProjectBuilder.class );
File child = new File( tempDir, "child/pom.xml" );
// build project once
projectBuilder.build( child, configuration );
// modify parent
File parent = new File( tempDir, "pom.xml" );
String parentContent = FileUtils.fileRead( parent );
parentContent = parentContent.replaceAll( "<packaging>pom</packaging>",
"<packaging>pom</packaging><properties><addedProperty>addedValue</addedProperty></properties>" );
FileUtils.fileWrite( parent, "UTF-8", parentContent );
// re-build pom with modified parent
ProjectBuildingResult result = projectBuilder.build( child, configuration );
assertTrue( result.getProject().getProperties().containsKey( "addedProperty" ) );
}
finally
{
if ( initialValue == null )
{
System.clearProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY );
}
else
{
System.setProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, initialValue );
}
FileUtils.deleteDirectory( tempDir );
}
}
} }