2011-09-06 87 views
1

我刚刚问了一个关于分发可执行JAR及其依赖关系的最新问题,这让我意识到我对JAR的理解可能存在根本性缺陷。编译Java和JAR

因此,有些人可能会说:“嘿现在!这这里是一个重复的问题!”但是我会拒绝,这个问题的this 原来的问题一个完全独立的分支,并涉及Java的基础!

如果我有一个依赖于Apache Commons CLI和JODA Time的应用程序,并且将此应用程序打包为可分发的JAR,我的原始问题是:不包括CLI和JODA JAR我的JAR,程序如何在客户端运行?

我现在在想,因为我的代码使用CLI和JODA编译到类文件中,并且字节码是打包的,所以不需要包含CLI或JODA(或任何其他第三方JAR )在我的JAR中,因为它现在都在运行字节码。

有人可以确认或纠正我吗?这个启示虽然很晚,但却令人震惊。

+0

一个的* .jar *是你应该在包装罐中的清单文件中指定的类路径基本上是一个* .zip *,所以我建议你通过解压几个* .jar *然后看看里面是什么来自己做实验。请注意,您可以**将“罐子放在罐子里”*,但是您需要编写自己的类加载器(或者使用一个程序来完成这一切)。另一种方法是将你所依赖的* .class *(*即*字节码)放在你的* .jar *文件中(不推荐,但它可以工作)。 – SyntaxT3rr0r

+0

你的应用程序。有一个GUI? –

+0

@Mara:btw你的* .class *文件不包含整个CLI和JODA库。 .class文件具有依赖性:您需要在* .jar *或CLI和JODA *中使用来自CLI和JODA的.class文件。jar *某处。运行* .jar *时,这些依赖关系将得到解决(或尝试解决)。如果你有自己的类加载器,默认的类加载器将检查几个地方(在路径中,在你的*。jar *中,在jar中的jar中)等,并看看它是否能解决你的依赖。 – SyntaxT3rr0r

回答

1

不,这不太对。一切的关键是类路径。是类路径中的所有编译代码和/或其他资源?如果您将所有资源打包在一个jar文件中,那么是的,它位于classpath中,JVM将定位所有要运行的资源。否则,您需要指定(使用.bat或.sh文件或其他东西)应用程序所依赖的所有资源,以便JVM能够适当地查找这些资源(无论是Java代码或属性文件还是其他任何资源)。

另外,如果我正在阅读你的问题,你是否假设CLI和JODA代码被编译到你的代码中?如果是这样,我不想破坏你的泡沫,但事实并非如此。当你的代码编译时,它不会引入依赖关系(不是你可能会想到的)。它在概念层面上做了什么(纠正我,如果我错了JVM大师)是否引用其他类。这些引用是您编写类并编译它时构建的内容。在运行时,JVM将尝试在引用后面定位已编译的类,并且这是您需要带有类路径中的这些类的jar或者需要那些可执行jar中的类的地方。

有意义吗?

+0

Chris thios确实有道理 - 谢谢!但是现在我想我很困惑,我不知道该怎么问......在Eclipse中,我在类路径中拥有所有的JAR,因此Eclipse知道如何链接到所有正确的资源。在我的Ant build.xml文件中,如何将JAR添加到类路径中(从Ant内部),以便当我的可执行JAR作为独立命令行工具运行时,一切正常? – IAmYourFaja

+0

Java使用类路径知道在哪里查找.class文件。通常,将.jar文件添加到类路径中,Java将加载这些文件。您可以通过几种不同的方式设置课程路径。对于你的情况,你应该在MANIFEST.MF文件中设置'Class-Path'属性。蚂蚁可以在这里帮助你。只需在'jar'任务中添加一个'manifest'元素并设置'Main-Class'和'Class-Path'属性即可。有关更多详细信息,请参阅http://ant.apache.org/manual/Tasks/jar.html –