2010-04-17 48 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

相关问题