4

我有一个 Java (6) 应用程序,它使用 Hibernate (V3.3.2) 从 HSQLDB 读取数据,我使用 Eclipse (V3.5.1) 构建和调试/运行它,它工作正常。

然后,我创建了一个 GWT (V1.7) Servlet Web 应用程序,将我的 hibernate 类复制到其中,并添加了相同的用户库依赖项。但是,当我运行 servlet 并尝试访问调用我的代码的 URL 时,我得到了这个:

java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
    at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:152)
    at xxx.daoimpl.DAOSession.initialise(DAOSession.java:40)

其中 DAOSession.java:40 是:

AnnotationConfiguration config = new AnnotationConfiguration ();

谷歌搜索这个错误表明我在类路径中缺少 slf4j-api.jar,但是如果我查看调试属性的命令行,我可以在那里看到这个 jar:

C:\java\jsedk_6\jre\bin\javaw.exe
-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:54541
-Xmx512m -Dfile.encoding=Cp1252
-classpath
    D:\dev\workspace\xxx\src;
    D:\dev\workspace\xxx\resources;
    D:\dev\workspace\xxx\war\WEB-INF\classes;
    C:\java\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1\gwt-user.jar;
    C:\java\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1\gwt-dev-windows.jar;
    C:\java\hibernate-annotations-3.4.0.GA\hibernate-annotations.jar;
    C:\java\hibernate-annotations-3.4.0.GA\lib\ejb3-persistence.jar;
    C:\java\hibernate-annotations-3.4.0.GA\lib\hibernate-commons-annotations.jar;
    C:\java\hibernate-distribution-3.3.2.GA\hibernate3.jar;
    C:\java\hibernate-distribution-3.3.2.GA\lib\required\antlr-2.7.6.jar;
    C:\java\hibernate-distribution-3.3.2.GA\lib\required\commons-collections-3.1.jar;
    C:\java\hibernate-distribution-3.3.2.GA\lib\required\dom4j-1.6.1.jar;
    C:\java\hibernate-distribution-3.3.2.GA\lib\required\javassist-3.9.0.GA.jar;
    C:\java\hibernate-distribution-3.3.2.GA\lib\required\jta-1.1.jar;
    C:\java\hibernate-validator-4.0.1.GA\hibernate-validator-4.0.1.GA.jar;
    C:\java\hibernate-validator-4.0.1.GA\lib\validation-api-1.0.0.GA.jar;
    C:\java\hibernate-validator-4.0.1.GA\lib\log4j-1.2.14.jar;
    C:\java\hsqldb\lib\hsqldb.jar;
    C:\java\restlet-jse-2.0m5\lib\org.restlet.jar;
    C:\java\restlet-jee-2.0m5\lib\org.restlet.ext.servlet.jar;
    C:\java\restlet-jse-2.0m5\lib\org.restlet.ext.xml.jar;
    C:\java\slf4j-1.5.8\slf4j-api-1.5.8.jar;
    C:\java\slf4j-1.5.8\slf4j-log4j12-1.5.8.jar
    com.google.gwt.dev.HostedMode
    ...

如果我打开 jar,我可以在其中看到 LoggerFactory 类。

知道为什么类加载器找不到它吗?

Edit 1: If try to access org.slf4j.LoggerFactory from my code, Eclipse compiles it ok, but i get the same error at runtime.

Edit 2: If i add a Test class with a main which calls the same code and run it, it works. So this classpath problem seems specific to the Servlet.

thanks, jon

4

4 回答 4

6

It seems that copying the two slf4j jars to the war/WEB-INF/lib sub-project/dir fixed the problem. I'm not really sure why i should need to do this for these two jars and not for all the other Hibernate, Restlet etc jars that the project also uses, though i suppose for consistency i will do that anyway - i guess it will make deployment easier as well.

If someone can provide some sort of explanation as to why this worked and why exactly i need to do it i will select it as the "correct" answer, otherwise i'll select this one.

于 2009-11-07T15:32:22.337 回答
3

Can you please reconfirm that you have at least two slf4j.jar files in the classpath, the slf4j-api.jar and exactly one implementation, such as slf4j-jdk14.jar?

You must not have multiple sflj4-implementations in the classpath.

于 2009-11-06T19:16:39.070 回答
1

You have a runtime dependency issue so everything compiles fine but the dependency is in your jars. You need to visit the Hibernate site and look at the compatibility matrix and make sure you are matched up correctly then check the dependencies for annotations and core. You log4J jars look fine so it's definitely some quirk.

If it works in Eclipse then logically it's definitely some diff between the 2 runtimes (eclipse and non-eclipse), if the matrix checks out fine then see if you can factor out the commonalities in the 2 then work out the differences -- your answer should be in there.

于 2009-11-07T00:56:02.547 回答
1

I had a similar issue except I was using Tomcat and the NoClassDefFound error was on the juli logger. I fixed it by removing the Tomcat dependencies from my classpath when running in hosted mode because hosted mode embeds a Tomcat server that was conflicting. So I would see what happens if you remove some or all of the restlet jars from your classpath to see if they conflict.

于 2009-11-07T03:39:43.613 回答