java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

10,796 views
Skip to first unread message

Kris

unread,
Apr 26, 2013, 7:53:39 PM4/26/13
to google-we...@googlegroups.com
Hi, I have a class path problem. 

Using eclipse juno, maven plugin and gwt plugin. 

In my gwt server code I use slf4j. When doing something on the gui that makes a RPC I get.. 

java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

My project has a maven structure, and has 
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>

Google settings : War directory : src/main/webapp

I seem to have a lot of problem with having a maven GWT project. Seems like the maven plugin and the GWT plugin really dont work together that well. 



Kris

unread,
Apr 26, 2013, 8:00:18 PM4/26/13
to google-we...@googlegroups.com
Actually it is caused by... 
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory

Thomas Broyer

unread,
Apr 27, 2013, 6:14:54 AM4/27/13
to google-we...@googlegroups.com


On Saturday, April 27, 2013 1:53:39 AM UTC+2, Kris wrote:
Hi, I have a class path problem. 

Using eclipse juno, maven plugin and gwt plugin. 

In my gwt server code I use slf4j. When doing something on the gui that makes a RPC I get.. 

java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

My project has a maven structure, and has 
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>

scope=provided means the JAR won't end up in your WEB-INF/lib and will have to be provided (sic!) by the servlet container (in DevMode's case, by the DevMode)

Google settings : War directory : src/main/webapp

I seem to have a lot of problem with having a maven GWT project. Seems like the maven plugin and the GWT plugin really dont work together that well.

They do play well together, but you have to understand the basics of how they work and the implications of your choices.
It seems like you'll have a particular deployment setup (it'll provide Slf4j, rather than Slf4j being bundled in the WAR), in which case you'd better run DevMode in -noserver mode (i.e. only for client-code) and deploy the server code in your own container (using whichever Eclipse plugin is appropriate; I like to simply use the jetty-maven-plugin or tomcat7-maven-plugin, but you can use Sonatype's Webby or Eclipse WTP).

Kris

unread,
Apr 29, 2013, 11:50:30 AM4/29/13
to google-we...@googlegroups.com
If I remove the 
<scope>provided</scope>
it is still not going in the WEB-INF/lib. But should it, maven doesn't know about putting it there... 

If I add the jar file to the classpath of the run configuration the problem is still there.. 
The reason why it is provided is that I use JBoss that has the jar file. 



Thomas Broyer

unread,
Apr 29, 2013, 12:00:43 PM4/29/13
to google-we...@googlegroups.com


On Monday, April 29, 2013 5:50:30 PM UTC+2, Kris wrote:
If I remove the 
<scope>provided</scope>
it is still not going in the WEB-INF/lib. But should it, maven doesn't know about putting it there...

The maven-war-plugin's war mojo (called by default in the package phase when packaging=war) will put it there.

If I add the jar file to the classpath of the run configuration the problem is still there.. 
The reason why it is provided is that I use JBoss that has the jar file.


Then use JBoss for your dev, and run the DevMode in -noserver mode. 

Kris

unread,
May 1, 2013, 1:33:12 PM5/1/13
to google-we...@googlegroups.com
Maybe I am way off, but I jsut run my webapp from eclipse. I do not run maven war plugin... 

Thomas Broyer

unread,
May 1, 2013, 2:04:30 PM5/1/13
to google-we...@googlegroups.com


On Wednesday, May 1, 2013 7:33:12 PM UTC+2, Kris wrote:
Maybe I am way off, but I jsut run my webapp from eclipse. I do not run maven war plugin... 

Let's try again:

1. either you run your app in JBoss, and you're on your own (use Eclipse WTP or whatever), and then run the DevMode in -noserver mode (in Eclipse, it's something like Run as… → Web Application (with external server)); but you can have Slf4j with scope=provided
2. or you run your app in the DevMode embedded server, and you then have to run "mvn package" (or "mvn compile war:exploded") to copy the dependencies to WEB-INF/lib before you run the DevMode; but all your dependencies should be there then, so Slf4j cannot have scope=provided

