Как бороться с ошибками LinkageErrors в Java?

Разрабатывая Java-приложение на основе XML, я 9X_openjdk недавно столкнулся с интересной проблемой 9X_jdk в Ubuntu Linux.

Мое приложение, использующее 9X_.java Java Plugin Framework, похоже, не может преобразовать XML-документ, созданный 9X_classloaders dom4j, в реализацию Batik's спецификации SVG.

На консоли 9X_linkageerror я узнаю, что произошла ошибка:

Exception in thread "AWT-EventQueue-0" java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;" the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader) of the current class, org/apache/batik/dom/svg/SVGOMDocument, and the class loader (instance of ) for interface org/w3c/dom/Document have different Class objects for the type org/w3c/dom/Attr used in the signature
    at org.apache.batik.dom.svg.SVGDOMImplementation.createDocument(SVGDOMImplementation.java:149)
    at org.dom4j.io.DOMWriter.createDomDocument(DOMWriter.java:361)
    at org.dom4j.io.DOMWriter.write(DOMWriter.java:138)

Я полагаю, что 9X_core-java проблема вызвана конфликтом между исходным 9X_linux загрузчиком классов из JVM и загрузчиком 9X_javax классов, развернутым фреймворком надстройки.

Насколько 9X_classloader мне известно, невозможно указать загрузчик 9X_java-libraries классов для использования фреймворком. Возможно, его 9X_core-java можно взломать, но я бы предпочел менее 9X_classloaders агрессивный подход к решению этой проблемы, поскольку 9X_jre (по какой-либо причине) это происходит только 9X_.java в системах Linux.

Сталкивался ли кто-нибудь 9X_classloaders из вас с такой проблемой и знает, как ее 9X_class-loading исправить или хотя бы разобраться в сути 9X_classloaders проблемы?

65
0
7
Общее количество ответов: 7

Ответ #1

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

LinkageError - это то, что вы получите в 9X_openjdk классическом случае, когда у вас есть класс 9X_class-loading C, загруженный более чем одним загрузчиком 9X_java-libraries классов, и эти классы используются вместе 9X_classloaders в одном коде (сравниваются, приводятся и 9X_j2se т. д.). Не имеет значения, является ли это 9X_java тем же именем класса или даже если он загружен 9X_java из идентичной банки - класс из одного загрузчика 9X_java классов всегда обрабатывается как другой 9X_classloader класс, если он загружен из другого загрузчика 9X_core-java классов.

В сообщении (которое с годами значительно 9X_linkageerror улучшилось) говорится:

Exception in thread "AWT-EventQueue-0" java.lang.LinkageError: 
loader constraint violation in interface itable initialization: 
when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;" 
the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader) 
of the current class, org/apache/batik/dom/svg/SVGOMDocument, 
and the class loader (instance of ) for interface org/w3c/dom/Document 
have different Class objects for the type org/w3c/dom/Attr used in the signature

Итак, здесь проблема 9X_java-api заключается в разрешении метода SVGOMDocument.createAttribute(), который 9X_java-api использует org.w3c.dom.Attr (часть стандартной 9X_openjdk библиотеки DOM). Но версия Attr, загруженная 9X_jre с помощью Batik, была загружена из другого 9X_java-libraries загрузчика классов, чем экземпляр Attr, который 9X_classloader вы передаете методу.

Вы увидите, что версия 9X_classloaders Batik, похоже, загружена из подключаемого 9X_java-api модуля Java. А ваш загружается из "", который, скорее 9X_core-java всего, является одним из встроенных загрузчиков 9X_oraclejdk JVM (путь к классам загрузки, ESOM или путь 9X_j2se к классам).

Три известные модели загрузчика 9X_linux классов:

  • делегирование (по умолчанию в JDK - спросить родителя, затем меня)
  • пост-делегирование (часто используется в плагинах, сервлетах и ​​местах, где вам нужна изоляция - спросите меня, затем родительский)
  • родственник (обычно используется в моделях зависимости, таких как OSGi, Eclipse и т. д.)

