2010-08-20 6 views
17

sto lavorando su una piccola applicazione e sto cercando di usare le annotazioni di ibernazione per mappare le mie entità. Volevo testare se tutto va bene quando ho questa eccezione:Che cos'è un'eccezione IncompatibleClassChangeError in Java?

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 

Qualcuno può spiegare cos'è questa eccezione? Questa è la prima volta che la vedo. Qui è la principale della mia candidatura:

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

} 

mio hibernate configurazione è molto semplice:

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

Ecco la dipendenza ibernazione Maven sto usando:

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

qualcuno può aiutarmi io per favore ??

+0

[non un duplicato ma un'altra domanda su questo errore] (http://stackoverflow.com/questions/1980452/what-causes-java-lang-incompatibleclasschangeerror) –

risposta

25

Significa che a un certo punto, un interface è stato modificato in un class, ma un implementatore dell'interfaccia originale non è stato modificato e ricompilato per accogliere questa modifica (incompatibile).

Ad esempio, considerare i seguenti tipi:

interface Fooable { 
    void foo(); 
} 

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

Ora supponiamo Fooable viene modificato e ricompilato, ma FooImpl è non:

abstract class Fooable { 
    public abstract void foo(); 
} 
+0

Ciao, grazie per la tua risposta. Come posso risolvere questo?? – Dimitri

+3

Attendi, questa è solo * una * possibile causa. Come cambiare i campi da statico a non statico o viceversa. [Guarda qui.] (Http://stackoverflow.com/questions/1980452/what-causes-java-lang-incompatibleclasschangeerror/1980474#1980474) –

+4

@Andreas_D - Non con il messaggio "Implementing class". Questo è specifico del problema che descrivo. – erickson

0

Quale server applicazioni stai utilizzando? Potrebbe essere un vaso di ibernazione duplicato o in conflitto.

+0

Nessun server applicazioni. – Dimitri

2

Destra, Erickson ha identificato il problema in modo corretto.

Questo è probabilmente causato dall'avere due versioni in conflitto della stessa definizione di tipo nel classpath. Ad esempio, library-version2.jar definisce alcune cose, ma hai anche library-version5.jar nel classpath.

In fase di esecuzione, ciò comporta il dolore e la sofferenza descritti da erickson.

3

Verificare se tutte le librerie sono compatibili. Prova la stessa cosa con una versione stabile di hibernate, c'è la possibilità che la beta sia difettosa o che la versione beta beta 3.6.0 di ibernazione abbia alcune dipendenze incompatibili.

Provare a costruirlo senza Maven e con le librerie beta 2.0 di ibernazione 3.6.0 dai server ufficiali.


OK - il problema non è un bug, ma una nuova funzionalità. Le note di rilascio per Hibernate 3.6.0 Beta2 rilevano una modifica importante alla beta precedente: the AnnotationConfiguration is now totally deprecated. Quindi dovresti (a) aggiornare alla beta più recente (Beta3) se vuoi mantenere una versione 3.6.0 e (b) non continuare ad usare AnnotationConfiguration.

4

Il supporto JDK 1.4 è stato eliminato in 3.6. Quindi Hibernate Annotations è stato fuso in Core e non c'è più bisogno di avere sia Configuration e AnnotationConfiguration che il successivo non dovrebbe essere usato in 3.6.x (in realtà, dovresti probabilmente usare l'API JPA EntityManager, non questa, ma questa è un'altra storia).

Ma il mio vero consiglio sarebbe quello di utilizzare il ramo 3.5.x di Hibernate, non il 3.6.x. Come abbiamo già visto, il team di Hibernate sta introducendo grandi cambiamenti in 3.6, che è in cima a quello ancora in Beta, ea meno che tu non stia seguendo da vicino le modifiche, dovrai affrontare alcune sorprese e non troverai molte risorse su Internet ancora. Basta usare Hibernate 3.5 (3.5.5-Final al momento della stesura di questo).

+0

Grazie per il tuo commento. Su un progetto legacy recentemente migrato da WebSphere a JBoss, sono passato attraverso questo "IncompatibleClassChangeError' a causa del mio uso dell'interfaccia" org.primitive.type.PrimitiveType' (in un Hibernate personalizzato "UserType') che era una classe astratta precedente alla versione 3.6. Ma il problema sono i numerosi pom.xml con diverse dipendenze da Hibernate, come 3.3.2.GA vs 3.6.10.Final. – maxxyme

1

Scrivo questo per aiutare chi cerca questo errore. A volte i file jar provenienti da Spring Roo generano conflitti tra le librerie pom.xml e Tomcat Server Runtime e hanno prodotto questo errore durante il test dell'unità. Mentre si costruiscono tecnologie di frontend come Flex, le librerie di runtime del server non sono necessarie per la presentazione nel classpath, quindi è sufficiente rimuovere le librerie di runtime del server da classpath.