部署概念:打包JAR依赖关系,何时&为什么

时间:2011-09-19 15:21:25

标签: deployment jar java

所以我对Java EE相对较新,我很难理解Java部署文件何时,何地以及为何与其依赖关系打包。

假设我将项目构建到 myapp.jar ,这取决于fizz.jar,buzz.jar和JODA(joda-time-2.0.jar)。

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

这是因为心态是部署main - 在容器或其他系统中减少罐子,这些罐子会在运行时提供它的要求吗?如果没有,那么myapp.jar如何正常运行?

可执行罐子怎么样?要满足,这些必须main - 更少的罐子不同,因为它们是独立的单位,对吧?这意味着他们需要将所有依赖项打包在一起,对吧?

最后但并非最不重要的,那些依赖于依赖于罐子的罐子的罐子等等。 (即,依赖图很大)?

我想所有这些问题可归纳如下:

  1. 非可执行jar背后的想法是,它将以这样一种方式运行,它将知道在运行时为其依赖关系查找哪些类路径? (因此不需要与其依赖项一起打包)?
  2. 可执行jar背后的想法是它是一个独立的单元,是否应该使用它的依赖?
  3. 如果我对上面问题#1的断言是正确的,那么这样的类路径配置是如何发生的?这些设置是否存储在jar中(例如清单中)?否则,JRE如何知道在运行时搜索特定jar依赖项的位置?
  4. 这些问题的答案实际上会澄清我用Java基础知识的很多挂断,所以任何输入/帮助都会受到极大的欢迎!感谢

2 个答案:

答案 0 :(得分:5)

罐子不知道其他罐子(除非像Maven这样的工具辅助)。罐子的依赖性纯粹由类加载器解决。我强烈建议some idea about classloaders

要解决您的问题,

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

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

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

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

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

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

简而言之,它是提取所有线程的类加载器。有标准的地方可以找到所有相关的罐子。 This link很好地描述了独立应用程序和部署(在某个容器中)中的类加载器如何工作。

答案 1 :(得分:0)

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

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

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

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

当然你的代码需要jdbc jar才能正常工作。这里解释虚拟机如何搜索extarnal类:

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

-it在类路径指定的目录中搜索(类路径是环境变量或java命令的选项)

例如:

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

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

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