CLASSPATH vs java.ext.dirs

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

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

1) Было бы хорошо и целесообразно заменить все это, просто установив свойство java.ext.dirs, чтобы он содержал то, что он содержит + мой дополнительный lib dir в моем script? Любые оговорки, скрытые там?

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

Ответы

Ответ 1

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

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

Ответ 2

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

Одно из отличий заключается в том, что если мы укажем наши библиотеки под флагом -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
[email protected]
[email protected]

когда приложение запускается с помощью команды java -cp "folder/*;." Main.

Однако, когда приложение запускается с помощью команды java -Djava.ext.dirs=folder Main, вместо этого вывод будет:

folder
false
[email protected]
[email protected]

Ответ 3

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

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

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

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