我正在尝试将一个基于JSF的应用程序部署到Tomcat 6。按照我的构建系统的设置方式,WAR本身没有任何库,因为该服务器总共为43个应用程序提供服务。相反,这些库被复制到一个共享库文件夹中,并在应用程序之间共享。当我进行部署时,出现以下错误
SEVERE: Error deploying configuration descriptor SSOAdmin.xml
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/faces/webapp/FacesServlet
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1667)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
at org.apache.catalina.startup.WebAnnotationSet.loadApplicationServletAnnotations(WebAnnotationSet.java:108)
at org.apache.catalina.startup.WebAnnotationSet.loadApplicationAnnotations(WebAnnotationSet.java:58)
at org.apache.catalina.startup.ContextConfig.applicationAnnotationsConfig(ContextConfig.java:297)
at org.apache.catalina.startup.ContextConfig.start(ContextConfig.java:1078)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:261)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4611)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:675)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:601)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1315)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1061)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at org.apache.catalina.core.StandardService.start(StandardService.java:525)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
现在,在我的研究中,我发现这个问题应该通过下载JSF源代码并自己编译来解决。在我的情况下,这是一个糟糕的解决方案。这将给我的团队带来巨大的问题,我们必须应对各种配置。有没有其他解决方案?
下面是我的pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<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.nms.sso</groupId>
<artifactId>SSOAdmin</artifactId>
<version>09142011-BETA</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<!-- <dependency> -->
<!-- <groupId>com.sun.faces</groupId> -->
<!-- <artifactId>jsf-api</artifactId> -->
<!-- <scope>${myExeScope}</scope> -->
<!-- </dependency> -->
<!-- <dependency> -->
<!-- <groupId>com.sun.faces</groupId> -->
<!-- <artifactId>jsf-impl</artifactId> -->
<!-- <scope>${myExeScope}</scope> -->
<!-- </dependency> -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>net.sf.jt400</groupId>
<artifactId>jt400</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>nmsc</groupId>
<artifactId>nmsc_api</artifactId>
<version>09142011-BETA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.icefaces</groupId>
<artifactId>icefaces</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.icefaces</groupId>
<artifactId>icefaces-ace</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.icefaces</groupId>
<artifactId>icefaces-compat</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.jibx</groupId>
<artifactId>jibx-extras</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.jibx</groupId>
<artifactId>jibx-run</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>${myExeScope}</scope>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>${myExeScope}</scope>
</dependency>
</dependencies>
<parent>
<groupId>nmsc</groupId>
<artifactId>nmsc_lib</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../libs</relativePath>
</parent>
<build>
<finalName>SSOAdmin</finalName>
</build>
<name>SSOAdmin Maven Webapp</name>
</project>
这里必须有一个解决方案。我一点也不相信Maven distributable for JSF只适合编译而不适合部署。
1条答案
按热度按时间4uqofj5v1#
当您遇到一个“奇怪”的异常,表明类/方法/文件/组件/标记不存在或不同,而它们似乎显式地包含在Web应用程序中,如下面所示,
java.lang.ClassFormatError:在类文件javax/faces/webapp/FacesServlet中,方法中缺少不是本机或抽象的代码属性
资源丢失异常:找不到javax.faces.logStrings包
无法将WebContainerInjectionProvider强制转换为
com.sun.faces.config.ConfigurationException:配置失败
命名空间www.example.com中名为inputFile的标记http://xmlns.jcp.org/jsf/html定义了空的处理程序类。
在运行时出现异常错误。
在javax.faces.application.视图处理程序 Package 器中出现错误
异常错误发生在服务器上。
或者当您面临“奇怪”的运行时行为(如中断的HTTP会话(
jsessionid
出现在所有位置的链接URL中)和/或中断的JSF视图作用域(它的行为与请求作用域相同)和/或中断的CSS/JS/图像资源)时,则Web应用程序的运行时类路径很可能被重复的不同版本的JAR文件污染。在
FacesServlet
上使用ClassFormatError
的特定情况下,这意味着第一次发现的包含上述类的JAR文件实际上是一个“蓝图”APIJAR文件,旨在用于实现供应商(例如为Mojarra和MyFaces工作的开发人员)。它包含只有类和方法签名的类文件,没有任何代码体和资源文件。这正是“缺少代码属性”的意思。它纯粹是为了javadoc和编译。始终将服务器提供的库标记为
provided
所有在Maven中标记为“Java Specifications“并且在工件ID中具有
-api
后缀的依赖项都是蓝图API。您绝对不应该在运行时类路径中包含它们。如果您真的需要在pom中包含它们,您应该始终将它们标记为<scope>provided</scope>
。一个著名的例子是Jakarta EE (Web) API(以前称为Java EE):如果没有
provided
作用域,那么这个JAR将在webapp的/WEB-INF/lib
中结束,从而导致您现在所面临的所有麻烦。在您的特定案例中,您有一个不必要的JSF API相依性:
这会造成问题,因为它包含
FacesServlet
的蓝图类。删除它并依赖如上所示的provided
Jakarta EE(Web)API应该可以解决这个问题。Tomcat作为一个准系统的JSP/Servlet容器已经提供了JSP、Servlet和EL(因为8也提供了WebSocket)。所以你应该至少将
jsp-api
、servlet-api
和el-api
标记为provided
。Tomcat只是不提供JSF(和JSTL)。所以你需要通过webapp安装它。成熟的Jakarta EE服务器(如WildFly、TomEE、GlassFish、Payara、WebSphere等)已经提供了开箱即用的整个Jakarta EE API,包括JSF。因此您绝对不需要通过webapp安装JSF。如果服务器已经提供了不同的实现和/或现成的版本,这只会导致冲突。您需要的唯一依赖项是
jakartaee-api
,与上面所示完全相同。在Tomcat 10或更高版本上安装JSF
您需要的最低JSF版本是3.0而不是2.3,因为
javax.*
包从3.0开始就被重命名为jakarta.*
。在Tomcat 10或更高版本上安装Mojarra 3.0:
您也可以检查
org.glassfish:jakarta.faces
repository以取得目前最新的3.0.x出版版本(目前是3.0.2
)。另请参阅Mojarra installation instructions以取得其他必要的相依性(CDI、BV、JSONP)。在Tomcat 10或更高版本上安装MyFaces 3.0:
您也可以检查
org.apache.myfaces.core:myfaces-impl
repository,了解当前最新的3.0.x发行版本(当前为3.0.2
)。顺便说一句,不要忘记安装JSTL API,Tomcat中也没有。
另外请注意,从JSF 2.3开始,CDI已经成为一个必需的依赖项。这在普通的Jakarta EE服务器上是现成的,但在servlet容器(如Tomcat)上却不是。在这种情况下,请转到如何在Tomcat上安装和使用CDI?
在Tomcat 9或更早版本上安装JSF
有两种JSF实现:Mojarra and MyFaces。您应该选择安装其中一个,而不是两个都安装。
在Tomcat 9或更早版本上安装Mojarra 2.3:
您也可以检查
org.glassfish:jakarta.faces
repository以取得目前最新的2.3.x出版版本(目前是2.3.16
)。另请参阅Mojarra installation instructions以取得其他必要的相依性(CDI、BV、JSONP)。在Tomcat 9或更早版本上安装MyFaces 2.3:
您也可以检查
org.apache.myfaces.core:myfaces-impl
repository,了解当前最新的2.3.x发行版本(当前为2.3.9
)。请注意,Tomcat 6作为Servlet 2.5容器支持最高JSF 2.1。
顺便说一句,不要忘记安装JSTL API,Tomcat中也没有。
另外请注意,从JSF 2.3开始,CDI已经成为一个必需的依赖项。这在普通的Jakarta EE服务器上是现成的,但在servlet容器(如Tomcat)上却不是。在这种情况下,请转到如何在Tomcat上安装和使用CDI?
另请参阅: