CLASSPATH vs java.ext.dirs

Jan*_*yka 17 java jar properties classpath

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

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

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

谢谢你的回复:)

Joa*_*uer 34

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

请改用通配符*.它是在Java 6中引入的,所以很多人仍然不知道它是可能的.

  • 谢谢你的意见.但正如我上面所描述的,我的lib目录只包含真正需要的jar,不多也不少.我不想将它们硬编码到脚本中,因为jar版本可能会更改.你会建议让maven为我生成脚本,并在脚本中硬编码罐子吗? (2认同)

Pac*_*ier 5

Joachim对通配符快捷方式提出了很好的意见。但由于问题是要注意差异和警告,因此需要注意...

一个区别是,如果我们在-Djava.ext.dirs标志下指定我们的库,则将使用扩展类加载器(例如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);
    }
}
Run Code Online (Sandbox Code Playgroud)

控制台输出将是:

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
Run Code Online (Sandbox Code Playgroud)

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

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

folder
false
sun.misc.Launcher$AppClassLoader@107077e
sun.misc.Launcher$ExtClassLoader@7ced01
Run Code Online (Sandbox Code Playgroud)