我可以将jar添加到maven 2生成类path而不安装它们?
在实验/快速和肮脏的模拟阶段的发展过程中,Maven2正在让我疯狂。
我有一个pom.xml
文件,它定义了我想要使用的Web应用程序框架的依赖关系,并且可以从该文件快速生成启动项目。 但是,有时我想链接到一个尚未定义pom.xml
文件的第三方库,而不是手工创build第三方库的pom.xml
文件并安装它,并将依赖关系添加到我的pom.xml
,我只想告诉Maven:“除了我定义的依赖项之外,还包括任何在/lib
jar”。
这似乎应该是简单的,但如果是这样,我错过了一些东西。
任何指针如何做到这一点非常感谢。 简而言之,如果有一个简单的方法可以将maven指向/lib
目录,并且可以轻松创build一个pom.xml
并将所有封闭的jar映射到一个单独的依赖项,然后我可以一举命名/安装并链接到该目录。也足够了。
stream行方法的问题
你可以在互联网上find的大部分答案都build议你将依赖项安装到你的本地仓库,或者在pom
指定一个“系统”范围,然后把依赖关系和你的项目源一起分发。 但是这两种解决scheme实际上都是有缺陷的。
为什么不应用“安装到本地回购”的方法
当你安装一个依赖到你的本地仓库时,它仍然在那里。 只要有权访问此存储库,分发工件就会正常工作。 问题是在大多数情况下,这个仓库将驻留在你的本地机器上,所以在任何其他机器上都无法解决这个依赖关系。 清楚地使你的神器依赖于特定的机器不是一种处理事物的方法。 否则,这个依赖关系将不得不在每个使用该项目的机器上本地安装,这是不太好的。
为什么不应用“系统范围”方法
您使用“系统范围”方法所依赖的jar既不会被安装到任何存储库,也不会被附加到您的目标包中。 这就是为什么您的发行包在使用时无法解决依赖关系的原因。 我相信这是系统范围的使用甚至被废弃的原因。 无论如何,你不想依靠一个弃用的function。
静态的项目库中的解决scheme
把这个pom
你的pom
:
<repository> <id>repo</id> <releases> <enabled>true</enabled> <checksumPolicy>ignore</checksumPolicy> </releases> <snapshots> <enabled>false</enabled> </snapshots> <url>file://${project.basedir}/repo</url> </repository>
对于具有xyz
forms的组ID的每个工件,Maven将在您的项目dir中包含以下位置以search工件:
repo/ | - x/ | | - y/ | | | - z/ | | | | - ${artifactId}/ | | | | | - ${version}/ | | | | | | - ${artifactId}-${version}.jar
详细说明这一点,你可以阅读这篇博文 。
使用Maven安装到项目回购
我不build议用手工创build这个结构,而是使用Maven插件将你的jar子安装成工件。 因此,要在repo
文件夹下将项目安装到项目库中,请执行以下命令:
mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]
如果你select这种方法,你将能够简化在pom
的库声明:
<repository> <id>repo</id> <url>file://${project.basedir}/repo</url> </repository>
帮手脚本
因为为每个lib执行安装命令有点麻烦,而且肯定有错误,所以我创build了一个实用程序脚本 ,它自动将lib
文件夹中的所有jar lib
到项目存储库,同时自动parsing所有元数据(groupId,artifactId等)从文件的名字。 该脚本还打印出来的依赖xml为你复制粘贴在你的pom
。
在您的目标包中包含依赖关系
当你创build了你的项目库时,你已经解决了项目的依赖关系和源代码的问题,但是从那时起,你的项目的目标工件将依赖于未发布的jar,所以当你安装它到一个仓库将有无法解决的依赖关系。
为了解决这个问题,我build议在你的目标包中包含这些依赖关系。 您可以使用Assembly Plugin或OneJar插件更好地完成此操作 。 OneJar上的官方文档很容易理解。
仅用于扔掉代码
设置范围==系统,只是组成一个groupId,artifactId和版本
<dependency> <groupId>org.swinglabs</groupId> <artifactId>swingx</artifactId> <version>0.9.2</version> <scope>system</scope> <systemPath>${project.basedir}/lib/swingx-0.9.3.jar</systemPath> </dependency>
注意:系统依赖不会被复制到结果jar / war中
(请参阅如何在使用maven构build的war中包含系统依赖关系 )
您可以在您的项目上创build本地存储库
例如,如果在项目结构中有libs
文件夹
-
在
libs
文件夹中,您应该创build如下目录结构:/groupId/artifactId/version/artifactId-version.jar
-
在你的pom.xml中,你应该注册仓库
<repository> <id>ProjectRepo</id> <name>ProjectRepo</name> <url>file://${project.basedir}/libs</url> </repository>
-
并照常添加依赖项
<dependency> <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>version</version> </dependency>
就这些。
有关详细信息: 如何在Maven中添加外部库
注意:当使用系统作用域( 如本页所述 )时,Maven需要绝对path。
如果你的jar文件在你的项目的根目录下,你需要在$ {basedir}前加上你的systemPath值。
你真的应该通过一个仓库来获得一个框架,并预先确定你的依赖关系。 使用系统范围是人们常用的错误,因为他们“不关心依赖pipe理”。 麻烦的是,这样做最终会导致一个变形的maven版本,在正常情况下不会显示maven。 遵循这样的方法会更好。
Maven安装插件有命令行用法安装一个jar到本地仓库,POM是可选的,但你将不得不指定GroupId,ArtifactId,版本和包装(所有的POM的东西)。
这是我所做的,它也适用于包问题,它与检出代码一起工作。
我在项目中创build了一个新的文件夹,我使用repo
,但是可以使用src/repo
在我的POM中,我有一个不在公共Maven仓库中的依赖项
<dependency> <groupId>com.dovetail</groupId> <artifactId>zoslog4j</artifactId> <version>1.0.1</version> <scope>runtime</scope> </dependency>
然后,我创build了以下目录repo/com/dovetail/zoslog4j/1.0.1
并将JAR文件复制到该文件夹中。
我创build了下面的POM文件来表示下载的文件(这一步是可选的,但它删除了警告),并帮助下一个家伙找出我从哪里开始的文件。
<?xml version="1.0" encoding="UTF-8" ?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dovetail</groupId> <artifactId>zoslog4j</artifactId> <packaging>jar</packaging> <version>1.0.1</version> <name>z/OS Log4J Appenders</name> <url>http://dovetail.com/downloads/misc/index.html</url> <description>Apache Log4j Appender for z/OS Logstreams, files, etc.</description> </project>
我创build的两个可选文件是POM和JAR的SHA1校验和,以删除缺less的校验和警告。
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文件中,该文件允许我引用本地存储库
<repositories> <repository> <id>project</id> <url>file:///${basedir}/repo</url> </repository> </repositories>
这是我们如何添加或安装本地jar
<dependency> <groupId>org.example</groupId> <artifactId>iamajar</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/iamajar.jar</systemPath> </dependency>
我给了一些默认的groupId和artifactId,因为它们是必须的
使用<scope>system</scope>
对于别人解释的原因是一个可怕的想法,手动将文件安装到本地存储库使得构build不可重现,并使用<url>file://${project.basedir}/repo</url>
不是一个好主意,因为(1)这可能不是一个格式正确的file
URL(例如,如果项目被检出到一个不常用的字符目录中),(2)如果这个项目的POM结果是不可用的被用作别人的项目的依赖。
假设你不愿意将工件上传到公共仓库,Simeonbuild议使用辅助模块来完成这项工作。 但现在有一个更简单的方法…
build议书
使用非maven-jar-maven-plugin 。 是不是你所要求的,没有其他方法的缺点。
我find了另一种方法来做到这一点,从Heroku的post看到这里
总结(对于一些复制和粘贴抱歉)
- 在根文件夹下创build一个
repo
目录:
yourproject + - pom.xml + - src + - 回购
- 运行这个将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
:
<repositories> <!--other repositories if any--> <repository> <id>project.local</id> <name>project</name> <url>file:${project.basedir}/repo</url> </repository> </repositories> <dependency> <groupId>com.example</groupId> <artifactId>mylib</artifactId> <version>1.0</version> </dependency>
经过与CloudBees人员长时间讨论有关这种JAR的正确的Maven包装,他们为解决scheme提出了一个有趣的好build议:
创build一个假的Maven项目,将预先存在的JAR作为主要工件,运行到属于POM install:install-file execution。 下面是一个这样的POM的例子:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <version>2.3.1</version> <executions> <execution> <id>image-util-id</id> <phase>install</phase> <goals> <goal>install-file</goal> </goals> <configuration> <file>${basedir}/file-you-want-to-include.jar</file> <groupId>${project.groupId}</groupId> <artifactId>${project.artifactId}</artifactId> <version>${project.version}</version> <packaging>jar</packaging> </configuration> </execution> </executions> </plugin> </plugins> </build>
但为了实施,现有的项目结构应该改变。 首先,你应该记住,对于每种这样的JAR,都应该创build不同的假的Maven项目(模块)。 应该创build一个Maven项目的父项目,包括所有的JAR包装器和现有的主项目。 结构可以是:
根项目(这包含父POM文件包含所有具有模块 XML元素的子模块)(POM打包)
JAR 1包装Maven儿童项目(POM包装)
JAR 2包装Maven儿童项目(POM包装)
主要存在的Maven儿童项目(WAR,JAR,EAR ….包装)
当通过mvn:install或mvn:packaging运行的父级被强制执行并且子模块被执行时。 这可能会被视为一个负面因素,因为项目结构应该改变,但是最终会提供一个非静态的解决scheme
systemPath
的问题是依赖关系的jar不会作为传递依赖关系沿着你的构件分发。 试试我在这里发布的信息: 最好是将项目的jar文件放到Maven中,或者放在WEB-INF / lib中?
然后像往常一样声明依赖关系。
并请阅读页脚注。
如果你想要一个快速和肮脏的解决scheme,你可以做到以下几点(尽pipe除了testing项目我不build议这样做,maven会长时间抱怨这是不正确的)。
为每个需要的jar文件添加一个依赖项,最好使用perl脚本或类似的东西,并将其复制/粘贴到你的pom文件中。
#! /usr/bin/perl foreach my $n (@ARGV) { $n=~s@.*/@@; print "<dependency> <groupId>local.dummy</groupId> <artifactId>$n</artifactId> <version>0.0.1</version> <scope>system</scope> <systemPath>\${project.basedir}/lib/$n</systemPath> </dependency> ";
我发现一个奇怪的解决scheme
使用Eclipse
- 创build简单的(非maven)java项目
- 添加一个Main类
- 将所有的jar添加到类path中
- 导出可运行的JAR(这很重要,因为在这里没有其他的方式来做)
- select将所需的库提取到生成的JAR中
- 决定许可证问题
- tadammm …将生成的jar安装到你的m2repo
- 添加这个单一的依赖到你的其他项目。
欢呼,Balint
即使它不完全适合你的问题,我会放在这里。 我的要求是:
- 无法在在线Maven仓库中find的Jars应该在SVN中。
- 如果一个开发人员添加另一个库,其他开发人员不应该为手动安装而烦恼。
- IDE(在我的情况下,NetBeans)应该能够find源和javadocs来提供自动完成和帮助。
首先我们来讨论一下(3):只需将文件夹放在一个文件夹中,然后将它们合并到最终的jar文件中就行不通了,因为IDE不会理解这个。 这意味着所有的库都必须正确安装。 但是,我不想让每个人都使用“mvn install-file”来安装它。
在我的项目中,我需要metawidget。 开始了:
- 创build一个新的Maven项目(将其命名为“shared-libs”或类似的东西)。
- 下载metawidget并将zip解压到src / main / lib中。
- 文件夹doc / api包含javadocs。 创build内容的压缩文件(doc / api / api.zip)。
- 像这样修改pom
- build立项目和库将被安装。
- 将库作为依赖项添加到项目中,或者(如果您在shared-libs项目中添加了依赖项)将shared-libs作为依赖项添加到一次获取所有库。
每当你有一个新的图书馆,只需添加一个新的执行,并告诉每个人再次build立项目(你可以改善这个过程与项目hierachies)。
对我来说最简单的是configuration你的maven-compiler-plugin来包含你的自定义jar。 这个例子将加载lib目录中的任何jar文件。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <includes> <include>lib/*.jar</include> </includes> </configuration> </plugin>
一个快速和肮脏的批次解决scheme(根据亚历克斯的答案):
libs.bat
@ECHO OFF FOR %%I IN (*.jar) DO ( echo ^<dependency^> echo ^<groupId^>local.dummy^</groupId^> echo ^<artifactId^>%%I^</artifactId^> echo ^<version^>0.0.1^</version^> echo ^<scope^>system^</scope^> echo ^<systemPath^>${project.basedir}/lib/%%I^</systemPath^> echo ^</dependency^> )
像这样执行它: libs.bat > libs.txt
。 然后打开libs.txt
并将其内容作为依赖项复制。
就我而言,我只需要库来编译我的代码,这个解决scheme是最好的。
要安装不在maven仓库中的第三方jar,请使用maven-install-plugin。
以下是步骤:
- 从源(网站)手动下载jar文件
- 创build一个文件夹,并在其中放置你的jar文件
- 运行以下命令将第三方jar安装到本地maven仓库中
mvn install:install-file -Dfile = -DgroupId = -DartifactId = -Dversion = -Dpackaging =
下面是我用它simonsite log4j的例子
mvn install:install-file -Dfile = / Users / athanka / git / MyProject / repo / log4j-rolling-appender.jar -DgroupId = uk.org.simonsite -DartifactId = log4j-rolling-appender -Dversion = 20150607-2059 – Dpackaging =jar子
-
在pom.xml中包含依赖如下
<dependency> <groupId>uk.org.simonsite</groupId> <artifactId>log4j-rolling-appender</artifactId> <version>20150607-2059</version> </dependency>
-
运行mvn clean install命令来创build您的打包
以下是参考链接:
https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
对于那些在这里没有find好答案的人来说,这就是我们正在做的事情,以获得一个具有所有必要的依赖关系的jar。 这个答案( https://stackoverflow.com/a/7623805/1084306 )提到使用Maven Assembly插件,但实际上并没有在答案中给出一个例子。 如果你没有读到答案的最后(这很长),你可能会错过它。 将下面的内容添加到您的pom.xml中将生成target/${PROJECT_NAME}-${VERSION}-jar-with-dependencies.jar
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.4.1</version> <configuration> <!-- get all project dependencies --> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- MainClass in mainfest make a executable jar --> <archive> <manifest> <mainClass>my.package.mainclass</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <!-- bind to the packaging phase --> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
这不会回答如何将它们添加到您的POM,可能是一个没有道理,但只是将lib目录添加到您的类path工作? 我知道,当我需要一个外部的jar,我不想将其添加到我的Maven仓库中。
希望这可以帮助。
在我们的项目中有什么作品是Archimedes Trajano写的,但是我们在.m2 / settings.xml里有这样的东西:
<mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <url>http://url_to_our_repository</url> </mirror>
和*应该改为中央。 所以如果他的回答不适合你,你应该检查你的settings.xml
我在@alex lehmann's的回答中提到了一些python代码,所以在这里发表。
def AddJars(jarList): s1 = '' for elem in jarList: s1+= """ <dependency> <groupId>local.dummy</groupId> <artifactId>%s</artifactId> <version>0.0.1</version> <scope>system</scope> <systemPath>${project.basedir}/manual_jars/%s</systemPath> </dependency>\n"""%(elem, elem) return s1
我只是想要一个快速和肮脏的解决方法…我无法从Nikita Volkov运行脚本:语法错误+它需要严格的格式的jar名称。
我制作了这个Perl脚本,它可以与任何格式的jar文件名一起工作,并在xml中生成依赖关系,因此可以直接复制到pom中。
如果您想使用它,请确保您了解脚本正在做什么,您可能需要更改lib
文件夹以及groupId
或artifactId
的值…
#!/usr/bin/perl use strict; use warnings; open(my $fh, '>', 'dependencies.xml') or die "Could not open file 'dependencies.xml' $!"; foreach my $file (glob("lib/*.jar")) { print "$file\n"; my $groupId = "my.mess"; my $artifactId = ""; my $version = "0.1-SNAPSHOT"; if ($file =~ /\/([^\/]*?)(-([0-9v\._]*))?\.jar$/) { $artifactId = $1; if (defined($3)) { $version = $3; } `mvn install:install-file -Dfile=$file -DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version -Dpackaging=jar`; print $fh "<dependency>\n\t<groupId>$groupId</groupId>\n\t<artifactId>$artifactId</artifactId>\n\t<version>$version</version>\n</dependency>\n"; print " => $groupId:$artifactId:$version\n"; } else { print "##### BEUH...\n"; } } close $fh;