CLASSPATH vs java.ext.dirs

心已入冬 提交于 2020-01-01 02:13:11

问题


is there any reason why to favor using (possibly very long) CLASSPATH variable to set which jars should be on classpath durign application run then to use the java 1.5+ property -Djava.ext.dirs which specifies whole directory(directories) of jars to be searched?

To make it real-life example I have standalone java application with lib folder containig all dependent jars. Sofar the start script is setting all the (maybe 20) jars to CLASSPATH variable one by one. Since now my application archive is generated by Maven I can't see in advance what the jar names would be (e.g. I change version of a JAR). Of course I can go through the lib dir in the startup script and add all jars found there to the CLASSPATH variable again. Or probably make maven to generate this script for me. But here comes the quiestions:

1) Would it be OK and appropriate to replace all of this by simply setting the java.ext.dirs property to contain what it contains + my extra lib dir in my script? Any caveats hidden there?

Thanks for replies :)


回答1:


java.ext.dirs has a very specific use: it's used to specify where the extension mechanism loads classes from. Its used to add functionality to the JRE or to other libraries (such as JAI). It's not meant as a general-purpose class-loading mechanism.

Use the wildcard character * instead. It was introduced in Java 6, so many people still don't know it's possible.




回答2:


Joachim made a good point about the wildcard character shortcut. But since the question is asking about differences and caveats to watch out for...

One difference is that if we specify our libraries under the -Djava.ext.dirs flag, they will be loaded using the extension classloader (e.g. sun.misc.Launcher.ExtClassLoader) instead of the system classloader (e.g. sun.misc.Launcher.AppClassLoader).

Assuming that in our library, we have a class named Lib. And our application runs this code:

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);
    }
}

The console output will be:

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

when the application is run using the command java -cp "folder/*;." Main.

However, when the application is run using the command java -Djava.ext.dirs=folder Main, then the output will instead be:

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



回答3:


A big problem with putting things in the lib.ext directory is that different applications may require different versions of libraries, and those may well conflict with one another.

Think of the old DLL hell from the Windows 3 days (if you remember those) when a similar situation developed when many if not most software developers placed shared libraries in the Windows/System directory because they're picked up automatically from there rather than include them with their applications and loading them explicitly.

What you want instead is to have a separate classpath for every application (so no system level classpath!), set in its startup script, and pointing to only those jar files and class directories applicable for that specific application. That way several applications with conflicting library needs can be launched side by side without interfering with each others functionality.

The same is true even more if you're a developer, where you don't want any outside libraries interfering with your application while testing it. And there's another thing: if you're developing and using the lib/ext trick (or a system level classpath), how can you ever be sure that the application you're going to ship ships with the correct libraries? If you forget to include on in your installer or installation package, you'd never notice because it's on your machine in a shared location. But the customer, who doesn't have that library, would get runtime errors and shortly be on the phone demanding support (and possibly a refund, and giving you bad reviews in the press for shipping a defective product).



来源:https://stackoverflow.com/questions/5039862/classpath-vs-java-ext-dirs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!