2010-04-17 105 views

回答

17

找到了answer

好的,帕斯卡是對的,這裏是基礎!

所以這裏是最乾淨的方式(據我所知)將編譯類路徑添加到您的插件的執行。

下面是我的code-gen插件的一些代碼示例,它實際上是基於編譯的代碼生成一些模板代碼。所以我首先需要編譯代碼,然後進行分析,生成一些代碼,然後再次編譯。

  1. 使用@configurator在魔類:

    /** 
    * @goal generate 
    * @phase process-classes 
    * @configurator include-project-dependencies 
    * @requiresDependencyResolution compile+runtime 
    */ 
    public class CodeGenMojo 
         extends AbstractMojo 
    { 
        public void execute() 
          throws MojoExecutionException 
        { 
         // do work.... 
        } 
    } 
    

    請注意在Javadoc頭的@configurator線,它是essetial爲叢IOC容器不只是一個註釋行。

  2. 執行include-project-dependencies配置程序。我從Brian Jackson那裏拿到了這個非常好的課程,並將它添加到你的插件的源代碼中。

    /** 
    * A custom ComponentConfigurator which adds the project's runtime classpath elements 
    * to the 
    * 
    * @author Brian Jackson 
    * @since Aug 1, 2008 3:04:17 PM 
    * 
    * @plexus.component role="org.codehaus.plexus.component.configurator.ComponentConfigurator" 
    *     role-hint="include-project-dependencies" 
    * @plexus.requirement role="org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup" 
    *     role-hint="default" 
    */ 
    public class IncludeProjectDependenciesComponentConfigurator extends AbstractComponentConfigurator { 
    
        private static final Logger LOGGER = Logger.getLogger(IncludeProjectDependenciesComponentConfigurator.class); 
    
        public void configureComponent(Object component, PlexusConfiguration configuration, 
                ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm, 
                ConfigurationListener listener) 
         throws ComponentConfigurationException { 
    
         addProjectDependenciesToClassRealm(expressionEvaluator, containerRealm); 
    
         converterLookup.registerConverter(new ClassRealmConverter(containerRealm)); 
    
         ObjectWithFieldsConverter converter = new ObjectWithFieldsConverter(); 
    
         converter.processConfiguration(converterLookup, component, containerRealm.getClassLoader(), configuration, 
                 expressionEvaluator, listener); 
        } 
    
        private void addProjectDependenciesToClassRealm(ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm) throws ComponentConfigurationException { 
         List<String> runtimeClasspathElements; 
         try { 
          //noinspection unchecked 
          runtimeClasspathElements = (List<String>) expressionEvaluator.evaluate("${project.runtimeClasspathElements}"); 
         } catch (ExpressionEvaluationException e) { 
          throw new ComponentConfigurationException("There was a problem evaluating: ${project.runtimeClasspathElements}", e); 
         } 
    
         // Add the project dependencies to the ClassRealm 
         final URL[] urls = buildURLs(runtimeClasspathElements); 
         for (URL url : urls) { 
          containerRealm.addConstituent(url); 
         } 
        } 
    
        private URL[] buildURLs(List<String> runtimeClasspathElements) throws ComponentConfigurationException { 
         // Add the projects classes and dependencies 
         List<URL> urls = new ArrayList<URL>(runtimeClasspathElements.size()); 
         for (String element : runtimeClasspathElements) { 
          try { 
           final URL url = new File(element).toURI().toURL(); 
           urls.add(url); 
           if (LOGGER.isDebugEnabled()) { 
            LOGGER.debug("Added to project class loader: " + url); 
           } 
          } catch (MalformedURLException e) { 
           throw new ComponentConfigurationException("Unable to access project dependency: " + element, e); 
          } 
         } 
    
         // Add the plugin's dependencies (so Trove stuff works if Trove isn't on 
         return urls.toArray(new URL[urls.size()]); 
        } 
    
    } 
    
  3. 這是我的插件的構建部分,你將不得不添加。

    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.delver</groupId> 
    <artifactId>reference-gen-plugin</artifactId> 
    <name>Reference Code Genration Maven Plugin</name> 
    
    <packaging>maven-plugin</packaging> 
    <version>1.2</version> 
    
    <url>http://maven.apache.org</url> 
    
    <properties> 
        <maven.version>2.2.1</maven.version> 
    </properties> 
    
    <build> 
        <plugins> 
         <plugin> 
          <groupId>org.codehaus.plexus</groupId> 
          <artifactId>plexus-maven-plugin</artifactId> 
          <executions> 
           <execution> 
            <goals> 
             <goal>descriptor</goal> 
            </goals> 
           </execution> 
          </executions> 
         </plugin> 
        </plugins> 
    </build> 
    <dependencies> 
    
        <dependency> 
         <groupId>org.apache.maven</groupId> 
         <artifactId>maven-artifact</artifactId> 
         <version>${maven.version}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.apache.maven</groupId> 
         <artifactId>maven-plugin-api</artifactId> 
         <version>${maven.version}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.apache.maven</groupId> 
         <artifactId>maven-project</artifactId> 
         <version>${maven.version}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.apache.maven</groupId> 
         <artifactId>maven-model</artifactId> 
         <version>${maven.version}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.apache.maven</groupId> 
         <artifactId>maven-core</artifactId> 
         <version>2.0.9</version> 
        </dependency> 
    
    </dependencies> 
    

    這裏是插件的這些誰需要它的pom.xml。現在應該編譯沒有問題。 (有毛病的頭,所以忽略它)

