2012-12-07 11 views
5

Obecnie próbuję zmienić naszą kompilację z procesu ręcznego (MyEclipse/export as war) na automatyczną kompilację Maven.Tomcat 7.0.29 servlet-api classloader issue

Aplikacja uruchomiona przez MyEclipse działa i działa dobrze na naszej instalacji Tomcat 7.0.29 (Windows 7). W ścieżce budowania MyEclipse skonfigurowaliśmy bibliotekę użytkownika (tomcat), która zawiera wszystkie słoiki z $CATALINA_HOME/lib.

Mamy kilka apletów i filtrów serwletów, które używają klas javax.servlet.http. * (HttpSessionEvent itp.). Są one pakowane pod WEB-INF\classes\com\mycompany\filters

Podczas rozmieszczania wojny zbudowanej przez Mavena otrzymuję NoClassDefFoundError na klasie HttpSessionEvent. Zrobiłem śledzenie za pomocą opcji -verbose: class JVM i zobaczyłem, że ostatnia załadowana klasa to mój filtr z katalogu c:\apache\webapps\myapp\WEB-INF\classes\com\mycompany\filters. Następnie próbuję załadować/znaleźć HttpSessionEvent i nie można tego zrobić.

Numer servlet-api.jar znajduje się oczywiście w katalogu $CATALINA_HOME\lib.

W moim pom.xml mam to zależność

<dependency> 
     <groupId>org.apache.tomcat</groupId> 
     <artifactId>tomcat-servlet-api</artifactId> 
     <version>7.0.29</version> 
     <scope>provided</scope> 
    </dependency> 

mam żadnych innych plików serwletów-api.jar gdziekolwiek w moim ścieżki/ścieżki klasy (doublechecked lib/ext i zatwierdzony katalogów mojego JDK i JRE również)

Moje uzależnienie Maven: drzewo wygląda następująco:

