【问题标题】:how does a Java program find its Maven packages?Java 程序如何找到它的 Maven 包?
【发布时间】:2018-03-14 20:59:22
【问题描述】:

我在 IntelliJ 中有一个 Java 程序,它有一个 pom.xml 并使用 Maven。软件包已下载,目前由 IntelliJ 找到。

我有点困惑,因为据我所知,Maven 存储库不是 CLASSPATH 的一部分。那么,IntelliJ 是否只是在查看其 Maven 存储库以查找包时做了一些魔术? (我认为 IntelliJ 有自己的 Maven 存储库。我单独安装了 Maven 3,但我认为它没有使用它。)

但更一般地说:如果您使用 Maven 构建 JAR,那么我想它会将依赖项放在 Java 程序可以找到它们的 JAR 中,所以不会有问题。但是如果你只是直接运行一个 Java 程序,你需要将 Maven 存储库添加到你的类路径中还是会发生其他事情?

感谢您提供的任何信息以减少我的困惑:)

【问题讨论】:

  • Maven 是一个(依赖和构建)工具,独立于 Java。当 Maven 生成 Jar 时,您可以选择确定如何处理依赖项。您可以忽略它们——这对于预期在类路径中已经有其他依赖项可用的库很有用;您可以生成一个“fat jar”,它将所有依赖项解包,然后将它们与您的程序一起打包到一个 jar 中;您可以生成一个 Jar Manifest,其中包括 Java 在加载条目 Jar 时将使用的 class-path。这要求您还需要将 Jars 复制到指定位置

标签: java maven intellij-idea


【解决方案1】:

当您使用 main() 方法的运行时配置从 IntelliJ 启动程序时,IntelliJ 会根据所有项目依赖项构造类路径。您可以在“运行”窗口中看到这一点,第一条日志行是用于启动main()java 命令。这是一条很长的线,但通常看起来类似于:

java -javaagent:/opt/idea/idea-IC-173.3727.127/lib/idea_rt.jar=40165:/opt/infra/idea/idea-IC-173.3727.127/bin -Dfile.encoding=UTF-8 -classpath /home/ [...]

IntelliJ 构造 -classpath 参数,添加模块 target 目录和从本地 Maven 存储库引用的 Maven 依赖项。

当您使用 Maven mvn clean package 打包项目时,通常它会变成一个仅包含您的代码的独立 JAR(除非您更改了默认值)。现在您有几个选择如何提供启动main() 所需的依赖项:

  1. 像 IntelliJ 一样使用 -classpath 参数提供它们。
  2. 添加maven-shade-plugin 并使用shade 目标构建a runnable Uber JAR。这会创建一个不需要 -classpath 的胖 JAR。
  3. 使用其他一些 Maven 插件来执行第 2 点,例如Spring Boot spring-boot:repackage 目标。

【讨论】:

  • 你知道它为什么要添加目标目录吗?当我在 IntelliJ 中运行时,它实际上是编译成目标 jar 吗?如果没有,则不需要添加目标。
  • 哦,我猜它正在编译,但不一定放在 JAR 中。
  • JAR 不是由 Maven compile 而是由 package 阶段创建的。要运行应用程序 IntelliJ 不必创建打包的 JAR,只需编译为源代码即可。这里有陷阱,例如Maven可以生成或资源。尝试了解 JAR 打包的默认 Maven 生命周期和阶段,并查看 IntelliJ 在执行期间处理哪些部分。
【解决方案2】:

在 pom.xml 文件中定义的所有必需依赖项都从 Maven Central(或其他配置的)下载到本地 Maven 存储库。该存储库位于<user home>/.m2/repository

Maven 生成/计算一个依赖关系树,以了解项目所需的所有依赖关系。 (您也可以使用命令mvn dependency:tree 转储该树。我总是将结果通过管道传输到文件中,因为树可能很大mvn dependency:tree > deptree.txt)。 Maven 将它们全部放在类路径中,当执行像 mvn compile 这样的 maven 命令时

IntelliJ 还使用/计算依赖树并将所有 jar 文件添加到项目类路径(指向 <user home>/.m2/repository 文件夹中的文件)。您可以在外部库列表中看到它们,它们将在类路径中用于编译和运行应用程序。

在构建 JAR 文件时,不会将依赖项添加到 JAR 中。只有您自己项目中的字节码(java 类)和资源被打包到 JAR 文件中。 (如果您配置源文件也可以打包) 通过添加 Maven 插件 (maven-shade-plugin),您可以将项目配置为也将依赖项打包到 JAR 中。 SpringBoot 项目也会这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2021-02-14
    • 2020-12-30
    • 2012-02-15
    • 1970-01-01
    • 2011-02-19
    • 2020-01-18
    相关资源
    最近更新 更多