java.lang.AbstractMethodError после обновления до Hibernate 3.3.2

У нас есть устаревшее приложение, использующее Hibernate 3.0.5, и мы пытаемся обновить его до Hibernate 3.3.2 (версия, которая меньше влияет на текущий код).

После обновления зависимостей в pom.xml приложение развертывается правильно, но при запросах с отложенной ассоциацией возникает следующая ошибка:

java.lang.AbstractMethodError: org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.setUnwrap(Z)V

Зависимости настроены следующим образом:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>3.3.2.GA</version>
  <exclusions>
    <!-- 
      Excludes to avoid conflict with JBoss libs
      See http://stackoverflow.com/questions/3413488/saxparser-errors-with-hibernate-and-jboss-conflicting-versions
     -->
    <exclusion>
      <groupId>xml-apis</groupId>
      <artifactId>xml-apis</artifactId>
      <version>1.0.b2</version>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>1.5.2</version>
</dependency>
<dependency>
  <groupId>javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.4.GA</version>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.14</version>
</dependency>

Мы уже пытались переключиться на CGLIB вместо Javassist, но получаем ту же ошибку на эквивалентном классе (org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer). Трассировки стека нет. Вот изображение стека выполнения в момент возникновения ошибки.

Трассировка стека в момент возникновения ошибки

Приложение работает на JBoss 5.1.0.

Любые советы об этой ошибке? Может ли это быть неправильная версия библиотеки javassist?

ОТРЕДАКТИРОВАНО

  • Добавлена ​​версия JBoss и исправлена ​​версия javassist до 3.4.GA.
  • Копнув дальше, я обнаружил, что (Z)V означает «пустой возврат» и «логический параметр» (http://www.rgagnon.com/javadetails/java-0286.html)

person Joaquim Oliveira    schedule 18.02.2014    source источник
comment
Вы используете JBoss? Если нет, то какой сервер приложений? Я видел эту проблему раньше (в основном с JBoss), но мне было бы интересно узнать об этом, прежде чем предлагать какие-либо конкретные рекомендации.   -  person J Steven Perry    schedule 19.02.2014
comment
Это полное сообщение об ошибке? java.lang.AbstractMethodError: org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.setUnwrap(Z)V   -  person Peter Svensson    schedule 19.02.2014
comment
@JStevenPerry, добавил к вопросу версию JBoss.   -  person Joaquim Oliveira    schedule 19.02.2014
comment
Я предполагаю, что это вызвано конфликтующими банками ASM, CGLIB зависит от ASM. Обходной путь для CGLIB — это spacial cglib-nodep.jar, он включает правильную версию ASM с переименованными пакетами.   -  person jbaliuka    schedule 19.02.2014
comment
@jabliuka, ASM и CGLIB не включены в качестве зависимостей. Кроме того, согласно этому руководству по миграции, Hibernate 3.3 по умолчанию теперь javassist   -  person Joaquim Oliveira    schedule 20.02.2014


Ответы (1)


Я столкнулся с проблемой, очень похожей на эту, и оказалось, что это проблема с загрузчиком классов JBoss. Конфигурации JBoss быстро меняются от одной версии к другой, и предлагаемое мной решение сработало для меня с использованием JBoss EAP 5.1.2.

Вот оно.

Во-первых, не забудьте явно указать версию Hibernate в POM:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>3.3.2.GA</version>
</dependency>

Затем вы захотите переопределить изоляцию ClassLoader JBoss по умолчанию, включив файл с именем jboss-web.xml в папку WEB-INF вашего файла WAR (этот же подход также должен работать, если вы развертываете EAR). Его формат выглядит следующим образом:

<jboss-web>
  <class-loading>
    <loader-repository>
        org.hibernate=my-application.war
        <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
    </loader-repository>
  </class-loading>
</jboss-web>

Где my-application.war — это имя вашего WAR-файла. Обратите внимание, что java2ParentDelegation, установленное в false, может помочь с другими проблемами ClassLoader (особенно с slf4j по моему опыту).

Наконец, проблемы JBoss 5.1.x ClassLoader сводят с ума, поэтому я надеюсь, что это поможет. Следует иметь в виду, что проблема не связана с javassist как таковым (и вы можете рассмотреть возможность удаления явного javassist <dependency> в вашем POM и позволить Maven разрешить ее на основе Hibernate <dependency>). Скорее всего, это проблема ClassLoader. И стратегия JBoss по умолчанию для ClassLoading отлично работает большую часть времени, пока вы не подключите Hibernate. Предварительная версия JBoss 6 тесно связана с конкретной версией Hibernate, которая поставляется с JBoss, поэтому попытка использовать версию Hibernate, отличную от той, которую хочет использовать JBoss, является настоящей головной болью. Но это можно сделать!

Для файлов EAR файл называется jboss-app.xml и находится в папке META-INF вашего файла EAR:

<jboss-app>
  <loader-repository> 
  org.hibernate:archive=my-application.ear 
     <loader-repository-config> 
     java2ParentDelegation=false 
     </loader-repository-config> 
  </loader-repository>
</jboss-app>

Удачи!

person J Steven Perry    schedule 19.02.2014
comment
Ошибка сохраняется, несмотря на конфигурацию. Я включил журнал загрузки классов JBoss, и используемые файлы JAR (javassist, hibernate-core) (очевидно) соответствуют файлам WEB-INF/lib. - person Joaquim Oliveira; 20.02.2014
comment
Я не совсем уверен, что вы говорите. Вы можете уточнить? JAR-файлы находятся в WEB-INF/lib, но файл jboss-web.xml должен находиться в WEB-INF. - person J Steven Perry; 20.02.2014
comment
Извините, я смешал два ответа в одном предложении. Я сделал конфигурацию, которую вы предложили в jboss-web.xml, а также удалил явную зависимость javassist в pom.xml, но это не сработало. Итак, я заметил javassist.jar в $JBOSS_HOME/lib и подумал, что он не загружается (потому что он был настроен так, чтобы не загружаться из родителя) и явно объявил его в POM. Журнал подтвердил, что банка читалась из WEB-INF/lib, но я получил то же сообщение об ошибке. - person Joaquim Oliveira; 20.02.2014
comment
облом. Загрузка классов JBoss в EAP 5.1 просто адская. Извините, мое предложение не сработало для вас. - person J Steven Perry; 20.02.2014
comment
Самое странное, что версия 3.3.1, поставляемая с JBoss, прекрасно работает. Спасибо в любом случае за вашу помощь! - person Joaquim Oliveira; 21.02.2014