I have web application written in Java using gucie-servlet framework being built by Maven 3. When I deploy it on Tomcat 7 container and try to access it using browser, Tomcat replies with 404 status code. This is log from Tomcat:
Apr 4, 2013 11:39:50 AM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextDestroyed()
Apr 4, 2013 11:39:50 AM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextDestroyed()
Apr 4, 2013 11:39:55 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class ru.hive.webserver.config.HiveServletConfig
java.lang.NoClassDefFoundError: ru/hive/base/db/modules/DatabaseModule
at ru.hive.webserver.config.HiveServletConfig.getInjector(HiveServletConfig.java:24)
at com.google.inject.servlet.GuiceServletContextListener.contextInitialized(GuiceServletContextListener.java:45)
at ru.hive.webserver.config.HiveServletConfig.contextInitialized(HiveServletConfig.java:19)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:977)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1655)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: ru.hive.base.db.modules.DatabaseModule
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1713)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1558)
... 17 more
Apr 4, 2013 11:39:55 AM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Apr 4, 2013 11:39:55 AM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Apr 4, 2013 11:39:55 AM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: attributeAdded('org.apache.jasper.compiler.TldLocationsCache', 'org.apache.jasper.compiler.TldLocationsCache@e8606c')
Exception says that there is no class named ru.hive.base.db.modules.DatabaseModule in CLASSPATH of my app, but it is not true:
frodo@shire:~/apache-tomcat-7.0.37/webapps/hive/WEB-INF/lib$ ls -l
total 30132
-rw-rw-r-- 1 frodo frodo 4467 нояб. 22 13:46 aopalliance-1.0.jar
-rw-rw-r-- 1 frodo frodo 27010023 апр. 4 11:39 base-0.0.42-SNAPSHOT.jar
-rw-rw-r-- 1 frodo frodo 232019 дек. 18 10:12 commons-beanutils-1.8.3.jar
-rw-rw-r-- 1 frodo frodo 58160 авг. 2 2011 commons-codec-1.4.jar
-rw-rw-r-- 1 frodo frodo 196768 дек. 18 10:12 commons-digester-2.1.jar
-rw-rw-r-- 1 frodo frodo 163151 нояб. 22 13:46 commons-io-2.1.jar
-rw-rw-r-- 1 frodo frodo 60686 авг. 2 2011 commons-logging-1.1.1.jar
-rw-rw-r-- 1 frodo frodo 189285 нояб. 28 15:01 gson-2.2.2.jar
-rw-rw-r-- 1 frodo frodo 710492 февр. 6 18:59 guice-3.0.jar
-rw-rw-r-- 1 frodo frodo 65012 февр. 13 13:21 guice-servlet-3.0.jar
-rw-rw-r-- 1 frodo frodo 352585 нояб. 22 13:46 httpclient-4.1.3.jar
-rw-rw-r-- 1 frodo frodo 181410 нояб. 22 13:46 httpcore-4.1.4.jar
-rw-rw-r-- 1 frodo frodo 26938 нояб. 22 13:46 httpmime-4.1.3.jar
-rw-rw-r-- 1 frodo frodo 2497 февр. 6 18:59 javax.inject-1.jar
-rw-rw-r-- 1 frodo frodo 31866 февр. 6 18:59 jsr305-2.0.1.jar
-rw-rw-r-- 1 frodo frodo 25962 нояб. 22 13:46 slf4j-api-1.6.4.jar
-rw-rw-r-- 1 frodo frodo 371816 нояб. 22 13:46 solr-solrj-4.0.0.jar
-rw-rw-r-- 1 frodo frodo 520969 нояб. 22 13:46 wstx-asl-3.2.7.jar
-rw-rw-r-- 1 frodo frodo 608239 нояб. 22 13:46 zookeeper-3.3.6.jar
JAR base-0.0.42-SNAPSHOT.jar contains class which Tomcat can't find. The directory structure inside JAR is the same as in full class name in stack trace. The pom.xml for my project is:
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>webserver</artifactId>
<version>0.0.42-SNAPSHOT</version>
<packaging>war</packaging>
<name>Api servlet</name>
<parent>
<groupId>ru.hive</groupId>
<artifactId>main</artifactId>
<version>0.0.41-SNAPSHOT</version>
<relativePath>../main</relativePath>
</parent>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<solr.url>http://localhost:8983/solr</solr.url>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<server>local_tomcat</server>
<url>http://192.168.0.39:8080/manager/text</url>
<path>/hive</path>
<update>true</update>
<username>user</username>
<password>pass</password>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>production</id>
<properties>
<solr.url>http://localhost:8983/solr/hive</solr.url>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<server>production_tomcat</server>
<url>http://some.ip.address:8080/manager/text</url>
<path>/hive</path>
<update>true</update>
<username>user</username>
<password>pass</password>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>ru.hive</groupId>
<artifactId>base</artifactId>
<version>0.0.42-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Maven Repository Switchboard</name>
<url>http://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>repo</id>
<releases>
<enabled>true</enabled>
<checksumPolicy>ignore</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>file://${project.basedir}/lib</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2</url>
</pluginRepository>
</pluginRepositories>
<build>
<finalName>hive</finalName>
<sourceDirectory>src/main/java</sourceDirectory>
<scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<outputDirectory>target/classes</outputDirectory>
<testOutputDirectory>target/test-classes</testOutputDirectory>
<directory>target</directory>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>default-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<webResources>
<webResource>
<directory>src/main/webapp/META-INF</directory>
<includes>
<include>context.xml</include>
</includes>
<filtering>true</filtering>
<targetPath>META-INF</targetPath>
</webResource>
</webResources>
</configuration>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>default-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-install</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>default-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
<execution>
<id>default-testResources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<reporting>
<outputDirectory>target/site</outputDirectory>
</reporting>
</project>
So the question is what am I doing wrong and why I get this ClassDefNotFound exception?
PS. Edited version of maven-war-plugin config:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>default-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
<configuration>
<webResources>
<webResource>
<directory>src/main/webapp/META-INF</directory>
<includes>
<include>context.xml</include>
</includes>
<filtering>true</filtering>
<targetPath>META-INF</targetPath>
</webResource>
</webResources>
</configuration>
</plugin>
PPS. ru.hive.webserver.config.HiveServletConfig class listing
package ru.hive.webserver.config;
import javax.servlet.ServletContextEvent;
import ru.hive.base.db.modules.DatabaseModule;
import ru.hive.base.state.modules.StateManagerModule;
import ru.hive.webserver.api.ApiServlet;
import ru.hive.webserver.scheduler.Scheduler;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;
public class HiveServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule() {
@Override
protected void configureServlets() {
install(new DatabaseModule());
install(new StateManagerModule());
serve("/api").with(ApiServlet.class);
serve("/scheduler").with(Scheduler.class);
}
});
}
}
PPPS. The list of JARs in <TOMCAT_HOME>/lib
:
`-rw-r--r-- 1 jcdenton jcdenton 15264 марта 22 18:38 annotations-api.jar
-rw-r--r-- 1 jcdenton jcdenton 54176 марта 22 18:38 catalina-ant.jar
-rw-r--r-- 1 jcdenton jcdenton 132729 марта 22 18:38 catalina-ha.jar
-rw-r--r-- 1 jcdenton jcdenton 1563926 марта 22 18:38 catalina.jar
-rw-r--r-- 1 jcdenton jcdenton 255182 марта 22 18:38 catalina-tribes.jar
-rw-r--r-- 1 jcdenton jcdenton 1796326 марта 22 18:38 ecj-4.2.1.jar
-rw-r--r-- 1 jcdenton jcdenton 46085 марта 22 18:38 el-api.jar
-rw-r--r-- 1 jcdenton jcdenton 123241 марта 22 18:38 jasper-el.jar
-rw-r--r-- 1 jcdenton jcdenton 599131 марта 22 18:38 jasper.jar
-rw-r--r-- 1 jcdenton jcdenton 88690 марта 22 18:38 jsp-api.jar
-rw-r--r-- 1 jcdenton jcdenton 177599 марта 22 18:38 servlet-api.jar
-rw-r--r-- 1 jcdenton jcdenton 6873 марта 22 18:38 tomcat-api.jar
-rw-r--r-- 1 jcdenton jcdenton 795308 марта 22 18:38 tomcat-coyote.jar
-rw-r--r-- 1 jcdenton jcdenton 235411 марта 22 18:38 tomcat-dbcp.jar
-rw-r--r-- 1 jcdenton jcdenton 77364 марта 22 18:38 tomcat-i18n-es.jar
-rw-r--r-- 1 jcdenton jcdenton 48693 марта 22 18:38 tomcat-i18n-fr.jar
-rw-r--r-- 1 jcdenton jcdenton 51678 марта 22 18:38 tomcat-i18n-ja.jar
-rw-r--r-- 1 jcdenton jcdenton 123958 марта 22 18:38 tomcat-jdbc.jar
-rw-r--r-- 1 jcdenton jcdenton 23174 марта 22 18:38 tomcat-util.jar`
OK, I've found the solution. After careful study of my <TOMCAT_HOME>/logs/catalina.log
I've found this record:
Apr 5, 2013 1:38:26 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/home/frodo/apache-tomcat-7.0.37/webapps/hive/WEB-INF/lib/base-0.0.42-SNAPSHOT.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
This question explains the reason of this message - my JAR base-0.0.42-SNAPSHOT.jar
contains something related to Servlet API and can't be loaded by Tomcat because of it. So, my web app can't find classes in this JAR after start. I'm using some parts of Twitter commons inside this JAR which contain realization of Servlet API. After revision of the dependencies of base-0.0.42-SNAPSHOT.jar
my app starts and loads classes needed. Thank you to everyone!