1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.internal;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.stream.Collectors;
29 import java.util.stream.Stream;
30
31 import org.apache.maven.RepositoryUtils;
32 import org.apache.maven.model.Dependency;
33 import org.apache.maven.model.Plugin;
34 import org.apache.maven.plugin.PluginResolutionException;
35 import org.eclipse.aether.DefaultRepositorySystemSession;
36 import org.eclipse.aether.RepositorySystem;
37 import org.eclipse.aether.RepositorySystemSession;
38 import org.eclipse.aether.RequestTrace;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.artifact.DefaultArtifact;
41 import org.eclipse.aether.collection.CollectRequest;
42 import org.eclipse.aether.collection.DependencyCollectionChecker;
43 import org.eclipse.aether.collection.DependencyCollectionException;
44 import org.eclipse.aether.collection.DependencySelector;
45 import org.eclipse.aether.collection.VersionFilterBuilder;
46 import org.eclipse.aether.graph.DependencyFilter;
47 import org.eclipse.aether.graph.DependencyNode;
48 import org.eclipse.aether.repository.RemoteRepository;
49 import org.eclipse.aether.resolution.ArtifactDescriptorException;
50 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
51 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
52 import org.eclipse.aether.resolution.ArtifactRequest;
53 import org.eclipse.aether.resolution.ArtifactResolutionException;
54 import org.eclipse.aether.resolution.DependencyRequest;
55 import org.eclipse.aether.resolution.DependencyResolutionException;
56 import org.eclipse.aether.resolution.DependencyResult;
57 import org.eclipse.aether.util.artifact.JavaScopes;
58 import org.eclipse.aether.util.filter.AndDependencyFilter;
59 import org.eclipse.aether.util.filter.ScopeDependencyFilter;
60 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
61 import org.eclipse.aether.util.graph.visitor.DependencyGraphDumper;
62 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66
67
68
69
70
71
72
73
74 @Singleton
75 @Named
76 public class DefaultPluginDependenciesResolver implements PluginDependenciesResolver {
77
78 private static final String REPOSITORY_CONTEXT = "plugin";
79
80 private final Logger logger = LoggerFactory.getLogger(getClass());
81
82 @Inject
83 private RepositorySystem repoSystem;
84
85 @Inject
86 private List<MavenPluginDependenciesValidator> dependenciesValidators;
87
88 private Artifact toArtifact(Plugin plugin, RepositorySystemSession session) {
89 return new DefaultArtifact(
90 plugin.getGroupId(),
91 plugin.getArtifactId(),
92 null,
93 "jar",
94 plugin.getVersion(),
95 session.getArtifactTypeRegistry().get("maven-plugin"));
96 }
97
98 @Override
99 public Artifact resolve(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session)
100 throws PluginResolutionException {
101 RequestTrace trace = RequestTrace.newChild(null, plugin);
102
103 Artifact pluginArtifact = toArtifact(plugin, session);
104
105 try {
106 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
107 pluginSession.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(true, false));
108
109 ArtifactDescriptorRequest request =
110 new ArtifactDescriptorRequest(pluginArtifact, repositories, REPOSITORY_CONTEXT);
111 request.setTrace(trace);
112 ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor(pluginSession, request);
113
114 for (MavenPluginDependenciesValidator dependenciesValidator : dependenciesValidators) {
115 dependenciesValidator.validate(session, pluginArtifact, result);
116 }
117
118 pluginArtifact = result.getArtifact();
119
120 if (logger.isWarnEnabled()) {
121 if (!result.getRelocations().isEmpty()) {
122 String message = pluginArtifact instanceof org.apache.maven.repository.internal.RelocatedArtifact
123 ? ((org.apache.maven.repository.internal.RelocatedArtifact) pluginArtifact).getMessage()
124 : null;
125 logger.warn("The artifact " + result.getRelocations().get(0) + " has been relocated to "
126 + pluginArtifact + (message != null ? ": " + message : ""));
127 }
128 }
129
130 String requiredMavenVersion = (String) result.getProperties().get("prerequisites.maven");
131 if (requiredMavenVersion != null) {
132 Map<String, String> props = new LinkedHashMap<>(pluginArtifact.getProperties());
133 props.put("requiredMavenVersion", requiredMavenVersion);
134 pluginArtifact = pluginArtifact.setProperties(props);
135 }
136 } catch (ArtifactDescriptorException e) {
137 throw new PluginResolutionException(
138 plugin, e.getResult().getExceptions(), logger.isDebugEnabled() ? e : null);
139 }
140
141 try {
142 ArtifactRequest request = new ArtifactRequest(pluginArtifact, repositories, REPOSITORY_CONTEXT);
143 request.setTrace(trace);
144 pluginArtifact = repoSystem.resolveArtifact(session, request).getArtifact();
145 } catch (ArtifactResolutionException e) {
146 throw new PluginResolutionException(
147 plugin, e.getResult().getExceptions(), logger.isDebugEnabled() ? e : null);
148 }
149
150 return pluginArtifact;
151 }
152
153
154
155
156
157 @Deprecated
158 public DependencyNode resolveCoreExtension(
159 Plugin plugin,
160 DependencyFilter dependencyFilter,
161 List<RemoteRepository> repositories,
162 RepositorySystemSession session)
163 throws PluginResolutionException {
164 return resolveInternal(plugin, null , dependencyFilter, repositories, session)
165 .getRoot();
166 }
167
168
169
170
171 @Override
172 public DependencyResult resolveCoreExtensionAndFlatten(
173 Plugin plugin,
174 DependencyFilter dependencyFilter,
175 List<RemoteRepository> repositories,
176 RepositorySystemSession session)
177 throws PluginResolutionException {
178 return resolveInternal(plugin, null , dependencyFilter, repositories, session);
179 }
180
181 @Override
182 public DependencyNode resolve(
183 Plugin plugin,
184 Artifact pluginArtifact,
185 DependencyFilter dependencyFilter,
186 List<RemoteRepository> repositories,
187 RepositorySystemSession session)
188 throws PluginResolutionException {
189 return resolveInternal(plugin, pluginArtifact, dependencyFilter, repositories, session)
190 .getRoot();
191 }
192
193 @Override
194 public DependencyResult resolvePluginAndFlatten(
195 Plugin plugin,
196 Artifact pluginArtifact,
197 DependencyFilter dependencyFilter,
198 List<RemoteRepository> repositories,
199 RepositorySystemSession session)
200 throws PluginResolutionException {
201 return resolveInternal(plugin, pluginArtifact, dependencyFilter, repositories, session);
202 }
203
204 private DependencyResult resolveInternal(
205 Plugin plugin,
206 Artifact pluginArtifact,
207 DependencyFilter dependencyFilter,
208 List<RemoteRepository> repositories,
209 RepositorySystemSession session)
210 throws PluginResolutionException {
211 RequestTrace trace = RequestTrace.newChild(null, plugin);
212
213 if (pluginArtifact == null) {
214 pluginArtifact = toArtifact(plugin, session);
215 }
216
217 DependencyFilter collectionFilter = new ScopeDependencyFilter("provided", "test");
218 DependencyFilter resolutionFilter = AndDependencyFilter.newInstance(collectionFilter, dependencyFilter);
219
220 try {
221 DependencySelector selector =
222 AndDependencySelector.newInstance(session.getDependencySelector(), new WagonExcluder());
223
224 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
225 pluginSession.setConfigProperty(VersionFilterBuilder.VERSION_FILTER_SUPPRESSED, Boolean.TRUE.toString());
226 pluginSession.setConfigProperty(
227 DependencyCollectionChecker.COLLECTOR_CHECKER_SUPPRESSED, Boolean.TRUE.toString());
228 pluginSession.setDependencySelector(selector);
229 pluginSession.setDependencyGraphTransformer(session.getDependencyGraphTransformer());
230
231 CollectRequest request = new CollectRequest();
232 request.setRequestContext(REPOSITORY_CONTEXT);
233 request.setRepositories(repositories);
234 request.setRoot(new org.eclipse.aether.graph.Dependency(pluginArtifact, null));
235 for (Dependency dependency : plugin.getDependencies()) {
236 org.eclipse.aether.graph.Dependency pluginDep =
237 RepositoryUtils.toDependency(dependency, session.getArtifactTypeRegistry());
238 if (!JavaScopes.SYSTEM.equals(pluginDep.getScope())) {
239 pluginDep = pluginDep.setScope(JavaScopes.RUNTIME);
240 }
241 request.addDependency(pluginDep);
242 }
243
244 DependencyRequest depRequest = new DependencyRequest(request, resolutionFilter);
245 depRequest.setTrace(trace);
246
247 request.setTrace(RequestTrace.newChild(trace, depRequest));
248
249 DependencyNode node =
250 repoSystem.collectDependencies(pluginSession, request).getRoot();
251
252 if (logger.isDebugEnabled()) {
253 node.accept(new DependencyGraphDumper(logger::debug));
254 }
255
256 depRequest.setRoot(node);
257 return repoSystem.resolveDependencies(session, depRequest);
258
259 } catch (DependencyCollectionException e) {
260 throw new PluginResolutionException(
261 plugin, e.getResult().getExceptions(), logger.isDebugEnabled() ? e : null);
262 } catch (DependencyResolutionException e) {
263 List<Exception> exceptions = Stream.concat(
264 e.getResult().getCollectExceptions().stream(),
265 e.getResult().getArtifactResults().stream()
266 .filter(r -> !r.isResolved())
267 .flatMap(r -> r.getExceptions().stream()))
268 .collect(Collectors.toList());
269 throw new PluginResolutionException(plugin, exceptions, logger.isDebugEnabled() ? e : null);
270 }
271 }
272 }