Я не знаю, какую стратегию делегирования 9X_java-libraries использует загрузчик классов JPF, но суть 9X_java-api в том, что вы хотите, чтобы была загружена 9X_java-api одна версия библиотеки dom и чтобы все исходили 9X_java из одного и того же места. Это может означать 9X_oraclejdk удаление его из пути к классам и загрузку 9X_class-loading как плагина, или запрет на загрузку Batik, или 9X_jre что-то еще.

77
0

Ответ #2

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

Похоже на проблему иерархии загрузчика классов. Я 9X_java-se не могу сказать, в какой среде развернуто 9X_javax ваше приложение, но иногда эта проблема 9X_java-se может возникать в веб-среде, когда сервер 9X_core-java приложений создает иерархию загрузчиков 9X_j2se классов, напоминающую что-то вроде:

javahome 9X_jre / lib - от имени пользователя root
appserver 9X_.java / lib - как потомок root
webapp / WEB-INF 9X_linux / lib - как дочерний элемент корня
и т. д.

Обычно 9X_jdk загрузчики классов делегируют загрузку своему 9X_classloaders родительскому загрузчику классов (это известно 9X_linux как «parent-first»), и если этот загрузчик классов не 9X_java-se может найти класс, то загрузчик классов 9X_.java дочерних классов пытается это сделать. Например, если 9X_java-libraries класс, развернутый как JAR в webapp / WEB-INF 9X_javax / lib, пытается загрузить класс, сначала 9X_linkageerror он просит загрузчик классов, соответствующий 9X_jdk appserver / lib, загрузить класс (который, в 9X_.java свою очередь, запрашивает загрузчик классов, соответствующий 9X_oraclejdk javahome / lib для загрузки класса), и если 9X_class-loading этот поиск завершился неудачно, тогда WEB-INF 9X_java-se / lib ищет совпадение с этим классом.

В веб-среде 9X_j2se вы можете столкнуться с проблемами с этой 9X_oraclejdk иерархией. Например, одна ошибка / проблема, с 9X_java-se которой я сталкивался раньше, заключалась 9X_oraclejdk в том, что класс в WEB-INF / lib зависел 9X_classloaders от класса, развернутого в appserver / lib, который, в 9X_oraclejdk свою очередь, зависел от класса, развернутого 9X_jdk в WEB-INF / lib. Это вызвало сбои, потому 9X_classloaders что, хотя загрузчики классов могут делегировать 9X_java-se родительскому загрузчику классов, они не 9X_classloaders могут делегировать обратно вниз по дереву. Итак, загрузчик 9X_java-api классов WEB-INF / lib запросит загрузчик 9X_.java классов appserver / lib для класса, загрузчик 9X_classloader классов appserver / lib загрузит этот класс 9X_java-se и попытается загрузить зависимый класс и 9X_java-libraries потерпит неудачу, поскольку не сможет найти 9X_jre этот класс в appserver / lib или javahome 9X_classloader / lib.

Итак, хотя вы можете не развертывать 9X_java-libraries свое приложение в среде веб-сервера или 9X_class-loading сервера приложений, мое слишком длинное 9X_.java объяснение может быть применимо к вам, если 9X_openjdk в вашей среде настроена иерархия загрузчиков 9X_oraclejdk классов. Является ли? Использует ли JPF 9X_java-se какую-то магию загрузчика классов, чтобы 9X_java-libraries иметь возможность реализовать свои функции 9X_j2se плагина?

22
0

Ответ #3

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

Может быть, это кому-то поможет, потому 9X_core-java что у меня это неплохо получается. Проблема 9X_java-libraries может быть решена путем интеграции ваших 9X_classloaders собственных зависимостей. Следуйте этим 9X_classloaders простым шагам

