2010-04-17 11 views

Respuesta

17

Encontrado el answer!

OK, Pascal tiene razón, aquí está para la fundación !!

Así que aquí está la manera más limpia (hasta donde yo sé) para agregar el classpath de compilación a la ejecución de su plugin.

Aquí hay algunos ejemplos de código de mi plugin code-gen, que en realidad está generando algún código de plantilla basado en el código compilado. Así que primero necesitaba compilar el código, luego analizarlo, generar código y luego volver a compilarlo.

  1. Uso @configurator en la clase Mojo:

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

    preste atención a la línea @configurator en la cabecera Javadoc, es essetial para el contenedor del plexo COI y no es más que otra línea de comentario.

  2. La implementación del configurador include-project-dependencies. Esta es una clase muy buena que tomé de Brian Jackson y la agregué a la fuente de tu complemento.

    /** 
    * 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. Aquí es la parte de construcción de mi plugin que tendrá que añadir.

    <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> 
    

    Aquí es el pom.xml del plugin para éstos que lo necesitan. Debe compilar sin un problema ahora. (Algo incorrecto en la cabecera, por lo ignorarlo)

+1

+1 Sí, ese es el camino a seguir yo sepa. Sin embargo, sería bueno explicar o resumir el enlace en tu respuesta. Eso mejoraría en gran medida el valor de su pregunta y su respuesta para los lectores en mi humilde opinión. –

+0

Esta es la solución que necesito también, pero no puedo hacer que compile. Creo que tengo la versión incorrecta de algunas de las clases. Me pregunto si podría agregar las secciones relevantes de su pom.xml a su respuesta también, por favor. –

+3

Para que 'project.runtimeClasspathElements' incluya todas las dependencias transitivas, debe anotar el mojo con [' @ requiresDependencyResolution'] (http://maven.apache.org/developers/mojo-api-specification.html#The_Descriptor_and_Annotaciones). –

1

siguieron este enlace .... hicieron algo muy similar para mi código ... he creado un experto-fit-plugin he utilizado exactamente el mismo pom.xml para mi complemento, reutilizando el IncludeProjectDependenciesComponentConfigurator

Estoy usando maven 2.2.0 si puede ayudar, aquí está pom esperanza de nuevo

<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> 

esto ayuda

rgds Marco

<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

Tomé este enfoque y al parecer está funcionando:

1 - un parámetro de MavenProject es necesario DED dentro de su clase Mojo:

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

2 - y entonces se puede obtener los elementos de ruta de clases de ejemplo de proyecto:

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. En lugar de acceder a los elementos classpath a través del campo 'MavenProject', también se puede pedir que los elementos se inyecten de inmediato, p. '@Parameter (property =" project.compileClasspathElements ", required = true, readonly = true) private List classpath;' – Stephan202

+1

Si está utilizando esto para buscar clases utilizando 'org.reflections.Reflections', querrá para instanciar 'Reflections' usando:' new ConfigurationBuilder(). setUrls (ClasspathHelper.forClassLoader (contextClassLoader)) ' – CorayThan

Cuestiones relacionadas