Maven:包括在公共存储库中找不到的 jar

Posted

技术标签:

【中文标题】Maven:包括在公共存储库中找不到的 jar【英文标题】:Maven: Including jar not found in public repository 【发布时间】:2010-11-24 05:48:23 【问题描述】:

如果我要使用不在 maven 公共存储库中的 3rd 方库,将它作为我的项目的依赖项包含在内的最佳方法是什么,以便当其他人检查我的代码时它仍然能够构建?

我的应用程序“A”依赖于公共存储库中不存在的 jar “B”。但是,我希望将“B”添加为“A”的依赖项,这样当世界另一端的人可以检查代码并仍然能够构建“A”时

【问题讨论】:

Can I add jars to maven 2 build classpath without installing them? 的可能重复项 【参考方案1】:

您可以自己安装项目。

或者您可以使用system 范围,如下所示:

<dependency>
    <groupId>org.group.project</groupId>
    <artifactId>Project</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>$basedir/lib/project-1.0.0.jar</systemPath>
</dependency>

systemPath 需要项目的绝对路径。为方便起见,如果 jar 文件位于存储库/项目中,您可以使用绑定到项目根目录的 $basedir 属性。

【讨论】:

如果 jar 在存储库管理器中不可用,这对于验证 jar 的使用非常有效。 为什么我在我的 maven web 项目中使用这个变通方法,该项目不能部署到 tomcat,但可以编译。有什么建议吗?(不要告诉我安装到本地 maven 存储库),谢谢 你拯救了我的一天,谢谢,不是noop。以某种方式通过项目属性添加外部 jar 是行不通的。 在我的测试中,这种方法可以防止本地jar被包含在war文件中。 Maven 没有给出错误信息,它只是不包括战争。【参考方案2】:

如果您的父项目带有处于这种情况的模块(需要不在存储库中的依赖项),您可以设置您的父项目以使用 exec-maven-plugin 插件来自动安装您的依赖文件。例如,我必须使用 authorize.net jar 文件来执行此操作,因为它不是公开可用的。

父 POM:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <inherited>false</inherited>
            <executions>
                <execution>
                    <id>install-anet</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <executable>mvn</executable>
                <arguments>
                    <argument>install:install-file</argument>
                    <argument>-Dfile=service/lib/anet-java-sdk-1.4.6.jar</argument>
                    <argument>-DgroupId=net.authorize</argument>
                    <argument>-DartifactId=anet-java-sdk</argument>
                    <argument>-Dversion=1.4.6</argument>
                    <argument>-Dpackaging=jar</argument>
                </arguments>
            </configuration>
        </plugin>
    </plugins>
</build>

在上面的例子中,jar 的位置在“service”模块的 lib 文件夹中。

当服务模块进入验证阶段时,jar 将在本地存储库中可用。只需按照您在父 pom.xml 中设置 groupid、artifact 等的方式引用它。例如:

<dependency>
    <groupId>net.authorize</groupId>
    <artifactId>anet-java-sdk</artifactId>
    <version>1.4.6</version>
</dependency>

【讨论】:

这似乎是正确的答案。有没有办法在上面的示例上安装多个依赖项? 插件中应该可以有多个 元素。 我能弄明白。我在执行部分中移动了配置,然后进行了多次执行,每个依赖项执行一次。谢谢! 所以,我的问题是,通过遵循这种方法,如果您在最初运行 install 之前将依赖项包含在您的 pom 中,那么它会尝试在插件启动之前收集和解决依赖项有机会安装第三方 jar,因此构建失败。 II 删除第三方依赖声明,运行install,然后jar被安装到我的本地存储库,我可以将jar声明添加回pom,然后构建成功。 不确定你的情况是@liltius27。如果您在父 pom 中安装文件,并在模块中使用 validate 阶段,它应该可以正常工作。如果您试图在一个独立的模块中完成这一切,它可能无法正常工作。不过,我会考虑在预清理阶段运行安装插件代码。我没有尝试过,但这是您可以挂钩以执行自己的任务的最早阶段。【参考方案3】:

使用系统范围可能有效,但即使在 Maven 规范中也不建议这样做。 它不是便携式的。

来自 Maven 书:

system- 系统范围与提供的类似,不同之处在于您 必须提供一个 本地文件系统上 JAR 的显式路径。这是为了允许编译 针对可能是系统库一部分的本机对象。假设工件 始终可用并且不在存储库中查找。如果您声明范围为 是系统,您还必须提供 systemPath 元素。请注意,此范围不是 推荐(您应该始终尝试在公共或自定义 Maven 中引用依赖项 存储库)。

最好的方法是安装到您的本地存储库或企业存储库,以便您的所有同行都可以访问。

如果您使用的是 Nexus 等存储库管理器,这非常容易。

