This is an automated email from the ASF dual-hosted git repository. rfscholte pushed a commit to branch MNG-7063 in repository https://gitbox.apache.org/repos/asf/maven.git
commit 6456668c181bcc0d5f1349270dff1d5901654d85 Author: Guillaume Nodet <gno...@gmail.com> AuthorDate: Sat Nov 28 22:27:49 2020 +0100 Do not use a "persistent" cache which is the root cause MNG-6530 The root of the problem is MNG-5312 which is a performance issue because a ModelCache was not always involved during a model build. This lead to MNG-6030 (memory consumption issue because of the usage of multiple caches). The fix for MNG-6030 lead to MNG-6311 (problem with changes not being picked up in M2E). The root problem is that the fix for MNG-5312 was wrong. The caches and its data should be managed at the RepositorySystemSession level, especially as the data is related to a given session parameters (maven global settings). This commit brings back the cache at the session level, and a default cache is now set on the session by the MavenCli. The cache is used later by DefaultArtifactDescriptorReader and DefaultProjectBuilder to build a DefaultModelCache. * use the cache on the MavenExecutionRequest * get rid of the hack for MNG-6530. * MavenCli configures a cache for the whole execution request * merge ReactorModelCache into DefaultModelCache # Conflicts: # maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java # maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java --- .../maven/project/DefaultProjectBuilder.java | 32 +---- .../apache/maven/project/ReactorModelCache.java | 160 --------------------- .../apache/maven/project/ProjectBuilderTest.java | 9 -- .../main/java/org/apache/maven/cli/MavenCli.java | 6 + .../repository/internal/DefaultModelCache.java | 153 ++++++++++++++++---- 5 files changed, 137 insertions(+), 223 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java index fa3b3e4..29f86b8 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java @@ -71,6 +71,7 @@ import org.apache.maven.model.building.StringModelSource; import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.resolution.ModelResolver; import org.apache.maven.repository.internal.ArtifactDescriptorUtils; +import org.apache.maven.repository.internal.DefaultModelCache; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.Os; import org.codehaus.plexus.util.StringUtils; @@ -92,9 +93,6 @@ public class DefaultProjectBuilder implements ProjectBuilder { - public static final String DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY = - "maven.defaultProjectBuilder.disableGlobalModelCache"; - @Inject private Logger logger; @@ -119,8 +117,6 @@ public class DefaultProjectBuilder @Inject private ProjectDependenciesResolver dependencyResolver; - private final ReactorModelCache modelCache = new ReactorModelCache(); - // ---------------------------------------------------------------------- // MavenProjectBuilder Implementation // ---------------------------------------------------------------------- @@ -130,12 +126,7 @@ public class DefaultProjectBuilder throws ProjectBuildingException { return build( pomFile, new FileModelSource( pomFile ), - new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null, null ) ); - } - - private boolean useGlobalModelCache() - { - return !Boolean.getBoolean( DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY ); + new InternalConfig( request, null, null ) ); } @Override @@ -143,7 +134,7 @@ public class DefaultProjectBuilder throws ProjectBuildingException { return build( null, modelSource, - new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null, null ) ); + new InternalConfig( request, null, null ) ); } private ProjectBuildingResult build( File pomFile, ModelSource modelSource, InternalConfig config ) @@ -288,7 +279,7 @@ public class DefaultProjectBuilder request.setUserProperties( configuration.getUserProperties() ); request.setBuildStartTime( configuration.getBuildStartTime() ); request.setModelResolver( resolver ); - request.setModelCache( config.modelCache ); + request.setModelCache( DefaultModelCache.newInstance( config.session ) ); request.setTransformerContextBuilder( config.transformerContextBuilder ); return request; @@ -309,7 +300,7 @@ public class DefaultProjectBuilder pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact ); InternalConfig config = - new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null, null ); + new InternalConfig( request, null, null ); boolean localProject; @@ -382,8 +373,7 @@ public class DefaultProjectBuilder final ReactorModelPool modelPool = poolBuilder.build(); InternalConfig config = - new InternalConfig( request, modelPool, useGlobalModelCache() ? getModelCache() : new ReactorModelCache(), - modelBuilder.newTransformerContextBuilder() ); + new InternalConfig( request, modelPool, modelBuilder.newTransformerContextBuilder() ); Map<File, MavenProject> projectIndex = new HashMap<>( 256 ); @@ -1023,16 +1013,13 @@ public class DefaultProjectBuilder private final ReactorModelPool modelPool; - private final ReactorModelCache modelCache; - private final TransformerContextBuilder transformerContextBuilder; - InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool, ReactorModelCache modelCache, + InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool, TransformerContextBuilder transformerContextBuilder ) { this.request = request; this.modelPool = modelPool; - this.modelCache = modelCache; this.transformerContextBuilder = transformerContextBuilder; session = @@ -1044,9 +1031,4 @@ public class DefaultProjectBuilder } - private ReactorModelCache getModelCache() - { - return this.modelCache; - } - } diff --git a/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java b/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java deleted file mode 100644 index 10ca878..0000000 --- a/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.apache.maven.project; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.building.Source; -import org.apache.maven.model.building.ModelCache; - -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -/** - * A simple model cache used to accelerate model building during a reactor build. - * - * @author Benjamin Bentmann - */ -class ReactorModelCache - implements ModelCache -{ - - private final Map<Object, Object> models = new ConcurrentHashMap<>( 256 ); - - @Override - public Object get( String groupId, String artifactId, String version, String tag ) - { - return models.get( new GavCacheKey( groupId, artifactId, version, tag ) ); - } - - @Override - public void put( String groupId, String artifactId, String version, String tag, Object data ) - { - models.put( new GavCacheKey( groupId, artifactId, version, tag ), data ); - } - - @Override - public Object get( Source source, String tag ) - { - return models.get( new SourceCacheKey( source, tag ) ); - } - - @Override - public void put( Source source, String tag, Object data ) - { - models.put( new SourceCacheKey( source, tag ), data ); - } - - private static final class GavCacheKey - { - - private final String groupId; - - private final String artifactId; - - private final String version; - - private final String tag; - - private final int hashCode; - - GavCacheKey( String groupId, String artifactId, String version, String tag ) - { - this.groupId = ( groupId != null ) ? groupId : ""; - this.artifactId = ( artifactId != null ) ? artifactId : ""; - this.version = ( version != null ) ? version : ""; - this.tag = ( tag != null ) ? tag : ""; - this.hashCode = Objects.hash( groupId, artifactId, version, tag ); - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - - if ( !( obj instanceof GavCacheKey ) ) - { - return false; - } - - GavCacheKey that = (GavCacheKey) obj; - - return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId ) - && version.equals( that.version ) && tag.equals( that.tag ); - } - - @Override - public int hashCode() - { - return hashCode; - } - } - - private static final class SourceCacheKey - { - private final Source source; - - private final String tag; - - private final int hashCode; - - SourceCacheKey( Source source, String tag ) - { - this.source = source; - this.tag = tag; - this.hashCode = Objects.hash( source, tag ); - } - - @Override - public int hashCode() - { - return hashCode; - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - if ( !( obj instanceof SourceCacheKey ) ) - { - return false; - } - - SourceCacheKey other = (SourceCacheKey) obj; - if ( !Objects.equals( this.source, other.source ) ) - { - return false; - } - - if ( !Objects.equals( this.tag, other.tag ) ) - { - return false; - } - - return true; - } - } - -} diff --git a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java index f23132c..e2babbf 100644 --- a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java @@ -150,7 +150,6 @@ public class ProjectBuilderTest @Test 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 @@ -177,14 +176,6 @@ public class ProjectBuilderTest } 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.toFile() ); } } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 792a831..c217c9e 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -83,6 +83,7 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupExcepti import org.codehaus.plexus.logging.LoggerManager; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.eclipse.aether.DefaultRepositoryCache; import org.eclipse.aether.transfer.TransferListener; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; @@ -975,6 +976,11 @@ public class MavenCli { MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request ); + if ( cliRequest.request.getRepositoryCache() == null ) + { + cliRequest.request.setRepositoryCache( new DefaultRepositoryCache() ); + } + eventSpyDispatcher.onEvent( request ); MavenExecutionResult result = maven.execute( request ); diff --git a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java index 86edf16..339bc08 100644 --- a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java +++ b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java @@ -19,8 +19,12 @@ package org.apache.maven.repository.internal; * under the License. */ +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.maven.building.Source; import org.apache.maven.model.building.ModelCache; -import org.eclipse.aether.RepositoryCache; import org.eclipse.aether.RepositorySystemSession; /** @@ -28,68 +32,107 @@ import org.eclipse.aether.RepositorySystemSession; * * @author Benjamin Bentmann */ -class DefaultModelCache +public class DefaultModelCache implements ModelCache { - private final RepositorySystemSession session; + private static final String KEY = DefaultModelCache.class.getName(); - private final RepositoryCache cache; + private final Map<Object, Object> cache; public static ModelCache newInstance( RepositorySystemSession session ) { + Map<Object, Object> cache; if ( session.getCache() == null ) { - return null; + cache = new ConcurrentHashMap<>(); } else { - return new DefaultModelCache( session ); + cache = ( Map ) session.getCache().get( session, KEY ); + if ( cache == null ) + { + cache = new ConcurrentHashMap<>(); + session.getCache().put( session, KEY, cache ); + } } + return new DefaultModelCache( cache ); + } + + private DefaultModelCache( Map<Object, Object> cache ) + { + this.cache = cache; + } + + public Object get( Source path, String tag ) + { + return get( new SourceCacheKey( path, tag ) ); } - private DefaultModelCache( RepositorySystemSession session ) + public void put( Source path, String tag, Object data ) { - this.session = session; - this.cache = session.getCache(); + put( new SourceCacheKey( path, tag ), data ); } public Object get( String groupId, String artifactId, String version, String tag ) { - return cache.get( session, new Key( groupId, artifactId, version, tag ) ); + return get( new GavCacheKey( groupId, artifactId, version, tag ) ); } public void put( String groupId, String artifactId, String version, String tag, Object data ) { - cache.put( session, new Key( groupId, artifactId, version, tag ), data ); + put( new GavCacheKey( groupId, artifactId, version, tag ), data ); } - static class Key + protected Object get( Object key ) { + return cache.get( key ); + } - private final String groupId; + protected void put( Object key, Object data ) + { + cache.put( key, data ); + } - private final String artifactId; + static class GavCacheKey + { - private final String version; + private final String gav; private final String tag; private final int hash; - Key( String groupId, String artifactId, String version, String tag ) + GavCacheKey( String groupId, String artifactId, String version, String tag ) + { + this( gav( groupId, artifactId, version ), tag ); + } + + GavCacheKey( String gav, String tag ) { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; + this.gav = gav; this.tag = tag; + this.hash = Objects.hash( gav, tag ); + } - int h = 17; - h = h * 31 + this.groupId.hashCode(); - h = h * 31 + this.artifactId.hashCode(); - h = h * 31 + this.version.hashCode(); - h = h * 31 + this.tag.hashCode(); - hash = h; + private static String gav( String groupId, String artifactId, String version ) + { + StringBuilder sb = new StringBuilder(); + if ( groupId != null ) + { + sb.append( groupId ); + } + sb.append( ":" ); + if ( artifactId != null ) + { + sb.append( artifactId ); + } + sb.append( ":" ); + if ( version != null ) + { + sb.append( version ); + } + return sb.toString(); } @Override @@ -103,10 +146,8 @@ class DefaultModelCache { return false; } - - Key that = (Key) obj; - return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId ) - && version.equals( that.version ) && tag.equals( that.tag ); + GavCacheKey that = (GavCacheKey) obj; + return Objects.equals( this.gav, that.gav ) && Objects.equals( this.tag, that.tag ); } @Override @@ -115,5 +156,59 @@ class DefaultModelCache return hash; } + @Override + public String toString() + { + return "GavCacheKey{" + + "gav='" + gav + '\'' + + ", tag='" + tag + '\'' + + '}'; + } + } + + private static final class SourceCacheKey + { + private final Source source; + + private final String tag; + + private final int hash; + + SourceCacheKey( Source source, String tag ) + { + this.source = source; + this.tag = tag; + this.hash = Objects.hash( source, tag ); + } + + @Override + public String toString() + { + return "SourceCacheKey{" + + "source=" + source + + ", tag='" + tag + '\'' + + '}'; + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( null == obj || !getClass().equals( obj.getClass() ) ) + { + return false; + } + SourceCacheKey that = (SourceCacheKey) obj; + return Objects.equals( this.source, that.source ) && Objects.equals( this.tag, that.tag ); + } + + @Override + public int hashCode() + { + return hash; + } } }