+1

+1沒錯,就是去AFAIK的方式。儘管解釋或總結答案中的鏈接會很好。這將大大提高你的問題的價值和你的答案爲讀者恕我直言。 – 2010-04-17 17:49:17

+0

這也是我需要的解決方案 - 雖然我無法編譯它。 我想我有一些類的錯誤版本。 我不知道你是否可以將你的pom.xml的相關部分添加到你的答案中。 – 2010-04-21 16:18:36

+3

要使'project.runtimeClasspathElements'包含所有傳遞依賴項,您需要使用['@ requiresDependencyResolution'](http://maven.apache.org/developers/mojo-api-specification.html#The_Descriptor_and_Annotations)對註釋進行註釋。 – 2012-07-11 14:28:13

1

遵循此鏈接....做了非常類似的事情,我的代碼...我創建我有完全使用Maven的裝修插件 相同的pom.xml爲我的插件,重新使用IncludeProjectDependenciesComponentConfigurator

我使用maven 2.2。0 如果它可以幫助,這裏的POM再次

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/maven-v4_0_0.xsd"> 

<modelVersion>4.0.0</modelVersion> 
<groupId>com.worldcorpservices.plugins</groupId> 
<artifactId>maven-fit-plugin</artifactId> 
<packaging>maven-plugin</packaging> 
<version>1.0-SNAPSHOT</version> 
<name>maven-fit-plugin Maven Mojo</name> 
<url>http://maven.apache.org</url> 

<properties> 
    <fitlibrary.version>2.0</fitlibrary.version> 
    <maven.version>2.2.0</maven.version> 
</properties> 


<dependencies> 
    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-plugin-api</artifactId> 
     <version>2.0</version> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.7</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>commons-logging</groupId> 
     <artifactId>commons-logging</artifactId> 
     <version>1.1.1</version> 
    </dependency> 

    <dependency> 
     <groupId>org.fitnesse</groupId> 
     <artifactId>fitlibrary</artifactId> 
     <version>${fitlibrary.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>log4j</groupId> 
     <artifactId>log4j</artifactId> 
     <version>1.2.12</version> 
    </dependency> 
    <dependency> 
     <groupId>poi</groupId> 
     <artifactId>poi</artifactId> 
     <version>3.7-20101029</version> 
    </dependency> 

    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-artifact</artifactId> 
     <version>${maven.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-plugin-api</artifactId> 
     <version>${maven.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-project</artifactId> 
     <version>${maven.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-model</artifactId> 
     <version>${maven.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-core</artifactId> 
     <version>2.0.9</version> 
    </dependency> 


</dependencies> 
<build> 

希望這有助於

RGDS 馬爾科

<plugins> 
     <plugin> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <configuration> 
       <source>1.6</source> 
       <target>1.6</target> 
      </configuration> 
     </plugin> 
     <plugin> 
      <groupId>org.codehaus.plexus</groupId> 
      <artifactId>plexus-maven-plugin</artifactId> 
      <executions> 
       <execution> 
        <goals> 
         <goal>descriptor</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 


    </plugins> 

</build> 

16

我採取這種做法,顯然它的工作:

1 - MavenProject參數是nee DED你的Mojo類中:

@Parameter(defaultValue = "${project}", required = true, readonly = true) 
private MavenProject project; 

2 - 然後你可以從工程實例的路徑元素:

try { 
    Set<URL> urls = new HashSet<>(); 
    List<String> elements = project.getTestClasspathElements(); 
            //getRuntimeClasspathElements() 
            //getCompileClasspathElements() 
            //getSystemClasspathElements() 
    for (String element : elements) { 
     urls.add(new File(element).toURI().toURL()); 
    } 

    ClassLoader contextClassLoader = URLClassLoader.newInstance(
      urls.toArray(new URL[0]), 
      Thread.currentThread().getContextClassLoader()); 

    Thread.currentThread().setContextClassLoader(contextClassLoader); 

} catch (DependencyResolutionRequiredException e) { 
    throw new RuntimeException(e); 
} catch (MalformedURLException e) { 
    throw new RuntimeException(e); 
} 
+5

+1。除了通過'MavenProject'字段訪問類路徑元素外,還可以要求元素立即被注入,例如, '@Parameter(property =「project.compileClasspathElements」,required = true,readonly = true)private列表 classpath;' – Stephan202 2013-09-07 19:34:03

+1

如果您正在使用'org.reflections.Reflections'來掃描類,您需要使用新實例化'Reflections':new ConfigurationBuilder()。setUrls(ClasspathHelper.forClassLoader(contextClassLoader))' – CorayThan 2015-01-19 06:03:25