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 }