我可以在没有安装的情况下将jar添加到maven 2 build classpath吗?

686 java maven-2

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

我有一个pom.xml文件定义了我想要使用的web-app框架的依赖项,我可以从该文件快速生成启动项目.但是,有时我想链接到尚未pom.xml定义文件的第三方库,所以不是pom.xml手动创建第三方库的文件并安装它,并将依赖项添加到我的pom.xml,我只是想告诉Maven:"除了我定义的依赖项,还要包含任何罐子/lib."

看起来这应该很简单,但如果是这样,我就会遗漏一些东西.

任何关于如何做到这一点的指针都非常感谢.除此之外,如果有一种简单的方法将maven指向一个/lib目录并轻松创建一个pom.xml所有封闭的jar映射到单个依赖项,然后我可以一次命名/安装和链接就足够了.

Nik*_*kov 586

流行方法的问题

您将在互联网上找到的大多数答案都建议您将依赖项安装到本地存储库,或者在其中指定"系统"范围,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>
Run Code Online (Sandbox Code Playgroud)

对于具有表单组ID的每个工件,x.y.zMaven将在项目目录中包含以下位置以搜索工件:

repo/
| - x/
|   | - y/
|   |   | - z/
|   |   |   | - ${artifactId}/
|   |   |   |   | - ${version}/
|   |   |   |   |   | - ${artifactId}-${version}.jar
Run Code Online (Sandbox Code Playgroud)

要详细说明这一点,您可以阅读此博客文章.

使用Maven安装到项目仓库

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

mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]
Run Code Online (Sandbox Code Playgroud)

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

<repository>
    <id>repo</id>
    <url>file://${project.basedir}/repo</url>
</repository>
Run Code Online (Sandbox Code Playgroud)

帮助脚本

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

在目标包中包含依赖项

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

为了解决这个问题,我建议在目标包中包含这些依赖项.这可以使用Assembly Plugin或更好的OneJar插件.关于OneJar的官方文档很容易理解.

  • 需要注意两点:1)我建议使用"$ {project.baseUri} repo"而不是"file:// $ {project.basedir}/repo"来获取符合RFC标准的URL.2)如果将项目构建为子模块,则此方法似乎失败,因为$ {project.baseUri}被解析为模块的子目录.知道如何解决这个问题吗? (19认同)
  • 这几乎让我在那里 - 但尼基塔的剧本试图用我刚才命名的JAR文件太聪明了.所以我做了一个简化的版本,不会对groupId做任何猜测:https://github.com/carchrae/install-to-project-repo (7认同)
  • 我一直以为你可以在项目中创建一个存储库,最后确认它,太棒了! (3认同)
  • 这么精彩的答案!! 有两种做事方式,正确的方式和工作方式,先生,你做对了! (3认同)

Pyr*_*cal 475

仅限丢弃代码

set 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>
Run Code Online (Sandbox Code Playgroud)

