Maven 程序集:添加同一工件的不同版本

Posted

技术标签:

【中文标题】Maven 程序集:添加同一工件的不同版本【英文标题】:Maven assembly : add different version of the same artifact 【发布时间】:2011-05-17 18:53:48 【问题描述】:

我使用 maven 程序集插件创建我的应用程序存档。 我的 pom 中存在的所有依赖项都包含在内,没有任何问题。

现在我需要包含同一工件的两个或多个版本。

如果我在我的 pom 中放了

<dependencies>
        [...]
        <dependency>
            <groupId>db.test</groupId>
            <artifactId>my-model</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>db.test</groupId>
            <artifactId>my-model</artifactId>
            <version>1.1.0</version>
        </dependency>
</dependencies>

从源代码中,dependenvcy 解析器删除旧版本,存档中仅打包 1.1.0

我尝试通过使用程序集 xml 描述符文件来包含 jar。我没有找到任何解决方案。

一种可能的解决方案是将所有需要的 model.jar 手动放入一个文件夹中,并告诉程序集将其复制到存档中。但我正在寻找更可配置的解决方案。

有什么想法吗?

【问题讨论】:

不用担心需要/冲突/.. 其他任何事情。 【参考方案1】:

Maven 假设一次拥​​有多个版本的模块没有任何意义。它假定新版本替换旧版本。如果不是,则不是同一个模块。我建议你给新的模块起一个不同的名字,并确保它有不同的包,以避免选择随机模块。

总的来说,Maven 试图鼓励良好的应用程序设计,并故意让其被认为是坏主意的事情变得困难。

【讨论】:

这个 jar 有不同的类和不同的包名。它们将通过使用 ServiceLoader 来加载以构建不同的 xml 模型以保持兼容性。我认为就我而言,这不是一个坏习惯。我会尝试看看是否可以在每个版本上更改名称并且不会无聊。 如果您要同时使用这两个名称,我会担保名称更改两个。 当然可以!一切都不一样,只有 groupeid 和 artifactid 相同。 我们需要在我们的发行版中发布多个不同版本的数据库驱动程序,以便我们的应用程序可以支持不同的旧版本和当前版本的数据库。它们都是相同的 groupId:artifactId 但版本不同。我们当然会将它们打包在 .zip 中的单独子目录中。但是 maven 不应该假设这么多,而不考虑每个用例。 创建 maven 的原因是,您需要为 Java 构建指定太多细节,以至于手动完成所有事情是无法管理的——这就是 ant 对您的要求。因此,maven always 按照设计假设。只是,它也(几乎)总是有办法改变它假设的每一个可能的默认值。【参考方案2】:

另一个丑陋的解决方案可能是使用 WAR 文件覆盖,利用这种机制在应用覆盖时不注意组件 JAR 文件的版本这一事实。

【讨论】:

【参考方案3】:

我通过使用 maven-dependency-plugin 复制已解决的 pom 依赖项和其他 jar 找到了解决方案。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
    <execution>
        <id>copy-dependencies</id>
        <phase>package</phase>
        <goals>
            <goal>copy-dependencies</goal>
        </goals>
        <configuration>
            <outputDirectory>$project.build.directory/lib</outputDirectory>
            <overWriteReleases>false</overWriteReleases>
            <overWriteSnapshots>false</overWriteSnapshots>
            <overWriteIfNewer>true</overWriteIfNewer>
            <includeScope>runtime</includeScope>
        </configuration>
    </execution>
    <execution>
        <id>copy-model</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>my.test.pkg</groupId>
                    <artifactId>my-model</artifactId>
                    <classifier>server</classifier>
                    <version>1.0.3</version>
                    <type>jar</type>
                </artifactItem>
                <artifactItem>
                    <groupId>my.test.pkg</groupId>
                    <artifactId>my-model</artifactId>
                    <classifier>server</classifier>
                    <version>1.1.0</version>
                    <type>jar</type>
                </artifactItem>
            </artifactItems>
            <outputDirectory>$project.build.directory/lib</outputDirectory>
        </configuration>
    </execution>
</executions>

现在我只需在我的程序集 xml 中添加以下几行

    <fileSet>
        <directory>$project.build.directory/lib</directory>
        <outputDirectory>/lib</outputDirectory>
        <filtered>false</filtered>
        <includes>
            <include>*.jar</include>
        </includes>
        <fileMode>0600</fileMode>
    </fileSet>

【讨论】:

可能会问,如果你这样做,当两个版本都加载到jvm时,不应该有冲突吗? 我有完全相同的要求,您的解决方案节省了时间。 @lucky_start_izumi - 在大多数情况下都可以,但在我的情况下,它适用于使用 YAJSW 的应用程序,它需要一个较旧的库,而我的应用程序需要一个较新的库。在我的场景中,它们在不同的类路径上运行。【参考方案4】:

我同意,不同的版本意味着替换旧版本。如果我们必须为某些业务需求使用两个不同版本的 Web 服务。在不同的包中生成存根是个好主意,在添加到 maven 时,您可以在 groupid 中指定不同的存根。这应该可以。

【讨论】:

以上是关于Maven 程序集:添加同一工件的不同版本的主要内容,如果未能解决你的问题,请参考以下文章

maven:添加相同的 2 个工件,但版本不同

扫描多个 maven pom 以获取不同的依赖版本

maven 仅部署更改的工件

20190904_ 警告 发现同一依赖程序集的不同版本间存在冲突。

发现同一依赖程序集的不同版本之间存在无法解决的冲突

C# 依赖同一个强签名程序集的不同版本