【问题标题】:Local jars are not included in class path (`<scope>system</scope>`)本地 jar 不包含在类路径中(`<scope>system</scope>`)
【发布时间】:2011-03-17 21:17:41
【问题描述】:

我正在尝试使用 maven 和 eclipse 构建我的应用程序。 我依赖于我本地机器上的 3rd 方 jars。 这是我的 pom.xml

<dependency>
    <groupId>sourceforge.net</groupId>
   <artifactId>zipdiff</artifactId>
   <version>0.4</version>
   <scope>system</scope>
   <systemPath>C:/gelcap/lib/zipdiff-0.4.jar</systemPath>
</dependency>

<dependency>
    <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.11</version>
</dependency>

当我运行 mvn : install 时,它会为我的项目创建 war 文件。 但问题是它不包含 zipdiff.jar 文件到 web-inf/lib 文件夹它只包含下载的文件。我还需要从本地系统复制文件,但 maven 会忽略它们。 我没有任何想法为什么会发生为什么 maven 没有将具有系统范围的文件包含到我的 war 文件中。 请告诉我如何解决这个问题。 提前致谢

【问题讨论】:

    标签: java maven-2


    【解决方案1】:

    对于“系统”范围,容器应提供人工制品。来自maven docs

    提供

    这很像 compile,但表示您期望 JDK 或 提供依赖的容器 运行。例如,当构建一个 用于 Java 的 Web 应用程序 企业版,您将设置 依赖于 Servlet API 和 提供范围的相关 Java EE API 因为 web 容器提供 那些课。此范围仅 可用于编译和测试 类路径,并且不传递。

    [...]

    系统

    这个范围类似于提供的,除了你必须 提供包含它的 JAR 明确地。神器总是 可用且未在 存储库。

    通过使用系统范围,您向 war 插件指示容器将提供此依赖项。由于这不是您打算做的,因此最简单的解决方案是将工件放在存储库中,可以是您的本地 maven 存储库,也可以是您自己的 Intranet 上的 maven 存储库(如果有的话)。

    install:install-file 目标可用于将单个文件(没有 POM)安装到本地存储库。完成此操作后,将依赖类型更改为“编译”并删除“systemPath”元素。

    在我的日常工作中,我们使用Nexus 来管理我们内部网上的公司范围的存储库。您可以为自己的人工制品和第三方人工制品建立单独的存储库。 Nexus 还充当代理,缓存来自外部存储库的人工制品,大大加快了构建速度。这意味着只有使用其他 repos 中不可用的新依赖项的开发人员必须上传 - 之后,所有其他开发人员都可以使用它 - 他们可以从 SCM 签出并构建,而不必担心依赖项的位置。

    【讨论】:

    • +1 表示 Nexus,另一个虚拟 +1 表示只为库创建工件的建议(使用 nexus,您可以从 Web 前端执行此操作 - 所以即使是本地人,我也建议使用 nexus,单用户环境)
    【解决方案2】:

    我不知道为什么会发生这种情况,为什么 maven 没有将具有系统范围的文件包含到我的 war 文件中。请告诉我如何解决这个问题。

    这是设计使然,system 范围的依赖项应该以documented 的形式提供。

    实际上,我已经写过很多次(herehereherehere)应该避免使用system 范围依赖。它们在大多数情况下都是一种不好的做法,人们在滥用它们,而且它们带来的麻烦几乎总是比好处多。

    如果你想要一个“官方”的观点,让我引用 Dependency Scopes 迷你指南:

    • system:此依赖项在项目生命周期的某个阶段是必需的,但特定于系统。 不鼓励使用此范围:这被认为是一种“高级”功能,只有在您真正了解其使用的所有后果时才应使用,如果不是实际上无法量化,这可能会非常困难。 根据定义,此范围使您的构建不可移植。在某些边缘情况下可能是必要的。系统范围包括&lt;systemPath&gt; 元素,它指向本地机器上此依赖项的物理位置。因此,它用于指代预期会出现在给定本地机器上而不是存储库中的某些工件;并且其路径可能因机器而异。 systemPath 元素可以引用其路径中的环境变量:例如${JAVA_HOME}

    因此,不要使用system 范围,而是:

    • 通过install:install-file 将您的库添加到本地存储库。这是一种让事情顺利进行的快速而肮脏的方式,如果你一个人,它可能是一个选择,但它会使你的构建不可移植。
    • 安装并运行“企业存储库”,如 Nexus、Archiva 或 Artifactory,并通过 deploy:deploy-file 添加您的库。这是理想的场景。
    • 按照this previous answer 中的描述设置一个基于文件的存储库,并将您的库放在那里。如果您没有公司存储库但需要作为一个团队工作并且不想牺牲可移植性,这是最佳折衷方案。

    请停止使用system 范围。

    【讨论】:

      【解决方案3】:

      试试installing the jars to your local repository。当构建时间到时,本地 jar 和更大存储库中的 jar 之间应该没有区别。

      【讨论】:

      • 嗨艾伦,我将我的 jar 文件安装到本地 maven 存储库,但是当我运行目标 maven:install form eclipse 但它仍然没有将 jar 复制到 web-inf/lib 文件夹。我做了以下步骤: 1. 运行以下命令 mvn install:install-file -DgroupId=sourceforge.net -DartifactId=zipdiff -Dversion=0.4 -Dfile=C:/gelcap/lib/zipdiff-0.4.jar -Dpackaging=jar -DgeneratePom=true 它在本地 maven 存储库中为 zipdiff jar 文件创建了一个文件夹。然后从 Eclipse 运行 maven:install。但是仍然创建的战争没有 zipdiff.jar 文件
      • 您还必须更改您的 pom 文件并删除依赖项的范围。然后,Maven 应该从存储库中提取依赖项并将其包含在战争中。
      【解决方案4】:

      只是让我眼前一亮: 在路径中,您使用的是普通的 unix 风格的斜杠 /。 Windows 对路径使用反斜杠: . 我不知道maven是否能够将它们相互转换,所以也许尝试输入路径如下:

      C:\gelcap\lib\zipdiff-0.4.jar

      【讨论】:

      • 不,这并没有什么不同
      【解决方案5】:

      之前没有尝试过这个,所以它可能不起作用,你能改变范围来编译吗?

      <dependency>
         <groupId>sourceforge.net</groupId>
         <artifactId>zipdiff</artifactId>
         <version>0.4</version>
         <scope>compile</scope>
         <systemPath>C:/gelcap/lib/zipdiff-0.4.jar</systemPath>
      </dependency>
      

      【讨论】:

      • 嗨,克里斯,仅供参考,您不能使用具有编译范围的系统路径
      猜你喜欢
      • 2010-09-16
      • 2021-04-12
      • 2012-02-15
      • 2023-03-18
      • 1970-01-01
      • 2015-04-08
      • 2017-04-28
      • 2023-03-11
      相关资源
      最近更新 更多