具有依赖项的 Maven 2 程序集:不包括范围“系统”下的 jar
Posted
技术标签:
【中文标题】具有依赖项的 Maven 2 程序集:不包括范围“系统”下的 jar【英文标题】:Maven 2 assembly with dependencies: jar under scope "system" not included 【发布时间】:2011-01-05 04:10:41 【问题描述】:我正在使用 maven-assembly 插件来创建我的应用程序的 jar,包括它的依赖项如下:
<assembly>
<id>macosx</id>
<formats>
<format>tar.gz</format>
<format>dir</format>
</formats>
<dependencySets>
<dependencySet>
<includes>
<include>*:jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
(我省略了一些与问题无关的其他内容)
到目前为止,这一切正常,因为它创建了一个包含所有依赖项的 lib
目录。但是,我最近添加了一个新的依赖项,其范围为system
,并且它不会将其复制到lib
输出目录。我必须在这里缺少一些基本的东西,所以我寻求帮助。
我刚才添加的依赖是:
<dependency>
<groupId>sourceforge.jchart2d</groupId>
<artifactId>jchart2d</artifactId>
<version>3.1.0</version>
<scope>system</scope>
<systemPath>$project.basedir/external/jchart2d-3.1.0.jar</systemPath>
</dependency>
我能够包含此依赖项的唯一方法是将以下内容添加到程序集元素:
<files>
<file>
<source>external/jchart2d-3.1.0.jar</source>
<outputDirectory>lib</outputDirectory>
</file>
</files>
但是,这迫使我在重命名此 jar 时更改 pom 和程序集文件(如果有的话)。而且,这似乎是错误的。
我曾尝试在dependencySets
和<include>sourceforge.jchart2d:jchart2d</include>
中使用<scope>runtime</scope>
,但没有成功。
那么,如何在 maven 2 中将 system
作用域 jar 包含到您的程序集文件中?
非常感谢
【问题讨论】:
范围“runtime”不会改变结果,因为它是默认值。 我刚刚将 jchart2d 推送到了 Maven 中心! sourceforge.net/news/?group_id=50440 - 享受吧! 【参考方案1】:没有添加系统范围依赖项我并不感到惊讶(毕竟,具有系统范围的依赖项必须通过定义显式提供)。实际上,如果您真的不想将该依赖项放在本地存储库中(例如,因为您想将其作为项目的一部分进行分发),我会这样做:
我会将依赖项放在项目本地的“文件系统存储库”中。我会在我的pom.xml
中声明该存储库,如下所示:
<repositories>
<repository>
<id>my</id>
<url>file://$basedir/my-repo</url>
</repository>
</repositories>
我只会声明没有system
范围的工件,这只是麻烦的根源:
<dependency>
<groupId>sourceforge.jchart2d</groupId>
<artifactId>jchart2d</artifactId>
<version>3.1.0</version>
</dependency>
我不能 100% 确定这会满足您的需求,但我认为它是比使用系统范围更好的解决方案。
更新:我应该在我的原始答案中提到这一点,我现在正在修复它。要在基于文件的存储库中安装第三方库,请使用 install:install-file
和 localRepositoryPath
参数:
mvn install:install-file -Dfile=<path-to-file> \
-DgroupId=<myGroup> \
-DartifactId=<myArtifactId> \
-Dversion=<myVersion> \
-Dpackaging=<myPackaging> \
-DlocalRepositoryPath=<path-to-my-repo>
您可以将其粘贴到 *nix shell 中。在 Windows 上,删除“\
”并将所有内容放在一行中。
【讨论】:
好主意,我会试试的。 它确实有效,但将文件安装在不同于 $HOME/.m2/repository 的本地存储库中并非易事。我不得不做一个 mvn install:install-file [...install-file options...] -Dmaven.repo.local=path_to_my_local_repo 这迫使 maven 下载其最基本的插件。你能建议如何将文件安装到这个本地仓库吗? 我应该提到 :) 我会使用install:install-file
在本地 repo (~/.m2/repository
) 中安装工件,然后将目录树移动到 $basedir/my-repo
。在你的情况下,我只是从$basedir/my-repo
中删除不需要的东西。
是的,我最终做到了……它并不漂亮,但它确实有效。非常感谢。【参考方案2】:
顺便说一句,您可以将其自动化并使其成为您的 maven 构建的一部分。以下将在编译之前将您的 jar 安装到您的本地存储库中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>validate</phase>
<configuration>
<file>$basedir/lib/your-lib.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
【讨论】:
不支持一次安装多个文件吗? 哇,这太棒了!太感谢了! @Tuukka Mustonen 您必须为每个文件复制validate
阶段的插件之前解决所有依赖项(在 compile
之前,等等...... )。因此,一旦安装了工件,这将重新安装它,但它不会进行初始安装 - 这是一个鸡/蛋问题。一个可以将其绑定到clean
阶段(因为这不需要首先解析依赖项)并告诉开发人员首先运行mvn clean
,但随后它不再使用“标准程序”了盒子。
@Chadwick 简单地将其绑定到 clean 阶段是行不通的。我有一个项目可以很好地构建(和清理),但由于分辨率错误甚至没有进入其他环境的清理阶段。只是暂时更改依赖项的范围以允许安装似乎有所帮助。
绑定到initialize
对我有用。我的 IDE 抱怨未解决的依赖关系,但是当我运行它时,每次都会安装本地 JAR 文件,然后解决得很好。出色的解决方案@alx!【参考方案3】:
如果您创建 jar,我会找到简单的解决方案
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>dependencies/mydep</directory>
<targetPath>WEB-INF/lib</targetPath>
<filtering>true</filtering>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
【讨论】:
这要简单得多...为什么要添加到本地仓库等? 这是一种快速完成工作的肮脏方式。谢谢。有一天,世界都将在 maven 中运行,但在那之前,这可以挽救我们的生命。 恕我直言,过滤会更安全:false【参考方案4】:您也可以通过在您的dependencySets 中添加补充dependencySet 来处理此问题。
<dependencySet>
<scope>system</scope>
<includes>
<include>*:jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
最好的办法是使用存储库管理器(如 Nexus、Artifactory、Archiva)并将这种依赖项安装在特定存储库中。之后,您可以使用诸如简单依赖项之类的东西。这将简化您的生活。
Docs:
【讨论】:
【参考方案5】:已编辑:抱歉,我没有意识到 alx 还提到了干净的生命周期解决方法。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>clean</phase>
<configuration>
<file>$basedir/lib/your-lib.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
基于alx提供的解决方案,可以在clean阶段执行安装文件步骤。但由于 clean 阶段不在默认生命周期中,因此您必须在第一时间执行 mvn clean
以确保 jar 在本地 repo 中准备好。
ex: mvn clean; mvn 包
【讨论】:
【参考方案6】:一个简单的解决方案是将其添加到本地 maven 存储库中
一种方法是按照上一篇文章中的建议通过 mvn install 命令。
另一种简单的方法是, 1)在你的 Eclipse IDE 中右键单击项目选择 Maven 选项。 2) 选择安装或将工件部署到 Maven 存储库选项,然后单击下一步。 3)单击工件文件复选框旁边的浏览并选择您的jar文件 4)输入 GroupId 和 ArtifactId 和版本确保生成 pom 和创建校验和被检查并且包装是 jar
点击完成就可以了!您的工作已完成,jar 已添加到您可以在 setting.xml 或 m2 目录中定义的本地存储库中
现在只需根据您根据导入输入的 GroupId、ArtifactId 和 jar 版本添加简单的 maven 依赖项,这样您的外部 jar 将由 maven 打包。
【讨论】:
感谢您的帮助。它对我很有用,而且绝对比这里给出的其他方法更容易。干杯:)【参考方案7】:它在我的解决方案中以更简单的方式工作:
从你的依赖中移除:
<dependency>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
</dependency>
然后在 pom.xml 中添加 maven-install-plugin。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-external</id>
<phase>clean</phase>
<configuration>
<file>$basedir/external/tiago.medici-0.0.1.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
【讨论】:
以上是关于具有依赖项的 Maven 2 程序集:不包括范围“系统”下的 jar的主要内容,如果未能解决你的问题,请参考以下文章
具有依赖项的 Maven2 + JMeter + JUnit