web-dev-qa-db-ja.com

JavaのIncompatibleClassChangeError例外とは何ですか?

小さなアプリケーションで作業していて、Hibernate Annotationsを使用してエンティティをマップしようとしています。私はこの例外を得たときにすべてが問題ないかどうかをテストしたかった:

    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依存関係です:

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

誰かが私を助けてくれますか?

17
Dimitri

つまり、ある時点でinterfaceclassに変更されましたが、元のインターフェースの実装者は、この(互換性のない)変更に対応するために変更および再コンパイルされていません。

たとえば、次のタイプを検討してください。

interface Fooable {
  void foo();
}

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

ここで、Fooableが変更および再コンパイルされているが、FooImplnotであるとします。

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

JDK 1.4のサポートは3.6で削除されました。そのため、Hibernate Annotationsはコアにマージされ、ConfigurationAnnotationConfigurationの両方を使用する必要がなくなりました。後者は3.6.xでは使用しないでください(実際には、 JPA EntityManager、コアAPIではありませんが、これは別の話です)。

しかし、私の本当のアドバイスは、3.6.xではなくHibernateの.5.xブランチを使用することです。すでに見たように、Hibernateチームは3.6に大きな変更を導入しています。これはまだベータ版ですが、変更に注意深く従わない限り、いくつかの驚きに直面し、インターネット上で多くのリソースを見つけることができません。まだ。 Hibernate 3.5(これを書いている時点では3.5.5-Final)を使用してください。

4
Pascal Thivent

すべてのライブラリに互換性があるかどうかを再確認してください。 hibernateの安定したバージョンで同じことを試してください。ベータ版に欠陥があるか、hibernate 3.6.0ベータ版POMに互換性のない依存関係がある可能性があります。

Mavenを使用せず、公式サーバーのHibernate 3.6.0 Beta1ライブラリを使用してビルドしてみてください。


OK-あなたの問題はバグではなく新しい機能です。 Hibernate 3.6.0 Beta2のリリースノートでは、以前のベータ版に大きな変更が加えられています AnnotationConfigurationは完全に非推奨になりました 。したがって、(a)3.6.0バージョンを保持する場合は(a)最新のベータ(Beta3)に更新し、(b)AnnotationConfigurationの使用を継続しないでください。

3
Andreas_D

そう、エリクソンは問題を正しく特定しました。

これは、クラスパスに同じタイプ定義の2つのバージョンが競合していることが原因である可能性があります。たとえば、library-version2.jarはいくつかのものを定義しますが、classpathにlibrary-version5.jarもあります。

実行時に、これはエリクソンが説明する痛みと苦しみをもたらします。

2
RonU

私はこれを書いて、このエラーを探す人を助けます。 Spring Rooで生成されたjarファイルがpom.xmlとTomcat Serverランタイムライブラリで競合し、ユニットテスト中にこのエラーが発生することがあります。 Flexのようなフロントエンドテクノロジーを構築する場合、サーバーランタイムライブラリをクラスパスに含める必要はないので、クラスパスからサーバーランタイムライブラリを削除するだけです。

1
zawhtut

どのアプリケーションサーバーを使用していますか?重複または競合する休止状態のjarである可能性があります。

0
Julian Bonilla