View Javadoc

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