java - maven介绍 - maven安装




我可以将jar添加到maven 2生成类路径而不安装它们吗? (16)

在实验/快速和肮脏的模拟开发阶段,Maven2令我疯狂。

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

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

任何指示如何做到这一点非常感谢。 简而言之,如果有一种简单的方法可以将maven指向/lib目录,并轻松创建一个pom.xml并将所有封闭的jar映射到单个依赖项,然后我可以一举命名/安装并链接到该目录。也足够了。


流行方法的问题

你可以在互联网上找到的大部分答案都建议你将依赖关系安装到本地存储库,或者在pom指定一个“系统”作用域,并将依赖项与项目源分配。 但是这两种解决方案实际上都有缺陷。

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

当你将一个依赖项安装到本地存储库时,它仍然存在。 只要有权访问此存储库,分发工件就会正常工作。 问题是在大多数情况下,这个存储库将驻留在本地计算机上,因此无法解决对其他任何计算机的依赖关系。 清楚地让你的神器依赖于特定的机器不是一种处理事物的方式。 否则,这种依赖性必须在每个使用该项目的机器上进行本地安装,这种情况并不会好转。

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

您使用“系统范围”方法所依赖的jar既不会被安装到任何存储库,也不会附加到您的目标程序包。 这就是为什么您的发行包在使用时无法解决该依赖性的原因。 我相信这就是为什么系统范围的使用甚至被弃用的原因。 无论如何,你不想依赖于不推荐使用的功能。

静态的项目内库解决方案

把它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形式的组ID的每个工件,Maven将在您的工程目录中包含以下位置以查找工件:

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

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

使用Maven安装到项目回购

我建议使用Maven插件将瓶子安装为工件,而不是手动创建此结构。 因此,要在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 lib到项目存储库,同时自动解析所有元数据(groupId,artifactId等)从文件的名字。 该脚本还会打印出依赖关系xml供您复制粘贴到您的pom

将依赖包括在你的目标包中

当你创建了你的项目库时,你已经解决了项目的依赖关系和源代码的问题,但是从那时起,你的项目的目标项目将取决于未发布的jar,所以当你安装它到一个仓库它将有无法解决的依赖关系。

为了解决这个问题,我建议将这些依赖包括在你的目标包中。 这可以通过Assembly Plugin或OneJar插件更好地完成 。 OneJar上的官方文档很容易理解。


Maven安装插件具有命令行用法将jar安装到本地存储库中,POM是可选的,但您必须指定GroupId,ArtifactId,Version和Packaging(所有POM内容)。


快速和肮脏的批次解决方案(基于Alex的回答):

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并将其内容作为依赖项复制。

就我而言,我只需要库来编译我的代码,而这个解决方案就是最好的解决方案。


仅用于丢弃代码

设置范围==系统,只是组成一个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构建的war中包含系统依赖关系


即使它不完全适合你的问题,我会在这里放弃。 我的要求是:

  1. 无法在在线Maven存储库中找到的Jars应该位于SVN中。
  2. 如果一个开发人员添加了另一个库,则其他开发人员不应该为手动安装而烦恼。
  3. IDE(我的NetBeans)应该能够找到源代码和javadoc以提供自动完成和帮助。

先来讨论一下(3):只需将文件夹放在一个文件夹中,并将它们合并到最终的jar文件中就行不通了,因为IDE不会理解这一点。 这意味着所有库必须正确安装。 但是,我不想让每个人都使用“mvn install-file”来安装它。

在我的项目中,我需要metawidget。 开始了:

  1. 创建一个新的Maven项目(将其命名为“shared-libs”或类似的东西)。
  2. 下载metawidget并将zip解压缩到src / main / lib中。
  3. 文件夹doc / api包含javadocs。 创建内容的压缩文件(doc / api / api.zip)。
  4. 像这样修改pom
  5. 构建项目并安装库。
  6. 将库作为依赖项添加到项目中,或者(如果您在shared-libs项目中添加了依赖项)将shared-libs作为依赖项添加到一次获取所有库。

每当你有一个新的图书馆,只需添加一个新的执行,并告诉每个人再次建立项目(你可以改善项目层面的这个过程)。


在与CloudBees人员进行了长时间的讨论之后,他们就这种类型的JAR进行了适当的Maven打包,他们为解决方案提出了一个有趣的好建议:

创建一个假的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,都应该创建不同的假Maven项目(模块)。 并且应该创建一个父Maven项目,其中包括所有的子模块,它们是:所有JAR包装器和现有的主项目。 结构可以是:

根项目(这包含父POM文件包含所有具有模块 XML元素的子模块)(POM打包)

JAR 1包装Maven儿童项目(POM包装)

JAR 2包装Maven儿童项目(POM包装)

主要存在的Maven儿童项目(WAR,JAR,EAR ....包装)

当通过mvn:install或mvn:packaging运行的父级被强制执行并且子模块将被执行时。 这可能会被忽视,因为项目结构应该改变,但最终会提供非静态解决方案


如果你想要一个快速和肮脏的解决方案,你可以做以下事情(尽管除了测试项目我不建议这样做,maven会长时间抱怨这是不合适的)。

为每个需要的jar文件添加一个依赖项,最好使用perl脚本或类似的东西,并将其复制/粘贴到你的pom文件中。

#! /usr/bin/perl

foreach my $n (@ARGV) {

    [email protected]*/@@;

    print "<dependency>
    <groupId>local.dummy</groupId>
    <artifactId>$n</artifactId>
    <version>0.0.1</version>
    <scope>system</scope>
    <systemPath>\${project.basedir}/lib/$n</systemPath>
</dependency>
";

对于那些在这里没有找到好答案的人,这就是我们正在做的事情,以获得一个具有所有必要的依赖关系的jar。 这个答案( https://.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>

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

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

  • libs文件夹中,您应该创建如下目录结构: /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构建,在正常情况下不会显示maven。 遵循这样的方法会更好。


我只是想要一个快速和肮脏的解决方法......我无法从Nikita Volkov运行脚本:语法错误+它需要严格的jar名称格式。

我制作了这个Perl脚本,它可以处理任何jar文件名的格式,并且它会在xml中生成依赖关系,因此它可以直接复制到pom中。

如果您想使用它,请确保您了解脚本正在执行的操作,您可能需要更改lib文件夹以及groupIdartifactId的值...

#!/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;

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

注意:使用系统范围时( 如本页所述 ),Maven需要绝对路径。

如果您的jar包在您项目的根目录下,那么您需要在$ {basedir}前添加systemPath值。


要安装不在maven仓库中的第三方jar,请使用maven-install-plugin。

以下是步骤:

  1. 从源(网站)手动下载jar文件
  2. 创建一个文件夹并将你的jar文件放入其中
  3. 运行以下命令以在本地maven存储库中安装第三方jar

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 =罐子

  1. 在pom.xml中包含如下的依赖项

      <dependency> 
            <groupId>uk.org.simonsite</groupId>
            <artifactId>log4j-rolling-appender</artifactId>
            <version>20150607-2059</version> 
      </dependency>
    
  2. 运行mvn clean install命令来创建包装

以下是参考链接:

https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html


这并没有回答如何将它们添加到您的POM中,并且可能是一个没有道理的,但只是将lib目录添加到您的类路径工作? 我知道当我需要一个外部的jar时,我不想将这个jar添加到我的Maven仓库中。

希望这可以帮助。


这是我们如何添加或安装本地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,因为它们是必需的:)







maven-2