Проблема Classloader - PullRequest
       8

Проблема Classloader

0 голосов
/ 14 декабря 2010

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

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

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

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

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

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

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

Даны следующие jar и содержащие классы (пример realworld):

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

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

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

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

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

Ответы [ 2 ]

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

  2. Нет, имена не являются уникальными.Будет использован первый из найденных в порядке поиска.

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

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

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

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

0 голосов
/ 23 декабря 2010
  1. файлы загружаются в том порядке, в котором содержащиеся банки появляются в пути к классам. это относится к классам. если вы загружаете другие ресурсы (например, spring.schema), вы можете использовать либо classloader.getResource (...), либо classloader.getResources (...). первый возвращает первый ресурс на пути к классам, второй также возвращает теневые ресурсы.
  2. Я не думаю, что действительный zip-архив содержит повторяющиеся записи.

привет

...