【问题标题】:Deployment Concepts: Packaging JAR Dependencies, When & Why部署概念:打包 JAR 依赖项、时间和原因
【发布时间】:2011-11-20 08:33:54
【问题描述】:

所以我对 Java EE 还比较陌生,我很难理解 Java 部署文件何时、何地以及为何与它们的依赖项一起打包。

假设我将我的项目构建到 myapp.jar 中,它依赖于 fizz.jar、buzz.jar 和 JODA (joda-time-2.0.jar)。

我听说默认的类加载器不会将 jar 打包到其他 jar 中,所以我必须假设如果我从 Ant 调用 jar 任务,那么默认的类加载器会被调用并且 myapp.jar 将在其中不包含这 3 个依赖项的情况下创建。

这是因为我们的想法是在容器或其他系统中部署main-less jar 以在运行时提供其需求?如果没有,那么 myapp.jar 是如何正确运行的?

可执行 jars 呢?为了满足,这些必须不同于main-less jars,因为它们是独立的单元,对吧?这意味着他们需要将所有依赖项打包在一起,对吧?

最后但并非最不重要的一点是,依赖于 jars 的 jars 的 jars 依赖于 jars...等等。 (即巨大的依赖图)?

我想所有这些问题都可以总结如下:

  1. 一个不可执行的 jar 背后的想法是,它将以这样一种方式运行,即它会知道在运行时查找其依赖项的类路径吗? (因此不需要与其依赖项一起打包)?
  2. 可执行 jar 背后的想法是它是一个独立的单元并且应该与其依赖项一起打包吗?
  3. 如果我对上述问题 #1 的断言是正确的,那么这种类路径配置是如何发生的?这些设置是否存储在 jar 中(例如清单中)?否则,JRE 怎么知道在运行时在哪里搜索特定的 jars 依赖项?

这些问题的答案实际上将澄清我在 Java 基础方面遇到的很多问题,因此我们将不胜感激任何输入/帮助!谢谢

【问题讨论】:

    标签: deployment jar java


    【解决方案1】:

    Jars 不知道其他 jars(除非有 Maven 等工具的帮助)。 jar 的相互依赖完全由类加载器解决。我强烈建议使用some idea about classloaders

    为了解决您的问题,

    一个不可执行的 jar 背后的想法是,它将以这样一种方式运行,即它会知道在运行时查找其依赖项的类路径吗? (因此不需要与其依赖打包)?

    • 没有。如前所述,它是类加载器,它查看类路径和其中提到的 jar。这些罐子没有关于其他罐子的任何信息。

    可执行 jar 背后的想法是它是一个独立的单元,应该与其依赖项一起打包吗?

    • 没有。类加载器在执行开始时加载独立的可执行 jar。如果它需要其他依赖 jar,它将查看这些 jar 的类路径。

    如果我对上述问题 #1 的断言是正确的,那么这种类路径配置是如何发生的?这些设置是否存储在 jar 中(例如清单中)?否则,JRE 怎么知道在运行时在哪里搜索特定的 jars 依赖项?

    • 对于独立 jar(可执行 jar),类加载器会查找调用应用程序时传递的类路径变量或类路径。
    • 对于其他类型的应用程序(WAR、EAR),有预定义的位置/文件夹应该放置依赖项以便获取。这是按规范标准化的。

    简而言之,是类加载器正在拉动所有线程。有一个标准的地方可以查找所有依赖的 jar。 This link 很好地描述了独立应用程序和已部署(在某些容器中)中的类加载器是如何工作的。

    【讨论】:

    • 哇 - 多么棒的答案!非常感谢!
    【解决方案2】:

    JAR 文件是一种将复杂的 Java 应用程序打包在一起的方法。 Jar 应用程序很容易在不同的机器和操作系统之间移动。

    我认为使用 Jars 的正确方法不是将所有内容(每个依赖项)都放入一个 jar 中。

    例如,如果您的应用程序使用 jar libryra(例如 jdbc)来访问数据库,则不应将 jdbc jar 放入您的 jar。

    你最好只用你的 .class 文件构建一个 jar 文件。

    当然,您的代码需要 jdbc jar 才能正常工作。下面来解释一下虚拟机是如何搜索外部类的:

    -它首先在包含J2SE标准类的目录中搜索(路径取决于您的安装)

    -它在classpath指定的目录中搜索(classpath要么是环境变量,要么是java命令的一个选项)

    例如:

    java -jar -c /your/path/yourApp.jar

    将运行您的应用程序并在目录 /your/path/ 中搜索您的应用程序引用的类,因此如果您有外部 jar,您可以将它们放在该目录中。

    详细文档:http://download.oracle.com/javase/tutorial/deployment/jar/index.html

    【讨论】:

    • 好的,所以 JRE 首先查看其默认的类路径设置(在安装时定义),然后查看 CLASSPATH 环境变量?所以我假设你没有在你的 jar/manifest 中的任何地方指定 CLASSPATH?
    • 当然你也可以在清单文件中指定一个类路径作为一个条目。但在这种情况下,您在清单中配置的路径是相对于清单字段本身的位置的。因此,如果您移动 jar 文件,则必须更新清单的类路径条目。
    • 这就是为什么我不想在 jar 清单文件中使用 clappath 选项。
    猜你喜欢
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    相关资源
    最近更新 更多