如何通过Maven正确安装和configurationJSF库?
我试图将一个基于JSF的应用程序部署到Tomcat 6.我的构build系统的设置方式,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源代码并自己编译来解决。 对我而言,这是一个可怕的解决办法。 这会给我们的团队带来很多问题,我们需要应对各种不同的configuration。 有没有另外的解决办法?
这是我的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>
这里必须有一个解决scheme。 我不能相信,JSF的Maven可分发只适合编译,不适合部署。
当你面对一个“奇怪的”exception,表明类/方法/文件/组件/标签是不存在或不同的,而他们似乎明确包含在Web应用程序,如下面的,
java.lang.ClassFormatError:在类文件中不是本机或抽象的方法中缺less代码属性javax / faces / webapp / FacesServlet
java.util.MissingResourceException:找不到javax.faces.LogStrings包
com.sun.faces.vendor.WebContainerInjectionProvider不能转换为com.sun.faces.spi.InjectionProvider
com.sun.faces.config.ConfigurationException:CONFIGURATION FAILED
名称空间http://xmlns.jcp.org/jsf/html中名为inputFile的标签具有一个空处理程序类定义。;
java.lang.NullPointerException在javax.faces.CurrentThreadToServletContext.getFallbackFactory
或者当您面临“怪异”的运行时行为,例如断开的HTTP会话( jsessionid
出现在所有地方的链接URL中)和/或破坏的JSF视图范围(其行为与请求范围相同)和/或CSS / JS /图像资源,那么webapp的运行时类path被重复的不同的版本化的JAR文件所污染的机会是很大的。
在你使用FacesServlet
情况下,这意味着包含所提到的类的JAR文件第一次被发现实际上是一个“蓝图”API JAR文件,供实现供应商(例如为Mojarra和MyFaces工作的开发者)使用。 它包含只有类和方法签名的类文件,没有任何代码体和资源文件。 这就是“缺less代码属性”的意思。 这纯粹是为了javadocs和编译。
始终标记服务器提供的库
在Maven中标记为“ Java规范 ”的所有依赖-api
在工件ID中具有-api
后缀的是那些蓝图API。 你绝对不应该在运行时类path中。 如果你真的需要把它放在你的pom中,你应该总是把它们标记为<scope>provided</scope>
。 一个众所周知的例子是Java EE(Web)API :
<dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version><!-- 6.0 or 7.0 or newer --></version> <scope>provided</scope> </dependency>
如果provided
范围不存在,那么这个JAR将以webapp的/WEB-INF/lib
结尾,导致你现在遇到的所有麻烦。 这个JAR还包含了FacesServlet
的蓝图类。
在你的具体情况下,你有一个不必要的JSF API依赖:
<dependency> <groupId>javax.faces</groupId> <artifactId>javax.faces-api</artifactId> </dependency>
这造成了麻烦,因为它包含了FacesServlet
的蓝图类。 删除它并依靠上面provided
Java EE(Web)API应该可以解决这个问题。
Tomcat作为一个准系统的JSP / Servlet容器已经提供了JSP,Servlet和EL(以及8个也是WebSocket)。 所以你应该至less标记jsp-api
, servlet-api
和el-api
。 Tomcat只是不提供JSF(和JSTL )。 所以你需要通过webapp安装它。
全function的Java EE服务器,如WildFly,TomEE,GlassFish,Payara,WebSphere等已经提供了整个Java EE API,包括JSF。 所以你绝对不需要通过webapp安装JSF。 如果服务器已经提供了不同的实现和/或版本,那只会导致冲突。 你需要的唯一的依赖是javaee-web-api
完全如上所示。
在Tomcat上安装JSF
在我们的JSF wiki – 安装JSF中提到了在Tomcat中安装JSF的正确方法。 有2个JSF实现, Mojarra和MyFaces 。 你应该select安装其中的一个,因此不能同时安装。
在Tomcat上安装Mojarra:
<dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version><!-- Check https://javaserverfaces.github.io --></version> </dependency>
您还可以检查org.glassfish:javax.faces
存储库中当前的最新发行版本(目前是2.2.13
)。 另请参阅Mojarra自己的安装说明 。
在Tomcat上安装MyFaces:
<dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-api</artifactId> <version><!-- Check http://myfaces.apache.org --></version> </dependency> <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-impl</artifactId> <version><!-- Check http://myfaces.apache.org --></version> </dependency>
您也可以检查org.apache.myfaces.core:myfaces-bundle
版本库以了解当前的最新版本(目前是2.2.10
)。
请注意,Tomcat 6作为Servlet 2.5容器支持最大的JSF 2.1。 顺便说一下,别忘了安装JSTL。 另请参阅我们的JSF wiki – 安装JSF 。
也可以看看:
- Java EE究竟是什么?
- java.lang.NoClassDefFoundError:javax / servlet / jsp / jstl / core / Config
- 如何在Tomcat上安装和使用CDI?
- JSF使用plain / raw XHTML / XML / EL源返回空白/未分析的页面,而不是呈现的HTML输出