Glassfish中的Hibernate - Ejb3Configuration NoClassDefFoundError

时间:2009-05-22 17:40:31

标签: hibernate netbeans java-ee glassfish ejb-3.0

我已将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 个答案:

答案 0 :(得分:8)

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

该行

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本身依赖于类路径中缺少的类。可能值得浏览Ejb3Configuration编辑的所有类import的列表,并确保所有不在java.*javax.*下的人都在Glassfish和Netbeans的JAR中可以看到。

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

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

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

如果我的回答仍然无法帮助您,请您发布您看到的整个堆栈跟踪吗?

答案 1 :(得分:3)

我也有这个问题,虽然在我的案例中它似乎是特定于版本的问题。较新版本的hibernate依赖于Simple Logging Facade for Java(SLF4J),但maven工件仅包含API,因此您需要WAR或服务器的lib文件夹中的运行时库。

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