【问题标题】:Install modular maven project jars into the parent directory inside the local repository将模块化 maven 项目 jar 安装到本地存储库中的父目录中
【发布时间】:2019-04-08 08:52:27
【问题描述】:

我的项目结构如下:

parent (packing: pom)
    + framework (packing: jar)
    + plugins (packing: pom)
        + plugin_1 (packing: pom)
            + impl (packing: jar)
            + e2e_test (packing: jar)
        + plugin_2 (packing: pom)
            + impl (packing: jar)
            + e2e_test (packing: jar)

plugin_1.implplugin_2.impl 中,我有一个描述插件的resource.xml

构建很好,这意味着当我想构建它按顺序构建的整个项目时。 但是,安装无法创建相同的结构。 安装后本地存储库如下所示:

com/company
    + parent/version
        + pom file
    + framework/version
        + jars
    + plugins/version
        + pom file
    + plugin_1/version
        + pom file
    + plugin_1.impl/version
        + jar
    + plugin_1.e2e_tests/version
        + jar
    + plugin_2/version
        + pom file
    + plugin_2.impl/version
        + jar
    + plugin_2.e2e_tests/version
        + jar

但我想要:

com/company/parent/version
    + framework.jar
    + plugins
        + plugin_1.jar
        + plugin_1.xml (renamed resource.xml)
        + plugin_2.jar
        + plugin_2.xml (renamed resource.xml)

有没有办法创建所需的结构?

我试过maven-install-plugin 例如:

mvn org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file \
    -Dfile=parent/plugins/plugin_1/impl/resource.xml \
    -DgroupId=com.company \
    -DartifactId=parent \
    -Dversion=1.0-SNAPSHOT \
    -Dpackaging=file \
    -DgeneratePom=true

pom.xml 的等效项(但对于 jar):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-install-plugin</artifactId>
    <version>3.0.0-M1</version>
    <executions>
        <execution>
            <phase>install</phase>
            <goals>
                <goal>install-file</goal>
            </goals>
            <configuration>
                <groupId>${project.groupId}</groupId>
                <artifactId>${project.parent.parent.artifactId}</artifactId>
                <version>${project.version}</version>
                <packaging>jar</packaging>
                <file>${project.build.directory}/${project.build.finalName}.jar</file>
            </configuration>
        </execution>
    </executions>
</plugin>

但这总是会根据artifactId 重命名文件,我最终会覆盖同一个文件。

我能够通过在最高父级的目标目录中使用copy-rename-maven-plugin 创建所描述的结构。

我想要这个结构,因为:

  1. framework 可以使用任何 jar 放在 plugins 目录中并带有适当的描述符。
  2. 我不想每次重新编译或更改多个插件中的某些内容时都手动执行此操作。
  3. 模块的端到端测试通过在测试中调用framework plugin_1 (args) 并检查结果来工作。为此,我需要本地存储库中的工作结构供测试项目依赖。

有没有办法在本地存储库中创建所需的结构?

【问题讨论】:

  • 你不能将插件添加到你的框架 pom 并让它们驻留在你的框架代码之外?仅仅是因为您有测试项目,并且只想将依赖项添加到框架项目而不在测试项目POM中定义任何插件吗?
  • 我想单独保留插件代码。我颠倒了依赖关系,插件依赖于框架,而不是相反。这样,任何实现接口并具有适当描述符 xml 的 jar 都可以成为插件。而且您不必更改框架代码。端到端测试可以在另一个项目中。我不坚持将它们保留在插件 pom 项目下。它可以与框架处于同一级别。

标签: java maven maven-install-plugin


【解决方案1】:

看来你对Maven (local) repositories有几个方面的误解:

  1. 本地存储库是远程存储库中工件的缓存(尽管您不必将后者用于您创建的工件,如果您不必与他人共享它们)。
  2. 存储库旨在在构建时解决依赖关系,而不是在运行时
  3. 存储库中的完整路径标识具有特定版本的特定工件(JAR、WAR、EAR...或只是 POM),因为它的路径源自其 Maven Coordinates 及其标识三元组 GAV (groupIdartifactIdversion)。地点:

    <groupId>com.my.company</groupId>
    <artifactId>my-artifact</artifactId>
    <version>1.0.0</version>
    

    变成目录结构:

    ~/.m2/repositories
      + com
        + my
          + company
            + my-artifact
              + 1.0.0
                + my-artifact-1.0.0.jar  [or war, ear, ...]
                + my-artifact-1.0.0.pom
    

    不知道在运行时(测试)期间动态使用的 Maven 存储库(本地或远程)中工件的分层(子)结构中的依赖项(或 *.xml 等资源)。

    这就是为什么您在构建后会在同一级别 com/company 上看到所有工件(包括 install)。它们都是平等的。就 Maven 而言,它们中没有一个比另一个更受欢迎。

更新

可能的解决方案:

framework 和相应的插件实现作为依赖项添加到您的测试项目中,并相应地在测试代码中使用它们:

plugin_1.e2e_tests:

<dependency>
    <groupId>com.mycompany</groupId>
    <artifactId>framework</artifactId>
    <version>...</version>
</dependency>
<dependency>
    <groupId>com.mycompany</groupId>
    <artifactId>plugin_1.impl</artifactId>
    <version>...</version>
</dependency>

plugin_2.e2e_tests:

<dependency>
    <groupId>com.mycompany</groupId>
    <artifactId>framework</artifactId>
    <version>...</version>
</dependency>
<dependency>
    <groupId>com.mycompany</groupId>
    <artifactId>plugin_2.impl</artifactId>
    <version>...</version>
</dependency>

【讨论】:

  • 感谢您的回答!我想我没有误解 maven 本地存储库。误解源于maven的父子关系仅代表构建顺序,不能创建具有自动发现功能的插件式框架。您必须手动创建它。就其本身而言,这并不是世界末日,但我需要端到端测试。
  • 构建时间是什么意思?我知道java在编译时需要运行时依赖,但构建过程也包含测试阶段。
  • 关于 Maven 的父子关系你说得对。构建时间是指执行mvn install 或一般mvn &lt;phase&gt;
  • 此时我无法摆脱我试图滥用maven的感觉。 “无法创建相同的结构”是指我不能偏离默认行为。
  • 当我第一次阅读您的问题时,我也想到了这一点。 ;)
【解决方案2】:

Maven 本地存储库具有固定的目录结构。不应更改此结构。它反映了 Maven 坐标(groupId、artifactId、version)。

【讨论】:

  • 感谢您的回答!不幸的是,这是真的。无论如何,项目都不能偏离默认行为。其他一切都只是黑客行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 2019-03-09
相关资源
最近更新 更多