Загрузка классов и ресурсов в Java 9
Я читал эту статью в InfoQ, цитируя Reinhold:
Разработчики могут по-прежнему использовать путь Java-класса в Java 9 для Java runtime для поиска классов и файлов ресурсов. Это просто с Java 9, разработчикам больше не нужен путь к классу.
Итак, теперь мой вопрос: каков правильный способ Java 9 для выполнения перечисленных выше задач? Как вы динамически загружаете, например. изображение (за исключением путаницы с относительными путями)?
Еще интереснее, как бы проверить, доступен ли класс и принять решение динамически (например, проверить, доступен ли Джексон, и если да, используйте его для сериализации JSON и если не используете что-то другое)?
В статье также упоминается Spring Boot, уже поддерживающий Java 9, и Spring Boot определенно выполняет много динамической загрузки. Так что, может быть, кто-то знает, какой код из Spring я могу посмотреть?
Ответы
Ответ 1
Во-первых, чтобы установить запись прямо, я не сказал и не написал текст
цитируется выше. Ид никогда не говорил так. Это просто неряшливо
отчетности со стороны соответствующих публикаций.
Самое важное, что нужно знать о загрузке и ресурсе классов
поиск в Java 9 - это то, что на фундаментальном уровне они не изменились.
Вы можете искать классы и ресурсы так же, как всегда
имеют, вызывая Class::forName
и различные методы getResource*
в классах Class
и ClassLoader
, независимо от того, является ли ваш код
загружается из пути класса или пути к модулю. Есть еще три
встроенные загрузчики классов, как и в JDK 1.2, и они имеют
те же отношения с делегациями. Поэтому много существующего кода просто
работает, из коробки.
Есть некоторые нюансы, как указано в JEP
261: Тип бетона
встроенных загрузчиков классов, и некоторые классы ранее
загруженные загрузчиком класса bootstrap, теперь загружаются классом платформы
погрузчик для повышения безопасности. Существующий код, предполагающий, что
встроенный загрузчик классов - это URLClassLoader
или что класс загружается
загрузчик классов начальной загрузки, поэтому могут потребоваться незначительные корректировки.
Последнее важное различие заключается в том, что неклассовые ресурсы в модуле
инкапсулируются по умолчанию, и, следовательно, не может быть расположен снаружи
модуль, если их эффективный пакет не является
open
.
Чтобы загрузить ресурсы из вашего собственного модуля, лучше всего использовать
методы поиска ресурсов в Class
или Module
, которые могут находить любые
ресурса в вашем модуле, а не в ClassLoader
, который может
только найдите ресурсы неклассического файла в пакетах open
модуля.
Ответ 2
[Изменить: этот ответ был написан до авторитарного ответа Марка. Я переработал мой, чтобы предоставить простой пример: в GitHub.]
Per это видео, загрузка классов в Java 9 не изменилась.
В качестве примера предположим, что мы имеем:
- a
example.jar
, который содержит изображение в пакете net.codetojoy.example.resources
- чтобы усилить банку,
net.codetojoy.example.Composer
является общедоступным (и экспортируется, если применимо).
- простой класс
App
, который использует example.jar
как библиотеку и пытается загрузить изображение из него
Соответствующий код в App
:
static InputStream getResourceAsStream(String resource)
throws Exception {
// Load net/codetojoy/example/resource/image.jpg
// Assume net.codetojoy.example.Composer is public/exported
// resource is 'resource/image.jpg'
InputStream result = Composer.class.getResourceAsStream(resource);
return result;
}
Вот несколько примеров для example.jar
в JDK 9:
Старомодный, немодульный ящик
Если example.jar
не является модулем, код просто работает. Загрузка классов не изменяется.
Модульная банка с открытым пакетом
В этом случае это файл module-info.java
:
module net.codetojoy.example {
// export the Composer class
exports net.codetojoy.example;
// image is available
opens net.codetojoy.example.resources;
}
В этом случае изображение может быть загружено клиентом, потому что пакет открыт.
Модульный ящик без открытого пакета
В этом случае module-info.java
:
module net.codetojoy.example {
// export the Composer class
exports net.codetojoy.example;
// package not opened: image not available
// opens net.codetojoy.example.resources;
}
В этом случае изображение не может быть загружено из-за сильной инкапсуляции: модуль защищает изображение, не открывая пакет.
Полный источник здесь, на GitHub.