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), как вы можете быть уверены, что приложение, в которое вы собираетесь отправлять корабли с правильными библиотеками?
Если вы забыли включить в свой установочный или установочный пакет, вы никогда не заметите, потому что это на вашем компьютере в общем месте. Но у клиента, у которого нет этой библиотеки, появятся ошибки времени выполнения и в скором времени будут на телефоне, требующие поддержки (и, возможно, возмещение и дадут вам плохие отзывы в прессе за отправку дефектного продукта).