【问题标题】:How to let plugin execution inherit project dependencies with MavenMaven如何让插件执行继承项目依赖
【发布时间】:2013-12-17 15:00:04
【问题描述】:

我正在使用 Maven,我想在不重复某些必需依赖项的情况下执行插件:

<build>
<plugins>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>sql-maven-plugin</artifactId>
    <version>1.5</version>

    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.168</version>
        </dependency>
        <!-- ^^^ unnecessary duplication, IMO, because the project
                 already imports the dependency below -->
    </dependencies>

    <!-- ... -->
</plugin>
</plugins>
</build>

<dependencies>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.3.168</version>
    </dependency>
</dependencies>

在上面的例子中,我想省略 com.h2database:h2 依赖,因为我已经在项目中指定了它。这可以做到吗?怎么样?

【问题讨论】:

  • 嗨,卢卡斯。这是一个小世界。我正在为我的课程中的数据库模块编写 Flyway 课程,我对org.flywaydb:flyway-maven-plugin:5.0.7 有同样的问题:如果项目已经在主项目中使用了,例如,org.postgresql:postgresql:42.2.2(很可能),为什么我是否需要为 Flyway 架构迁移插件再次指定它?如果您找到答案,请告诉我。现在我将在课程中指出必须在两个地方都列出依赖项。干杯!
  • @GarretWilson:您好 :) 据我所知,Flyway 插件(就像 jOOQ 插件一样)可以访问项目的类路径以发现 JDBC 驱动程序。这里的这个问题是关于sql-maven-plugin,它不这样做。开箱即用,Maven 不支持这种依赖“继承”机制。我认为您最好创建一个新问题...
  • 哦,你的意思是我不需要在 Flyway 插件依赖部分指定 JDBC 驱动,如果项目已经在主依赖中有 JDBC 驱动?
  • @GarretWilson:没错。请参阅此示例:github.com/jOOQ/jOOQ/blob/version-3.10.6/jOOQ-examples/…

标签: java maven dependencies maven-plugin


【解决方案1】:

您可以像这样使用父级中的 pluginManagement 块来做到这一点:

<pluginManagement>
  <plugins>
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>sql-maven-plugin</artifactId>
    <version>1.5</version>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.168</version>
        </dependency>
    </dependencies>
  </plugin> 
  </plugins>
</pluginManagement>

在您的孩子中,您只需要像这样使用执行:

 <build>
  <plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>sql-maven-plugin</artifactId>
        <executions>
          <execution>
           ....
          </execution>
        </executions>
    </plugin>
  </plugins>
 </build>

这将解决您仅在一个地方维护补充类路径依赖项 (h2) 的问题。

【讨论】:

  • 好的,如果我有 10 个模块都使用同一个插件,那会有所帮助。但是我的设置更像是我有一个依赖于 H2 的模块,然后,有 3 个插件也使用相同的 H2 依赖...
  • 您的意思是不是 plugins 的其他模块使用的依赖项?如果是,您可以使用dependencyManagement。
  • 我已经更新了问题。我的意思是该插件是从一个已经声明了 H2 依赖项的项目中调用的。我想在不重新声明该依赖项的情况下调用插件(在该特定项目中)
  • 这是两个不同的东西。声明一个依赖项并将依赖项用作插件的类路径元素。
  • 所以不可能?
【解决方案2】:

虽然插件不会自动从包含它们的模块/项目中继承依赖项 (see khmarbaise's answer),但插件作者仍然可以以模块/项目类路径可用的方式实现其插件插件也是如此。例如,Flyway migration pluginjOOQ 代码生成器就是这样做的。

如何在插件中完成此操作的一个示例是:

@Mojo
public class Plugin extends AbstractMojo {

    @Parameter(property = "project", required = true, readonly = true)
    private MavenProject project;

    @Override
    public void execute() throws MojoExecutionException {
        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();

        try {
            Thread.currentThread().setContextClassLoader(getClassLoader());
            // Plugin logic
        }
        finally {
            Thread.currentThread().setContextClassLoader(oldCL);
        }
    }

    @SuppressWarnings("unchecked")
    private ClassLoader getClassLoader() throws MojoExecutionException {
        try {
            List<String> classpathElements = project.getRuntimeClasspathElements();
            URL urls[] = new URL[classpathElements.size()];

            for (int i = 0; i < urls.length; i++)
                urls[i] = new File(classpathElements.get(i)).toURI().toURL();

            return new URLClassLoader(urls, getClass().getClassLoader());
        }
        catch (Exception e) {
            throw new MojoExecutionException("Couldn't create a classloader.", e);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多