View Javadoc

1   package org.apache.maven.plugin;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
5    * agreements. See the NOTICE file distributed with this work for additional information regarding
6    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance with the License. You may obtain a
8    * copy of the License at
9    * 
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software distributed under the License
13   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14   * or implied. See the License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  
18  import java.io.ByteArrayOutputStream;
19  import java.io.PrintStream;
20  import java.util.List;
21  
22  import org.apache.maven.execution.MavenSession;
23  import org.apache.maven.model.Plugin;
24  import org.apache.maven.plugin.descriptor.MojoDescriptor;
25  import org.apache.maven.plugin.descriptor.PluginDescriptor;
26  import org.apache.maven.project.MavenProject;
27  import org.codehaus.plexus.PlexusContainer;
28  import org.codehaus.plexus.classworlds.realm.ClassRealm;
29  import org.codehaus.plexus.component.annotations.Component;
30  import org.codehaus.plexus.component.annotations.Requirement;
31  import org.sonatype.aether.RepositorySystemSession;
32  import org.sonatype.aether.repository.RemoteRepository;
33  
34  // TODO: the antrun plugin has its own configurator, the only plugin that does. might need to think about how that works
35  // TODO: remove the coreArtifactFilterManager
36  
37  @Component(role = BuildPluginManager.class)
38  public class DefaultBuildPluginManager
39      implements BuildPluginManager
40  {
41  
42      @Requirement
43      private PlexusContainer container;
44  
45      @Requirement
46      private MavenPluginManager mavenPluginManager;
47  
48      @Requirement
49      private LegacySupport legacySupport;
50  
51      /**
52       * 
53       * @param plugin
54       * @param repositoryRequest
55       * @return PluginDescriptor The component descriptor for the Maven plugin.
56       * @throws PluginNotFoundException The plugin could not be found in any repositories.
57       * @throws PluginResolutionException The plugin could be found but could not be resolved.
58       * @throws InvalidPluginDescriptorException 
59       */
60      public PluginDescriptor loadPlugin( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
61          throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException
62      {
63          return mavenPluginManager.getPluginDescriptor( plugin, repositories, session );
64      }
65  
66      // ----------------------------------------------------------------------
67      // Mojo execution
68      // ----------------------------------------------------------------------
69  
70      public void executeMojo( MavenSession session, MojoExecution mojoExecution )
71          throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException
72      {
73          MavenProject project = session.getCurrentProject();
74  
75          MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
76  
77          Mojo mojo = null;
78  
79          ClassRealm pluginRealm;
80          try
81          {
82              pluginRealm = getPluginRealm( session, mojoDescriptor.getPluginDescriptor() );
83          }
84          catch ( PluginResolutionException e )
85          {
86              throw new PluginExecutionException( mojoExecution, project, e );
87          }
88  
89          ClassRealm oldLookupRealm = container.getLookupRealm();
90          ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
91  
92          MavenSession oldSession = legacySupport.getSession();
93  
94          try
95          {
96              mojo = mavenPluginManager.getConfiguredMojo( Mojo.class, session, mojoExecution );
97  
98              Thread.currentThread().setContextClassLoader( pluginRealm );
99  
100             legacySupport.setSession( session );
101 
102             // NOTE: DuplicateArtifactAttachmentException is currently unchecked, so be careful removing this try/catch!
103             // This is necessary to avoid creating compatibility problems for existing plugins that use
104             // MavenProjectHelper.attachArtifact(..).
105             try
106             {
107                 mojo.execute();
108             }
109             catch ( ClassCastException e )
110             {
111                 // to be processed in the outer catch block
112                 throw e;
113             }
114             catch ( RuntimeException e )
115             {
116                 throw new PluginExecutionException( mojoExecution, project, e );
117             }
118         }
119         catch ( PluginContainerException e )
120         {
121             throw new PluginExecutionException( mojoExecution, project, e );
122         }
123         catch ( NoClassDefFoundError e )
124         {
125             ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
126             PrintStream ps = new PrintStream( os );
127             ps.println( "A required class was missing while executing " + mojoDescriptor.getId() + ": "
128                 + e.getMessage() );
129             pluginRealm.display( ps );
130 
131             Exception wrapper = new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), e );
132 
133             throw new PluginExecutionException( mojoExecution, project, wrapper );
134         }
135         catch ( LinkageError e )
136         {
137             ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
138             PrintStream ps = new PrintStream( os );
139             ps.println( "An API incompatibility was encountered while executing " + mojoDescriptor.getId() + ": "
140                 + e.getClass().getName() + ": " + e.getMessage() );
141             pluginRealm.display( ps );
142 
143             Exception wrapper = new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), e );
144 
145             throw new PluginExecutionException( mojoExecution, project, wrapper );
146         }
147         catch ( ClassCastException e )
148         {
149             ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
150             PrintStream ps = new PrintStream( os );
151             ps.println( "A type incompatibility occured while executing " + mojoDescriptor.getId() + ": "
152                 + e.getMessage() );
153             pluginRealm.display( ps );
154 
155             throw new PluginExecutionException( mojoExecution, project, os.toString(), e );
156         }
157         finally
158         {
159             mavenPluginManager.releaseMojo( mojo, mojoExecution );
160 
161             if ( oldLookupRealm != null )
162             {
163                 container.setLookupRealm( null );
164             }
165 
166             Thread.currentThread().setContextClassLoader( oldClassLoader );
167 
168             legacySupport.setSession( oldSession );
169         }
170     }
171 
172     /**
173      * TODO pluginDescriptor classRealm and artifacts are set as a side effect of this
174      *      call, which is not nice.
175      * @throws PluginResolutionException 
176      */
177     public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) 
178         throws PluginResolutionException, PluginManagerException
179     {
180         ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
181         if ( pluginRealm != null )
182         {
183             return pluginRealm;
184         }
185 
186         mavenPluginManager.setupPluginRealm( pluginDescriptor, session, session.getCurrentProject().getClassRealm(),
187                                              null, null );
188 
189         return pluginDescriptor.getClassRealm();
190     }
191 
192     public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories,
193                                              RepositorySystemSession session )
194         throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
195         MojoNotFoundException, InvalidPluginDescriptorException
196     {
197         return mavenPluginManager.getMojoDescriptor( plugin, goal, repositories, session );
198     }
199 
200 }