Maven:包含未在公共仓库中找到的jar包

65

如果我想使用一个不在maven公共仓库中的第三方库,最好的方法是什么,可以将其作为项目的依赖项包含进去,以便当别人检查我的代码时,仍然能够构建它?

例如:

我的应用程序"A"依赖于jar包"B",但该jar包不存在于公共仓库中。然而,我希望将"B"作为"A"的依赖项添加,这样世界另一端的人可以检出代码并仍然能够构建"A"。


6个回答

65

你可以自己安装这个项目。

或者你可以像下面这样使用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 包,则此方法非常适用于验证其使用情况。 - awhie29urh2
1
为什么我在我的Maven Web项目中使用这个解决方法,该项目无法部署到Tomcat,但编译正常。有什么建议吗?(请不要告诉我安装到本地Maven存储库),谢谢。 - Mr Lou
你救了我的一天,谢谢,notnoop。通过项目属性添加外部jar包似乎就是行不通。 - oohtj
在我的测试中,这种方法可以防止本地jar包被包含在war文件中。Maven不会给出错误消息,它只是不包括war文件。 - Haroldo_OK

18
如果您有一个包含模块的父项目处于这种情况(需要不在仓库中的依赖项),则可以设置父项目使用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中设置的groupid、artifact等方式引用它即可。例如:
<dependency>
    <groupId>net.authorize</groupId>
    <artifactId>anet-java-sdk</artifactId>
    <version>1.4.6</version>
</dependency>

1
这似乎是正确的答案。有没有办法在上面的示例中安装多个依赖项? - javydreamercsw
插件中应该能够有多个<configuration>元素。 - Domenic D.
2
我成功解决了这个问题。我将配置移至执行部分,并对每个依赖项进行多次执行。谢谢! - javydreamercsw
2
所以,我的问题是,如果在最初运行“install”之前将依赖项包含在您的pom中,那么它会尝试在插件有机会安装第三方jar之前收集和解决依赖关系,从而导致构建失败。如果我删除第三方依赖声明,运行“install”,然后将jar声明添加回pom中,然后构建将成功。 - liltitus27
不确定你的情况如何 @liltius27。如果你正在父POM中安装文件,并在模块中使用validate阶段,它应该可以正常工作。如果你试图在一个自包含的模块中完成所有操作,则可能无法正常工作。尽管如此,我会考虑在pre-clean阶段运行安装插件代码。我没有尝试过这样做,但那是你可以钩入并执行自己任务的最早阶段。 - Domenic D.

15

虽然在Maven规范中使用系统作用域可能会生效,但不建议这样做,因为它是不可移植的。

Maven书籍中的描述如下:

system-系统作用域与provided作用域类似,但您必须提供本地文件系统中JAR的显式路径。这旨在允许编译针对可能是系统库的本地对象。假定始终可用该构件,并且不会在存储库中查找。如果将作用域声明为系统,则还必须提供systemPath元素。请注意,不建议使用此作用域(应始终尝试引用公共或自定义Maven存储库中的依赖项)。

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

如果您使用像Nexus这样的存储库管理器,则非常容易实现。


如果我要将它安装到我的本地仓库,那么如果其他人没有访问我的本地仓库的权限,他们该如何构建这个项目呢?例如,如果我有一个公开可用的应用程序,然后你(rperez)想要下载该项目并构建它,那么你如何访问我的本地仓库来构建它呢? - digiarnie
4
因此,我建议使用企业级存储库。像我们正在使用的Nexus这样的企业级存储库具有两种功能: 1)代理公共存储库 - 下载所有所需的第三方库并存储以备将来使用 2)存储组织的所有构件 此外,您还可以存储不在公共域中的库。该存储库可供您希望访问它的任何人使用。您可以将其放在公司内部网络或提供公共URL-由您选择。 - rperez
我认为你的意思是“稳定”或“可重现”,而不是“可移植”。虽然您可以通过确保二进制源是稳定的(即稳定的网络共享或从稳定的服务器下载)来确保稳定性。我认为Maven的建议在这里过于保守了。(话虽如此,将其放入本地Maven存储库仍然是最简单的方法,Maven确保您拥有一致的本地缓存,并且更多的插件可以读取GAV坐标而不是文件路径。) - toolforger

1

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

例如:

1.首先将jar包放入本地存储库中:

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

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

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 来打包或部署您的项目。

第三方 jar 包也将包含在打包文件中。


“mvn install” 如何获取正确的版本/包名称? - monojohnny
Maven将在要安装的JAR的pom.xml中查找版本/包名称。@monojohnny - Chen Zhu
啊,好的 - 所以它假设添加的 JAR 也是由 Maven 生成的(并且也包括 'pom.xml')- 我想是这样的吧? - monojohnny
1
抱歉没有考虑周到。如果JAR包没有pom.xml文件,您可以指定以下内容:mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging> - Chen Zhu
感谢您澄清! - monojohnny
在我的测试中,它仍然无法打包war文件。 - Haroldo_OK

1
这个解决方案对我有用: 1. 在我的项目根目录下创建了一个本地maven仓库,并将所有的jar包复制进去。 2. 执行以下命令,为我需要使用的每个jar包生成必要的pom文件和元数据等;
mvn deploy:deploy-file -DgroupId=<某个组ID> -DartifactId=<某个构件ID> -Dversion=1.0.0 -Durl=file:./local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile= 这样就在local-maven-repo中生成了一个新的带有pom文件的jar文件,我可以像这样将其作为依赖项包含到我的项目中;
    <dependency>
        <groupId>somegroupid</groupId>
        <artifactId>someartifact</artifactId>
        <version>1.0.0</version>
    </dependency>

然后,mvn package 确保我的项目依赖项已解决,并将其打包到我的 war 文件中。

0

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

  1. 转到项目资源管理器,右键单击项目。
  2. 单击导入选项。
  3. 展开Maven选项,选择安装或部署Maven存储库中的构件并单击下一步。
  4. 使用Artifact File选项浏览并选择第三方依赖项,并使用POM.xml文件输入Group Id、Artifact Id和Version的详细信息,然后单击完成

等待一段时间,可能会消除该问题的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接