浏览 10291 次
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-10-03
org.springframework.web.context.ContextLoader initWebApplicationContext FATAL: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxWebService': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: portName Caused by: java.lang.NoSuchMethodError: portName at org.apache.cxf.jaxws.support.JaxWsImplementorInfo.getEndpointName(JaxWsImplementorInfo.java:154) at org.apache.cxf.jaxws.support.JaxWsServiceConfiguration.getEndpointName(JaxWsServiceConfiguration.java:89) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.getEndpointName(ReflectionServiceFactoryBean.java:983) at org.apache.cxf.frontend.AbstractEndpointFactory.createEndpoint(AbstractEndpointFactory.java:91) at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:107) at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:147) at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source) at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown Source) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1214) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1179) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1145) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:427) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:144) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:279) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:360) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:241) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49) 从 Stack Trace 来分析,Spring 在 ContextLoaderListener 进行加载配置文件时出错了。 通过查看 JaxWsImplementorInfo.java:154 的源程序 portName = wsAnnotations.get(x).portName(); 可以知道 wsAnnotations 的定义为 private List<WebService> wsAnnotations = new ArrayList<WebService>(2); 得到List里的对象类型为WebService,并得到全称为javax.jws.WebService 通过 JarClassFind 来搜索,可以得到 Apache CXF 中的 geronimo-ws-metadata_2.0_spec-1.1.1.jar 包含有这个类 而 WebLogic 9.2 中的则有两个 .jar 文件包含有此类: No.1 Jar Package:%WLS_HOME%/server/lib/api.jar No.2 Jar Package:%WLS_HOME%/server/lib/weblogic.jar 经过对比,WebLogic 9.2 里的两个 .jar 文件里带个类是一样的,况且,正常启动时 WebLogic 也只是将 weblogic.jar 加到 CLASSPATH 中。 问题猜测应当是由于这两类的版本不一样导致的,拆出来 jad 一下,WebLogic 中的 javax.jws.WebService.java 代码为: package javax.jws; import java.lang.annotation.Annotation; public interface WebService extends Annotation { public abstract String name(); public abstract String targetNamespace(); public abstract String serviceName(); public abstract String wsdlLocation(); public abstract String endpointInterface(); } 拆出 Apache CXF 里的 javax.jws.WebService jad 一下,代码为: package javax.jws; import java.lang.annotation.Annotation; public interface WebService extends Annotation { public abstract String name(); public abstract String targetNamespace(); public abstract String serviceName(); public abstract String wsdlLocation(); public abstract String endpointInterface(); public abstract String portName(); } 这下就完全明白了,是 Apache CXF 期望加载的 javax.jws.WebService 注解与 Weblogic 中 javax.jws.WebService 注解版本不一致导致的。 OK,现在首先想到的是在 weblogic.xml 设置 prefer-web-inf-classes 为 true 来提前加载了。如下: <?xml version="1.0" encoding="UTF-8"?> <weblogic-web-app> <container-descriptor> <prefer-web-inf-classes>true</prefer-web-inf-classes> </container-descriptor> </weblogic-web-app> 总以为能够象往常一样,这样可以了,但是将 prefer-web-inf-classes 设置为 true 后,却发生了另一个异常了: FATAL: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxWebService': Invocation of init method failed; nested exception is java.lang.LinkageError: Class javax/xml/namespace/QName violates loader constraints Caused by: java.lang.LinkageError: Class javax/xml/namespace/QName violates loader constraints at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.<clinit>(RuntimeBuiltinLeafInfoImpl.java:186) at com.sun.xml.bind.v2.model.impl.RuntimeTypeInfoSetImpl.<init>(RuntimeTypeInfoSetImpl.java:25) at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:84) at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:41) at com.sun.xml.bind.v2.model.impl.ModelBuilder.<init>(ModelBuilder.java:104) at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:49) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:372) at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:236) at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76) at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55) at jrockit.reflect.InitialMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source) at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown Source) at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:210) at javax.xml.bind.ContextFinder.find(ContextFinder.java:366) at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574) at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContext(JAXBDataBinding.java:377) at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:182) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:244) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:272) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:146) at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:89) at org.apache.cxf.frontend.AbstractEndpointFactory.createEndpoint(AbstractEndpointFactory.java:83) at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:107) at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:147) 面对这个 java.lang.LinkageError: Class javax/xml/namespace/QName 错误,自然又联想到了版本不一致的问题。 继续 JarClassFind ,在 Apache CXF 里找到 stax-api-1.0.1.jar 包含有这个类。 No.1 Jar Package:%WLS_HOME%/server/lib/api.jar No.2 Jar Package:%WLS_HOME%/server/lib/weblogic.jar No.3 Jar Package:%WLS_HOME%/server/lib/webserviceclient+ssl.jar No.4 Jar Package:%WLS_HOME%/server/lib/webserviceclient.jar No.5 Jar Package:%WLS_HOME%/server/lib/xbean.jar 同样与 WebLogic 启动时有关的仍是 weblogic.jar ,怪异的是 WebLogic 中居然有三个版本的 javax/xml/namespace/QName 这个类,真是比较糟糕的事情。 api.jar、weblogic.jar 与 webserviceclient+ssl.jar、webserviceclient.jar 和 xbean.jar 中各是一个版本。 但是通过 jad 发现 weblogic 里的 javax/xml/namespace/QName 与 Apache CXF 里的是一样的,比较奇怪了。。。 再进行认真地比较发现,文件的时间不同,再直接进行对比 .class 文件,还是有两处有不同之处。Apache CXF 的时间晚于 WebLogic 里的类的时间,于是只能怀疑后者引起类在加载时发生了 java.lang.LinkageError 错误。 经查JDK文档:LinkageError 的子类指示一个类在一定程度上依赖于另一个类;但是,在编译前一个类之后,后一个类发生了不相容的改变。 于是真相大明了?因为 Apache CXF 里的类的时间晚于 WebLogic 里的类的时间,而且类的二进制内容也发生了改变,于是原来 WebLogic 里的其它类由于我们通过了 prefer-web-inf-classes 设置为 true 后,而引用到了现在的 Apache CXF 里的类了,就发生了 java.lang.LinkageError 错误。 由于设置 prefer-web-inf-classes 设置为 true 后,提前加载了应用程序中 lib 目录下的 .jar 文件,而发生了这个问题,于是就尝试去掉 prefer-web-inf-classes 的设置,直接在 WebLogic 的启动脚本中增加第一次异常时相关的 jar 到 CLASSPATH 中,即 geronimo-ws-metadata_2.0_spec-1.1.1.jar 文件,只提前加载这个 jar 文件。 set CLASSPATH_CXF=X:/xyz/geronimo-ws-metadata_2.0_spec-1.1.1.jar set CLASSPATH=%CLASSPATH_CXF%;%CLASSPATH%;%MEDREC_WEBLOGIC_CLASSPATH% 于是,再次进行启动,这下则可以正常启动了。 为了支持 Aegis ,除了必需的之外,还需要再增加如下 jar 包: - jaxen.jar - jdom.jar - stax-utils.jar 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-10-04
不知道你遇到的LinkError具体的错误信息是什么样的。
java.lang.LinkageError: Class ** violates loader constraints |
|
返回顶楼 | |
发表时间:2007-10-11
通过打成ear也可以解决这个问题...
http://cwiki.apache.org/confluence/display/CXF20DOC/AppServerGuide |
|
返回顶楼 | |
发表时间:2008-07-30
按照楼上和搂主的方法。
在cxf2.1.1版本中 仍然抛nested exception is javax.xml.ws.WebServiceException: java.lang.ArrayIndexOutOfBoundsException Caused by: java.lang.ArrayIndexOutOfBoundsException at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createMessageParts(ReflectionServiceFactoryBean.j ava:1272) 异常。 在tomcat中也是对的。 比较郁闷。 |
|
返回顶楼 | |
发表时间:2008-07-30
我用的是cxf2.1.1版本
抛上面的错误 将版本回退到2.0.7就没有异常了。 |
|
返回顶楼 | |
发表时间:2008-08-06
好样的,帮我解决了大问题!!
|
|
返回顶楼 | |
发表时间:2008-08-06
分析透彻,非常好,谢谢了.
|
|
返回顶楼 | |
发表时间:2008-08-07
其实这个问题的根本原因是,WLS9.2中的WLS9.2自带的JWS Package(weblogic.jar)与JSR181 JSR181 2.0 Final Release有部分annotation不一致
包括 @WebService 的portName 解决方法是使用@WLHttpTransport (portName="ServiceProt"…) @WebMethod 的exclude @WebParam 的partName @WebResult 的partName,header 原因很简单,当WLS9.2 出来的时候JSR181 Final Relase还没有出来。 可以参考JSR181草案-->FINAL的中间所有文档。 在JCP的PDF里面清晰的有 Web Services Metadata for the JavaTM Platform Specification ("Specification") Version: 2.0 Status: FCS 同时在JavaDoc里面也有 这个说明,Since. portName public abstract java.lang.String portNameThe port name of the Web Service. Used as the name of the wsdl:port when mapped to WSDL 1.1. This member-value is not allowed on endpoint interfaces. Since: 2.0 Specification Default: @WebService.name+擯ort? Default: "" 上面说的几个都是Since 2.0增加的。不过大部分人因为一开始就使用了2.0 FCS版 所有就不太清楚这个。 |
|
返回顶楼 | |