WRONG_DOCUMENT_ERR при вызове клиента CXF с перехватчиком WSS из JBoss 5.1.0GA

У меня есть клиент веб-службы CXF с перехватчиком WSS, который работает с консоли, но при запуске из JBoss выдает следующее исключение:

Произошло неожиданное исключение

Unexpected exception occured 
javax.xml.ws.soap.SOAPFaultException: WRONG_DOCUMENT_ERR: A node is
used in a different document
than the one that created
it.    
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)   
at $Proxy1020.getAccountStatements(Unknown Source)  
at com.sru.statement.impl.cs.CSStatementGetter.getStatementFromBank(CSStatementGetter.java:164)   
at com.sru.statement.impl.cs.CSStatementGetter.getStatement(CSStatementGetter.java:90)   
at com.sru.hub.common.statement.CommonStatementImportExecutor.execute(CommonStatementImportExecutor.java:89)   
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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)   
(...)
at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:260)   
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)   
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)   
at java.lang.Thread.run(Thread.java:662)   
Caused by: org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A
node is used in a
different document than the one
that created it.  
at org.apache.xerces.dom.ParentNode.internalInsertBefore(Unknown Source)  
at org.apache.xerces.dom.ParentNode.insertBefore(Unknown Source)  
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(Unknown Source)  
at org.apache.xerces.dom.NodeImpl.appendChild(Unknown Source)  
at org.jboss.ws.core.soap.SOAPDocument.appendChild(SOAPDocument.java:222)   
at org.jboss.ws.core.soap.SOAPPartImpl.appendChild(SOAPPartImpl.java:297)   
at org.apache.cxf.staxutils.W3CDOMStreamWriter.setChild(W3CDOMStreamWriter.java:119)   
at org.apache.cxf.staxutils.W3CDOMStreamWriter.newChild(W3CDOMStreamWriter.java:109)   
at org.apache.cxf.staxutils.W3CDOMStreamWriter.writeStartElement(W3CDOMStreamWriter.java:137)   
at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.writeSoapEnvelopeStart(SoapOutInterceptor.java:122)   
at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.handleMessage(SoapOutInterceptor.java:81)   
at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.handleMessage(SoapOutInterceptor.java:61)   
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)   
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)   
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:462)   
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:365)   
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:318)   
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:95)   
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)   
... 80 more  

Работает с этими библиотеками:

/org/apache/cxf/cxf-rt-frontend-jaxws/2.4.2/cxf-rt-frontend-jaxws-2.4.2.jar
/org/apache/cxf/cxf-api/2.4.2/cxf-api-2.4.2.jar
/org/apache/cxf/cxf-common-utilities/2.4.2/cxf-common-utilities-2.4.2.jar
/org/apache/cxf/cxf-rt-core/2.4.2/cxf-rt-core-2.4.2.jar
/org/apache/cxf/cxf-rt-frontend-simple/2.4.2/cxf-rt-frontend-simple-2.4.2.jar
/wsdl4j/wsdl4j/1.6.2/wsdl4j-1.6.2.jar
/org/apache/ws/xmlschema/xmlschema-core/2.0/xmlschema-core-2.0.jar
/org/apache/cxf/cxf-rt-bindings-soap/2.4.2/cxf-rt-bindings-soap-2.4.2.jar
/org/apache/cxf/cxf-tools-common/2.4.2/cxf-tools-common-2.4.2.jar
/org/apache/cxf/cxf-rt-databinding-jaxb/2.4.2/cxf-rt-databinding-jaxb-2.4.2.jar
/org/apache/cxf/cxf-rt-ws-addr/2.4.2/cxf-rt-ws-addr-2.4.2.jar
/org/apache/neethi/neethi/3.0.1/neethi-3.0.1.jar
/org/apache/cxf/cxf-rt-ws-security/2.4.2/cxf-rt-ws-security-2.4.2.jar
/org/apache/ws/security/wss4j/1.6.2/wss4j-1.6.2.jar
/commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.jar
/org/apache/cxf/cxf-rt-transports-http/2.4.2/cxf-rt-transports-http-2.4.2.jar
/org/apache/xmlsec/1.4.2/xmlsec-1.4.2.jar
/commons-io/commons-io/2.4/commons-io-2.4.jar

Если клиент вызывается без перехватчика WSS, все работает нормально.

Код перехватчика WSS:

Client client = ClientProxy.getClient(port);
Endpoint cxfEndpoint = client.getEndpoint();
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
outProps.put(WSHandlerConstants.USER, "username_alex");
outProps.put(WSHandlerConstants.ADD_UT_ELEMENTS, WSConstants.NONCE_LN + " " +WSConstants.CREATED_LN);
outProps.put(WSHandlerConstants.PW_CALLBACK_REF, this);
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);

Есть идеи, что здесь происходит?

Обновить:

Некоторые дополнительные советы. Я надеюсь, что это будет полезно:

  1. Я попытался запустить приложение на Tomcat. Оно работает,
  2. Из-за этого билета: https://issues.apache.org/jira/browse/CXF-4612?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel Я протестировал приложение с двумя дополнительными версиями CXF: 2.5.7 и 2.5.8. Это не удалось.
  3. В /lib/ одобрено моего JBoss у меня есть две реализации SAAJ: axis-saaj.jar и jboss-native-saaj.jar. Я попытался объединить эти библиотеки и обнаружил, что без обеих сторон приложение раздает при обработке веб-службы с WSS (приложение работает, но ничего не произошло: в браузере и журналах нет ошибок),
  4. Я также попытался добавить axis-saaj и jboss-native-saaj (отдельно) в файл WAR приложения. Результат аналогичен пункту 3: приложение руки.

1 ответ

Не уверен, актуальна ли эта проблема или нет, но я столкнулся с этим вопросом, когда столкнулся с этой проблемой на JBoss 6.1.0. Поэтому я думал, что выложу решение.

JBoss устанавливает значения по умолчанию для ряда фабрик, задействованных при создании и обработке сообщения SOAP. В частности, здесь возникает проблема: javax.xml.soap.MessageFactory,

Apache CXF имеет перехватчик SAAJOutInterceptor, Это жестко закодировано в org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor,

Я не уверен, но я думаю, что идея здесь состоит в том, чтобы изменить Сообщение SOAP с конкретного объекта CXF на конкретный объект платформы. При этом инициализируется MessageFactory org.jboss.ws.core.soap.MessageFactoryImpl, Этот класс происходит из банки common/lib/jbossws-native-core.jar,

Одним из решений проблемы грубой силы было бы избавиться от этой банки. Это не создавало никаких проблем в нашем приложении. Но более приличным решением будет переопределить JBoss MessageFactory, определив файл в этой точной структуре META-INF/services/javax.xml.soap.MessageFactory на пути к классам вашего приложения.

Для файла WAR его нужно поместить в WEB-INF/classes. Этот файл имеет одну строку следующим образом:

com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl

Перезапустите процесс JBoss после внесения этого изменения. Надеюсь, что это работает для всех.

Другие вопросы по тегам