【问题标题】:Maven: keeping dependent jars in project version controlMaven:在项目版本控制中保留依赖的 jar
【发布时间】:2011-03-14 16:00:53
【问题描述】:

所以,我有一个包含多个依赖 jar 的战争项目,这些 jar 在任何存储库中都不可用。直到最近,我一直将它们保存在 src/main/webapp/WEB-INF/lib 中,并使用 system scope 将它们添加到 pom 中。

我知道这是有问题的,所以我正在寻找清理我的构建。我已经通过install:install-file 插件将罐子半手动安装到我的.m2/repository 中。这对我来说很好,但我团队中的其他人呢?我们很小,设置 Nexus 对我们来说并不是一个真正的选择。我已经求助于将 cmets 添加到 pom.xml 解释如何为每个 jar 运行 install:install-file

install:install-file 解决方案我没问题,但我仍然想将这些工件包含在我的项目的版本控制中,而不仅仅是让它们散布在我的文件系统中。

将它们保存在src/main/webapp/WEB-INF/lib 中不起作用,因为这会自动将它们添加到生成的战争工件中(题外话:如果 maven 只是继续并将它们添加到这里的类路径中,我就完成了,无需安装:安装文件!)

问题:在 maven 目录布局中是否有一个允许的位置,我可以将这些 .jar 文件放入其中,以便我可以将它们作为我项目的一部分?

我确实意识到这里发生了什么 - Maven 试图将依赖 jars 放在我的构建之外,以便当其他项目依赖于我的构建时,它们可以解决传递依赖关系。这对于进入公共 maven 存储库的开源项目来说非常棒,但我敢打赌,绝大多数使用 Maven 的人都在从事诸如此类的“叶”项目,并且有一种方法真的很方便将 jar 文件作为项目的一部分包含在内,而无需跳过这么多环节。

【问题讨论】:

  • 设置 Nexus 非常简单。我在家里有一个只为我自己运行的实例。
  • 使用 nexus 创建本地存储库会不会太过分了?您可以使用它来代理所有 maven 存储库并保留那些 3rd 方 jar。
  • 当然,我可以安装 Nexus。但后来我不得不要求所有接触这个项目的人也这样做。或者在服务器上设置、备份、担心安全等。处理几个自定义 jar 文件似乎是一个非常麻烦的解决方案。
  • 如果您按照预期使用 Maven 的方式使用 Maven,这不是“越过障碍”。 maven-release-plugin 以及正确的 maven-scm-plugin<distributionManagement/> 指令在您的 pom.xml 中使这一切变得透明。
  • 看我的回答,你不用要求每个接触项目的人做任何事情,都在用于构建项目的pom.xml。如果编辑他们的settings.xml 要求太多,那么只需将存储库信息嵌入pom.xml,这是不好的做法,但进入门槛很低。

标签: java maven


【解决方案1】:

如果按照 Jan 的建议设置 Nexus 或只是一个简单的文件服务器存储库真的太麻烦了,这里有一些其他选项:

  • 只需包含 JAR 和脚本,即可将它们全部安装到您在版本控制中选择的目录中。不需要 Maven 结构来批准它。
  • 将您的版本控制系统用作存储库的主机,可以在主项目中的分支上单独使用,也可以作为单独的项目使用。让您在版本控制方面已有的任何备份、安全性等都应用到存储库,而无需在实际签出和提交的文件集中包含 jar。
  • 将 jars 包含在一个文件夹中,该文件夹充当与其余代码一起签出的迷你存储库。让 pom.xml 指向该文件夹作为它使用的存储库。我不能 100% 确定这是可能的,但似乎很有可能。

【讨论】:

  • 我们遵循您的第一个建议。 Maven 不支持您最后的建议。
  • +1:最后一个建议似乎也有效(使用 Maven 2.2.1)。
  • 我几乎想给你一个 +1 只是因为没有回应“但实际上,设置 Nexus 并不难。” :-) 在一些(很多?)项目中,设置像 Nexus 这样的工具根本不是一种选择。如果您没有团队/资源来像维护源代码库一样仔细维护该外部存储库,那么将工件保留在主源代码库之外并不是一个好主意。使用 ant 的人只需将 jar 塞入 lib 目录即可。我经常希望 Maven 采用“简单的事情应该简单”的口号。感谢您的回复。
  • 我们目前正在做第一个选项。这让我不满意,因为它仍然引入了在构建可以以 Maven 不知道的方式完成之前需要执行的步骤。例如,如果您在某处设置 CI 服务器或远程构建,则不能将其指向 Maven 项目并让它正常工作。在我看来,这是一个非常常见的用例,Maven 假装它不存在。
