2015-05-21 12 views
29

Ho avviato un nuovo progetto con Spring Boot 1.2.3. Sto ottenendo l'erroreSpring Boot java.lang.NoClassDefFoundError: javax/servlet/Filter

java.lang.NoClassDefFoundError: javax/servlet/Filter 

Gradle Dipendenze:

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' 
} 

Ecco la completa analisi dello stack

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 

risposta

2

che si presenta come si è tentato di aggiungere le librerie servlet.jar o servlet-api.jar nel progetto Cartella /lib/, ma Tomcat dovrebbe già fornire tali librerie. Rimuoverli dal progetto e dal classpath. Cercalo ovunque nel tuo progetto o classpath e rimuovilo.

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

Questo dovrebbe essere

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

ho provato questo già, ma che mostra ancora lo stesso errore – Ibrahim

91

per gli utenti Maven, commentare la portata prevista nel seguente dipendenze:

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

UPDATE

Come feed.me accennato che devi disapprovare t ha fornito una parte in base al tipo di app che si sta distribuendo.

Ecco un link utile con i dettagli: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging

+9

E 'importante fare questa dipendenza "a condizione" di nuovo prima di costruire un file di guerra! Altrimenti il ​​file war si bloccherà quando verrà implementato (mi è successo con tomcat) –

+1

Ho anche scoperto che dovevo reimportare il progetto maven in intellij, presumibilmente per forzare la dipendenza da scaricare senza questo scope aggiuntivo che stava causando l'applicazione uscire fuori. – Opentuned

+1

Questo va tutto bene, il problema è che quando costruisci la guerra, questi vasi sono inclusi e questa non è un'opzione. Perché IntelliJ non riesce a trovare il classpath corretto per eseguire un'applicazione Gradle + Spring Boot? –

10

E 'cose interessanti con IDE (IntelliJ in questo caso):

  • se si lascia di default, vale a dire non dichiaranospring-boot-starter-tomcat come fornito, a spring-boot-maven-plug (SBMP) metti i vasi di tomcat sulla tua guerra -> e probabilmente otterrete errori che implementano questa guerra al contenitore (ci potrebbe essere un conflitto versioni)

  • altro si otterrà classpath con senza compilazione dipendenza su tomcat-incorporare (SBMP costruirà guerra eseguibile/vaso con dipendenze fornite inclusi in ogni caso)

    • IntelliJ hornestly non vede dipendenze forniti in fase di esecuzione (non sono nel classpath) quando si esegue la sua configurazione di esecuzione SpringBoot .
    • e senza tomcat-incorporare non è possibile eseguire primavera-Stivale servlet container incorporato.

C'è qualche soluzione: mettere vasi di Tomcat al classpath della vostra idea del modulo tramite l'interfaccia utente: File->Project Structure->(Libraries or Modules/Dependencies tab).

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

Maven ha mvn dependency:get comando per scaricare arbitraria barattoli al repository locale. Gradle potrebbe avere lo stesso

UPD. Per caso esperto. Invece di aggiungere dipendenze del modulo in Idea, è meglio dichiarare il profilo di maven con scope compile di spring-boot-starter-tomcat lib.

+1

il tuo aggiornamento risolve il problema, ** ma ** quando crei un file di guerra (artefatto di produzione) devi tenere presente che devi attivare il profilo. che non viene fatto automaticamente per te. – eav

+0

Se l'artefatto di produzione (PA) deve essere con incorporato tomcat (ET) all'interno (in .war), non è necessario dichiarare _spring-boot-starter-tomcat_ come dipendenza _provided_. La mia risposta spiega il caso in cui abbiamo bisogno di PA con ** no ** ET (come doveva essere distribuito su qualche contenitore stesso) e voglio avviare localmente 'SpringBootApplication' ** con ** embed-tomcat in IntelliJ con il suo run- configurazioni. –

+1

Penso che l'aggiornamento sia la soluzione corretta per questo problema secondo me: puoi costruire la guerra senza Tomcat incorporato e puoi usare il profilo all'interno di IntelliJ. Molto elegante e non richiede commenti/commenti – Peter

0

La configurazione here sta lavorando per 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" 
}