Безопасный импорт классов из JAR-файлов - PullRequest
1 голос
/ 21 января 2010

Рассмотрим сценарий, когда java-программа импортирует классы из jar-файлов.Если один и тот же класс находится в двух или более jar-файлах, может возникнуть проблема.

  1. В таких случаях какой класс импортируется программой?Это класс с более старой отметкой времени?

  2. Какими методами мы можем следовать, чтобы избежать таких осложнений.

ПравитьЭто пример.У меня есть 2 файла jar my1.jar и my2.jar.Оба файла содержат com.mycompany.CrazyWriter

Ответы [ 6 ]

2 голосов
/ 21 января 2010

По умолчанию классы загружаются ClassLoader с использованием пути к классам, который ищется по порядку.

Если у вас есть две реализации одного и того же класса, будет загружена та, которую загрузчик классов найдет первой.

Если классы на самом деле не являются одним и тем же классом (одинаковыми именами, но разными методами), вы получите исключение при попытке его использовать.

Вы можете загрузить два класса с одинаковыми именами в одну виртуальную машину, используя несколько загрузчиков классов. Фреймворк OSGI может управлять многими сложными объектами за вас, обеспечивая загрузку правильной версии и т. Д.

0 голосов
/ 21 января 2010

Если один и тот же класс находится еще в двух банках, должна возникнуть проблема.

Что именно вы имеете в виду? Почему должно быть проблемой?

В таких случаях какой класс импортируется программой? (Класс с более старой отметкой времени ??)

Если класс существует в двух JAR, класс будет загружен из первого JAR в пути к классу, где он найден. Цитирование Установка пути к классу (цитируемая часть относится и к архивным файлам):

Порядок, в котором вы указываете несколько записей пути к классам, важен. Интерпретатор Java будет искать классы в каталогах в порядке их появления в переменной пути к классам. В приведенном выше примере интерпретатор Java сначала ищет необходимый класс в каталоге C:\java\MyClasses. Только если он не найдет класс с правильным именем в этом каталоге, интерпретатор будет искать в каталоге C:\java\OtherClasses.

Другими словами, если требуется определенный порядок, просто явно перечислите файлы JAR в пути к классам. Это то, что обычно используют поставщики серверов приложений: для исправления определенного класса (классов) продукта вы помещаете JAR (например, CR1234.jar), содержащий исправленные классы (ы), в путь к классу перед основным JAR (скажем, weblogic.jar). ).

Какими методами мы можем следовать, чтобы избежать таких осложнений.

Ну, очевидный ответ: не делайте этого (или только нарочно, как в приведенном выше примере).

0 голосов
/ 21 января 2010

Если у вас есть проблема с выяснением, какая версия класса используется, то jwhich может быть полезным: http://www.fullspan.com/proj/jwhich/index.html

0 голосов
/ 21 января 2010
  1. Не уверен, что вы имели в виду " тот же класс находится в двух других классах "

    если вы имели в виду внутренние / вложенные классы, проблем не должно быть, поскольку они находятся в разных пространствах имен.
    Если вы имели в виду еще два JAR-файла, как уже ответили, используется порядок в classpath.

  2. Как избежать?
    Пакет должен быть только в одном JAR, чтобы избежать дублирования классов. Если два класса имеют одно и то же простое имя, например java.util.Date и java.sql.Date, но находятся в разных пакетах, это фактически разные классы. Вы должны использовать полное имя, по крайней мере, от одного из классов, чтобы отличить их.

0 голосов
/ 21 января 2010

ClassLoader отвечает за загрузку классов. Он сканирует ClassPath и загружает найденный первым класс. Если у вас есть один и тот же Jar дважды в ClassPath или у вас есть два Jar, которые содержат две разные версии одного и того же класса (то есть com.packagename.Classname), загружается тот, который найден первым.

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

0 голосов
/ 21 января 2010

Во-первых, я предполагаю, что вы имеете в виду, что один и тот же класс находится в еще двух jar файлах ...

Теперь, отвечая на ваши вопросы:

  1. Какой класс импортируется, зависит от вашего загрузчика классов и JVM. Вы не можете гарантировать, какой это будет класс, но в обычном загрузчике классов это будет класс из первого файла jar на вашем пути к классам.
  2. Не помещайте один и тот же класс в несколько jar-файлов, или, если вы пытаетесь переопределить системные классы, используйте -bootclasspath.

Редактировать : Для ответа на один из комментариев к этому ответу. Первоначально я думал, что запечатывание jar будет иметь значение, поскольку теоретически он не должен загружать два класса из одного пакета из разных файлов jar. Однако после некоторых экспериментов я вижу, что это предположение не выполняется, по крайней мере с поставщиком безопасности по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...