Kris

unread,
May 1, 2013, 2:50:57 PM5/1/13
to google-we...@googlegroups.com
ok, I will try to get solution 2 to work..

I am a little confused about how to set... 

In the properties of the project -> Google -> Web Application -> WAR directory ( here I have src/main/webapp )... 
and Launch and deploy from this directory. (disabled because this is a Maven project)

In the properties of the project -> Java Build Path -> Source -> Default output folder... what should I have here... 

Here is part of my pom.xml

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Convenience property to set the GWT version -->
<errai.version>2.2.0.Final</errai.version>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
<gwtVersion>2.5.1</gwtVersion>
</properties>


<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- GWT Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<goal>i18n</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see gwt-maven-plugin 
documentation at codehaus.org -->
<configuration>
<runTarget>ppmock.html</runTarget>
<hostedWebapp>${webappDirectory}</hostedWebapp>
<i18nMessagesBundle>com.farheap.jsi.ppmock.client.GUIConstants</i18nMessagesBundle>
<gwtSdkFirstInClasspath>true</gwtSdkFirstInClasspath>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webappDirectory>${webappDirectory}</webappDirectory>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
<archive>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>



Thomas Broyer

unread,
May 1, 2013, 5:10:24 PM5/1/13
to google-we...@googlegroups.com


On Wednesday, May 1, 2013 8:50:57 PM UTC+2, Kris wrote:
ok, I will try to get solution 2 to work..

I am a little confused about how to set... 

In the properties of the project -> Google -> Web Application -> WAR directory ( here I have src/main/webapp )... 
and Launch and deploy from this directory. (disabled because this is a Maven project)

In the properties of the project -> Java Build Path -> Source -> Default output folder... what should I have here... 

target/<myapp>/WEB-INF/classes
 

Here is part of my pom.xml

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Convenience property to set the GWT version -->
<errai.version>2.2.0.Final</errai.version>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
<gwtVersion>2.5.1</gwtVersion>
</properties>


<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<source>1.7</source>
<target>1.7</target>

Be careful, GWT only supports Java 6 sources.
(mixing client-side and server-side in the same Maven module is an anti-pattern to begin with, but not impossible).
 
</configuration>
</plugin>
<!-- GWT Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<goal>i18n</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see gwt-maven-plugin 
documentation at codehaus.org -->
<configuration>
<runTarget>ppmock.html</runTarget>
<hostedWebapp>${webappDirectory}</hostedWebapp>

Remove that line unless you really know what you're doing (you're actually not using it anyway, as you're not using "mvn gwt:run")
 
<i18nMessagesBundle>com.farheap.jsi.ppmock.client.GUIConstants</i18nMessagesBundle>
<gwtSdkFirstInClasspath>true</gwtSdkFirstInClasspath>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webappDirectory>${webappDirectory}</webappDirectory>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
<archive>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>

With that configuration, you'll never have any JAR in WEB-INF/lib, so that won't work.
You have to move that to a profile so you can easily disable it (but then be very careful when releasing your app; changing the produced artifact with profiles is an anti-pattern, though very useful in GWT's case, but for other use-cases)

Kris

unread,
May 2, 2013, 12:23:37 PM5/2/13
to google-we...@googlegroups.com
I changed to
<source>1.6</source>
<target>1.6</target>

project -> Java Build Path -> Source -> Default output folder  = ppmock/target/ppmock-1.0.0-SNAPSHOT/WEB-INF/classes
project -> Google -> Web Application -> WAR directory = target/ppmock-1.0.0-SNAPSHOT
"Launch and deploy from this directory (disbaled because this is a Maven project)" = checked

Before launch : 
mvn clean compile war:exploded

Launch configuration arguments :
-remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9997 -port 8888 -war C:\jsi-workspace2\JSI\ppmock\target\ppmock-1.0.0-SNAPSHOT com.farheap.jsi.ppmock.ppmock

This seems to work for me... so far :)
Reply all
Reply to author
Forward
0 new messages