注意:系统依赖关系不会复制到生成的jar/war中
(请参阅如何在使用maven构建的war中包含系统依赖关系)

  • 虽然我理解这是OP所要求的,但我仍然想强调,使用`system`范围是一种可怕的做法,而且非常气馁**.请参阅[依赖关系+范围](http://docs.codehaus.org/display/MAVENUSER/Dependency+Scopes). (75认同)
  • 使用类似这样的systemPath:"<systemPath> $ {basedir} /lib/BrowserLauncher2-1_3.jar </ systemPath>"$ {basedir}指向项目的根目录. (11认同)
  • @marioosh记得这个问题的初衷是为了快速实验.如果你想做一个mvn包,请将jar安装到repo中. (6认同)
  • 谢谢这非常接近我想要的.有什么方法可以将它们全部添加为单个条目?假设我有10个罐子的/ lib,我可以以某种方式添加它们,例如使用/some/path/*.jar作为systemPath吗?或者我仍然需要将每个视为一个已知的依赖?仍然,非常接近我需要的,谢谢! (4认同)
  • 最好使用该项目.路径中的前缀如下:<systemPath> $ {project.basedir} /lib/AwesomeLib.jar </ systemPath> (4认同)
  • @BigMikeW Nikita是男性.这是俄罗斯常见的男性名字. (3认同)
  • 范围系统意味着您必须向Maven2指明必须找到库(在systemPath中指定),因为在Maven2的本地存储库中不会找到依赖项.当库不在任何存储库中并且您不想安装它时,这可能很有用.但是,不鼓励范围系统! (2认同)

Dmy*_*nko 58

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

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

  • libs文件夹中,您应该创建目录结构,如:/groupId/artifactId/version/artifactId-version.jar

  • 在您的pom.xml中,您应该注册存储库

    <repository>
        <id>ProjectRepo</id>
        <name>ProjectRepo</name>
        <url>file://${project.basedir}/libs</url>
    </repository>
    
    Run Code Online (Sandbox Code Playgroud)
  • 并像往常一样添加依赖项

    <dependency>
        <groupId>groupId</groupId>
        <artifactId>artifactId</artifactId>
        <version>version</version>
    </dependency>
    
    Run Code Online (Sandbox Code Playgroud)

就这些.

有关详细信息:如何在Maven中添加外部库

  • 当然,如果您有像'com.foo.bar'那样复杂的groupId,那么您的目录结构应该是/com/foo/bar/artifactId/version/artifactId-verion.jar (5认同)

Ed *_*nin 30

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

如果您的jar位于项目的根目录下,则需要使用$ {basedir}为systemPath值添加前缀.


Arc*_*ano 14

这就是我所做的,它也适用于包问题,它适用于检出的代码.

在我使用的情况下,我在项目中创建了一个新文件夹repo,但随意使用src/repo

在我的POM中,我有一个不在任何公共maven存储库中的依赖项

<dependency>
    <groupId>com.dovetail</groupId>
    <artifactId>zoslog4j</artifactId>
    <version>1.0.1</version>
    <scope>runtime</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)

然后我创建了以下目录repo/com/dovetail/zoslog4j/1.0.1并将JAR文件复制到该文件夹​​中.

我创建了以下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>
Run Code Online (Sandbox Code Playgroud)

我创建的两个可选文件是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
Run Code Online (Sandbox Code Playgroud)

最后,我将以下片段添加到我的pom.xml中,允许我引用本地存储库

<repositories>
    <repository>
        <id>project</id>
        <url>file:///${basedir}/repo</url>
    </repository>
</repositories>
Run Code Online (Sandbox Code Playgroud)


Bri*_*Fox 13

您真的应该通过存储库获得一个框架,并预先确定您的依赖项.使用系统范围是人们常用的错误,因为他们"不关心依赖管理".麻烦的是,这样做你最终会得到一个变态的maven构建,它不会在正常情况下显示maven.你会过得更好像下面的方法这样.


toa*_*oad 12

Maven安装插件有命令行用法将jar安装到本地存储库,POM是可选的,但你必须指定GroupId,ArtifactId,Version和Packaging(所有POM的东西).

  • -1,有时你只想添加一个jar文件而不用安装它. (4认同)

Pra*_*ITI 10

这是我们添加或安装本地jar的方式

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>iamajar</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/iamajar.jar</systemPath>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

我给了一些默认的groupId和artifactId,因为它们是强制性的:)


Jes*_*ick 8

<scope>system</scope>由于其他人解释的原因,使用是一个可怕的想法,手动将文件安装到本地存储库使得构建<url>file://${project.basedir}/repo</url>不可复制,并且使用不是一个好主意,因为(1)可能不是格式良好的fileURL(例如,如果项目在具有异常字符的目录中检出),(2)如果该项目的POM用作其他人项目的依赖项,则结果不可用.

假设您不愿意将工件上传到公共存储库,Simeon建议使用辅助模块来完成工作.但现在有一种更简单的方法......

建议书

使用非maven-jar-maven-plugin.完全是你要求的,没有其他方法的缺点.


xbe*_*eta 8

我找到了另一种方法,从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:
<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>
Run Code Online (Sandbox Code Playgroud)


rea*_*lgt 7

对我来说似乎最简单的就是配置你的 maven-compiler-plugin 来包含你的自定义 jars。此示例将加载 lib 目录中的任何 jar 文件。

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <includes>
                    <include>lib/*.jar</include>
                </includes>
            </configuration>
        </plugin>
Run Code Online (Sandbox Code Playgroud)

  • 如果我添加这个 maven`没有什么可编译的`! (2认同)

Sim*_*lov 6

在与CloudBees人员进行了长时间的讨论之后,他们就这种JAR的正确编组进行了讨论,他们为解决方案提出了一个有趣的好建议:

创建一个假的Maven项目,该项目将预先存在的JAR作为主要工件附加,运行到属于POM的安装:安装文件执行.这是POM的这种kinf的一个例子:

 <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>
Run Code Online (Sandbox Code Playgroud)

但是为了实现它,应该改变现有的项目结构.首先,您应该记住,对于每种这样的JAR,应该创建不同的假Maven项目(模块).应该创建一个父Maven项目,包括所有子模块:所有JAR包装器和现有主项目.结构可以是:

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

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

JAR 2包装Maven子项目(POM包装)

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

当通过mvn:install或mvn:packaging运行父进程时,将执行子模块.这可能是一个减号,因为项目结构应该改变,但最后提供非静态解决方案


atr*_*atr 5

要安装不在 Maven 存储库中的第 3 方 jar,请使用 maven-install-plugin。

以下是步骤:

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

mvn install:安装文件 -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 - D包装=jar

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

      <dependency> 
            <groupId>uk.org.simonsite</groupId>
            <artifactId>log4j-rolling-appender</artifactId>
            <version>20150607-2059</version> 
      </dependency>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 运行 mvn clean install 命令来创建打包

下面是参考链接:

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


jav*_*y79 0

这并没有回答如何将它们添加到你的 POM 中,并且可能是一个简单的问题,但是仅仅将 lib 目录添加到你的类路径中就可以工作吗?我知道当我需要一个我不想添加到我的 Maven 存储库的外部 jar 时我就会这样做。

希望这可以帮助。