2010-04-17 3 views
30

Я пишу какой-то coge-gen maven-plugin.Добавить maven-build-classpath для выполнения плагина classpath

Мне нужно, чтобы мой путь к классу проекта был введен в мой путь к классу плагинов.

Я нашел это article. Решение там работает, но довольно долго. Может быть, кто-то из вас знает из коробки решение.

ответ

17

Найдено answer!

ОК, Паскаль прав, вот он для основания !!

Итак, это самый чистый способ (насколько я знаю), чтобы добавить компиляцию classpath к выполнению вашего плагина.

Вот несколько примеров кода из моего плагина code-gen, который фактически генерирует некоторый код шаблона на основе скомпилированного кода. Поэтому мне сначала нужно было скомпилировать код, затем проанализировать, сгенерировать некоторый код и затем скомпилировать его снова.

  1. Использование @configurator в классе 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.... 
        } 
    } 
    

    Пожалуйста, обратите внимание на @configurator линии в заголовке JavaDoc, это essetial для контейнера сплетение МОК и не просто строка комментария.

  2. Реализация конфигуратора include-project-dependencies. Это очень хороший класс, который я взял у какого-то Брайана Джексона, добавив его в источник вашего плагина.

    /** 
    * 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. Было бы неплохо объяснить или обобщить ссылку в вашем ответе. Это значительно повысило бы ценность вашего вопроса и вашего ответа для читателей IMHO. –

+0

Это решение, которое мне тоже нужно - я не могу его скомпилировать. Я думаю, что у меня неправильная версия некоторых классов. Интересно, можете ли вы также добавить соответствующие разделы вашего pom.xml к своему ответу. –

+3

Чтобы сделать 'project.runtimeClasspathElements' включать все транзитивные зависимости, вам необходимо аннотировать mojo с помощью' '@ requireDependencyResolution' '(http://maven.apache.org/developers/mojo-api-specification.html#The_Descriptor_and_Annotations). –

1

следовал этой ссылке .... сделал очень похожую вещь для моего кода ... я создал Maven-FIT-плагин я использовал именно такой же pom.xml для моего плагина, повторное использование IncludeProjectDependenciesComponentConfigurator

Я использую maven 2.2.0 , если это может помочь, вот ПОМ снова

<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 - это 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 List classpath;' – Stephan202

+1

Если вы используете это для поиска классов с использованием 'org.reflections.Reflections', вы захотите для создания экземпляра 'Reflections' с использованием:' new ConfigurationBuilder(). setUrls (ClasspathHelper.forClassLoader (contextClassLoader)) ' – CorayThan

Смежные вопросы