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