我有一个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,但是如果我查看Debug属性的命令行,我可以在那里看到这个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类。
知道为何没有被类加载器找到它?
编辑1:如果尝试从我的代码访问org.slf4j.LoggerFactory,Eclipse编译好了,但我在运行时遇到了同样的错误。
编辑2:如果我添加一个带有main的Test类,它调用相同的代码并运行它,它就可以了。所以这个类路径问题似乎特定于Servlet。
感谢, 乔恩
答案 0 :(得分:6)
似乎将两个slf4j jar复制到war / WEB-INF / lib子项目/ dir修复了问题。我不太确定为什么我需要为这两个罐子做这个,而不是对于项目也使用的所有其他Hibernate,Restlet等罐子,虽然我想为了一致性我仍然会这样做 - 我猜它会使部署也更容易。
如果有人可以提供某种解释,说明为什么这样做,以及为什么我需要这样做,我会选择它作为“正确”的答案,否则我会选择这个。
答案 1 :(得分:3)
请您再次确认您在类路径中至少有两个slf4j.jar文件,slf4j-api.jar和一个实现,例如slf4j-jdk14.jar?
您必须在类路径中没有多个sflj4实现。
答案 2 :(得分:1)
您有运行时依赖性问题,因此所有内容编译都很好,但依赖项在您的jar中。您需要访问Hibernate站点并查看兼容性matrix并确保正确匹配,然后检查注释和核心的依赖关系。你log4J jars看起来很好,所以它肯定是一些怪癖。
如果它在Eclipse中有效,那么逻辑上它肯定是两个运行时间(eclipse和非eclipse)之间的差异,如果矩阵检查得很好,那么看看你是否可以分解2中的共性然后计算出差异 - - 你的答案应该在那里。
答案 3 :(得分:1)
我有一个类似的问题,除了我使用Tomcat和NoClassDefFound错误在juli记录器上。我通过在托管模式下运行时从类路径中删除Tomcat依赖项来修复它,因为托管模式嵌入了一个冲突的Tomcat服务器。所以如果从类路径中删除部分或全部的restlet jar,看看它们是否冲突,我会看到会发生什么。