Вопрос

У меня есть интересный вопрос о поведении загрузчика класса.

Вопрос первый: Какой заказ, в котором загрузчик класса будет загружать банки?

Даны следующие банки и содержащие классы:

a.jar
  +-com/scheffield/foo/A.class

b.jar
  +-com/scheffield/foo/B.class

Какой класс будет загружен?

Вопрос второй: Правда ли, что путь и имя файла в пути класса уникальны?

Приведены следующие банки и содержащие классы (пример реального мира):

spring-beans-3.0.3.RELEASE.jar
  +-META-INF/spring.schemas

spring-aop-3.0.3.RELEASE.jar
  +-META-INF/spring.schemas

Что я могу вам сказать, так это то, что оба файла загружаются пружиной, в противном случае произошло бы исключение (см. Эта статья).

Почему я спрашиваю это:

Я сделал так называемый большая банка (Вход поваренной книги для Gradle) Это банка с классами приложений и всеми другими зависимостями, расстегнутыми и пакетами в большой банке. И я не совсем уверен, что делать с дублированными файлами.

Это было полезно?

Решение

  1. Занятия разрешаются, однако класс -загрузчик хочет их разрешить (это весь смысл иметь архитектуру загрузчика класса). Большинство загрузчиков, с которыми вы имеете дело на практике, являются вариантами java.net.urlclassloader который загружает классы (и ресурсы) на основе пути поиска (путь класса) каталогов и банок. Каждое место в пути поиска рассматривается как источник классов, а местоположения ищут по порядку.

  2. Нет, имена не уникальны. Первая встречается в заказе поиска.

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

Я говорю примерно потому, что манифесты в банках содержат дополнительные инструкции по обработке, которые также необходимо объединить. Например, манифест может содержать Атрибут класса Это включает в себя дополнительные банки в пути класса. Можно объединить банки, но потерять явные атрибуты, которые указывают часть вашей реальной необходимой дороги класса. Если ваш манифест содержит запечатанный или подписанный Данные банки, возможно, вы не сможете сделать это слияние вообще, не нарушая подписанные части банки.

Таким образом, банки на самом деле не предназначены для объединения таким образом. Это может работать, но есть много возможностей для ошибок, некоторые из которых невозможно решить. Одной из общей причины ошибки является объединение двух файлов JAR и в конечном итоге с одним входом с одним и тем же путем, который разрешен в файлах ZIP. Задачи ANT JAR и ZIP позволяют объединять несколько источников и могут создавать такие проблемы.

На самом деле, вместо этого лучше объединить веб -приложения, состоящие из многих банок и источников в единый архив войны или ушного уха. Вот в некотором смысле, почему они существуют.

Другие советы

  1. Файлы загружаются в заказе, которые содержат банки на трассе. Это относится к классам. Если вы загружаете другие ресурсы (например, Spring.schema), вы можете использовать либо classloader.getresource (...) или classloader.getresources (...). Первый возвращает первый ресурс на трассе, второй также возвращает затененные ресурсы.
  2. Я не думаю, что действительный zip -архив содержит дубликаты записей.

С Уважением

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top