Skip to content

Commit 6559599

Browse files
gnodetslawekjaranowski
authored andcommitted
[MNG-8711] Fix concurrent cache access
(cherry picked from commit ce15193) with simple conflict resolving
1 parent d213a7b commit 6559599

File tree

3 files changed

+31
-31
lines changed

3 files changed

+31
-31
lines changed

maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,26 +123,29 @@ public void resolveProjectDependencies(
123123
}
124124
}
125125

126-
Set<Artifact> resolvedArtifacts;
127126
ProjectArtifactsCache.Key cacheKey = projectArtifactsCache.createKey(
128127
project, scopesToCollect, scopesToResolve, aggregating, session.getRepositorySession());
129128
ProjectArtifactsCache.CacheRecord recordArtifacts;
130129
recordArtifacts = projectArtifactsCache.get(cacheKey);
131130

132-
if (recordArtifacts != null) {
133-
resolvedArtifacts = recordArtifacts.getArtifacts();
134-
} else {
135-
try {
136-
resolvedArtifacts = getDependencies(
137-
project, scopesToCollect, scopesToResolve, session, aggregating, projectArtifacts);
138-
recordArtifacts = projectArtifactsCache.put(cacheKey, resolvedArtifacts);
139-
} catch (LifecycleExecutionException e) {
140-
projectArtifactsCache.put(cacheKey, e);
141-
projectArtifactsCache.register(project, cacheKey, recordArtifacts);
142-
throw e;
131+
if (recordArtifacts == null) {
132+
synchronized (cacheKey) {
133+
recordArtifacts = projectArtifactsCache.get(cacheKey);
134+
if (recordArtifacts == null) {
135+
try {
136+
Set<Artifact> resolvedArtifacts = getDependencies(
137+
project, scopesToCollect, scopesToResolve, session, aggregating, projectArtifacts);
138+
recordArtifacts = projectArtifactsCache.put(cacheKey, resolvedArtifacts);
139+
} catch (LifecycleExecutionException e) {
140+
projectArtifactsCache.put(cacheKey, e);
141+
projectArtifactsCache.register(project, cacheKey, recordArtifacts);
142+
throw e;
143+
}
144+
}
143145
}
144146
}
145147
projectArtifactsCache.register(project, cacheKey, recordArtifacts);
148+
Set<Artifact> resolvedArtifacts = recordArtifacts.getArtifacts();
146149

147150
Map<Artifact, File> reactorProjects =
148151
new HashMap<>(session.getProjects().size());

maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@
5050
public class DefaultPluginDescriptorCache implements PluginDescriptorCache {
5151

5252
private Map<Key, PluginDescriptor> descriptors = new ConcurrentHashMap<>(128);
53+
private Map<Key, Key> keys = new ConcurrentHashMap<>();
5354

5455
public void flush() {
5556
descriptors.clear();
5657
}
5758

5859
public Key createKey(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session) {
59-
return new CacheKey(plugin, repositories, session);
60+
return keys.computeIfAbsent(new CacheKey(plugin, repositories, session), k -> k);
6061
}
6162

6263
public PluginDescriptor get(Key cacheKey) {
@@ -66,26 +67,20 @@ public PluginDescriptor get(Key cacheKey) {
6667
@Override
6768
public PluginDescriptor get(Key key, PluginDescriptorSupplier supplier)
6869
throws PluginDescriptorParsingException, PluginResolutionException, InvalidPluginDescriptorException {
70+
6971
try {
70-
return clone(descriptors.computeIfAbsent(key, k -> {
71-
try {
72-
return clone(supplier.load());
73-
} catch (PluginDescriptorParsingException
74-
| PluginResolutionException
75-
| InvalidPluginDescriptorException e) {
76-
throw new RuntimeException(e);
72+
PluginDescriptor desc = descriptors.get(key);
73+
if (desc == null) {
74+
synchronized (key) {
75+
desc = descriptors.get(key);
76+
if (desc == null) {
77+
desc = supplier.load();
78+
descriptors.putIfAbsent(key, clone(desc));
79+
}
7780
}
78-
}));
79-
} catch (RuntimeException e) {
80-
if (e.getCause() instanceof PluginDescriptorParsingException) {
81-
throw (PluginDescriptorParsingException) e.getCause();
82-
}
83-
if (e.getCause() instanceof PluginResolutionException) {
84-
throw (PluginResolutionException) e.getCause();
85-
}
86-
if (e.getCause() instanceof InvalidPluginDescriptorException) {
87-
throw (InvalidPluginDescriptorException) e.getCause();
8881
}
82+
return clone(desc);
83+
} catch (PluginDescriptorParsingException | PluginResolutionException | InvalidPluginDescriptorException e) {
8984
throw e;
9085
}
9186
}

maven-core/src/main/java/org/apache/maven/project/artifact/DefaultProjectArtifactsCache.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public boolean equals(Object o) {
161161
}
162162

163163
protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
164+
protected final Map<Key, Key> keys = new ConcurrentHashMap<>();
164165

165166
@Override
166167
public Key createKey(
@@ -169,13 +170,14 @@ public Key createKey(
169170
Collection<String> scopesToResolve,
170171
boolean aggregating,
171172
RepositorySystemSession session) {
172-
return new CacheKey(
173+
Key key = new CacheKey(
173174
project,
174175
project.getRemoteProjectRepositories(),
175176
scopesToCollect,
176177
scopesToResolve,
177178
aggregating,
178179
session);
180+
return keys.computeIfAbsent(key, k -> k);
179181
}
180182

181183
@Override

0 commit comments

Comments
 (0)