【讨论】:

如果我将它安装到我的本地 repo,如果其他人无法访问我的本地 repo,他们将如何构建项目?例如,如果我有一个在线公开的应用程序,然后您 (rperez) 想要下载该项目并构建它,您将如何访问我的本地存储库来构建它? 这就是我建议使用企业存储库的原因。当你有耳鼻喉科。像我们正在使用的 Nexus 这样的存储库,它以两种方式发挥作用:1) 代理到公共存储库 - 下载所有需要的第 3 方库并存储它们以备将来使用 2) 存储您组织的所有工件此外您还可以存储不在公共领域的图书馆。任何人都可以访问此存储库。您可以将其放在公司内部网中或给它一个公共 URL - 您的选择。 我认为您的意思是“稳定”或“可重现”,而不是便携。尽管您可以通过确保二进制文件的来源稳定来确保稳定性,即稳定的网络共享,或者从稳定的服务器下载。我认为 Maven 的建议在这里过于保守。 (也就是说,将它放在本地 Maven 存储库中仍然是最简单的方法,Maven 确保您拥有一致的本地缓存,并且更多插件可以读取 GAV 坐标而不是文件路径。)【参考方案4】:

一般来说,您应该首先将 3rd 方 jar 放入您的本地存储库。之后,您可以通过将依赖项添加到 pom.xml 中来使用它。

例如。

1.先将jar放入本地仓库:

mvn install:install-file -Dfile=<path-to-file>

注意:此命令需要 maven-install-plugin 2.5 或更高版本。如果没有,可以参考Here

2.通过将依赖项添加到项目的 pom.xml 中来使用 jar。 只需将其添加到项目的 pom.xml 中即可:

<dependency>
  <groupId>$the groupId in the jar's pom.xml</groupId>
  <artifactId>$the artifactId in the jar's pom.xml</artifactId>
  <version>$the version in the jar's pom.xml</version>
</dependency>

3.然后您可以通过运行mvn packagemvn deploy 来打包或部署您的项目

第 3 方 jar 也将包含在包中。

【讨论】:

“mvn install”如何在这里找到正确的版本/包名称? maven 会在要安装的 jar 的 pom.xml 中找到版本/包名。 @monojohnny 啊,好吧-所以它假设添加的 JAR 也是由 Maven 生成的(并且还包括“pom.xml”)-我想? sry 不体贴。如果 jar 没有 pom.xml,您可以指定它们:mvn install:install-file -Dfile=&lt;path-to-file&gt; -DgroupId=&lt;group-id&gt; -DartifactId=&lt;artifact-id&gt; -Dversion=&lt;version&gt; -Dpackaging=&lt;packaging&gt; 感谢您的澄清!【参考方案5】:

这个解决方案对我有用; 1.在我项目的根目录中创建了一个local-maven-repo,并将我所有的jar都复制到了 2. 执行以下命令,为我需要使用的每个 jar 生成必要的 pom 文件和元数据等;

mvn deploy:deploy-file -DgroupId=&lt;somegroupid&gt; -DartifactId=&lt;someartifact&gt; -Dversion=1.0.0 -Durl=file:./local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=&lt;path to jar file&gt;

这在 local-maven-repo 中生成了一个带有 pom 文件的新 jar 文件,我能够像这样将其作为依赖项包含到我的项目中;

    <dependency>
        <groupId>somegroupid</groupId>
        <artifactId>someartifact</artifactId>
        <version>1.0.0</version>
    </dependency>

然后mvn package 确保我的项目依赖项已解决并与我的war文件打包。

【讨论】:

【参考方案6】:

如果您使用的是 groovy/grail 工具套件 (GGTS),那么您可以使用以下步骤直接导入该第三方依赖项(但请确保您的本地存储库中有该第三方依赖项):

    转到项目资源管理器并右键单击项目。 点击导入选项。 展开 ma​​ven 选项并选择 Install or deploy an 工件到 Maven 存储库,然后单击下一步。 使用 工件文件 浏览并选择第三方依赖项 选项并输入 Group Id、Artifact Id 和 Version 的详细信息 使用 POM.xml 文件并点击 finish

稍等片刻,这个问题可能会出错。

【讨论】:

以上是关于Maven:包括在公共存储库中找不到的 jar的主要内容,如果未能解决你的问题,请参考以下文章

SBT 在本地 maven 存储库中找不到文件,尽管它在那里

maven 在我的存储库中找不到原型

Gradle在本地Maven存储库中找不到现有的依赖项

MVN 安装,在本地存储库中找不到工件

maven-shade-plugin 错误:在“资源”的 org.apache.maven.plugins.shade.resource.ManifestResourceTransformer 中找不

如何在maven存储库中找到正确的JAR版本