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 public PluginDescriptor loadPlugin(
85 Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session)
86 throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
87 InvalidPluginDescriptorException {
88 return mavenPluginManager.getPluginDescriptor(plugin, repositories, session);
89 }
90
91
92
93
94
95 public void executeMojo(MavenSession session, MojoExecution mojoExecution)
96 throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException {
97 MavenProject project = session.getCurrentProject();
98
99 MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
100
101 Mojo mojo = null;
102
103 ClassRealm pluginRealm;
104 try {
105 pluginRealm = getPluginRealm(session, mojoDescriptor.getPluginDescriptor());
106 } catch (PluginResolutionException e) {
107 throw new PluginExecutionException(mojoExecution, project, e);
108 }
109
110 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
111 Thread.currentThread().setContextClassLoader(pluginRealm);
112
113 MavenSession oldSession = legacySupport.getSession();
114
115 scope.enter();
116
117 try {
118 scope.seed(MavenProject.class, project);
119 scope.seed(MojoExecution.class, mojoExecution);
120 scope.seed(
121 org.apache.maven.api.plugin.Log.class,
122 new DefaultLog(LoggerFactory.getLogger(
123 mojoExecution.getMojoDescriptor().getFullGoalName())));
124 InternalMavenSession sessionV4 = InternalMavenSession.from(session.getSession());
125 scope.seed(Project.class, sessionV4.getProject(project));
126 scope.seed(org.apache.maven.api.MojoExecution.class, new DefaultMojoExecution(sessionV4, mojoExecution));
127
128 if (mojoDescriptor.isV4Api()) {
129 org.apache.maven.api.plugin.Mojo mojoV4 = mavenPluginManager.getConfiguredMojo(
130 org.apache.maven.api.plugin.Mojo.class, session, mojoExecution);
131 mojo = new MojoWrapper(mojoV4);
132 } else {
133 mojo = mavenPluginManager.getConfiguredMojo(Mojo.class, session, mojoExecution);
134 }
135
136 legacySupport.setSession(session);
137
138
139
140
141 try {
142 MojoExecutionEvent mojoExecutionEvent = new MojoExecutionEvent(session, project, mojoExecution, mojo);
143 mojoExecutionListener.beforeMojoExecution(mojoExecutionEvent);
144 mojo.execute();
145 mojoExecutionListener.afterMojoExecutionSuccess(mojoExecutionEvent);
146 } catch (ClassCastException | MavenException e) {
147
148 throw e;
149 } catch (RuntimeException e) {
150 throw new PluginExecutionException(mojoExecution, project, e);
151 }
152 } catch (MavenException e) {
153 throw e;
154 } catch (PluginContainerException e) {
155 mojoExecutionListener.afterExecutionFailure(
156 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
157 throw new PluginExecutionException(mojoExecution, project, e);
158 } catch (NoClassDefFoundError e) {
159 mojoExecutionListener.afterExecutionFailure(
160 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
161 ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
162 PrintStream ps = new PrintStream(os);
163 ps.println(
164 "A required class was missing while executing " + mojoDescriptor.getId() + ": " + e.getMessage());
165 pluginRealm.display(ps);
166 Exception wrapper = new PluginContainerException(mojoDescriptor, pluginRealm, os.toString(), e);
167 throw new PluginExecutionException(mojoExecution, project, wrapper);
168 } catch (LinkageError e) {
169 mojoExecutionListener.afterExecutionFailure(
170 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
171 ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
172 PrintStream ps = new PrintStream(os);
173 ps.println("An API incompatibility was encountered while executing " + mojoDescriptor.getId() + ": "
174 + e.getClass().getName() + ": " + e.getMessage());
175 pluginRealm.display(ps);
176 Exception wrapper = new PluginContainerException(mojoDescriptor, pluginRealm, os.toString(), e);
177 throw new PluginExecutionException(mojoExecution, project, wrapper);
178 } catch (ClassCastException e) {
179 mojoExecutionListener.afterExecutionFailure(
180 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
181 ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
182 PrintStream ps = new PrintStream(os);
183 ps.println("A type incompatibility occurred while executing " + mojoDescriptor.getId() + ": "
184 + e.getMessage());
185 pluginRealm.display(ps);
186 throw new PluginExecutionException(mojoExecution, project, os.toString(), e);
187 } catch (RuntimeException e) {
188 mojoExecutionListener.afterExecutionFailure(
189 new MojoExecutionEvent(session, project, mojoExecution, mojo, e));
190 throw e;
191 } finally {
192 mavenPluginManager.releaseMojo(mojo, mojoExecution);
193 scope.exit();
194 Thread.currentThread().setContextClassLoader(oldClassLoader);
195 legacySupport.setSession(oldSession);
196 }
197 }
198
199
200
201
202
203
204 public ClassRealm getPluginRealm(MavenSession session, PluginDescriptor pluginDescriptor)
205 throws PluginResolutionException, PluginManagerException {
206 ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
207 if (pluginRealm != null) {
208 return pluginRealm;
209 }
210
211 mavenPluginManager.setupPluginRealm(pluginDescriptor, session, null, null, null);
212
213 return pluginDescriptor.getClassRealm();
214 }
215
216 public MojoDescriptor getMojoDescriptor(
217 Plugin plugin, String goal, List<RemoteRepository> repositories, RepositorySystemSession session)
218 throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
219 MojoNotFoundException, InvalidPluginDescriptorException {
220 return mavenPluginManager.getMojoDescriptor(plugin, goal, repositories, session);
221 }
222
223 private static class MojoWrapper implements Mojo {
224 private final org.apache.maven.api.plugin.Mojo mojoV4;
225
226 MojoWrapper(org.apache.maven.api.plugin.Mojo mojoV4) {
227 this.mojoV4 = mojoV4;
228 }
229
230 @Override
231 public void execute() {
232 mojoV4.execute();
233 }
234
235 @Override
236 public void setLog(Log log) {}
237
238 @Override
239 public Log getLog() {
240 return null;
241 }
242 }
243 }