Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a IncompatibleClassChangeError exception in Java?

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

like image 255
Dimitri Avatar asked Aug 20 '10 20:08

Dimitri


5 Answers

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();
}
like image 122
erickson Avatar answered Nov 06 '22 15:11

erickson


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

like image 35
Pascal Thivent Avatar answered Nov 06 '22 16:11

Pascal Thivent


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.

like image 30
Andreas Dolk Avatar answered Nov 06 '22 16:11

Andreas Dolk


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.

like image 2
RonU Avatar answered Nov 06 '22 16:11

RonU


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.

like image 1
zawhtut Avatar answered Nov 06 '22 16:11

zawhtut