将 maven-build-classpath 添加到插件执行类路径

发布于 2024-08-29 14:07:43 字数 218 浏览 3 评论 0原文

我正在编写一些代码生成 maven-plugin。

我需要将我的项目类路径注入到我的插件执行类路径中。

我找到了这篇文章。那里的解决方案有效,但相当长。也许你们中有人知道开箱即用的解决方案。

I am writing some code-gen maven-plugin.

I need my project classpath be injected in to my plugin execution classpath.

I found this article. The solution there works but is quite long. Maybe someone of you know an out of the box solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

羅雙樹 2024-09-05 14:07:43

找到了 答案

好吧,帕斯卡是对的,这是基础!!

所以这是将编译类路径添加到插件执行中的最干净的方法(据我所知)。

以下是我的 code-gen 插件中的一些代码示例,它实际上是根据编译的代码生成一些模板代码。所以我需要首先编译代码,然后分析,生成一些代码,然后再次编译。

  1. 在Mojo类中使用@configurator

    <前><代码>/**
    * @目标生成
    * @phase过程类
    * @configurator 包含项目依赖项
    * @requiresDependencyResolution 编译+运行时
    */
    公共类 CodeGenMojo
    扩展 AbstractMojo
    {
    公共无效执行()
    抛出 MojoExecutionException
    {
    // 做工作....
    }
    }

    请注意javadoc头中的@configurator行,它对于plexus IOC容器来说是必需的,而不仅仅是另一个注释行。

  2. include-project-dependencies 配置器的实现。我从 Brian Jackson 那里得到了一个非常好的课程,将其添加到您的插件的源代码中。

    <前><代码>/**
    * 自定义 ComponentConfigurator 添加项目的运行时类路径元素
    * 到
    *
    * @作者布莱恩·杰克逊
    * @自 2008 年 8 月 1 日下午 3:04:17 起
    *
    * @plexus.component角色=“org.codehaus.plexus.component.configurator.ComponentConfigurator”
    * 角色提示=“包含项目依赖项”
    * @plexus.requirement角色=“org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup”
    * 角色提示=“默认”
    */
    公共类 IncludeProjectDependencyComponentConfigurator 扩展 AbstractComponentConfigurator {

    私有静态最终 Logger LOGGER = Logger.getLogger(InincludeProjectDependencyComponentConfigurator.class);

    public void configureComponent( 对象组件, PlexusConfiguration 配置,
    ExpressionEvaluator 表达式Evaluator、ClassRealm 容器Realm、
    ConfigurationListener监听器)
    抛出 ComponentConfigurationException {

    addProjectDependencyToClassRealm(表达式Evaluator,containerRealm);

    converterLookup.registerConverter(新的ClassRealmConverter(containerRealm));

    ObjectWithFieldsConverter 转换器 = new ObjectWithFieldsConverter();

    converter.processConfiguration(converterLookup,组件,containerRealm.getClassLoader(),配置,
    表达式评估器、监听器);
    }

    私人无效addProjectDependencyToClassRealm(ExpressionEvaluator表达式Evaluator,ClassRealm容器Realm)抛出ComponentConfigurationException {
    列表<字符串>运行时类路径元素;
    尝试 {
    //noinspection 未选中
    runtimeClasspathElements = (List) expressionEvaluator.evaluate("${project.runtimeClasspathElements}");
    } catch (ExpressionEvaluationException e) {
    throw new ComponentConfigurationException("评估时出现问题:${project.runtimeClasspathElements}", e);
    }

    // 将项目依赖添加到ClassRealm中
    最终 URL[] urls = buildURLs(runtimeClasspathElements);
    for (URL url : urls) {
    containerRealm.addConstituent(url);
    }
    }

    私有 URL[] buildURLs(ListruntimeClasspathElements) 抛出 ComponentConfigurationException {
    // 添加项目类和依赖项
    列表urls = new ArrayList(runtimeClasspathElements.size());
    for (字符串元素:runtimeClasspathElements) {
    尝试 {
    最终 URL url = new File(element).toURI().toURL();
    urls.add(url);
    如果(LOGGER.isDebugEnabled()){
    LOGGER.debug("已添加到项目类加载器:" + url);
    }
    } catch (MalformedURLException e) {
    throw new ComponentConfigurationException("无法访问项目依赖项:" + element, e);
    }
    }

    // 添加插件的依赖项(这样如果 Trove 没有打开,Trove 的东西就可以工作)
    return urls.toArray(new URL[urls.size()]);
    }

    }

  3. 这是我的插件的构建部分,您必须添加它。

    <模型版本>4.0.0
    com.delver;
    reference-gen-plugin;
    <名称>参考代码生成 Maven 插件
    
    <打包>maven-plugin
    <版本>1.2
    
    http://maven.apache.org
    
    <属性>
        2.2.1
    
    
    <构建>
        <插件>
            <插件>
                org.codehaus.plexus
                plexus-maven-plugin;
                <处决>
                    <执行>
                        <目标>
                            <目标>描述符
                        
                    
                
            
        
    
    <依赖关系>
    
        <依赖关系>
            org.apache.maven;
            maven-artifact;
            <版本>${maven.version}
        
        <依赖关系>
            org.apache.maven;
            maven-plugin-api;
            <版本>${maven.version}
        
        <依赖关系>
            org.apache.maven;
            maven-project;
            <版本>${maven.version}
        
        <依赖关系>
            org.apache.maven;
            maven-model;
            <版本>${maven.version};
        
        <依赖关系>
            org.apache.maven;
            maven-core;
            <版本>2.0.9
        
    
    
    

    这里是插件的pom.xml,供需要的人使用。现在编译应该没有问题了。 (标题有问题,所以忽略它)

Found the answer!

OK , Pascal is right , here it is for the foundation!!

So here is the cleanest way ( as far as i know ) to add the compile classpath to the execution of you plugin.

Here are some code samples from my code-gen plugin, that is actually generating some template code based on the code compiled. So I needed first the code compiled, then analyzed, generate some code, and then compiled again.

  1. Use @configurator in the Mojo class:

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

    Please pay attention to the @configurator line in the javadoc header, it is essetial for the plexus IOC container and is not just another comment line.

  2. The implementation of the include-project-dependencies configurator. There is this very nice class that I took from some Brian Jackson, add it to the source of your plugin.

    /**
     * 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. Here is the build part of my plugin that you will have to add.

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

    Here is the pom.xml of the plugin for these who need it. Should compile wihtout a problem now. ( something wrong with the header, so ignore it )

乖不如嘢 2024-09-05 14:07:43

我采用了这种方法,显然它有效:

1 - Mojo 类中需要 MavenProject 参数:

@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);
}

I took this approach and apparently it's working:

1 - a MavenProject parameter is needed within your Mojo class:

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

2 - and then you can get the classpath elements from project instance:

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);
}
对风讲故事 2024-09-05 14:07:43

按照此链接...对我的代码做了非常相似的事情...我创建了一个 maven-fit-plugin
我为我的插件使用了完全相同的 pom.xml,重用了 IncludeProjectDependencyComponentConfigurator

我正在使用 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>

followed this link.... did very similar thing for my code... i have created a maven-fit-plugin
I have used exactly the same pom.xml for my plugin, reusing the IncludeProjectDependenciesComponentConfigurator

I am using maven 2.2.0
if it can help, here's pom again

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

hope this helps

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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文