22

i am working on a small application and I am trying to use Hibernate Annotations to map my entities. I wanted to test if everything is alright when i got this exception :

    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

Can someone explain what is this exception ? This is the first time i see it. Here is the main of my application :

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

}

My hibernate config is very simple :

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

Here is the hibernate maven dependency i am using :

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

Can someone help me please ??

Dimitri
  • 8,122
  • 19
  • 71
  • 128
  • [not a duplicate but another question about this error](http://stackoverflow.com/questions/1980452/what-causes-java-lang-incompatibleclasschangeerror) – Andreas Dolk Aug 20 '10 at 21:02

6 Answers6

28

It means that at some point, an interface was changed to a class, but an implementer of the original interface was not modified and recompiled to accommodate this (incompatible) change.

For example, consider the following types:

interface Fooable {
  void foo();
}

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

Now suppose Fooable is modified and recompiled, but FooImpl is not:

abstract class Fooable {
  public abstract void foo();
}
erickson
  • 265,237
  • 58
  • 395
  • 493
  • 3
    Wait, this is just *one* possible cause. Like changing fields from static to non-static or vice-versa. [Look here.](http://stackoverflow.com/questions/1980452/what-causes-java-lang-incompatibleclasschangeerror/1980474#1980474) – Andreas Dolk Aug 20 '10 at 21:24
  • 4
    @Andreas_D - Not with the message, "Implementing class". That is specific to the problem I describe. – erickson Aug 20 '10 at 21:32
  • @Dimitri - Fixing it depends on the classes involved. Most likely, you have some code specific to your application that was compiled against a third-party library, and then that third-party library was replaced without recompiling your code. Make sure that you are deploying the JAR files that you actually compiled against, and that there is only one version of each class on the classpath. – erickson Aug 20 '10 at 21:34
  • oh, you're right. But I think, I found the problem. Have a look at my answer. Pretty sure, it's the hibernate version he used in combination with AnnotationConfiguration. – Andreas Dolk Aug 20 '10 at 21:39
  • @erickson Is the first class listed (reading down the stack trace) that is not a java.* or sun.* always the offending class referred to as "Implementing class" in the error message? – cclark Aug 03 '12 at 19:03
  • @cclark No, I don't think that is the name of the class that is actually wrongly implementing what is now a class rather than an interface. But, if you were to look at that line in that class, you should be able to see what class is being referenced there for the first time; that would be the offending class. – erickson Aug 03 '12 at 20:01
4

JDK 1.4 support has been dropped in 3.6. So Hibernate Annotations has been merged back into Core and there is no more need to have both Configuration and AnnotationConfiguration and the later should not be used in 3.6.x (actually, you should probably use the JPA EntityManager, not the core API, but this is another story).

But my real advice would be to use the 3.5.x branch of Hibernate, not the 3.6.x. As we already saw, the Hibernate team is introducing big changes in 3.6, which is on top of that still in Beta, and unless you are following the changes closely, you'll face some surprises and won't find many resources on the internet yet. Just use Hibernate 3.5 (3.5.5-Final at the time of writing this).

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • Thanks for your comment. On a legacy project recently migrated from WebSphere to JBoss, I came through this `IncompatibleClassChangeError` due to my use of interface `org.primitive.type.PrimitiveType` (in a custom Hibernate `UserType`) which was an abstract class prior to version 3.6. But the problem is the numerous pom.xml having different Hibernate dependencies, like 3.3.2.GA vs 3.6.10.Final. – maxxyme May 25 '16 at 09:22
3

Double check if all your libraries are compatible. Try the same with a stable version of hibernate, there's a chance that the beta is defect or the hibernate 3.6.0 beta POM has some incompatible dependencies.

Try to build it without maven and with hibernate 3.6.0 beta1 libraries from the official servers.


OK - your problem is not a bug but a new feature. The release notes for Hibernate 3.6.0 Beta2 note a major change to the previous beta: the AnnotationConfiguration is now totally deprecated. So you should (a) update to the most recent beta (Beta3) if you want to keep a 3.6.0 version and (b) do not continue using the AnnotationConfiguration.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
2

Right, erickson has identified the issue correctly.

This is likely caused by having two conflicting versions of the same type definition in your classpath. For example, library-version2.jar defines some stuff, but you've also got library-version5.jar in your classpath.

At runtime, this results in the pain and suffering erickson describes.

RonU
  • 5,525
  • 3
  • 16
  • 13
1

I write this to help whoever lookup to this error . Sometimes jar files coming from Spring Roo generated pom.xml and Tomcat Server Runtime libraries conflict and produced this error during unit testing. While building frontend technology like Flex, Server runtime libraries are not necessary to present in the classpath, so simply remove the Server runtime libraries from classpath.

zawhtut
  • 8,335
  • 5
  • 52
  • 76
0

Which application server are you using? Could be a duplicate or conflicting hibernate jar.

Julian Bonilla
  • 243
  • 3
  • 8