在实验/快速和肮脏的模拟开发阶段,Maven2让我发疯 .
我有一个 pom.xml
文件,它定义了我想要使用的web-app框架的依赖项,我可以从该文件快速生成启动项目 . 但是,有时我想链接到尚未定义 pom.xml
文件的第三方库,所以不要手动创建第三方库的 pom.xml
文件并安装它,并将依赖项添加到我的 pom.xml
,I我想告诉Maven:“除了我定义的依赖项,还要包含 /lib
中的任何jar . ”
看起来这应该很简单,但如果是这样,我就会遗漏一些东西 .
任何关于如何做到这一点的指针都非常感谢 . 除此之外,如果有一种简单的方法将maven指向 /lib
目录并轻松创建一个 pom.xml
,所有封闭的jar映射到单个依赖项,然后我可以命名/安装并一次性链接就足够了 .
23 回答
什么在我们的项目中工作的是Archimedes Trajano写的,但我们在.m2 / settings.xml中有这样的东西:
并且*应该改为中央 . 因此,如果他的答案对你不起作用,你应该检查你的settings.xml
流行方法的问题
您将在互联网上找到的大多数答案都建议您将依赖项安装到本地存储库,或者在
pom
中指定"system"范围,并将依赖项分配给项目源 . 但这两种解决方案实际上都存在缺陷 .为什么不应用“安装到本地回购”方法
当您将依赖项安装到本地存储库时,它仍然存在 . 只要它可以访问此存储库,您的分发工件就可以正常工作 . 问题是在大多数情况下,此存储库将驻留在您的本地计算机上,因此无法在任何其他计算机上解决此依赖关系 . 显然,使您的工件依赖于特定的机器并不是处理事情的方法 . 否则,必须在使用该项目的每台计算机上本地安装此依赖项,这不是更好 .
为什么不应用“系统范围”方法
您依赖“系统范围”方法的 jar 既不会安装到任何存储库,也不会连接到目标软件包 . 这就是为什么您的分发包在使用时无法解决该依赖关系的原因 . 我认为这就是为什么系统范围的使用甚至被弃用的原因 . 无论如何,您不希望依赖已弃用的功能 .
静态项目内存储库解决方案
把它放在你的
pom
之后:对于组ID为
x.y.z
的每个工件,Maven将在项目目录中包含以下位置以搜索工件:要详细说明这一点,您可以阅读this blog post .
使用Maven安装到项目仓库
我建议使用Maven插件将jar作为工件安装,而不是手动创建此结构 . 因此,要将工件安装到
repo
文件夹下的项目内存储库中,请执行:如果您能够将
pom
中的存储库声明简化为:帮助程序脚本
由于为每个lib执行安装命令有点烦人并且肯定容易出错,我创建了一个utility script,它自动将所有jar从
lib
文件夹安装到项目存储库,同时自动解析所有元数据(groupId,artifactId等)文件名 . 该脚本还会打印出依赖项xml,以便在pom
中进行复制粘贴 .在目标包中包含依赖项
当您创建项目中的存储库时,您将解决使用其源分发项目依赖项的问题,但从那时起,项目的目标工件将依赖于未发布的jar,因此当您安装时它到存储库它将具有无法解析的依赖关系 .
为了解决这个问题,我建议在目标包中包含这些依赖项 . 使用Assembly Plugin可以使用Assembly Plugin或更好 . 关于OneJar的官方文档很容易理解 .
如果你想要一个快速而肮脏的解决方案,你可以做以下事情(虽然我不建议除了测试项目以外的任何东西,maven会长篇大论抱怨这是不合适的) .
为您需要的每个jar文件添加一个依赖项,最好使用perl脚本或类似的东西,然后将其复制/粘贴到您的pom文件中 .
快速而肮脏的批处理解决方案(基于Alex的答案):
libs.bat
像这样执行:
libs.bat > libs.txt
. 然后打开libs.txt
并将其内容复制为依赖项 .在我的情况下,我只需要库来编译我的代码,这个解决方案是最好的 .
这是我们添加或安装本地jar的方式
我给了一些默认的groupId和artifactId,因为它们是强制性的:)
对于那些在这里找不到好答案的人来说,这就是我们正在做的事情,以获得一个包含所有必要依赖关系的jar . 这个答案(https://stackoverflow.com/a/7623805/1084306)提到使用Maven Assembly插件但是没有一直读到答案的结尾(它很长),你可能会错过它 . 将以下内容添加到您的pom.xml将生成
target/${PROJECT_NAME}-${VERSION}-jar-with-dependencies.jar
这就是我所做的,它也适用于包问题,它适用于检出的代码 .
我在项目中创建了一个新文件夹,我使用
repo
,但随意使用src/repo
在我的POM中,我有一个不在任何公共maven存储库中的依赖项
然后我创建了以下目录
repo/com/dovetail/zoslog4j/1.0.1
并将JAR文件复制到该文件夹中 .我创建了以下POM文件来表示下载的文件(这一步是可选的,但它删除了一个警告)并帮助下一个人弄清楚我从哪里开始获取文件 .
我创建的两个可选文件是POM的SHA1校验和,以及用于删除缺少的校验和警告的JAR .
最后,我将以下片段添加到我的pom.xml中,允许我引用本地存储库
Maven install plugin使用命令行将jar安装到本地存储库中,POM是可选的,但您必须指定GroupId,ArtifactId,Version和Packaging(所有POM内容) .
要安装不在maven存储库中的第三方jar,请使用maven-install-plugin .
以下是步骤:
从源(网站)手动下载jar文件
创建一个文件夹并将jar文件放入其中
运行以下命令在本地maven存储库中安装第三方jar
以下是我用于simonsite log4j的例子
以下是参考链接:
https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
For throw away code only
set scope == system,只需组成groupId,artifactId和version
注意:系统依赖关系不会复制到生成的jar / war中
(见How to include system dependencies in war built using maven)
注意:使用系统范围(as mentioned on this page)时,Maven需要绝对路径 .
如果您的jar位于项目的根目录下,则需要使用$ 为systemPath值添加前缀 .
systemPath
的问题在于依赖项' jars won' t作为传递依赖项沿着工件分布 . 试试我在这里发布的内容:Is it best to Mavenize your project jar files or put them in WEB-INF/lib?然后像往常一样声明依赖项 .
请阅读页脚说明 .
由于其他人解释的原因使用
<scope>system</scope>
是一个可怕的想法,手动将文件安装到本地存储库使得构建不可复制,并且使用<url>file://${project.basedir}/repo</url>
不是一个好主意,因为(1)可能不是格式良好的file
URL(例如如果项目在具有异常字符的目录中签出,)(2)如果该项目的POM用作其他人项目的依赖项,则结果不可用 .假设您不愿意将工件上传到公共存储库,Simeon建议使用辅助模块来完成工作 . 但现在有一种更简单的方法......
建议书
使用non-maven-jar-maven-plugin . 完全符合您的要求,没有其他方法的缺点 .
虽然它不完全适合你的问题,但我会把它放在这里 . 我的要求是:
在在线maven存储库中找不到的Jars应该在SVN中 .
如果一个开发人员添加了另一个库,其他开发人员不应该为手动安装它们而烦恼 .
IDE(在我的情况下是NetBeans)应该能够找到源和javadoc来提供自动完成和帮助 .
让我们首先谈谈(3):将jar放在一个文件夹中并以某种方式将它们合并到最终的jar中将无法在这里工作,因为IDE不会理解这一点 . 这意味着必须正确安装所有库 . 但是,我不希望每个人都使用“mvn install-file”安装它 .
在我的项目中,我需要metawidget . 开始了:
创建一个新的maven项目(将其命名为"shared-libs"或类似名称) .
下载metawidget并将zip解压缩到src / main / lib中 .
文件夹doc / api包含javadocs . 创建内容的zip(doc / api / api.zip) .
修改pom like this
构建项目和将安装库 .
将库添加为项目的依赖项,或者(如果在shared-libs项目中添加了依赖项)将shared-libs添加为依赖项以立即获取所有库 .
每次有新库时,只需添加一个新执行并告诉每个人再次构建项目(您可以使用项目层次结构改进此过程) .
我发现了另一种方法,从Heroku post看到这里
总结一下(抱歉一些复制和粘贴)
repo
目录:pom.xml
:<依赖性>
<的groupId> com . 示例</的groupId>
<artifactId的> MYLIB </ artifactId的>
<版本> 1.0 </版本>
</依赖性>
对我来说最简单的是配置你的maven-compiler-plugin来包含你的自定义jar . 此示例将加载lib目录中的任何jar文件 .
我只想要一个快速而肮脏的解决方法......我无法从Nikita Volkov运行脚本:语法错误它需要一个严格的jar名称格式 .
我制作了这个Perl脚本,它适用于jar文件名的任何格式,并且它在xml中生成依赖项,因此可以直接在pom中复制粘贴 .
如果要使用它,请确保您了解脚本正在执行的操作,您可能需要更改
lib
文件夹以及groupId
或artifactId
的值...您可以在项目中创建本地存储库
例如,如果项目结构中有
libs
文件夹在
libs
文件夹中,您应该创建如下目录结构:/groupId/artifactId/version/artifactId-version.jar
在您的pom.xml中,您应该注册存储库
就这些 .
详细信息:How to add external libraries in Maven
这没有回答如何将它们添加到您的POM中,并且可能没什么问题,但只是将lib目录添加到您的类路径工作中?我知道当我需要一个我不想添加到我的Maven回购中的外部jar时,我就会这样做 .
希望这可以帮助 .
您真的应该通过存储库获得一个框架,并预先确定您的依赖项 . 使用系统范围是人们常用的错误,因为它们是麻烦的是,这样做最终会导致变态的maven构建在正常情况下不会显示maven . 你最好采用像this这样的方法 .
我发现一个奇怪的解决方案
使用Eclipse
创建简单(非maven)java项目
添加一个Main类
将所有jar添加到类路径中
export Runnable JAR(这很重要,因为这里别无他法)
选择将所需库提取到生成的JAR中
决定许可证问题
tadammm ...将生成的jar安装到m2repo
将此单一依赖项添加到您的其他项目中 .
欢呼,巴林特
在与CloudBees人员就这种JAR的正确编组包装进行了长时间的讨论之后,他们为解决方案提出了一个有趣的好建议:
创建一个假的Maven项目,该项目将预先存在的JAR作为主要工件附加,运行到属于POM的安装:安装文件执行 . 这是POM的这种kinf的一个例子:
但是为了实现它,应该改变现有的项目结构 . 首先,您应该记住,对于每种这样的JAR,应该创建不同的假Maven项目(模块) . 应该创建一个父Maven项目,包括所有子模块:所有JAR包装器和现有主项目 . 结构可以是:
当通过mvn:install或mvn:packaging运行父进程时,将执行子模块 . 这可能是一个减号,因为项目结构应该改变,但最后提供一个非静态的解决方案
我在@alex lehmann的回答中提到了一些python代码,所以我在这里发帖 .