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