【解决方案2】:

这里已经有很多很好的答案,您应该强烈考虑为您的团队设置一个存储库管理器,例如 Archiva,因为它现在和随着时间的推移都会提供其他好处。

但是,为了直接回答您的问题,这里有一个使用 Maven 在版本控制中存储依赖项的模式:http://brettporter.wordpress.com/2009/06/10/a-maven-friendly-pattern-for-storing-dependencies-in-version-control/

请记住,它将项目限制为自包含使用 - 如果您开始希望将其作为其他 Maven 项目的依赖项共享,您仍然需要设置一个存储库。

【讨论】:

    【解决方案3】:

    我认为在您的情况下最好的解决方案是设置一个 internal 存储库。一开始不需要设置整个 Nexus。任何简单的网络服务器都足够或在某处共享文件夹。

    查看Maven DOC,了解如何设置内部存储库。

    【讨论】:

    • Maven 包含 install:install-file 只是为了这个目的。将 ~/.m2/repository 放到 /network/maven/repository 有多难?也许 nexus 是多余的,也许 HTTP 是多余的,但是文件服务器呢?这些怎么可能不是一个选择?
    • @Chris 在一个足够复杂的公司中,源代码控制服务器可能是所有相关方都可以访问的唯一服务器;虽然从长远来看,内部 maven 存储库可能是最佳选择,但需要一些东西来弥合过渡期。
    • @Lars:一个足够复杂的公司,有很多人在使用 Maven,绝对应该使用某种内部存储库,不仅仅是为了提供公共存储库中不可用的 3rd 方工件,而且还允许共享项目之间的内部工件。使用 Maven 意味着除了源代码控制之外还需要一个存储库。
    • @Lars:即使这是真的,您也可以使用 SCS 作为您的存储库,完全在 maven 外部。
    • @ColinD 我同意,应该是这样。但生活并不总是那么善良,这个问题被一遍又一遍地问到这一点就证明了这一点。 - @Chris 这不是 OP 所问的,如何访问签入源代码控制系统的工件? install:install-file 有效,但显得相当笨重。
    【解决方案4】:

    在我的公司,我们使用Archiva,它是迄今为止设置和维护最简单的存储库管理器。特别是如果您使用基于独立的版本。每个开发人员只需在他们的~/.m2/settings.xml 文件中设置一个profile 以指向内部存储库。如果这样比较麻烦,直接把<repositories/>里面的内部仓库放到pom.xml里面,但那确实是不好的做法。如果存储库 url 移动,您必须更新所有项目 pom.xml 文件。而使用settings.xml 会给开发人员带来更新其本地配置的负担。

    <?xml version="1.0" encoding="UTF-8"?>
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
        <profiles>
            <profile>
                <id>internal</id>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
                <repositories>
                    <repository>
                        <id>mycompany.internal</id>
                        <name>Internal Release Repository</name>
                        <url>http://maven.mycompany.com/repository/internal/</url>
                        <releases>
                            <enabled>true</enabled>
                        </releases>
                        <snapshots>
                            <enabled>false</enabled>
                        </snapshots>
                    </repository>
                    <repository>
                        <id>mycompany.snapshots</id>
                        <name>Internal Snapshot Repository</name>
                        <url>http://maven.mycompany.com/repository/snapshots/</url>
                        <releases>
                            <enabled>false</enabled>
                        </releases>
                        <snapshots>
                            <enabled>true</enabled>
                        </snapshots>
                    </repository>
                </repositories>
            </profile>
        </profiles>
    
    
        <servers>
            <server>
                <id>internal</id>
                <username>guest</username>
            </server>
            <server>
                <id>snapshots</id>
                <username>guest</username>
            </server>
        </servers>
    
    </settings>
    

    如果设置存储库管理器太麻烦,我认为您需要重新考虑手动将内容手动添加到本地存储库的替代方案,这非常容易出错且耗时。我为我的个人开发运行了一个 Archiva 实例,只是因为添加 release 插件和管理版本非常容易,而无需记住将内容添加到每台机器上的本地存储库所需的所有神秘的 -D 选项。复制~/.m2/settings.xml 文件非常简单,如果它可以在一台机器上运行,那么它可以在所有机器上运行。

    这是您添加到 pom.xml 的内容,以启用自动发布并将工件推送到存储库,在我的例子中是 Archiva。

    <distributionManagement>
       <repository>
           <id>internal</id>
           <name>Internal Archiva Repository</name>
           <url>http://maven.mycompany.com/repository/internal/</url>
           <layout>default</layout>
           <uniqueVersion>false</uniqueVersion>
       </repository>
       <snapshotRepository>
           <id>snapshots</id>
           <name>Internal Archiva Repository</name>
           <url>http://maven.mycompany.com/repository/snapshots/</url>
           <layout>default</layout>
           <uniqueVersion>false</uniqueVersion>
       </snapshotRepository>
    </distributionManagement>
    

    然后您只需mvn clean release:prepare 自动更新您的pom.xml 版本签入标签 和可选分支 版本和打包所有工件,然后mvn release:perform 将工件推送到远程存储库并签入新版本的pom.xml,您就可以开始下一个版本的开发了。

    Snapshots 到 snaphots,Release 到 internal一次也是。

    这就是 git 的样子,我们使用 Gitorious 作为我们的 git Repository Manager

    <scm>
        <connection>scm:git:git://gitorious.mycompany.com:myproject/myproject.git</connection>
        <developerConnection>scm:git:ssh://git@gitorious.mycompany.com/myproject/myproject.git</developerConnection>
        <url>http://gitorious.mycompany.com/myproject/myproject</url>
    </scm>
    

    运行 Linux 的旧台式计算机可以为开发团队处理此类存储库职责,而无需涉及采购和 IT。

    【讨论】:

      【解决方案5】:

      我在现实生活中没有使用过它,但它似乎正在工作:只需将存储库布局粘贴到源代码树中(我想使用 install:install-file)并签入。使用条目指向到那个回购。像这样的pom:

      <?xml version="1.0" encoding="utf-8"?>
      <project>
        <modelVersion>4.0.0</modelVersion>
        <name>Depending project</name>
      
        <groupId>com.example</groupId>
        <artifactId>dependent</artifactId>
        <version>0.9</version>
        <packaging>jar</packaging>
      
        <dependencies>
          <dependency>
            <groupId>com.example</groupId>
            <artifactId>dependency</artifactId>
            <version>0.9.3</version>
            <type>jar</type>
          </dependency>
        </dependencies>
      
        <repositories>
      
          <repository>
            <id>project-specific-deps</id>
            <name>project-specific-deps</name>
            <url>file:///${basedir}/repo</url>
          </repository>
      
        </repositories>
      
      </project>
      

      像这样的示例树:

      .
      |-- pom.xml
      |-- repo
      |   `-- com
      |       `-- example
      |           `--dependency
      |               |-- 0.9.3
      |               |   |-- dependency-0.9.3.jar
      |               |   |-- dependency-0.9.3.jar.md5
      |               |   |-- dependency-0.9.3.jar.sha1
      |               |   |-- dependency-0.9.3.pom
      |               |   |-- dependency-0.9.3.pom.md5
      |               |   `-- dependency-0.9.3.pom.sha1
      |               |-- maven-metadata.xml
      |               |-- maven-metadata.xml.md5
      |               `-- maven-metadata.xml.sha1
      |-- src
      |   `-- main
      |       `-- java
      |           `-- com
      |               `-- example
      |                   `-- dependent
      |                       `-- Foobar.java
      

      听起来怎么样?

      为了完整性:

      $ mvn -version
      Apache Maven 2.2.1 (rdebian-4)
      Java version: 1.6.0_20
      Java home: /usr/lib/jvm/java-6-sun-1.6.0.20/jre
      Default locale: sv_SE, platform encoding: ISO-8859-1
      OS name: "linux" version: "2.6.32-3-686" arch: "i386" Family: "unix"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-01
        • 1970-01-01
        • 2017-01-30
        • 1970-01-01
        • 2011-02-03
        • 2016-10-16
        • 2021-11-22
        • 2014-10-13
        相关资源
        最近更新 更多