Загрузка классов и ресурсов в 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.