CXF项目在tomcat下可以正常运行,部署到weblogic下出现各种问题。现记录下解决思路。
1.一开始到网上一通狂搜,搜索CXF+weblogic、搜索具体错误,搜到的最多的原因是包冲突了,但是按照解决方案却不能解决我的问题
严重: exception raied when invoking setter public final void org.apache.cxf.wsdl11.WSDLManagerImpl.setBus(org.apache.cxf.Bus)
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
Caused by: org.apache.cxf.bus.extension.ExtensionException: Could not create object of extension class org.apache.cxf.binding.corba.wsdl.WSDLExtensionRegister.
at org.apache.cxf.bus.extension.Extension.load(Extension.java:241)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadAndRegister(ExtensionManagerImpl.java:213)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.getBeansOfType(ExtensionManagerImpl.java:348)
at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:153)
at org.apache.cxf.wsdl11.WSDLManagerImpl.setBus(WSDLManagerImpl.java:122)
Caused by: java.lang.NegativeArraySizeException
at org.objectweb.asm.Frame.a(Unknown Source)
at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:90)
at com.sun.proxy.$Proxy64.visitMaxs(Unknown Source)
at org.apache.cxf.wsdl.JAXBExtensionHelper.createExtensionClass(JAXBExtensionHelper.java:543)
at org.apache.cxf.wsdl.JAXBExtensionHelper.addExtensions(JAXBExtensionHelper.java:199)
at org.apache.cxf.binding.corba.wsdl.WSDLExtensionRegister.createExtensor(WSDLExtensionRegister.java:71)
at org.apache.cxf.binding.corba.wsdl.WSDLExtensionRegister.registerCXFExtensors(WSDLExtensionRegister.java:44)
at org.apache.cxf.binding.corba.wsdl.WSDLExtensionRegister.<init>(WSDLExtensionRegister.java:39)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.apache.cxf.bus.extension.Extension.load(Extension.java:217)
2.网上的方案解决不了问题,只能回归到问题本身,通过分析出错信息发现上面的异常都是下面的异常导致的,问题的根本是最下面这个异常。最后这个异常出现在 org.objectweb.asm.Frame中,这个异常是试图创建大小为负的数组,猜测是jar包冲突导致的,于是修改weblogic.xml配置,这个配置是优先引用应用程序的类,而不是weblogic的。
<?xml version="1.0" encoding="UTF-8" ?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">
<container-descriptor>
<!-- <prefer-web-inf-classes>true</prefer-web-inf-classes> -->
<prefer-application-packages>
<package-name>antlr.*</package-name>
<package-name>org.objectweb.asm.*</package-name>
</prefer-application-packages>
</container-descriptor>
</weblogic-web-app>
3.配置修改后,上述错误果然没有了,报出新的异常
八月 03, 2017 10:09:04 上午 org.apache.cxf.ws.discovery.internal.WSDiscoveryServiceImpl startup
警告: Could not start WS-Discovery Service.
javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:375)
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:87)
at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.buildServiceFromWSDL(ReflectionServiceFactoryBean.java:394)
at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:528)
at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:263)
at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:199)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:103)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:168)
at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:211)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:460)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:338)
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: java.lang.RuntimeException: Cannot create a secure XMLInputFactory
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:228)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:163)
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:85)
Caused by: java.lang.RuntimeException: Cannot create a secure XMLInputFactory
at org.apache.cxf.staxutils.StaxUtils.createXMLInputFactory(StaxUtils.java:338)
at org.apache.cxf.staxutils.StaxUtils.getXMLInputFactory(StaxUtils.java:278)
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1798)
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1697)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:215)
4.按照上面的思路,最根本的问题还是最后这个异常,再次猜测有可能是jar包冲突,配置weblogic.xml,异常没有消失,说明并不是jar包冲突(weblogic也没有CXF的jar包)
5.既然这个思路走不通了,就去网上搜索,终于发现一篇有价值的博客,在jboss下部署CXF出现这个运行时异常的解决方案(http://blog.csdn.net/wuxuguang123/article/details/43676265),这篇文章是从源码的角度去分析的,从而发现是ALLOW_INSECURE_PARSER这个系统属性导致这个异常的
然而这篇文章给出的是jboss下的解决方案,不过没关系,继续搜索这个属性以及他的解决方案
6.搜索"org.apache.cxf.stax.allowInsecureParser"发现一篇解决这个问题的文章(http://blog.csdn.net/koudailidexiaolong/article/details/52239670),文章中采用的是监听器启动时重新设置系统属性来解决这个问题的
package com.shensu.listener;
import java.util.Properties;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SealManageListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
Properties props = System.getProperties();
props.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
}
}
7.最后部署,启动weblogic,控制台没有报错,在浏览器中访问wsdl地址http://localhost:7001/TestCXF/webservice/childinfo?wsdl成功
8.整个过程最大的收获是:不要太依赖搜索引擎,要学会看异常信息,学会看源代码
9.最后出现了异常,有时间再改
DefaultValidationEventHandler: [ERROR]: prefix wsdp is not bound to a namespace
Location: node: [wsd:Types: null]
javax.xml.bind.UnmarshalException: prefix wsdp is not bound to a namespace
- with linked exception:
[java.lang.IllegalArgumentException: prefix wsdp is not bound to a namespace]
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
Caused by: java.lang.IllegalArgumentException: prefix wsdp is not bound to a namespace
at com.sun.xml.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:358)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$23.parse(RuntimeBuiltinLeafInfoImpl.java:807)