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