CLASSPATH vs java.ext.dirs

2022-09-01 20:14:04

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

为了使它成为现实生活中的例子,我有独立的java应用程序,其中包含包含所有依赖jar的文件夹。到目前为止,启动脚本正在将所有(可能是20个)jar逐个设置为变量。由于现在我的应用程序存档是由Maven生成的,因此我无法提前看到jar名称是什么(例如,我更改JAR的版本)。当然,我可以遍历启动脚本中的dir,并将在那里找到的所有jar再次添加到变量中。或者可能制作maven为我生成这个脚本。libCLASSPATHlibCLASSPATH

问题:通过简单地将属性设置为包含它所包含的内容+脚本中的额外dir来替换所有这些内容是否可行且合适?那里隐藏着任何警告?java.ext.dirslib

感谢您的回复。


答案 1

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

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


答案 2

约阿希姆对通配符快捷方式提出了一个很好的观点。但是,由于问题询问的是差异和需要注意的警告......

一个区别是,如果我们在标志下指定我们的库,它们将使用扩展类加载器(例如sun.misc.Launcher.ExtClassLoader)而不是系统类加载器(例如sun.misc.Launcher.AppClassLoader)加载-Djava.ext.dirs

假设在我们的库中,我们有一个名为 的类。我们的应用程序运行以下代码: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