CLASSPATH vs java.ext.dirs

时间:2011-02-18 09:57:56

标签: java properties jar classpath

是否有任何理由支持使用(可能很长)CLASSPATH变量来设置哪个jar应该在classpath durign应用程序运行然后使用java 1.5+属性-Djava.ext.dirs指定整个目录(目录)要搜索的罐子?

为了使它成为现实生活中的例子我有一个独立的java应用程序,lib文件夹包含所有依赖的jar。 Sofar启动脚本将所有(可能是20个)罐子逐个设置为CLASSPATH变量。从现在开始,我的应用程序存档由Maven生成,我无法预先看到jar名称是什么(例如,我更改了JAR的版本)。当然,我可以在启动脚本中浏览lib目录,然后再将所有找到的jar添加到CLASSPATH变量中。或者可能让maven为我生成这个脚本。但是这里出现了问题:

1)通过在我的脚本中简单地设置java.ext.dirs属性以包含它包含的内容+我的额外lib目录,替换所有这些是否合适?隐藏在那里的任何警告?

感谢您的回复:)

3 个答案:

答案 0 :(得分:31)

java.ext.dirs有一个非常具体的用途:它用于指定extension mechanism加载类的位置。它用于向JRE或其他库(例如JAI)添加功能。它不是一种通用的类加载机制。

请改用wildcard character *。它是在Java 6中引入的,所以很多人仍然不知道它是可能的。

答案 1 :(得分:5)

Joachim对通配符快捷方式提出了一个很好的观点。但是,因为问题是要求注意差异和警告......

一个区别是,如果我们在-Djava.ext.dirs标记下指定我们的库,它们将是loaded using the extension classloader (例如sun.misc.Launcher.ExtClassLoader)而不是系统类加载器(例如sun.misc.Launcher.AppClassLoader)。

假设在我们的库中,我们有一个名为Lib的类。我们的应用程序运行此代码:

public class Main {
    public static void main(String args[]) {
        System.out.println(System.getProperty("java.ext.dirs"));
        ClassLoader test_cl = Main.class.getClassLoader();
        ClassLoader lib_cl = Lib.class.getClassLoader();
        System.out.println(test_cl == lib_cl);
        System.out.println(test_cl);
        System.out.println(lib_cl);
    }
}

控制台输出将是:

C:\Program Files\Java\jdk1.6.0\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
true
sun.misc.Launcher$AppClassLoader@107077e
sun.misc.Launcher$AppClassLoader@107077e

使用命令java -cp "folder/*;." Main运行应用程序时。

但是,当使用命令java -Djava.ext.dirs=folder Main运行应用程序时,输出将改为:

folder
false
sun.misc.Launcher$AppClassLoader@107077e
sun.misc.Launcher$ExtClassLoader@7ced01

答案 2 :(得分:4)

将内容放在lib.ext目录中的一个大问题是,不同的应用程序可能需要不同版本的库,这些库可能会相互冲突。

想想Windows 3天的旧DLL(如果你还记得那些)当类似的情况发生时,很多(如果不是大多数)软件开发人员将共享库放在Windows / System目录中,因为它们是从那里自动获取的而不是将它们包含在应用程序中并明确加载它们。

您想要的是为每个应用程序设置一个单独的类路径(因此没有系统级类路径!),在其启动脚本中设置,并指向仅适用于该特定应用程序的那些jar文件和类目录。 这样,可以并排启动具有冲突库需求的多个应用程序,而不会干扰彼此的功能。

如果您是开发人员,在测试时不希望任何外部库干扰您的应用程序,那么情况就更是如此。 还有一件事:如果你正在开发和使用lib / ext技巧(或系统级类路径),你怎么能确定你要发布的应用程序是否带有正确的库? 如果您忘记在安装程序或安装包中加入,您将永远不会注意到,因为它位于您的计算机上的共享位置。但是没有该库的客户会收到运行时错误,并且很快会在电话上要求支持(并且可能会退款,并且会在报刊上给您提供差评以便运送有缺陷的产品)。