Maven 2在开发的实验/快速和粗糙的模型阶段快把我逼疯了。

我有一个pom.xml文件,它定义了我想要使用的web-app框架的依赖关系,我可以从该文件快速生成启动项目。然而,有时我想链接到一个尚未定义pom.xml文件的第三方库,因此我不会手动为第三方库创建pom.xml文件并安装它,并将依赖项添加到我的pom.xml中,我只想告诉Maven:“除了我定义的依赖项之外,还包括/lib中的任何jar。”

似乎这应该是简单的,但如果是,我错过了一些东西。

任何关于如何做到这一点的建议都非常感谢。除此之外,如果有一种简单的方法将maven指向/lib目录,并轻松地创建一个pom.xml,将所有附带的jar映射到一个依赖项,然后我可以将其命名为/ install并链接到它,这也足够了。


当前回答

我只是想要一个快速而肮脏的变通办法……我不能从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;

其他回答

您可以在项目上创建本地存储库

例如,如果你在项目结构中有libs文件夹

在libs文件夹中创建目录结构:/groupId/artifactId/version/artifactId-version.jar 在pom.xml中,您应该注册存储库 <库> <标识> ProjectRepo id > < / <名称> ProjectRepo < /名称> < url >文件:/ / $ {project.basedir} / libs url > < / < /库> 并像往常一样添加依赖项 < >的依赖 < groupId > groupId < / groupId > < artifactId > artifactId < / artifactId > <版本> > < /版本 < / >的依赖

仅此而已。

有关详细信息:如何在Maven中添加外部库(已存档)

仅用于丢弃代码

设置scope == system,只需要创建groupId, artifactId和version

<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构建的war中包含系统依赖项)

这并没有回答如何将它们添加到您的POM中,并且可能是一个无需动脑的问题,但只是将lib目录添加到您的类路径工作吗?我知道,当我需要一个外部jar,但又不想添加到Maven reppos时,我就会这样做。

希望这能有所帮助。

流行方法的问题

在互联网上找到的大多数答案都会建议您将依赖项安装到本地存储库中,或者在pom中指定“系统”作用域,并将依赖项与项目的源代码一起分发。但这两种解决方案实际上都有缺陷。

为什么你不应该应用“安装到本地回购”的方法

When you install a dependency to your local repository it remains there. Your distribution artifact will do fine as long as it has access to this repository. The problem is in most cases this repository will reside on your local machine, so there'll be no way to resolve this dependency on any other machine. Clearly making your artifact depend on a specific machine is not a way to handle things. Otherwise this dependency will have to be locally installed on every machine working with that project which is not any better.

为什么不应该应用“系统范围”方法

使用“System Scope”方法依赖的jar既不能安装到任何存储库中,也不能附加到目标包中。这就是为什么你的发行包在使用时没有办法解决这个依赖。我相信这就是为什么不提倡使用系统作用域的原因。无论如何,你不想依赖一个已弃用的特性。

静态项目内存储库解决方案

把这个放进你的诗里后:

<repository>
    <id>repo</id>
    <releases>
        <enabled>true</enabled>
        <checksumPolicy>ignore</checksumPolicy>
    </releases>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <url>file://${project.basedir}/repo</url>
</repository>

对于每个具有x.y.z形式的组id的工件,Maven将在其搜索工件时在您的项目目录中包含以下位置:

repo/
| - x/
|   | - y/
|   |   | - z/
|   |   |   | - ${artifactId}/
|   |   |   |   | - ${version}/
|   |   |   |   |   | - ${artifactId}-${version}.jar

要详细说明这一点,你可以阅读这篇博文。

使用Maven安装到项目repo

我建议使用Maven插件将jar作为工件安装,而不是手工创建这个结构。因此,要在repo文件夹下将工件安装到项目内存储库执行:

mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]

如果你选择这种方法,你将能够在pom中简化存储库声明:

<repository>
    <id>repo</id>
    <url>file://${project.basedir}/repo</url>
</repository>

辅助脚本

由于为每个lib执行安装命令有点烦人,而且肯定容易出错,所以我创建了一个实用程序脚本,它自动将lib文件夹中的所有jar安装到项目存储库中,同时从文件名自动解析所有元数据(groupId, artifactId等)。该脚本还打印出依赖项xml,供您复制粘贴到pom中。

在目标包中包含依赖项

当您创建了项目内存储库时,您就解决了项目与其源的依赖关系分布问题,但是从那时起,项目的目标工件将依赖于未发布的jar,因此当您将其安装到存储库时,它将具有无法解决的依赖关系。

为了解决这个问题,我建议在目标包中包含这些依赖项。这可以用Assembly Plugin或者更好的OneJar Plugin来实现。OneJar的官方文档很容易掌握。

我在@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