views:

1996

answers:

4

I have a Java (6) application which uses Hibernate (V3.3.2) to read data from HSQLDB, which i build and debug/run with Eclipse (V3.5.1), and it works fine.

I then created a GWT (V1.7) Servlet web app, copied my hibernate classes into it, and added the same User Libraries dependencies. However when i run the servlet and try to access a URL which invokes my code i get this:

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

where DAOSession.java:40 is :

AnnotationConfiguration config = new AnnotationConfiguration ();

Googling for this error suggests i am missing slf4j-api.jar from the classpath, however if i look at the command line for the Debug properties i can see this jar there:

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
    ...

If i open the jar i can see the LoggerFactory class in there.

Any idea why it isn't being found by the class loader?

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

+3  A: 

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.

mhaller
The classpath listed above has the following slf4j jars: C:\java\slf4j-1.5.8\slf4j-api-1.5.8.jar C:\java\slf4j-1.5.8\slf4j-log4j12-1.5.8.jarI assume the latter is the log4j implementation.
jon hanson
Connect to the running process using VisualVM and check the real classpath. Perhaps GWT is adding additional classpath entries to the webapp and there might be an additional log4j.jar or something like that.
mhaller
+1  A: 

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.

non sequitor
+1  A: 

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.

Brian Deterling
+2  A: 

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.

jon hanson
I'd like to see what your classpath looks like now. I suspect GWT's embedded Tomcat was not finding the jars because they were below (after) it in the classpath, or because the restlet server was interfering, but when you put them in web-inf/lib, they were now above (after) it or overrode the restlet stuff.
Brian Deterling