在实验/快速和肮脏的模拟开发阶段,Maven2让我发疯.
我有一个pom.xml
文件定义了我想要使用的web-app框架的依赖项,我可以从该文件快速生成启动项目.但是,有时我想链接到尚未pom.xml
定义文件的第三方库,所以不是pom.xml
手动创建第三方库的文件并安装它,并将依赖项添加到我的pom.xml
,我只是想告诉Maven:"除了我定义的依赖项,还要包含任何罐子/lib
."
看起来这应该很简单,但如果是这样,我就会遗漏一些东西.
任何关于如何做到这一点的指针都非常感谢.除此之外,如果有一种简单的方法将maven指向一个/lib
目录并轻松创建一个pom.xml
所有封闭的jar映射到单个依赖项,然后我可以一次命名/安装和链接就足够了.
您将在互联网上找到的大多数答案都建议您将依赖项安装到本地存储库,或者在其中指定"系统"范围,pom
并将依赖项与项目源分发.但这两种解决方案实际上都存在缺陷.
当您将依赖项安装到本地存储库时,它仍然存在.只要它可以访问此存储库,您的分发工件就可以正常工作.问题是在大多数情况下,此存储库将驻留在您的本地计算机上,因此无法在任何其他计算机上解决此依赖关系.显然,使您的工件依赖于特定的机器不是处理事情的方法.否则,必须在使用该项目的每台计算机上本地安装此依赖项,这不是更好.
您依赖"系统范围"方法的罐子既不会安装到任何存储库,也不会连接到目标软件包.这就是为什么您的分发包在使用时无法解决该依赖关系的原因.我认为这就是为什么系统范围的使用甚至被弃用的原因.无论如何,您不希望依赖已弃用的功能.
静态项目内存储库解决方案把它放在你的pom
:
repo
true
ignore
false
file://${project.basedir}/repo
对于具有表单组ID的每个工件,x.y.z
Maven将在项目目录中包含以下位置以搜索工件:
repo/ | - x/ | | - y/ | | | - z/ | | | | - ${artifactId}/ | | | | | - ${version}/ | | | | | | - ${artifactId}-${version}.jar
要详细说明这一点,您可以阅读此博客文章.
我建议不要手动创建这个结构,而是使用Maven插件将你的jar作为工件安装.因此,要将工件安装到repo
文件夹execute 下的项目内存储库中:
mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]
如果您选择这种方法,您将能够将存储库声明简化pom
为:
repo
file://${project.basedir}/repo
由于为每个lib执行安装命令有点烦人并且肯定容易出错,因此我创建了一个实用程序脚本,它自动将所有jar从lib
文件夹安装到项目存储库,同时自动解析所有元数据(groupId,artifactId等)文件名.该脚本还打印出依赖项xml,供您复制粘贴pom
.
当您创建项目内存储库时,您将解决使用其源分发项目依赖项的问题,但从那时起,项目的目标工件将依赖于未发布的jar,因此当您安装时它到存储库它将具有无法解析的依赖项.
为了解决这个问题,我建议在目标包中包含这些依赖项.这可以使用Assembly Plugin或更好的OneJar插件.关于OneJar的官方文档很容易理解.
仅限丢弃代码
set scope == system,只需组成groupId,artifactId和version
org.swinglabs
swingx
0.9.2
system
${project.basedir}/lib/swingx-0.9.3.jar
注意:系统依赖关系不会复制到生成的jar/war中
(请参阅如何在使用maven构建的war中包含系统依赖关系)
您可以在项目上创建本地存储库
例如,如果libs
项目结构中有文件夹
在libs
文件夹中,您应该创建目录结构,如:/groupId/artifactId/version/artifactId-version.jar
在您的pom.xml中,您应该注册存储库
ProjectRepo ProjectRepo file://${project.basedir}/libs
并像往常一样添加依赖项
groupId artifactId version
就这些.
有关详细信息:如何在Maven中添加外部库
注意:使用系统范围(如本页所述)时,Maven需要绝对路径.
如果您的jar位于项目的根目录下,则需要使用$ {basedir}为systemPath值添加前缀.
这就是我所做的,它也适用于包问题,它适用于检出的代码.
在我使用的情况下,我在项目中创建了一个新文件夹repo
,但随意使用src/repo
在我的POM中,我有一个不在任何公共maven存储库中的依赖项
com.dovetail
zoslog4j
1.0.1
runtime
然后我创建了以下目录repo/com/dovetail/zoslog4j/1.0.1
并将JAR文件复制到该文件夹中.
我创建了以下POM文件来表示下载的文件(这一步是可选的,但它删除了一个警告)并帮助下一个人弄清楚我从哪里开始获取文件.
4.0.0
com.dovetail
zoslog4j
jar
1.0.1
z/OS Log4J Appenders
http://dovetail.com/downloads/misc/index.html
Apache Log4j Appender for z/OS Logstreams, files, etc.
我创建的两个可选文件是POM的SHA1校验和以及用于删除缺少的校验和警告的JAR.
shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar \ > repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar.sha1 shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom \ > repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom.sha1
最后,我将以下片段添加到我的pom.xml中,允许我引用本地存储库
project
file:///${basedir}/repo
您真的应该通过存储库获得一个框架,并预先确定您的依赖项.使用系统范围是人们常用的错误,因为他们"不关心依赖管理".麻烦的是,这样做你最终会得到一个变态的maven构建,它不会在正常情况下显示maven.你会过得更好像下面的方法这样.
Maven安装插件有命令行用法将jar安装到本地存储库,POM是可选的,但你必须指定GroupId,ArtifactId,Version和Packaging(所有POM的东西).
这是我们添加或安装本地jar的方式
org.example
iamajar
1.0
system
${project.basedir}/lib/iamajar.jar
我给了一些默认的groupId和artifactId,因为它们是强制性的:)
由于其他人解释的原因,使用是一个可怕的想法,手动将文件安装到本地存储库使得构建
不可复制,并且使用不是一个好主意,因为(1)可能不是格式良好的file
URL(例如,如果项目在具有异常字符的目录中检出),(2)如果该项目的POM用作其他人项目的依赖项,则结果不可用.
假设您不愿意将工件上传到公共存储库,Simeon建议使用辅助模块来完成工作.但现在有一种更简单的方法......
使用非maven-jar-maven-plugin.完全是你要求的,没有其他方法的缺点.
我找到了另一种方法,从Heroku帖子看到这里
总结一下(抱歉一些复制和粘贴)
repo
在根文件夹下创建一个目录:
yourproject +- pom.xml +- src +- repo
运行此命令将jar安装到本地repo目录
mvn deploy:deploy-file -Durl=file:///path/to/yourproject/repo/ -Dfile=mylib-1.0.jar -DgroupId=com.example -DartifactId=mylib -Dpackaging=jar -Dversion=1.0
添加这个你的pom.xml
:
project.local project file:${project.basedir}/repo com.example mylib 1.0
在与CloudBees人员进行了长时间的讨论之后,他们就这种JAR的正确编组进行了讨论,他们为解决方案提出了一个有趣的好建议:
创建一个假的Maven项目,该项目将预先存在的JAR作为主要工件附加,运行到属于POM的安装:安装文件执行.这是POM的这种kinf的一个例子:
org.apache.maven.plugins
maven-install-plugin
2.3.1
image-util-id
install
install-file
${basedir}/file-you-want-to-include.jar
${project.groupId}
${project.artifactId}
${project.version}
jar
但是为了实现它,应该改变现有的项目结构.首先,您应该记住,对于每种这样的JAR,应该创建不同的假Maven项目(模块).应该创建一个父Maven项目,包括所有子模块:所有JAR包装器和现有主项目.结构可以是:
root项目(这包含父POM文件包含所有带模块 XML元素的子模块)(POM打包)
JAR 1包装Maven儿童项目(POM包装)
JAR 2包装Maven子项目(POM包装)
主要存在的Maven子项目(WAR,JAR,EAR ....包装)
当通过mvn:install或mvn:packaging运行父进程时,将执行子模块.这可能是一个减号,因为项目结构应该改变,但最后提供非静态解决方案