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