[INFO] +- log4j:log4j:jar:1.2.15:compile 
[INFO] | \- javax.mail:mail:jar:1.4:compile 
[INFO] +- jstl:jstl:jar:1.2:compile 
[INFO] +- org.jdom:jdom:jar:1.1:provided 
[INFO] +- com.sun.xml.rpc:jaxrpc-impl:jar:1.1.3_01:provided 
[INFO] | +- javax.xml:jaxrpc-api:jar:1.1:provided 
[INFO] | +- com.sun.xml.messaging.saaj:saaj-impl:jar:1.3:provided 
[INFO] | | \- javax.xml.soap:saaj-api:jar:1.3:provided 
[INFO] | +- com.sun.xml.rpc:jaxrpc-spi:jar:1.1.3_01:provided 
[INFO] | \- com.sun.xml.fastinfoset:FastInfoset:jar:1.0.2:provided 
[INFO] +- org.apache.lucene:lucene-core:jar:3.6.0:compile 
[INFO] +- org.springframework:spring-context:jar:3.1.0.RELEASE:compile 
[INFO] | +- org.springframework:spring-beans:jar:3.1.0.RELEASE:compile 
[INFO] | +- org.springframework:spring-core:jar:3.1.0.RELEASE:compile 
[INFO] | | \- commons-logging:commons-logging:jar:1.1.1:compile 
[INFO] | +- org.springframework:spring-expression:jar:3.1.0.RELEASE:compile 
[INFO] | \- org.springframework:spring-asm:jar:3.1.0.RELEASE:compile 
[INFO] +- org.springframework:spring-web:jar:3.1.0.RELEASE:compile 
[INFO] | \- aopalliance:aopalliance:jar:1.0:compile 
[INFO] +- org.springframework:spring-orm:jar:3.1.0.RELEASE:compile 
[INFO] | +- org.springframework:spring-jdbc:jar:3.1.0.RELEASE:compile 
[INFO] | \- org.springframework:spring-tx:jar:3.1.0.RELEASE:compile 
[INFO] +- org.springframework:spring-aop:jar:3.1.0.RELEASE:compile 
[INFO] +- org.springframework:spring-test:jar:3.1.0.RELEASE:test 
[INFO] +- org.aspectj:aspectjrt:jar:1.7.1:compile 
[INFO] +- org.aspectj:aspectjweaver:jar:1.7.1:compile 
[INFO] +- javax.faces:javax.faces-api:jar:2.1:compile 
[INFO] +- com.sun.faces:jsf-impl:jar:2.1.15:compile 
[INFO] +- org.primefaces:primefaces:jar:3.4.2:compile 
[INFO] +- org.richfaces.core:richfaces-core-api:jar:4.2.3.Final:compile 
[INFO] | \- com.google.guava:guava:jar:11.0.2:compile 
[INFO] |  \- com.google.code.findbugs:jsr305:jar:1.3.9:compile 
[INFO] +- org.richfaces.ui:richfaces-components-ui:jar:4.2.3.Final:compile 
[INFO] | \- org.richfaces.ui:richfaces-components-api:jar:4.2.3.Final:compile 
[INFO] +- org.apache.tomcat:tomcat-servlet-api:jar:7.0.29:provided 
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.2:compile 
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.2:compile 
[INFO] +- org.hibernate:hibernate-core:jar:3.6.2.Final:compile 
[INFO] | +- antlr:antlr:jar:2.7.6:compile 
[INFO] | +- commons-collections:commons-collections:jar:3.1:compile 
[INFO] | +- dom4j:dom4j:jar:1.6.1:compile 
[INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile 
[INFO] | +- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.0.Final:compile 
[INFO] | \- javax.transaction:jta:jar:1.1:compile 
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.6.2.Final:compile 
[INFO] | +- cglib:cglib:jar:2.2:compile 
[INFO] | | \- asm:asm:jar:3.1:compile 
[INFO] | \- javassist:javassist:jar:3.12.0.GA:compile 
[INFO] +- org.hibernate:hibernate-validator:jar:4.1.0.Final:compile 
[INFO] | \- javax.validation:validation-api:jar:1.0.0.GA:compile 
[INFO] +- org.apache.commons:commons-email:jar:1.2:compile 
[INFO] | \- javax.activation:activation:jar:1.1:compile 
[INFO] +- junit:junit:jar:4.11:test 
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test 
[INFO] \- com.h2database:h2:jar:1.3.170:test 

Szukałam na to przez chwilę w internecie, az tego co czytałem to musi mieć jakiś co zrobić z programem ładującym klasy tomcat. Prawdopodobnie coś jest nie tak z opakowaniem mojej wojny. Jednak nie znalazłem jeszcze rozwiązania.

Wszelkie wskazówki będą mile widziane!

+0

Najprawdopodobniej sklonowałbym projekt i usunąłbym wszystko poza jednym serwletem lub filtrem i spróbowałbym, gdyby działał. I/lub spróbuj wdrożyć go na innym silniku, na przykład Jetty. – biziclop

Odpowiedz

0

Czy sprawdziłeś numer WEB-INF/lib wbudowanego pliku .war, aby mieć całkowitą pewność, że nie ma tam servlet-api.jar? Zależność Mavena ma odpowiedni zasięg, o ile mogę to stwierdzić.

Twój rozdział w pom.xml build powinien być podobny do tego:

<build> 
    <plugins> 
     <plugin> 
      <artifactId>maven-war-plugin</artifactId> 
      <version>2.2</version> 
      <configuration> 
       <warName>war_name</warName> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

I nie, nie umieścić servlet-api.jar w WEB-INF/lib folderze Twojej aplikacji WWW. Ponadto nie potrzebuję biblioteki użytkownika tomcat. Jedyne potrzebne biblioteki to JRE System Library xx i Maven Dependencies.

+0

Dzięki za odpowiedź. Tak, absolutnie, zbudowana wojna nie zawiera serwletu-api.war. I rzeczywiście, serwlet-api.jar nie powinien być umieszczany w katalogu WEB-INF/lib, będzie on w każdym przypadku ignorowany przez tomcat. Moja wersja wtyczki w wojnie to 2.1.1, sprawdzę, czy wersja 2.2 naprawia to (co wydaje się dziwne). – avhv

+0

Jakaś istotna różnica między .war zbudowaną przez MyEclipse a tą zbudowaną przez Mavena? (przy okazji, czy ostatnio uruchomiłeś 'mvn clean'?) –

+0

Tak, wojna zbudowana przez MyEclipse zawiera więcej słoików, takich jak Apache commons, lucene itp. Może być brakujące słoiki w moim maven-build, ale biorąc pod uwagę fakt, że projekt już się kompiluje, nie będzie ich wiele. BTW, już próbowałem usunąć wszystkie słoiki z rozbitego katalogu WEB-INF/lib, skopiować wszystkie słoiki z wojny MyEclipse i ponownie wdrożyć. To też nie działa (NoClassDefFoundError również w HttpSessionEvent). – avhv

0

Classloading in Tomcat to pomoże ci w zrozumieniu.

Umieść słoik w /WEB-INF/lib

Zastosowanie ClassLoader - Ładowarka klasa jest tworzona dla każdej aplikacji internetowej, która jest rozmieszczone w jednej instancji Tomcat.Wszystkie niepakowane klasy i zasoby w katalogu/WEB-INF/classes Twojej aplikacji internetowej, oraz klasy i zasoby w plikach JAR pod katalogiem/WEB-INF/lib Twojej aplikacji internetowej są widoczne dla tej sieci aplikacji, ale nie do innych.

+0

Dzięki temu zrozumiałem, że mój webapp pobiera program ładujący klasy "Webapp" (który ładuje klasy z WEB-INF/classes i WEB-INF/lib/*. Jar). Program ładujący klasy dziedziczy po klasie "Common", który powinien ładować klasę HttpSessionEvent. Czy mój moduł ładowania klas webapp nie deleguje do nadrzędnego programu ładującego klasy, jeśli nie znajdzie klasy (która w ogóle nie ma sensu)? – avhv

+1

'$ CATALINA_HOME \ ** libs **' wydaje się niepoprawne powinno być '$ nazwa katalogu CATALINA_HOME \ lib' jest nieprawidłowa w pytaniu? Czy to pomyłka, czy naprawdę słoiki są umieszczone w katalogu libs? W takim przypadku Commonloader nie będzie mógł znaleźć klasy. –

+0

Niestety, mój błąd (literówka), $ CATALINE_HOME = C: \ apache-tomcat-7.0.29 i jest w katalogu C: \ apache-tomcat-7.0.29 \ lib – avhv