使用maven雖然很方便,寫一個dependency的標簽就可以直接從倉庫下載對應的jar包,還能處理該jar包的繼承依賴關系.但是同時需要你對jar包更加了解,如果依賴關系很復雜,那么很可能會產生jar包沖突,從而使項目報一些莫名其妙的異常.
在用apache cxf的過程中就出現了這樣的問題.
1,在項目的pom.xml中加入apache cxf的依賴配置:
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yueguang.maven</groupId> <artifactId>springApacheCXF</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>springApacheCXF Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>apache-cxf</artifactId> <version>3.0.2</version> <!-- type默認為jar文件,當值為pom的時候代表引入的是一個項目.相當於多個jar文件 --> <type>pom</type> </dependency> </dependencies> <build> <finalName>springApacheCXF</finalName> </build> <properties> <springVersion>3.2.5.RELEASE</springVersion> </properties> </project>
2,項目報了如下異常:
嚴重: Exception starting filter encodingFilter java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275) at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422) at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:115) at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4001) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4651) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) at org.apache.catalina.core.StandardHost.start(StandardHost.java:785) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445) at org.apache.catalina.startup.Embedded.start(Embedded.java:825) at org.codehaus.mojo.tomcat.AbstractRunMojo.startContainer(AbstractRunMojo.java:558) at org.codehaus.mojo.tomcat.AbstractRunMojo.execute(AbstractRunMojo.java:255) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214) at org.apache.maven.cli.MavenCli.main(MavenCli.java:158) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) at org.codehaus.classworlds.Launcher.main(Launcher.java:46) 2015-3-6 10:14:39 org.apache.catalina.core.StandardContext start 嚴重: Error filterStart 2015-3-6 10:14:39 org.apache.catalina.core.StandardContext start 嚴重: Context [/springApacheCXF] startup failed due to previous errors
搜索查找后發現,其實這個異常是因為
tomcat 啟動后先將tomcat/lib目錄下的jar包全部讀入內存,如果webapps目錄里的應用程序中WEB-INF/lib目錄下有相同的包,將無法加載,不同版本的包之間也會造成類似問題.
那么具體是哪個jar包呢?是:geronimo-servlet_3.0_spec-1.0.jar 就是在pom中引入的cxf項目中的一個jar包.
剛開始想着可以直接把該jar包從builpath中刪除,發現刪除不掉.(因為屬於cxf項目的一部分?),然后想到maven中可以用exclusion標簽排除依賴.於是最終的解決方案如下:
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yueguang.maven</groupId> <artifactId>springApacheCXF</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>springApacheCXF Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springVersion}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>apache-cxf</artifactId> <version>3.0.2</version> <!-- type默認為jar文件,當值為pom的時候代表引入的是一個項目.相當於多個jar文件,必須填寫 --> <!-- 多個jar包中和容器的jar包有沖突怎么辦? --> <type>pom</type> <exclusions> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_3.0_spec</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <finalName>springApacheCXF</finalName> </build> <properties> <springVersion>3.2.5.RELEASE</springVersion> </properties> </project>
apache cxf 需要的最小jar包:
cxf-2.3.3.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-jaxws_2.2_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.3.jar
jaxb-api-2.2.1.jar
jaxb-impl-2.2.1.1.jar
neethi-2.0.4.jar
wsdl4j-1.6.2.jar
XmlSchema-1.4.7.jar
wstx-asl-3.2.9.jar
記錄下來,以免再犯..