Hibernate в Glassfish - Ejb3Configuration NoClassDefFoundError - PullRequest
2 голосов
/ 22 мая 2009

Я поместил библиотеки Hibernate в домен Glassfish и в коллекцию библиотек моего проекта в Netbeans. hibernate-entitymanager.jar содержит как HibernatePersistence (последний класс в стеке вызовов), так и Ejb3Configuration, поэтому я довольно озадачен тем, почему я получаю ошибку отсутствующего класса для Ejb3Configuration.

java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.ejb.Ejb3Configuration
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:130)
    at com.sun.enterprise.server.PersistenceUnitLoaderImpl.load(PersistenceUnitLoaderImpl.java:149)
    at com.sun.enterprise.server.PersistenceUnitLoaderImpl.load(PersistenceUnitLoaderImpl.java:84)
...

Ответы [ 2 ]

8 голосов
/ 23 мая 2009

Я никогда раньше не видел этого конкретного сообщения об ошибке, но могу немного объяснить, что оно означает, и указать одну возможную причину.

Линия

java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.ejb.Ejb3Configuration

не означает, что JVM не смогла найти класс org.hibernate.ejb.Ejb3Configuration. Это означает, что JVM может найти этот класс, но он уже пытался и не смог загрузить этот класс.

Это текст Could not initialize class ..., который указывает, что это произошло. Если JVM вообще не может найти класс, вы получите что-то вроде следующего:

java.lang.NoClassDefFoundError: org/hibernate/ejb/Ejb3Configuration

Кроме того, это также означает, что вы используете Java 6 - в Java 5 соответствующее исключение не имеет сообщения.

Следующие два класса демонстрируют это поведение. Класс Unloadable не может быть загружен, потому что его статический инициализатор всегда выдает исключение. Мы пытаемся загрузить этот класс, перехватить полученный результат ExceptionInInitializerError и попытаться загрузить Unloadable снова.

class Unloadable {
    static {
        if (true) { throw new RuntimeException(); }
    }
}

public class LoadingTest {
    public static void main(String[] args) throws Exception {
        try {
            Class.forName("Unloadable");
        }
        catch (ExceptionInInitializerError e) {
            try {
                Class.forName("Unloadable");
            }
            catch (NoClassDefFoundError e2) {
                System.out.println("XXXXXXXXXXXXXXXXXXXXX");
                e2.printStackTrace(System.out);
            }
        }
    }
}

Когда я запускаю класс LoadingTest, я получаю следующий вывод:

XXXXXXXXXXXXXXXXXXXXX
java.lang.NoClassDefFoundError: Could not initialize class Unloadable
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at LoadingTest.main(LoadingTest.java:14)

Я не могу сказать, что является причиной неудачной исходной попытки загрузки org.hibernate.ejb.Ejb3Configuration. Вполне может быть, что Ejb3Configuration сам по себе зависит от классов, которые отсутствуют в пути к классам. Возможно, стоит просмотреть список всех классов import, созданных Ejb3Configuration , и убедиться, что все те, кто не находится под java.* или javax.*, находятся в JAR, который могут видеть Glassfish и Netbeans. 1032 *

Кроме того, я могу только предположить, почему JVM пытается загрузить Ejb3Configuration дважды . Когда загрузка класса не удается в первый раз, генерируется исключение (обычно некоторый подкласс LinkageError). Этот тип исключения не часто встречается, поэтому я думаю, что происходит что-то вроде следующего:

try {
    // Some code that loads Ejb3Configuration and fails.
}
finally {
    // Some code that also loads Ejb3Configuration and fails.
}

Если код в блоке finally выдает исключение, это исключение заменит любое исключение, выброшенное в блоке try. Я предлагаю это, потому что подобное произошло на этом вопросе . Трассировка стека, опубликованная в этом вопросе, идет из блока finally.

Если мой ответ по-прежнему не помогает, не могли бы вы опубликовать всю трассировку стека, которую вы видите?

3 голосов
/ 06 августа 2009

У меня тоже была эта проблема, хотя в моем случае это была проблема, связанная с версией. Новые версии hibernate зависят от Simple Logging Facade для Java (SLF4J), но артефакты maven включают только API, поэтому вам нужны библиотеки времени выполнения в вашей WAR или в папке lib сервера.

Это относится к версии Hibernate Entity Manager версии 3.4.0, хотя может применяться и к другим версиям. Если вы используете Hibernate Core 3.3.x, вы используете Hibernate EM серии 3.4.x, поэтому вам НУЖНЫ эти библиотеки времени выполнения.

...