我试图用JSF 2.3.0-m05运行Tomcat,但我得到了错误
java.lang.NoSuchMethodError: javax.faces.view.facelets.FaceletCache.setCacheFactories(Ljavax/faces/view/facelets/FaceletCache$MemberFactory;Ljavax/faces/view/facelets/FaceletCache$MemberFactory;)V
完整日志文件:http://pastebin.com/UkhQ3L5D
Maven pom.xml:http://pastebin.com/P4ZJYm5v
有什么解决方案吗?或者这是一个已知的问题吗?
java.lang.NoSuchMethodError:javax.faces.view.facelets.FaceletCache.setCacheFactories
这种方法是JSF 2.3之后的新方法。因此,这个问题表明您在运行时类路径中有一个旧的JSF API版本。
根据您的pom.xml
,以下依赖项存在冲突:
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
</dependency>
第一个表示JSF2.2 API(它只是JavaEE7 API的javax.faces.*
部分)。将其完全移除。JSF 2.3依赖项已经有了自己的一套。
第二个表示整个Java EE 7 API,包括JSF2.2、Servlet3.1、EL3.0、CDI1.1、JAX-RS1.0、JSONP1.0等。这个可能绝对不会出现在webapp的运行时类路径中。这个应该已经由目标运行时提供了。您需要将其标记为provided
。
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
当您不是一个真正的Java EE服务器,而是一个针对像Tomcat 8.0这样的基本Servlet容器时,这实际上是一种误导,Tomcat 8.0只提供JSP 2.3、Servlet 3.1、EL 3.0和WebSockets 1.1。您应该单独指定它们,而不是整个JavaEE7neneneba API。否则,在编写代码时必须小心,以免意外导入/使用Java EE 7 API的某些部分,而这些部分实际上不是由Tomcat提供的,如JSF、JSTL、CDI等。然后,您需要将它们与Web应用程序一起显式提供(就像您已经为某些部分所做的那样)。