Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Fedorenko2014-08-08 05:12:48 -0400
committerIgor Fedorenko2014-08-15 09:19:01 -0400
commit75d4cc73239ccad3f45cd2452f14aaa5d019752c (patch)
tree9d25459b6b6baa386ef4399e5df3ea57dcfac02c
parent68d5af84ec40ada677b32a944eeab4169c80e640 (diff)
downloadm2e-core-75d4cc73239ccad3f45cd2452f14aaa5d019752c.tar.gz
m2e-core-75d4cc73239ccad3f45cd2452f14aaa5d019752c.tar.xz
m2e-core-75d4cc73239ccad3f45cd2452f14aaa5d019752c.zip
441257 implemented maven caches flush during forced dependency update
Maven maintains a number of caches meant to improve performance and memory utilization when multiple projects reference the same plugin or build extension. These caches were never flushed by m2e, which resulted in stale or inoperable plugins and build extensions used during workspace build. The fix was to flush these Maven caches during project forced dependency update. Change-Id: If179fb8bde7e51ab8f02092d76fba6a25c668219 Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
-rw-r--r--m2e-maven-runtime/pom.xml1
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/DefaultMavenComponentContributor.java9
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseExtensionRealmCache.java57
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseMavenMetadataCache.java10
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginArtifactsCache.java48
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginRealmCache.java57
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseProjectRealmCache.java57
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/IManagedCache.java14
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectCachePlunger.java88
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java2
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/BasicProjectRegistry.java30
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java14
-rw-r--r--org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java53
13 files changed, 381 insertions, 59 deletions
diff --git a/m2e-maven-runtime/pom.xml b/m2e-maven-runtime/pom.xml
index 3eeb472f..89f753d7 100644
--- a/m2e-maven-runtime/pom.xml
+++ b/m2e-maven-runtime/pom.xml
@@ -40,6 +40,7 @@
<repositories>
<!-- 440273 remove when aether-connector-okhttp 0.13 is released -->
+ <!-- 441257/440700 remove when maven 3.2.3 is released -->
<repository>
<id>takari-snapshots</id>
<url>http://repository.takari.io:8081/nexus/content/repositories/snapshots</url>
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/DefaultMavenComponentContributor.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/DefaultMavenComponentContributor.java
index fdfb6367..34916dc3 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/DefaultMavenComponentContributor.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/DefaultMavenComponentContributor.java
@@ -14,14 +14,20 @@ package org.eclipse.m2e.core.internal.embedder;
import org.eclipse.aether.RepositoryListener;
import org.apache.maven.classrealm.ClassRealmManagerDelegate;
+import org.apache.maven.plugin.ExtensionRealmCache;
import org.apache.maven.plugin.PluginArtifactsCache;
+import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.plugin.internal.PluginDependenciesResolver;
+import org.apache.maven.project.ProjectRealmCache;
import org.apache.maven.project.artifact.MavenMetadataCache;
import org.sonatype.plexus.build.incremental.BuildContext;
+import org.eclipse.m2e.core.internal.project.EclipseExtensionRealmCache;
import org.eclipse.m2e.core.internal.project.EclipseMavenMetadataCache;
import org.eclipse.m2e.core.internal.project.EclipsePluginArtifactsCache;
+import org.eclipse.m2e.core.internal.project.EclipsePluginRealmCache;
+import org.eclipse.m2e.core.internal.project.EclipseProjectRealmCache;
import org.eclipse.m2e.core.internal.project.registry.EclipsePluginDependenciesResolver;
@@ -29,6 +35,9 @@ public class DefaultMavenComponentContributor implements IMavenComponentContribu
public void contribute(IMavenComponentBinder binder) {
binder.bind(MavenMetadataCache.class, EclipseMavenMetadataCache.class, null);
+ binder.bind(ExtensionRealmCache.class, EclipseExtensionRealmCache.class, null);
+ binder.bind(ProjectRealmCache.class, EclipseProjectRealmCache.class, null);
+ binder.bind(PluginRealmCache.class, EclipsePluginRealmCache.class, null);
binder.bind(PluginArtifactsCache.class, EclipsePluginArtifactsCache.class, null);
binder.bind(PluginDependenciesResolver.class, EclipsePluginDependenciesResolver.class, null);
binder.bind(BuildContext.class, EclipseBuildContext.class, null);
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseExtensionRealmCache.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseExtensionRealmCache.java
new file mode 100644
index 00000000..794b00ad
--- /dev/null
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseExtensionRealmCache.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Takari, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Takari, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.core.internal.project;
+
+import java.io.File;
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.apache.maven.plugin.DefaultExtensionRealmCache;
+import org.apache.maven.project.MavenProject;
+
+import org.eclipse.m2e.core.embedder.ArtifactKey;
+
+
+/**
+ * @since 1.6
+ */
+@Singleton
+@SuppressWarnings("synthetic-access")
+public class EclipseExtensionRealmCache extends DefaultExtensionRealmCache implements IManagedCache {
+
+ private final ProjectCachePlunger<Key> plunger = new ProjectCachePlunger<Key>() {
+ @Override
+ protected void flush(Key cacheKey) {
+ CacheRecord cacheRecord = cache.remove(cacheKey);
+ if(cacheRecord != null) {
+ disposeClassRealm(cacheRecord.realm);
+ }
+ }
+ };
+
+ @Override
+ public void register(MavenProject project, Key key, CacheRecord record) {
+ plunger.register(project, key);
+ };
+
+ @Override
+ public Set<File> removeProject(File pom, ArtifactKey mavenProject, boolean forceDependencyUpdate) {
+ return plunger.removeProject(pom, forceDependencyUpdate);
+ }
+
+ @Override
+ public void flush() {
+ super.flush();
+ plunger.flush();
+ }
+}
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseMavenMetadataCache.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseMavenMetadataCache.java
index 3abaf83a..796c1ab9 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseMavenMetadataCache.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseMavenMetadataCache.java
@@ -11,14 +11,15 @@
package org.eclipse.m2e.core.internal.project;
+import java.io.File;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
+import java.util.Set;
import javax.inject.Singleton;
-import org.eclipse.core.resources.IFile;
-
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -36,6 +37,7 @@ import org.eclipse.m2e.core.embedder.ArtifactKey;
@Singleton
public class EclipseMavenMetadataCache extends DefaultMavenMetadataCache implements MavenMetadataCache, IManagedCache {
+ @Override
public void put(Artifact artifact, boolean resolveManagedVersions, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories, ResolutionGroup result) {
@@ -49,8 +51,10 @@ public class EclipseMavenMetadataCache extends DefaultMavenMetadataCache impleme
super.put(artifact, resolveManagedVersions, localRepository, remoteRepositories, result);
}
- public void removeProject(IFile pom, ArtifactKey key) {
+ @Override
+ public Set<File> removeProject(File pom, ArtifactKey key, boolean force) {
removeProject(key);
+ return Collections.emptySet();
}
private void removeProject(ArtifactKey key) {
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginArtifactsCache.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginArtifactsCache.java
index 643bed31..c2284b86 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginArtifactsCache.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginArtifactsCache.java
@@ -11,43 +11,41 @@
package org.eclipse.m2e.core.internal.project;
-import javax.inject.Singleton;
+import java.io.File;
+import java.util.Set;
-import org.eclipse.aether.RepositoryCache;
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.repository.RepositoryPolicy;
+import javax.inject.Singleton;
import org.apache.maven.plugin.DefaultPluginArtifactsCache;
-import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.project.MavenProject;
-import org.eclipse.m2e.core.internal.embedder.MavenExecutionContext;
+import org.eclipse.m2e.core.embedder.ArtifactKey;
@Singleton
-public class EclipsePluginArtifactsCache extends DefaultPluginArtifactsCache {
-
- public CacheRecord get(Key key) throws PluginResolutionException {
- MavenExecutionContext context = MavenExecutionContext.getThreadContext();
+@SuppressWarnings("synthetic-access")
+public class EclipsePluginArtifactsCache extends DefaultPluginArtifactsCache implements IManagedCache {
- if(context == null) {
- return super.get(key);
+ private final ProjectCachePlunger<Key> plunger = new ProjectCachePlunger<Key>() {
+ protected void flush(Key cacheKey) {
+ cache.remove(cacheKey);
}
+ };
- RepositorySystemSession session = context.getRepositorySession();
- RepositoryCache sessionCache = session.getCache();
+ @Override
+ public void register(MavenProject project, Key cacheKey, CacheRecord record) {
+ plunger.register(project, cacheKey);
+ }
- if(!RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(session.getUpdatePolicy())
- || sessionCache.get(session, key) != null) {
- return super.get(key);
- }
+ @Override
+ public Set<File> removeProject(File pom, ArtifactKey mavenProject, boolean forceDependencyUpdate) {
+ return plunger.removeProject(pom, forceDependencyUpdate);
+ };
- // only force refresh once per repository session
- cache.remove(key);
- sessionCache.put(session, key, Boolean.TRUE);
- return null;
+ @Override
+ public void flush() {
+ super.flush();
+ plunger.flush();
}
- public EclipsePluginArtifactsCache() {
- super();
- }
}
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginRealmCache.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginRealmCache.java
new file mode 100644
index 00000000..835fea55
--- /dev/null
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipsePluginRealmCache.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Takari, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Takari, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.core.internal.project;
+
+import java.io.File;
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.apache.maven.plugin.DefaultPluginRealmCache;
+import org.apache.maven.project.MavenProject;
+
+import org.eclipse.m2e.core.embedder.ArtifactKey;
+
+
+/**
+ * @since 1.6
+ */
+@Singleton
+@SuppressWarnings("synthetic-access")
+public class EclipsePluginRealmCache extends DefaultPluginRealmCache implements IManagedCache {
+
+ private final ProjectCachePlunger<Key> plunger = new ProjectCachePlunger<Key>() {
+ protected void flush(Key cacheKey) {
+ CacheRecord cacheRecord = cache.remove(cacheKey);
+ if(cacheRecord != null) {
+ disposeClassRealm(cacheRecord.realm);
+ }
+ }
+ };
+
+ @Override
+ public void register(MavenProject project, Key cacheKey, CacheRecord record) {
+ plunger.register(project, cacheKey);
+ }
+
+ @Override
+ public Set<File> removeProject(File pom, ArtifactKey mavenProject, boolean forceDependencyUpdate) {
+ return plunger.removeProject(pom, forceDependencyUpdate);
+ }
+
+ @Override
+ public void flush() {
+ super.flush();
+ plunger.flush();
+ }
+
+}
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseProjectRealmCache.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseProjectRealmCache.java
new file mode 100644
index 00000000..4cd4c29d
--- /dev/null
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/EclipseProjectRealmCache.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Takari, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Takari, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.core.internal.project;
+
+import java.io.File;
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.apache.maven.project.DefaultProjectRealmCache;
+import org.apache.maven.project.MavenProject;
+
+import org.eclipse.m2e.core.embedder.ArtifactKey;
+
+
+/**
+ * @since 1.6
+ */
+@Singleton
+@SuppressWarnings("synthetic-access")
+public class EclipseProjectRealmCache extends DefaultProjectRealmCache implements IManagedCache {
+
+ private final ProjectCachePlunger<Key> plunger = new ProjectCachePlunger<Key>() {
+ protected void flush(Key cacheKey) {
+ CacheRecord cacheRecord = cache.remove(cacheKey);
+ if(cacheRecord != null) {
+ disposeClassRealm(cacheRecord.realm);
+ }
+ }
+ };
+
+ @Override
+ public void register(MavenProject project, Key key, CacheRecord record) {
+ plunger.register(project, key);
+ }
+
+ @Override
+ public Set<File> removeProject(File pom, ArtifactKey mavenProject, boolean forceDependencyUpdate) {
+ return plunger.removeProject(pom, forceDependencyUpdate);
+ }
+
+ @Override
+ public void flush() {
+ super.flush();
+ plunger.flush();
+ }
+
+}
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/IManagedCache.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/IManagedCache.java
index 25a4def4..df70fd47 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/IManagedCache.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/IManagedCache.java
@@ -11,22 +11,14 @@
package org.eclipse.m2e.core.internal.project;
-import org.eclipse.core.resources.IFile;
+import java.io.File;
+import java.util.Set;
import org.eclipse.m2e.core.embedder.ArtifactKey;
-/**
- * IManagedCache
- *
- * @author igor
- */
public interface IManagedCache {
- /**
- * @param pom
- * @param mavenProject
- */
- void removeProject(IFile pom, ArtifactKey mavenProject);
+ Set<File> removeProject(File pom, ArtifactKey mavenProject, boolean forceDependencyUpdate);
}
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectCachePlunger.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectCachePlunger.java
new file mode 100644
index 00000000..59f20f3b
--- /dev/null
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectCachePlunger.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Takari, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Takari, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.core.internal.project;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+import org.eclipse.aether.RepositoryCache;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RepositoryPolicy;
+
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+
+import org.apache.maven.project.MavenProject;
+
+import org.eclipse.m2e.core.internal.embedder.MavenExecutionContext;
+
+
+/**
+ * @since 1.6
+ */
+abstract class ProjectCachePlunger<Key> {
+
+ final Multimap<File, Key> projectKeys = HashMultimap.create();
+
+ final Multimap<Key, File> keyProjects = HashMultimap.create();
+
+ public void register(MavenProject project, Key cacheKey) {
+ // project.file is null for parent pom.xml resolved from repositories
+ File file = project.getFile();
+ if(file != null) {
+ projectKeys.put(file, cacheKey);
+ keyProjects.put(cacheKey, file);
+ }
+ }
+
+ public Set<File> removeProject(File pom, boolean forceDependencyUpdate) {
+ RepositorySystemSession session = MavenExecutionContext.getThreadContext().getRepositorySession();
+ RepositoryCache sessionCache = session.getCache();
+
+ final Set<File> affectedProjects = new HashSet<>();
+
+ for(Key cacheKey : projectKeys.removeAll(pom)) {
+ keyProjects.remove(cacheKey, pom);
+ if(forceDependencyUpdate && RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(session.getUpdatePolicy())
+ && sessionCache.get(session, cacheKey) == null) {
+ for(File affectedPom : keyProjects.removeAll(cacheKey)) {
+ affectedProjects.add(affectedPom);
+ projectKeys.remove(affectedPom, cacheKey);
+ }
+ }
+ if(!keyProjects.containsKey(cacheKey)) {
+ flush(cacheKey);
+ }
+ }
+
+ return affectedProjects;
+ }
+
+ protected void disposeClassRealm(ClassRealm realm) {
+ try {
+ realm.getWorld().disposeRealm(realm.getId());
+ } catch(NoSuchRealmException e) {
+ // ignore
+ }
+ }
+
+ protected abstract void flush(Key cacheKey);
+
+ public void flush() {
+ projectKeys.clear();
+ keyProjects.clear();
+ }
+}
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java
index bf3b8272..21477ad3 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java
@@ -547,7 +547,7 @@ public class ProjectConfigurationManager implements IProjectConfigurationManager
// Remove the m2e builder
removeMavenBuilder(project, description, monitor);
- project.setDescription(description, null);
+ project.setDescription(description, monitor);
// tell the projectManager to remove the project facade and notify MavenProjectChangeListeners
MavenPlugin.getMavenProjectRegistry().refresh(
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/BasicProjectRegistry.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/BasicProjectRegistry.java
index cacec629..daa2ad40 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/BasicProjectRegistry.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/BasicProjectRegistry.java
@@ -11,6 +11,7 @@
package org.eclipse.m2e.core.internal.project.registry;
+import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -36,29 +37,34 @@ abstract class BasicProjectRegistry implements Serializable {
private final String m2e_version = MavenPluginActivator.getQualifiedVersion();
/**
- * Map<ArtifactKey, IPath> Maps ArtifactKey to full workspace IPath of the POM file that defines this artifact.
+ * Maps ArtifactKey to IFile of the POM file that defines this artifact.
*/
- protected final Map<ArtifactKey, IFile> workspaceArtifacts = new HashMap<ArtifactKey, IFile>();
+ protected final Map<ArtifactKey, IFile> workspaceArtifacts = new HashMap<>();
/**
- * Maps full pom IPath to MavenProjectFacade
+ * Maps IFile to MavenProjectFacade
*/
- protected final Map<IFile, MavenProjectFacade> workspacePoms = new HashMap<IFile, MavenProjectFacade>();
+ protected final Map<IFile, MavenProjectFacade> workspacePoms = new HashMap<>();
+
+ /**
+ * Maps File to MavenProjectFacade
+ */
+ protected final Map<File, MavenProjectFacade> workspacePomFiles = new HashMap<>();
/**
* Maps required capabilities to projects that require them.
*/
- protected final Map<VersionlessKey, Map<RequiredCapability, Set<IFile>>> requiredCapabilities = new HashMap<VersionlessKey, Map<RequiredCapability, Set<IFile>>>();
+ protected final Map<VersionlessKey, Map<RequiredCapability, Set<IFile>>> requiredCapabilities = new HashMap<>();
/**
* Maps project pom.xml file to the capabilities provided by the project
*/
- protected final Map<IFile, Set<Capability>> projectCapabilities = new HashMap<IFile, Set<Capability>>();
+ protected final Map<IFile, Set<Capability>> projectCapabilities = new HashMap<>();
/**
* Maps project pom.xml file to the capabilities required by the project
*/
- protected final Map<IFile, Set<RequiredCapability>> projectRequirements = new HashMap<IFile, Set<RequiredCapability>>();
+ protected final Map<IFile, Set<RequiredCapability>> projectRequirements = new HashMap<>();
protected BasicProjectRegistry() {
}
@@ -75,6 +81,10 @@ abstract class BasicProjectRegistry implements Serializable {
copy(other.projectCapabilities, projectCapabilities);
copy(other.projectRequirements, projectRequirements);
copy(other.requiredCapabilities, requiredCapabilities);
+
+ for(MavenProjectFacade facade : workspacePoms.values()) {
+ workspacePomFiles.put(facade.getPomFile(), facade);
+ }
}
/**
@@ -100,6 +110,10 @@ abstract class BasicProjectRegistry implements Serializable {
return workspacePoms.get(pom);
}
+ public MavenProjectFacade getProjectFacade(File pom) {
+ return workspacePomFiles.get(pom);
+ }
+
public MavenProjectFacade getProjectFacade(String groupId, String artifactId, String version) {
IFile path = workspaceArtifacts.get(new ArtifactKey(groupId, artifactId, version, null));
if(path == null) {
@@ -122,6 +136,7 @@ abstract class BasicProjectRegistry implements Serializable {
protected void clear() {
workspaceArtifacts.clear();
workspacePoms.clear();
+ workspacePomFiles.clear();
requiredCapabilities.clear();
projectCapabilities.clear();
projectRequirements.clear();
@@ -131,6 +146,7 @@ abstract class BasicProjectRegistry implements Serializable {
return MavenPluginActivator.getQualifiedVersion().equals(m2e_version) //
&& workspaceArtifacts != null //
&& workspacePoms != null //
+ && workspacePomFiles != null //
&& requiredCapabilities != null //
&& projectCapabilities != null //
&& projectRequirements != null //
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java
index d7666cc9..0213924e 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MutableProjectRegistry.java
@@ -11,6 +11,7 @@
package org.eclipse.m2e.core.internal.project.registry;
+import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -77,7 +78,7 @@ public class MutableProjectRegistry extends BasicProjectRegistry implements IPro
removeRequiredCapabilities(pom);
// Remove the project from workspaceProjects, projectRequirements and projectCapabilities maps
- workspacePoms.remove(pom);
+ MavenProjectFacade facade = workspacePoms.remove(pom);
projectRequirements.remove(pom);
projectCapabilities.remove(pom);
@@ -85,6 +86,10 @@ public class MutableProjectRegistry extends BasicProjectRegistry implements IPro
if(mavenProject != null) {
workspaceArtifacts.remove(mavenProject);
}
+
+ if(facade != null) {
+ workspacePomFiles.remove(facade.getPomFile());
+ }
}
static boolean isSameProject(IResource r1, IResource r2) {
@@ -123,6 +128,13 @@ public class MutableProjectRegistry extends BasicProjectRegistry implements IPro
return super.getProjectFacade(pom);
}
+ public MavenProjectFacade getProjectFacade(File pom) {
+ if(isClosed()) {
+ return parent.getProjectFacade(pom);
+ }
+ return super.getProjectFacade(pom);
+ }
+
public MavenProjectFacade getProjectFacade(String groupId, String artifactId, String version) {
if(isClosed()) {
return parent.getProjectFacade(groupId, artifactId, version);
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java
index 856af866..493d1348 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/ProjectRegistryManager.java
@@ -63,9 +63,13 @@ import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
+import org.apache.maven.plugin.ExtensionRealmCache;
import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.PluginArtifactsCache;
+import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.ProjectRealmCache;
import org.apache.maven.project.artifact.MavenMetadataCache;
import org.apache.maven.repository.DelegatingLocalArtifactRepository;
@@ -236,7 +240,7 @@ public class ProjectRegistryManager {
MavenProjectFacade facade = state.getProjectFacade(pom);
ArtifactKey mavenProject = facade != null ? facade.getArtifactKey() : null;
- flushCaches(pom, facade);
+ flushCaches(state, pom, facade, false);
if(mavenProject == null) {
state.removeProject(pom, null);
@@ -269,6 +273,11 @@ public class ProjectRegistryManager {
}, monitor);
}
+ private boolean isForceDependencyUpdate() throws CoreException {
+ MavenExecutionContext context = maven.getExecutionContext();
+ return context != null && context.getExecutionRequest().isUpdateSnapshots();
+ }
+
/**
* This method acquires workspace root's lock and sends project change events. It is meant for synchronous registry
* updates.
@@ -360,7 +369,8 @@ public class ProjectRegistryManager {
monitor.subTask(NLS.bind(Messages.ProjectRegistryManager_task_project, pom.getProject().getName()));
MavenProjectFacade oldFacade = newState.getProjectFacade(pom);
- flushCaches(pom, oldFacade);
+
+ context.forcePomFiles(flushCaches(newState, pom, oldFacade, isForceDependencyUpdate()));
if(oldFacade != null) {
putMavenProject(oldFacade, null); // maintain maven project cache
}
@@ -1038,7 +1048,7 @@ public class ProjectRegistryManager {
final MavenProject mavenProject = notification.getValue();
final Map<MavenProjectFacade, MavenProject> contextProjects = getContextProjects();
if(contextProjects != null && !contextProjects.containsKey(facade)) {
- flushMavenCaches(facade.getPom(), facade.getArtifactKey(), mavenProject);
+ flushMavenCaches(facade.getPomFile(), facade.getArtifactKey(), mavenProject, false);
}
}
}
@@ -1046,7 +1056,8 @@ public class ProjectRegistryManager {
return CacheBuilder.newBuilder().maximumSize(5).removalListener(removalListener).build();
}
- private void flushCaches(IFile pom, MavenProjectFacade facade) {
+ private Set<IFile> flushCaches(MutableProjectRegistry newState, IFile pom, MavenProjectFacade facade,
+ boolean forceDependencyUpdate) {
ArtifactKey key = null;
MavenProject project = null;
@@ -1054,24 +1065,44 @@ public class ProjectRegistryManager {
key = facade.getArtifactKey();
project = getMavenProject(facade); // cached only
mavenProjectCache.invalidate(facade);
+ Set<IFile> ifiles = new HashSet<>();
+ for(File file : flushMavenCaches(facade.getPomFile(), key, project, forceDependencyUpdate)) {
+ MavenProjectFacade affected = projectRegistry.getProjectFacade(file);
+ if(affected != null) {
+ ifiles.add(affected.getPom());
+ }
+ }
+ return ifiles;
}
- flushMavenCaches(pom, key, project);
+
+ return Collections.emptySet();
}
/**
* Flushes caches maintained by Maven core.
*/
- void flushMavenCaches(IFile pom, ArtifactKey key, MavenProject project) {
+ Set<File> flushMavenCaches(File pom, ArtifactKey key, MavenProject project, boolean force) {
+ Set<File> affected = new HashSet<>();
+ affected.addAll(flushMavenCache(ProjectRealmCache.class, pom, key, force));
+ affected.addAll(flushMavenCache(ExtensionRealmCache.class, pom, key, force));
+ affected.addAll(flushMavenCache(PluginRealmCache.class, pom, key, force));
+ affected.addAll(flushMavenCache(MavenMetadataCache.class, pom, key, force));
+ affected.addAll(flushMavenCache(PluginArtifactsCache.class, pom, key, force));
+ if(project != null) {
+ ((MavenImpl) getMaven()).releaseExtensionsRealm(project);
+ }
+ return affected;
+ }
+
+ private Set<File> flushMavenCache(Class<?> clazz, File pom, ArtifactKey key, boolean force) {
try {
- IManagedCache cache = (IManagedCache) maven.getPlexusContainer().lookup(MavenMetadataCache.class);
- cache.removeProject(pom, key);
+ IManagedCache cache = (IManagedCache) maven.getPlexusContainer().lookup(clazz);
+ return cache.removeProject(pom, key, force);
} catch(ComponentLookupException ex) {
// can't really happen
} catch(CoreException ex) {
// can't really happen
}
- if(project != null) {
- ((MavenImpl) getMaven()).releaseExtensionsRealm(project);
- }
+ return Collections.emptySet();
}
}

Back to the top