Что такое исключение IncompatibleClassChangeError в Java?

Я работаю над небольшим приложением и пытаюсь использовать аннотации Hibernate для сопоставления своих объектов. Я хотел проверить, все ли в порядке, когда у меня появилось это исключение:

    Exception in thread "main" java.lang.ExceptionInInitializerError
 at fr.cc2i.intervention.dao.main.Main$HibernateUtil.<clinit>(Main.java:48)
 at fr.cc2i.intervention.dao.main.Main.test(Main.java:21)
 at fr.cc2i.intervention.dao.main.Main.main(Main.java:32)
Caused by: java.lang.IncompatibleClassChangeError: Implementing class
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
 at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
 at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
 at fr.cc2i.intervention.dao.main.Main$HibernateUtil.<clinit>(Main.java:44)
 ... 2 more

Может кто-нибудь объяснить, что это за исключение? Я впервые это вижу. Вот основная часть моего приложения:

 package fr.cc2i.intervention.dao.main;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import fr.cc2i.intervention.dao.beans.Client;
import fr.cc2i.intervention.dao.beans.Contrat;

public class Main {

 public static void test(){
  Client c = new Client();
  c.setCode("123343");
  c.setAdresse("fkhdhdmh");
  c.setNom("dgsfhgsdfgs");
  c.setPhone("53456464");
  c.setContrat(new Contrat());

  Session session = HibernateUtil.getSession();
        session.beginTransaction();        
        session.save(c);
        session.getTransaction().commit();

 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  Main.test();

 }

 public static class HibernateUtil {

 private static final SessionFactory sessionFactory;
     static {
         try {
             sessionFactory = new AnnotationConfiguration()
                     .configure().buildSessionFactory();
         } catch (Throwable ex) {
             // Log exception!
             throw new ExceptionInInitializerError(ex);
         }
     }

     public static Session getSession()
             throws HibernateException {
         return sessionFactory.openSession();
     }
 }

}

Моя конфигурация гибернации очень проста:

    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <!-- Database connection settings -->
  <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
  <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
  <property name="connection.username">sa</property>
  <property name="connection.password"></property>

  <!-- JDBC connection pool (use the built-in) -->
  <property name="connection.pool_size">1</property>

  <!-- SQL dialect -->
  <property name="dialect">org.hibernate.dialect.HSQLDialect</property>

  <!-- Enable Hibernate's automatic session context management -->
  <property name="current_session_context_class">thread</property>

  <!-- Disable the second-level cache  -->
  <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

  <!-- Echo all executed SQL to stdout -->
  <property name="show_sql">true</property>

  <!-- Drop and re-create the database schema on startup -->
  <property name="hbm2ddl.auto">update</property>

  <mapping package="fr.cc2i.intervention.dao.beans.Client" />
  <mapping class="fr.cc2i.intervention.dao.beans.Contrat" />
  <mapping class="fr.cc2i.intervention.dao.beans.Intervention" />
  <mapping class="fr.cc2i.intervention.dao.beans.Technicien" />



 </session-factory>
</hibernate-configuration>

Вот зависимость maven от hibernate, которую я использую:

<properties>
        <org.springframework.version>3.0.3.RELEASE</org.springframework.version>
        <hibernate.version>3.6.0.Beta1</hibernate.version></properties>

    <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

Может кто-то помочь мне, пожалуйста ??


person Dimitri    schedule 20.08.2010    source источник
comment
не дубликат, а еще один вопрос об этой ошибке   -  person Andreas Dolk    schedule 21.08.2010


Ответы (6)


Это означает, что в какой-то момент interface был изменен на class, но разработчик исходного интерфейса не был изменен и перекомпилирован с учетом этого (несовместимого) изменения.

Например, рассмотрим следующие типы:

interface Fooable {
  void foo();
}

class FooImpl implements Fooable {
  public void foo() {
     /* Do something... */
  }
}

Теперь предположим, что Fooable изменен и перекомпилирован, а FooImpl нет:

abstract class Fooable {
  public abstract void foo();
}
person erickson    schedule 20.08.2010
comment
Подождите, это всего лишь одна возможная причина. Как изменение поля со статического на нестатическое или наоборот. Посмотрите здесь. - person Andreas Dolk; 21.08.2010
comment
@Andreas_D - Не с сообщением, класс реализации. Это характерно для описываемой мной проблемы. - person erickson; 21.08.2010
comment
@Dimitri - Исправление зависит от задействованных классов. Скорее всего, у вас есть код, специфичный для вашего приложения, который был скомпилирован с использованием сторонней библиотеки, а затем эта сторонняя библиотека была заменена без перекомпиляции вашего кода. Убедитесь, что вы развертываете файлы JAR, с которыми вы действительно скомпилировали, и что в пути к классам есть только одна версия каждого класса. - person erickson; 21.08.2010
comment
о, ты прав. Но я думаю, что нашел проблему. Посмотри на мой ответ. Совершенно уверен, что это версия гибернации, которую он использовал в сочетании с AnnotationConfiguration. - person Andreas Dolk; 21.08.2010
comment
@erickson Является ли первый перечисленный класс (считывание трассировки стека), который не является java. * или sun. *, всегда является классом-нарушителем, который в сообщении об ошибке называется классом реализации? - person cclark; 03.08.2012
comment
@cclark Нет, я не думаю, что это имя класса, который на самом деле неправильно реализует то, что сейчас является классом, а не интерфейсом. Но если вы посмотрите на эту строку в этом классе, вы сможете увидеть, какой класс упоминается там впервые; это был бы оскорбительный класс. - person erickson; 04.08.2012

Поддержка JDK 1.4 была прекращена в версии 3.6. Итак, аннотации Hibernate были объединены обратно в Core, и больше нет необходимости иметь и Configuration, и AnnotationConfiguration, а более поздние версии не должны использоваться в 3.6.x (на самом деле вам, вероятно, следует использовать JPA EntityManager, а не основной API, но это это отдельная история).

Но я бы посоветовал использовать ветвь Hibernate 3.5.x, а не 3.6.x. Как мы уже видели, команда Hibernate вносит большие изменения в 3.6, которая является вершиной того, что все еще находится в бета-версии, и, если вы внимательно не следите за изменениями, вы столкнетесь с некоторыми сюрпризами и не найдете много ресурсов в Интернете. пока что. Просто используйте Hibernate 3.5 (3.5.5-Final на момент написания этой статьи).

person Pascal Thivent    schedule 21.08.2010
comment
Спасибо за ваш комментарий. В устаревшем проекте, недавно перенесенном с WebSphere на JBoss, я столкнулся с этим IncompatibleClassChangeError из-за того, что я использовал интерфейс org.primitive.type.PrimitiveType (в пользовательском Hibernate UserType), который был абстрактным классом до версии 3.6. Но проблема в том, что множество pom.xml имеют разные зависимости Hibernate, например 3.3.2.GA и 3.6.10.Final. - person maxxyme; 25.05.2016

Дважды проверьте, все ли ваши библиотеки совместимы. Попробуйте то же самое со стабильной версией спящего режима, есть вероятность, что бета-версия неисправна или POM спящего режима 3.6.0 бета имеет несовместимые зависимости.

Попробуйте собрать его без maven и с библиотеками hibernate 3.6.0 beta1 с официальных серверов.


Хорошо, ваша проблема не ошибка, а новая функция. В примечаниях к выпуску Hibernate 3.6.0 Beta2 отмечается значительное изменение предыдущей бета-версии: AnnotationConfiguration полностью устарела. Поэтому вам следует (а) обновиться до самой последней бета-версии (Beta3), если вы хотите сохранить версию 3.6.0, и (б) не продолжать использовать AnnotationConfiguration.

person Andreas Dolk    schedule 20.08.2010

Верно, Эриксон правильно определил проблему.

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

Во время выполнения это приводит к боли и страданиям, описанным Эриксоном.

person RonU    schedule 20.08.2010

Я пишу это, чтобы помочь тем, кто найдет эту ошибку. Иногда файлы jar, поступающие из Spring Roo, создают конфликт библиотек pom.xml и Tomcat Server Runtime и вызывают эту ошибку во время модульного тестирования. При создании интерфейсной технологии, такой как Flex, библиотеки времени выполнения сервера не обязательно должны присутствовать в пути к классам, поэтому просто удалите библиотеки времени выполнения сервера из пути к классам.

person zawhtut    schedule 05.05.2011

Какой сервер приложений вы используете? Это может быть повторяющаяся или конфликтующая банка гибернации.

person Julian Bonilla    schedule 20.08.2010