wake-up-neo.com

Was ist eine IncompatibleClassChangeError-Ausnahme in Java?

ich arbeite an einer kleinen Anwendung und versuche, Hibernate Annotations zu verwenden, um meine Entitäten abzubilden. Ich wollte testen, ob alles in Ordnung ist, als ich diese Ausnahme bekam:

    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

Kann jemand erklären, was diese Ausnahme ist? Dies ist das erste Mal, dass ich es sehe. Hier ist der Hauptteil meiner Bewerbung:

 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();
     }
 }

}

Meine Ruhezustand-Konfiguration ist sehr einfach:

    <!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>

Hier ist die Hibernate-Maven-Abhängigkeit, die ich verwende:

<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>

Kann mir bitte jemand helfen ??

17
Dimitri

Dies bedeutet, dass zu einem bestimmten Zeitpunkt eine interface in eine class geändert wurde, aber ein Implementierer der ursprünglichen Schnittstelle nicht modifiziert und neu kompiliert wurde, um diese (inkompatible) Änderung zu berücksichtigen.

Betrachten Sie zum Beispiel die folgenden Typen:

interface Fooable {
  void foo();
}

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

Nehmen wir an, Fooable wird geändert und neu kompiliert, aber FooImpl ist nicht :

abstract class Fooable {
  public abstract void foo();
}
25
erickson

Die Unterstützung für JDK 1.4 wurde in 3.6 eingestellt. Hibernate Annotations wurde also wieder in Core zusammengeführt, und es ist nicht mehr nötig, sowohl Configurationals auch AnnotationConfigurationzu verwenden. Letzteres sollte nicht in 3.6.x verwendet werden (tatsächlich sollten Sie wahrscheinlich die JPA EntityManagerverwenden, nicht jedoch die Core-API, sondern diese ist eine andere Geschichte).

Mein wirklicher Rat wäre jedoch die Verwendung von 3.5.x von Hibernate, nicht der 3.6.x. Wie wir bereits gesehen haben, führt das Hibernate-Team große Änderungen in 3.6 ein, die darüber hinaus noch in der Beta-Version sind. Wenn Sie die Änderungen nicht genau verfolgen, werden Sie mit Überraschungen konfrontiert sein und im Internet nicht viele Ressourcen finden noch. Verwenden Sie einfach Hibernate 3.5 (3.5.5-Final zum Zeitpunkt des Schreibens).

4
Pascal Thivent

Überprüfen Sie, ob alle Ihre Bibliotheken kompatibel sind. Versuchen Sie dasselbe mit einer stabilen Version von Hibernate. Es besteht die Möglichkeit, dass die Betaversion defekt ist oder dass die 3.6.0-Betaversion im Ruhezustand POM einige inkompatible Abhängigkeiten aufweist.

Versuchen Sie, es ohne Maven und mit Hibernate 3.6.0 Beta1-Bibliotheken von den offiziellen Servern zu erstellen.


OK - Ihr Problem ist kein Fehler, sondern eine neue Funktion . Die Versionshinweise für Hibernate 3.6.0 Beta2 weisen auf eine wesentliche Änderung der vorherigen Betaversion hin: Die AnnotationConfiguration ist jetzt völlig veraltet . Sie sollten also (a) auf die neueste Beta (Beta3) aktualisieren, wenn Sie eine Version 3.6.0 beibehalten möchten, und (b) die AnnotationConfiguration nicht weiter verwenden.

3
Andreas_D

Richtig, erickson hat das Problem richtig erkannt.

Dies wird wahrscheinlich durch zwei widersprüchliche Versionen derselben Typdefinition in Ihrem Klassenpfad verursacht. Beispielsweise definiert library-version2.jar etwas, aber Sie haben auch library-version5.jar in Ihrem Klassenpfad.

Zur Laufzeit führt dies zu den von erickson beschriebenen Schmerzen und Leiden.

2
RonU

Ich schreibe dies, um zu helfen, wer nach diesem Fehler sucht. In Jar-Dateien aus Spring Roo kam es manchmal zu Konflikten mit pom.xml und Tomcat Server Runtime-Bibliotheken, die diesen Fehler beim Komponententest verursachten. Beim Erstellen von Frontend-Technologien wie Flex müssen Server-Laufzeitbibliotheken nicht im Klassenpfad angezeigt werden. Entfernen Sie daher einfach die Server-Laufzeitbibliotheken aus Klassenpfad.

1
zawhtut

Welchen Applikationsserver verwenden Sie? Könnte ein doppeltes oder widersprüchliches Hibernatglas sein.

0
Julian Bonilla