Сначала проверьте ошибку, которая должна быть такой:

  • Выполнение метода не удалось:
  • java.lang.LinkageError: нарушение ограничения загрузчика:
  • при разрешении метода "org.slf4j.impl. StaticLoggerBinder .getLoggerFactory() Lorg / slf4j / ILoggerFactory;"
  • загрузчик классов (экземпляр org / openmrs / module / ModuleClassLoader) текущего класса, org / slf4j / LoggerFactory,
  • и загрузчик классов (экземпляр org / apache / catalina / loader / WebappClassLoader) для разрешенного класса org / slf4j / impl / StaticLoggerBinder,
  • иметь разные объекты класса для типа taticLoggerBinder.getLoggerFactory() Lorg / slf4j / ILoggerFactory; используется в подписи

  1. См. два выделенных класса. Google 9X_class-loading ищет их, например, "StaticLoggerBinder.class 9X_java jar download" и "LoggeraFactory.class 9X_classloader jar download". Это покажет вам первую 9X_java-libraries или, в некоторых случаях, вторую ссылку 9X_linux (сайт http://www.java2s.com), которая является одной из версий 9X_java-libraries jar, которые вы включили в свой проект. Вы 9X_.java можете определить это сами, но мы зависим 9X_java-libraries от Google;)

  2. После этого вы узнаете имя файла 9X_.java jar, в моем случае это похоже на slf4j-log4j12-1.5.6.jar 9X_classloader & slf4j-api-1.5.8

  3. Теперь последняя версия этого файла доступна здесь http://mvnrepository.com/ (фактически вся версия до настоящего времени, это сайт, с которого maven получает ваши зависимости).
  4. Теперь добавьте оба файла в качестве зависимостей с последней версией (или оставьте обе версии одинаковыми, либо выбранная версия устарела). Ниже приводится зависимость, которую необходимо включить в pom.xml


    org.slf4j
    slf4j-api
    1.7.7


    org.slf4j
    slf4j-log4j12
    1.7.7


9X_Как бороться с ошибками LinkageErrors в Java?_oraclejdk

6
0

Ответ #4

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

Вы можете указать загрузчик классов? Если 9X_j2se нет, попробуйте указать загрузчик класса 9X_java контекста следующим образом:

Thread thread = Thread.currentThread();
ClassLoader contextClassLoader = thread.getContextClassLoader();
try {
    thread.setContextClassLoader(yourClassLoader);
    callDom4j();
} finally {
    thread.setContextClassLoader(contextClassLoader);
}

Я не знаком 9X_openjdk с Java Plugin Framework, но я пишу код для 9X_java Eclipse и время от времени сталкиваюсь с 9X_java-libraries аналогичными проблемами. Я не гарантирую, что 9X_jre это исправит, но, вероятно, стоит попробовать.

5
0

Ответ #5

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

Очень полезны ответы Алекса и Мэтта. Я тоже 9X_j2se мог бы извлечь пользу из их анализа.

У меня 9X_oraclejdk была такая же проблема при использовании 9X_classloader библиотеки Batik в среде Netbeans RCP, при 9X_java-api этом библиотека Batik была включена как 9X_java «модуль оболочки библиотеки». Если какой-либо 9X_java-libraries другой модуль использует API XML и для этого 9X_linux модуля не требуется и не установлена ​​зависимость 9X_java-api от Batik, возникает проблема нарушения ограничений 9X_jdk загрузчика классов с аналогичными сообщениями 9X_openjdk об ошибках.

В Netbeans отдельные модули используют 9X_j2se выделенные загрузчики классов, а отношение 9X_java зависимости между модулями подразумевает 9X_java-libraries подходящую маршрутизацию делегирования загрузчика 9X_openjdk классов.

Я мог бы решить проблему, просто 9X_oraclejdk исключив файл jar xml-apis из пакета библиотеки 9X_java-se Batik.

3
0

Ответ #6

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

Как указано в this question, включение -verbose:class внесет в журнал 9X_classloader JVM информацию обо всех загружаемых классах, что 9X_openjdk может быть невероятно полезным для понимания 9X_oraclejdk того, откуда берутся классы в более сложных 9X_openjdk сценариях и приложениях.

Результат выглядит 9X_core-java примерно так (скопировано из этого вопроса):

[Opened /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/sunrsasign.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/jsse.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/jce.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/charsets.jar]
[Loaded java.lang.Object from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.io.Serializable from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.String from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]

1
0

Ответ #7

Ответ на вопрос: Как бороться с ошибками LinkageErrors в Java?

Я считаю, что этот класс загружается дважды. Причина 9X_java-api в том, что parallelWebappClassLoader сначала 9X_classloader загружает класс сам по себе, а не использует 9X_core-java его родительский classLoader.

1
0