Spring Boot java.lang.NoClassDefFoundError: javax/servlet/Filter

Spring Boot

Spring Boot Problem Overview


I Started a new project with Spring Boot 1.2.3. I'm getting error

java.lang.NoClassDefFoundError: javax/servlet/Filter

Gradle Dependencies:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-actuator")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.codehaus.groovy:groovy")
    compile("com.h2database:h2")
    compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity3")

    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
    testCompile("org.springframework.boot:spring-boot-starter-test")

    compile 'org.webjars:jquery:2.1.4'
    compile 'org.webjars:bootstrap:3.3.4'
}

Here is the full stack trace

Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2570)
	at java.lang.Class.getMethod0(Class.java:2813)
	at java.lang.Class.getMethod(Class.java:1663)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:125)
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
	at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	... 29 more

Process finished with exit code 1

Spring Boot Solutions


Solution 1 - Spring Boot

for the maven users, comment the scope provided in the following dependency:

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
		<!--<scope>provided</scope>-->
	</dependency>

UPDATE

As feed.me mentioned you have to uncomment the provided part depending on what kind of app you are deploying.

Here is a useful link with the details: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging

Solution 2 - Spring Boot

providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")

This should be

compile("org.springframework.boot:spring-boot-starter-tomcat")

Solution 3 - Spring Boot

It's not good to change the scope of your application dependencies. Putting the dependency as compile, will provide the dependency also in your artifact that will be installed somewere. The best think to do is configure the RUN configuration of your sping boot application by specifying as stated in documentation :

> "Include dependencies with 'Provided' scope" "Enable this option to > add dependencies with the Provided scope to the runtime classpath."

enter image description here

Solution 4 - Spring Boot

It's interesting things with IDE (IntelliJ in this case):

  • if you leave default, i.e. don't declare spring-boot-starter-tomcat as provided, a spring-boot-maven-plugin (SBMP) put tomcat's jars to your war -> and you'll probably get errors deploying this war to container (there could be a versions conflict)

  • else you'll get classpath with no compile dependency on tomcat-embed (SBMP will build executable war/jar with provided deps included anyway)

    • intelliJ honestly doesn't see provided deps at runtime (they are not in classpath) when you run its Spring Boot run configuration.
    • and with no tomcat-embed you can't run Spring-Boot with embedded servlet container.

There is some tricky workaround: put Tomcat's jars to classpath of your idea-module via UI: File->Project Structure->(Libraries or Modules/Dependencies tab) .

  • tomcat-embed-core
  • tomcat-embed-el
  • tomcat-embed-websocket
  • tomcat-embed-logging-juli

Better solution for maven case

Instead of adding module dependencies in Idea, it is better to declare maven profile with compile scope of spring-boot-starter-tomcat library.

<profiles>
    <profile>
        <id>embed-tomcat</id>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </profile>
</profiles>

while spring-boot-starter-tomcat was declared provided in <dependencies/>, making this profile active in IDE or CLI (mvn -Pembed-tomcat ...) allow you to launch build with embedded tomcat.

Solution 5 - Spring Boot

Add the following dependency. The scope should be compile then it will work.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<scope>compile</scope> 
</dependency>

Solution 6 - Spring Boot

In my case scope of that dependency was provided.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

So, I was getting the same issue. Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter

I had to enable the below option in Intellij

Add dependencies with "provided" scope to classpath

enter image description here

You will see below option enabled,

enter image description here

OR

You can add the below property to .intellij/workspace.xml file under your application configuration section. <option name="INCLUDE_PROVIDED_SCOPE" value="true" />

e.g.,

  <component name="RunManager" selected="Application.DemoApp">
    <configuration name="DemoApp" type="Application" factoryName="Application">
      <option name="INCLUDE_PROVIDED_SCOPE" value="true" /> ```

Solution 7 - Spring Boot

That looks like you tried to add the libraries servlet.jar or servlet-api.jar into your project /lib/ folder, but Tomcat already should provide you with those libraries. Remove them from your project and classpath. Search for that anywhere in your project or classpath and remove it.

Solution 8 - Spring Boot

For Jar

Add pom.xml

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>

Solution 9 - Spring Boot

The configuration here is working for me:

configurations {
    customProvidedRuntime
}

dependencies {
    compile(
        // Spring Boot dependencies
    )

    customProvidedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
}

war {
    classpath = files(configurations.runtime.minus(configurations.customProvidedRuntime))
}

springBoot {
    providedConfiguration = "customProvidedRuntime"
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIbrahimView Question on Stackoverflow
Solution 1 - Spring BootDr.AgosView Answer on Stackoverflow
Solution 2 - Spring BootJaiwo99View Answer on Stackoverflow
Solution 3 - Spring BootGaetano PiazzollaView Answer on Stackoverflow
Solution 4 - Spring BootTimur MilovanovView Answer on Stackoverflow
Solution 5 - Spring BootPulkitRajputView Answer on Stackoverflow
Solution 6 - Spring BootGanesh ThoratView Answer on Stackoverflow
Solution 7 - Spring BootFernando GarciaView Answer on Stackoverflow
Solution 8 - Spring Bootuser13782119View Answer on Stackoverflow
Solution 9 - Spring BootTom PowerView Answer on Stackoverflow