1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.ByteArrayOutputStream;
26 import java.io.PrintStream;
27 import java.util.List;
28
29 import org.apache.maven.api.Project;
30 import org.apache.maven.api.services.MavenException;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.execution.MojoExecutionEvent;
33 import org.apache.maven.execution.MojoExecutionListener;
34 import org.apache.maven.execution.scope.internal.MojoExecutionScope;
35 import org.apache.maven.internal.impl.DefaultLog;
36 import org.apache.maven.internal.impl.DefaultMojoExecution;
37 import org.apache.maven.internal.impl.InternalMavenSession;
38 import org.apache.maven.model.Plugin;
39 import org.apache.maven.plugin.descriptor.MojoDescriptor;
40 import org.apache.maven.plugin.descriptor.PluginDescriptor;
41 import org.apache.maven.plugin.logging.Log;
42 import org.apache.maven.project.MavenProject;
43 import org.codehaus.plexus.classworlds.realm.ClassRealm;
44 import org.eclipse.aether.RepositorySystemSession;
45 import org.eclipse.aether.repository.RemoteRepository;
46 import org.slf4j.LoggerFactory;
47
48
49
50
51
52
53
54 @Named
55 @Singleton
56 public class DefaultBuildPluginManager implements BuildPluginManager {
57
58 private final MavenPluginManager mavenPluginManager;
59 private final LegacySupport legacySupport;
60 private final MojoExecutionScope scope;
61 private final MojoExecutionListener mojoExecutionListener;
62
63 @Inject
64 public DefaultBuildPluginManager(
65 MavenPluginManager mavenPluginManager,
66 LegacySupport legacySupport,
67 MojoExecutionScope scope,
68 List<MojoExecutionListener> mojoExecutionListeners) {
69 this.mavenPluginManager = mavenPluginManager;
70 this.legacySupport = legacySupport;
71 this.scope = scope;
72 this.mojoExecutionListener = new CompoundMojoExecutionListener(mojoExecutionListeners);
73 }
74
75
76
77
78
79
80
81
82
83
84 @Override
85 public PluginDescriptor loadPlugin(
86 Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session)
87 throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
88 InvalidPluginDescriptorException {
89 return mavenPluginManager.getPluginDescriptor(plugin, repositories, session);
90 }
91
92
93
94
95
96 @Override
97 public void executeMojo(MavenSession session, MojoExecution mojoExecution)
98 throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException {
99 MavenProject project = session.getCurrentProject();
100
101 MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
102
103 Mojo mojo = null;
104
105 ClassRealm pluginRealm;
106 try {
107 pluginRealm = getPluginRealm(session, mojoDescriptor.getPluginDescriptor());
108 } catch (PluginResolutionException e) {
109 throw new PluginExecutionException(mojoExecution, project, e);
110 }
111
112 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
113 Thread.currentThread().setContextClassLoader(pluginRealm);
114
115 MavenSession oldSession = legacySupport.getSession();
116
117 scope.enter();
118
119 try {
120 scope.seed(MavenProject.class, project);
121 scope.seed(MojoExecution.class, mojoExecution);
122 scope.seed(
123 org.apache.maven.api.plugin.Log.class,
124 new DefaultLog(LoggerFactory.getLogger(
125 mojoExecution.getMojoDescriptor().getFullGoalName())));
126 InternalMavenSession sessionV4 = InternalMavenSession.from(session.getSession());
127 scope.seed(Project.class, sessionV4.getProject(project));
128 scope.seed(org.apache.maven.api.MojoExecution.class, new DefaultMojoExecution(sessionV4, mojoExecution));
129
130 if (mojoDescriptor.isV4Api()) {
131 org.apache.maven.api.plugin.Mojo mojoV4 = mavenPluginManager.getConfiguredMojo(
132 org.apache.maven.api.plugin.Mojo.class, session, mojoExecution);
133 mojo = new MojoWrapper(mojoV4);
134 } else {
135 mojo = mavenPluginManager.getConfiguredMojo(Mojo.class, session, mojoExecution);
136 }
137
138 legacySupport.setSession(session);
139
140
141
142
143 try {
144 MojoExecutionEvent mojoExecutionEvent = new MojoExecutionEvent(session, project, mojoExecution, mojo);
145 mojoExecutionListener.beforeMojoExecution(mojoExecutionEvent);
146 mojo.execute();
147 mojoExecutionListener.afterMojoExecutionSuccess(mojoExecutionEvent);
148 } catch (ClassCastException | MavenException e) {
149
150 throw e;
151 } catch (RuntimeException e) {
152 throw new PluginExecutionException(mojoExecution, project, e);
153 }
154 } catch (MavenException e) {
155 throw e;
156 } catch (PluginContainerException e) {
157 mojoExecutionListener.afterExecutionFailure(
158 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
159 throw new PluginExecutionException(mojoExecution, project, e);
160 } catch (NoClassDefFoundError e) {
161 mojoExecutionListener.afterExecutionFailure(
162 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
163 ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
164 PrintStream ps = new PrintStream(os);
165 ps.println(
166 "A required class was missing while executing " + mojoDescriptor.getId() + ": " + e.getMessage());
167 pluginRealm.display(ps);
168 Exception wrapper = new PluginContainerException(mojoDescriptor, pluginRealm, os.toString(), e);
169 throw new PluginExecutionException(mojoExecution, project, wrapper);
170 } catch (LinkageError e) {
171 mojoExecutionListener.afterExecutionFailure(
172 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
173 ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
174 PrintStream ps = new PrintStream(os);
175 ps.println("An API incompatibility was encountered while executing " + mojoDescriptor.getId() + ": "
176 + e.getClass().getName() + ": " + e.getMessage());
177 pluginRealm.display(ps);
178 Exception wrapper = new PluginContainerException(mojoDescriptor, pluginRealm, os.toString(), e);
179 throw new PluginExecutionException(mojoExecution, project, wrapper);
180 } catch (ClassCastException e) {
181 mojoExecutionListener.afterExecutionFailure(
182 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
183 ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
184 PrintStream ps = new PrintStream(os);
185 ps.println("A type incompatibility occurred while executing " + mojoDescriptor.getId() + ": "
186 + e.getMessage());
187 pluginRealm.display(ps);
188 throw new PluginExecutionException(mojoExecution, project, os.toString(), e);
189 } catch (RuntimeException e) {
190 mojoExecutionListener.afterExecutionFailure(
191 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
192 throw e;
193 } finally {
194 mavenPluginManager.releaseMojo(mojo, mojoExecution);
195 scope.exit();
196 Thread.currentThread().setContextClassLoader(oldClassLoader);
197 legacySupport.setSession(oldSession);
198 }
199 }
200
201
202
203
204
205
206 @Override
207 public ClassRealm getPluginRealm(MavenSession session, PluginDescriptor pluginDescriptor)
208 throws PluginResolutionException, PluginManagerException {
209 ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
210 if (pluginRealm != null) {
211 return pluginRealm;
212 }
213
214 mavenPluginManager.setupPluginRealm(pluginDescriptor, session, null, null, null);
215
216 return pluginDescriptor.getClassRealm();
217 }
218
219 @Override
220 public MojoDescriptor getMojoDescriptor(
221 Plugin plugin, String goal, List<RemoteRepository> repositories, RepositorySystemSession session)
222 throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
223 MojoNotFoundException, InvalidPluginDescriptorException {
224 return mavenPluginManager.getMojoDescriptor(plugin, goal, repositories, session);
225 }
226
227 private static class MojoWrapper implements Mojo {
228 private final org.apache.maven.api.plugin.Mojo mojoV4;
229
230 MojoWrapper(org.apache.maven.api.plugin.Mojo mojoV4) {
231 this.mojoV4 = mojoV4;
232 }
233
234 @Override
235 public void execute() throws MojoExecutionException {
236 try {
237 mojoV4.execute();
238 } catch (RuntimeException e) {
239 throw e;
240 } catch (Exception e) {
241 throw new MojoExecutionException(e);
242 }
243 }
244
245 @Override
246 public void setLog(Log log) {}
247
248 @Override
249 public Log getLog() {
250 return null;
251 }
252 }
253 }