2

我已经将 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)
...
4

2 回答 2

8

我以前从未见过这个特定的错误消息,但我可以解释一下它的含义并给出一个可能的原因。

线

java.lang.NoClassDefFoundError:无法初始化类 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);
            }
        }
    }
}

当我运行 classLoadingTest时,我得到以下输出:

XXXXXXXXXXXXXXXXXXXXX
java.lang.NoClassDefFoundError:无法初始化类 Unloadable
        在 java.lang.Class.forName0(本机方法)
        在 java.lang.Class.forName(Class.java:169)
        在 LoadingTest.main(LoadingTest.java:14)

我不能说是什么导致了最初的加载尝试org.hibernate.ejb.Ejb3Configuration失败。很可能它Ejb3Configuration本身取决于类路径中缺少的类。可能值得仔细阅读importEjb3Configuration编辑的所有类的列表,并确保所有那些不在Glassfish 和 Netbeans 可以看到的 JAR下java.*或在其中的所有类。javax.*

另外,我只能推测为什么 JVM 试图加载Ejb3Configuration 两次。当类加载第一次失败时,会抛出异常(通常是 的某个子类LinkageError)。这种类型的异常并不经常被捕获,所以我最好的猜测是正在发生类似以下的事情:

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

如果finally块中的代码抛出异常,则该异常将替换块中抛出的任何异常try我建议这样做是因为在这个问题上发生了类似的事情。此问题中发布的堆栈跟踪来自一个finally块内。

如果我的回答仍然对您没有帮助,您能否发布您看到的整个堆栈跟踪?

于 2009-05-22T20:59:50.373 回答
3

我也遇到了这个问题,尽管在我的情况下它似乎是一个特定于版本的问题。较新版本的 hibernate 依赖于 Java 的 Simple Logging Facade (SLF4J),但 maven 工件仅包含 API,因此您需要 WAR 或服务器的 lib 文件夹中的运行时库。

这是特定于 Hibernate Entity Manager 3.4.0 版本的,尽管它也可能适用于其他版本。如果您使用的是 Hibernate Core 3.3.x,那么您使用的是 3.4.x 系列的 Hibernate EM,因此您需要这些运行时库。

于 2009-08-06T09:11:46.850 回答