[MNG-6530] Introduce system property to disable global model cache
authorMickael Istria <mistria@redhat.com>
Tue, 27 Nov 2018 21:56:31 +0000 (22:56 +0100)
committerMichael Osipov <michaelo@apache.org>
Tue, 8 Jan 2019 14:25:27 +0000 (15:25 +0100)
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

maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java

index 35a4e9f..a402040 100644 (file)
@@ -81,6 +81,9 @@ public class DefaultProjectBuilder
     implements ProjectBuilder
 {
 
+    public static final String DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY =
+            "maven.defaultProjectBuilder.disableGlobalModelCache";
+
     @Requirement
     private Logger logger;
 
@@ -115,14 +118,21 @@ public class DefaultProjectBuilder
     public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest request )
         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
     public ProjectBuildingResult build( ModelSource modelSource, ProjectBuildingRequest request )
         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 )
@@ -293,7 +303,7 @@ public class DefaultProjectBuilder
         org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact );
         pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact );
 
-        InternalConfig config = new InternalConfig( request, null );
+        InternalConfig config = new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null );
 
         boolean localProject;
 
@@ -355,7 +365,8 @@ public class DefaultProjectBuilder
 
         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 );
 
@@ -951,11 +962,11 @@ public class DefaultProjectBuilder
 
         private final ReactorModelCache modelCache;
 
-        InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool )
+        InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool, ReactorModelCache modelCache )
         {
             this.request = request;
             this.modelPool = modelPool;
-            this.modelCache = getModelCache();
+            this.modelCache = modelCache;
             session =
                 LegacyLocalRepositoryManager.overlay( request.getLocalRepository(), request.getRepositorySession(),
                                                       repoSystem );
index 18f22bd..c472e47 100644 (file)
@@ -28,6 +28,9 @@ import org.apache.maven.AbstractCoreMavenComponentTestCase;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.building.FileModelSource;
 import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.shared.utils.io.FileUtils;
+
+import com.google.common.io.Files;
 
 public class ProjectBuilderTest
     extends AbstractCoreMavenComponentTestCase
@@ -126,4 +129,42 @@ public class ProjectBuilderTest
         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 );
+        }
+    }
 }