CLASSPATH vs java.доб.dirs

есть ли какая-либо причина, почему следует использовать (возможно, очень долго) CLASSPATH переменная, чтобы установить, какие банки должны быть в приложении classpath durign, затем использовать свойство java 1.5+-Djava.ext.dirs который определяет весь каталог (каталоги) банок для поиска?

чтобы сделать его реальным примером, у меня есть автономное приложение java с lib папка содержит все зависимые банки. Sofar сценарий запуска устанавливает все (возможно, 20) банки в переменную CLASSPATH один за другим. С теперь мой архив приложений генерируется Maven я не могу заранее видеть, какие имена jar будут (например, я меняю версию JAR). Конечно, я могу пройти через lib dir в сценарии запуска и добавьте все найденные там банки в CLASSPATH переменной снова. Или, возможно, сделать maven для создания этого сценария для меня. Но вот наступает затишье:--8-->

1) было бы нормально и целесообразно заменить все это, просто установив java.ext.dirs свойство содержать то, что оно содержит + my экстра lib dir в моем сценарии? Какие-нибудь предостережения там спрятаны?

Спасибо за ответы :)

3 ответов


java.ext.dirs имеет очень специфическое использование: он используется для указания, где механизм расширения загружает классы из. Он используется для добавления функциональности в JRE или в другие библиотеки (например, JAI). Это не означает, что это универсальный механизм загрузки классов.

использовать символ *. Он был представлен в Java 6, поэтому многие люди до сих пор не знают, что это возможно.


Иоахим сделал хороший момент о ярлыке подстановочного знака. Но так как вопрос спрашивает о различиях и предостережениях, чтобы следить за...

большая разница в том, что если мы указываем наши библиотеки под -Djava.ext.dirs флаг они будут загружено с помощью расширения 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

большая проблема с помещением вещей в lib.каталог ext заключается в том, что для разных приложений могут потребоваться разные версии библиотек, и они могут конфликтовать друг с другом.

подумайте о старом DLL hell из Windows 3 дней (если вы помните те), когда аналогичная ситуация сложилась, когда многие, если не большинство разработчиков программного обеспечения разместили общие библиотеки в каталоге Windows / System, потому что они автоматически выбираются оттуда, а не включают их с их приложения и загрузка их явно.

вместо этого вы хотите иметь отдельный путь к классам для каждого приложения (поэтому нет системного уровня classpath!), установленный в его сценарии запуска и указывающий только на те файлы jar и каталоги классов, применимые для этого конкретного приложения. Таким образом, несколько приложений с конфликтующими потребностями библиотеки могут быть запущены бок о бок, не мешая друг другу функциональность.

то же самое верно еще больше, если вы разработчик, где вы не хотите, чтобы какие-либо внешние библиотеки мешали вашему приложению во время его тестирования. И еще одно: если вы разрабатываете и используете трюк lib/ext (или путь к классам системного уровня), как вы можете быть уверены, что приложение, которое вы собираетесь отправить, поставляется с правильными библиотеками? Если вы забудете включить его в установщик или установочный пакет, вы никогда не заметите, потому что он находится на вашем компьютере в общем расположении. Но клиент, у которого этого нет библиотека, получит ошибки во время выполнения и в ближайшее время будет по телефону, требуя поддержки (и, возможно, возврат средств, и давая вам плохие отзывы в прессе для доставки дефектного продукта).