如何通过Maven正确安装和配置JSF库?
我正在尝试将基于JSF的应用程序部署到Tomcat 6。我的构建系统的设置方式,战争本身没有任何库,因为该服务器总共提供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>
这里必须有一个解决方案。我不能一秒钟相信JSF的Maven可以分配仅适用于编译,而对部署不利。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您面临“怪异”例外,表明类/方法/文件/组件/标签在Web应用程序中似乎不存在或不同,例如以下内容,例如下面的应用程序,
或面对“怪异”运行时行为时(例如损坏的http sessions)(
jsessionId ,和/或损坏的面部视图范围(它表现为请求范围)和/或损坏的CSS/JS/Image Resources,那么WebApp的Runtime Class Path被重复的不同版本的JAR文件污染的机会很大。
在您的特定情况下,
classFormaterRor
在facesservlet
上,这意味着首次找到包含上述类的JAR文件实际上是“ blueprint” API JAR文件,意图用于实施供应商(例如为Mojarra和MyFaces工作的开发人员)。它包含只有类和方法签名的类文件,而没有任何代码物体和资源文件。这正是“缺乏代码属性”的含义。它纯粹是针对Javadocs和汇编的。始终将服务器提供的库标记为
提供的
标记为“ /a>“在maven中,
-api
在伪影ID中的后缀是那些蓝图API。您绝对不应该在运行时类路径中拥有它们。如果您确实需要将其放入POM中,则应始终将它们标记为&lt; scope&gt;/scope&gt;
。一个众所周知的例子是如果不存在
提供的
范围,则此jar最终将进入WebApp的/web-inf/lib
,从而造成您现在面临的所有麻烦。该罐子还包含facesservlet
的蓝图类。在您的具体情况下,您有一个不必要的
引起麻烦,因为这包含
facesservlet
的蓝图类。如上图所示,将其删除并依赖提供的
jakarta ee(Web)API。Tomcat作为Barebones JSP/Servlet容器,已经提供JSP,Servlet和EL(以及8个也是Websocket)。因此,您至少应该将
JSP-API
,Servlet-api
和el-api
提供。 tomcat仅提供面孔(也不提供 jstl )。因此,您需要通过WebApp安装它。刚刚刚刚的雅加达EE服务器,例如Wildfly,Tomee,Glassfish,Payara,WebSphere等,已经为整个雅加达EE API提供了包装盒,包括面孔。因此,您绝对不需要通过WebApp安装面孔。只有当服务器已经提供了不同的实现和/或版本的框外,这才会导致冲突。您需要的唯一依赖性是
jakartaee-api
,如上所述。另请参见 jakarta ee库?
的maven pom.xml中的
适当地配置tomcat X是使用
jakarta的第一个版本。*
软件包而不是javax。因此,对于Tomcat 10.0.x,因此需要至少面对3.0而不是2.3,因为
javax。*
软件包已重命名为jakarta。*
,因为仅面部3.0。如果您有tomcat 10.1.x,则需要4.0的最小面部版本。有两个面孔实现: Mojarra和Myfaces 。您应该选择安装其中的一个 ,因此 都不是。
在tomcat 10或更新的情况下安装mojarra 4.0:
您也可以检查存储库对于当前最新的4.0.x版本版本(当前是
4.0.8
)。另请参见莫哈拉(Mojarra)安装指令CDI,BV,JSONP)。在tomcat 10或更新中安装myFaces 4.0:
您也可以检查存储库对于当前最新的4.0.x版本版本(当前是
4.0.2
)。顺便说一下,不要忘记至少安装JSTL API。这在tomcat中也不存在。
不,您不一定需要按照如何安装JSTL?它因“无法解决的绝对URI”或“无法找到Taglib”或NoclassDeffoundError或ClassCastException 而失败。仅当您还想在JSP文件中使用JSTL时,才需要。 Facelets具有自己的JSTL IMP-In-In-In-In-In-Inn。如果您要同时使用Facelets和JSP,请删除JSTL API依赖项,然后按照上述链接中的指示安装JSTL IMPH。
另请注意,由于面对2.3,CDI已成为所需的依赖性。这可以在普通的雅加达EE服务器中使用,但不能在诸如Tomcat之类的ServletContainers上使用。在这种情况下,前往
要清楚,在安装了Faces实现Mojarra或Myfaces后,您需要单独声明
jakarta.faces-api
依赖关系。这已经通过实施范围包含在内。在Tomcat 9或以上安装面孔
您只能在9或以上的Tomcat 9或以上的最大面上使用,因为它是仍使用
Javax的最新版本。*
package。在Tomcat 9或以上安装Mojarra 2.3:
您还可以检查存储库对于当前最新的2.3.x版本版本(当前是
2.3.21
)。另请参见 Mojarra安装指令CDI,BV,JSONP)。在Tomcat 9或以上安装MyFaces 2.3:
您也可以检查存储库对于当前最新的2.3.x版本版本(当前是
2.3.10
)。请注意,Tomcat 6作为Servlet 2.5最大面容器2.1的容器支撑。
顺便说一句,不要忘记在沿途安装JSTL API。这在tomcat中也不存在。
另请注意,由于面对2.3,CDI已成为所需的依赖性。这可以在普通的雅加达EE服务器中使用,但不能在诸如Tomcat之类的ServletContainers上使用。在这种情况下,前往
另请参阅:
When you're facing a "weird" exception suggesting that classes/methods/files/components/tags are absent or different while they are seemingly explicitly included in the web application such as the ones below,
or when you're facing "weird" runtime behavior such as broken HTTP sessions (
jsessionid
appears in link URLs over all place), and/or broken Faces view scope (it behaves as request scoped), and/or broken CSS/JS/image resources, then the chance is big that the webapp's runtime classpath is polluted with duplicate different versioned JAR files.In your specific case with the
ClassFormatError
on theFacesServlet
, it means that the JAR file containing the mentioned class has been found for the first time is actually a "blueprint" API JAR file, intented for implementation vendors (such as developers working for Mojarra and MyFaces). It contains class files with only class and method signatures, without any code bodies and resource files. That's exactly what "absent code attribute" means. It's purely intented for javadocs and compilation.Always mark server-provided libraries as
provided
All dependencies marked "Java Specifications" in Maven and having
-api
suffix in the artifact ID are those blueprint APIs. You should absolutely not have them in the runtime classpath. You should always mark them<scope>provided</scope>
if you really need to have it in your pom. A well known example is the Jakarta EE (Web) API (formerly known as Java EE):If the
provided
scope is absent, then this JAR will end up in webapp's/WEB-INF/lib
, causing all trouble you're facing now. This JAR also contains the blueprint class ofFacesServlet
.In your specific case, you have an unnecessary Faces API dependency:
This is causing trouble because this contains the blueprint class of
FacesServlet
. Removing it and relying on aprovided
Jakarta EE (Web) API as shown above should solve it.Tomcat as being a barebones JSP/Servlet container already provides JSP, Servlet and EL (and since 8 also WebSocket) out the box. So you should mark at least
jsp-api
,servlet-api
, andel-api
asprovided
. Tomcat only doesn't provide Faces (nor JSTL) out the box. So you'd need to install it via the webapp.Full fledged Jakarta EE servers such as WildFly, TomEE, GlassFish, Payara, WebSphere, etc already provide the entire Jakarta EE API out the box, including Faces. So you do absolutely not need to install Faces via the webapp. It would only result in conflicts if the server already provides a different implementation and/or version out the box. The only dependency you need is the
jakartaee-api
exactly as shown here above.See also How to properly configure Jakarta EE libraries in Maven pom.xml for Tomcat? for more elaborate explanation and examples of
pom.xml
for Tomcat 10 and 9.Installing Faces on Tomcat 10 or newer
Tomcat 10.0.x is the first version using
jakarta.*
package instead ofjavax.*
package. You'll for Tomcat 10.0.x thus need a minimum of Faces 3.0 instead of 2.3 because thejavax.*
package has been renamed tojakarta.*
since Faces 3.0 only. In case you have Tomcat 10.1.x, then you need a minimum Faces version of 4.0.There are two Faces implementations: Mojarra and MyFaces. You should choose to install one of them and thus not both.
Installing Mojarra 4.0 on Tomcat 10 or newer:
You can also check
org.glassfish:jakarta.faces
repository for current latest 4.0.x release version (which is currently4.0.8
). See also Mojarra installation instructions for other necessary dependencies (CDI, BV, JSONP).Installing MyFaces 4.0 on Tomcat 10 or newer:
You can also check
org.apache.myfaces.core:myfaces-impl
repository for current latest 4.0.x release version (which is currently4.0.2
).Don't forget to install at least the JSTL API along, by the way. This is also absent in Tomcat.
No, you don't necessarily need the JSTL impl along as instructed in How to install JSTL? It fails with "The absolute uri cannot be resolved" or "Unable to find taglib" or NoClassDefFoundError or ClassCastException. That's only needed when you also want to use JSTL in JSP files. Facelets has its own JSTL impl built-in. In case you want to use both Facelets and JSP, then remove the JSTL API dependency and install the JSTL impl as instructed in aforementioned link.
Also note that since Faces 2.3, CDI has become a required dependency. This is available out the box in normal Jakarta EE servers but not on servletcontainers such as Tomcat. In this case head to How to install and use CDI on Tomcat?
To be clear, after having installed the Faces implementation Mojarra or MyFaces, you do not need to separately declare the
jakarta.faces-api
dependency. This is already transitively included via the implementation.Installing Faces on Tomcat 9 or older
You can only use at maximum Faces 2.3 on Tomcat 9 or older because it is the latest version still using
javax.*
package.Installing Mojarra 2.3 on Tomcat 9 or older:
You can also check
org.glassfish:jakarta.faces
repository for current latest 2.3.x release version (which is currently2.3.21
). See also Mojarra installation instructions for other necessary dependencies (CDI, BV, JSONP).Installing MyFaces 2.3 on Tomcat 9 or older:
You can also check
org.apache.myfaces.core:myfaces-impl
repository for current latest 2.3.x release version (which is currently2.3.10
).Note that Tomcat 6 as being Servlet 2.5 container supports at maximum Faces 2.1.
Don't forget to install JSTL API along, by the way. This is also absent in Tomcat.
Also note that since Faces 2.3, CDI has become a required dependency. This is available out the box in normal Jakarta EE servers but not on servletcontainers such as Tomcat. In this case head to How to install and use CDI on Tomcat?
See also: