При переносе приложения с использованием Apache Axis 1.2 из Java 4 или 5 в Java 6 (JRE 1.6) вы, скорее всего, столкнетесь с несколькими странными ошибками SOAP / SAAJ / XML и ClassCastExceptions. Это связано с тем, что реализация SAAJ 1.3 в Sun была интегрирована непосредственно в 1.6 JRE . Благодаря этой интеграции он загружается загрузчиком классов начальной загрузки и поэтому не может видеть различные классы, на которые вы могли ссылаться в своем старом коде.
Как уже упоминалось на весенних страницах :
Java 1.6 поставляется с SAAJ 1.3, JAXB 2.0 и JAXP 1.4 (пользовательская версия Xerces и Xalan). Переопределение этих библиотек путем помещения другой версии в classpath приведет к различным проблемам загрузки классов или исключениям в org.apache.xml.serializer.ToXMLSAXHandler. Единственный вариант использования более поздних версий — поместить новую версию в утвержденный каталог (см. Выше).
К счастью, есть простое решение, по крайней мере, для Axis 1.2.
Некоторые из исключений, с которыми мы столкнулись
Пример кода оси
import javax.xml.messaging.URLEndpoint;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPConnection;import javax.xml.soap.SOAPConnectionFactory;import javax.xml.soap.SOAPMessage;...public static callAxisWebservice() {SOAPConnectionFactory soapconnectionfactory = SOAPConnectionFactory.newInstance();SOAPConnection soapconnection = soapconnectionfactory.createConnection();MessageFactory messagefactory = MessageFactory.newInstance();SOAPMessage soapmessage = messagefactory.createMessage();...URLEndpoint urlendpoint = new URLEndpoint(string);SOAPMessage soapmessage_18_ = soapconnection.call(soapmessage, urlendpoint);...}
SOAPExceptionImpl: неверный тип конечной точки
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad endPoint type http://example.com/ExampleAxisService at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:161)
Эта чрезвычайно запутанная ошибка вызвана следующим, казалось бы, невинным кодом, приведенным выше, а именно ‘… new URLEndpoint (string)’ и самим вызовом. Проблема здесь в том, что HttpSOAPConnection от Sun не может видеть javax.xml.messaging.URLEndpoint, потому что он не является частью JRE и содержится в другом JAR, невидим для классов, загружаемых загрузчиком начальной загрузки.
Если вы проверите код HttpSOAPConnection (это не совсем та версия, которая у меня есть, но достаточно близкая), вы увидите, что он вызывает «Class.forName (« javax.xml.messaging.URLEndpoint »);» в строке 101. По указанной причине происходит сбой с ClassNotFoundException (как указано в журнале «URLEndpoint доступен только при наличии JAXM», когда вы включаете протоколирование JDK для самого лучшего уровня), и, таким образом, метод не может распознать тип аргумента и завершается с ошибочным сообщением Bad endPoint.
Решением в этом случае будет передача java.net.URL или String вместо URLEndpoint (хотя это может привести к другим ошибкам, таким как приведенная ниже).
Связанный: Oracle saaj: ошибка soap1.2 SOAPExceptionImpl: Неверный тип конечной точки .
DOMException: NAMESPACE_ERR
org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. at org.apache.xerces.dom.AttrNSImpl.setName(Unknown Source) at org.apache.xerces.dom.AttrNSImpl.<init>(Unknown Source) at org.apache.xerces.dom.CoreDocumentImpl.createAttributeNS(Unknown Source)
Я не помню точно, что мы изменили на пути к классам, чтобы получить это запутанное исключение, и я понятия не имею, почему оно выбрасывается.
Бонус: конфликт между Axis и «тонким клиентом» IBM WebSphere JAX-RPC
Кроме того, если у вас есть com.ibm.ws.webservices.thinclient_7.0.0.jar где-то на пути к классам, вы можете получить это забавное исключение:
java.lang.ClassCastException: org.apache.axis.Message incompatible with com.ibm.ws.webservices.engine.Message at com.ibm.ws.webservices.engine.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:198)
Вы можете задаться вопросом, почему Java пытается использовать Axis Message с соединением WebSphere SOAP. Дело в том, что механизм поиска SAAJ предпочитает реализацию веб-сферы, поскольку он объявляет себя через META-INF / services / javax.xml.soap.SOAPFactory, указывая на com.ibm.ws.webservices.engine.soap.SOAPConnectionFactoryImpl, но создает экземпляр org.apache.axis.soap.MessageFactoryImpl для создания сообщений для тонкого клиента websphere не обеспечивает реализацию этой фабрики.
Решение здесь такое же, как и для всех остальных исключений, использовать исключительно Axis. Но если вам интересно, ознакомьтесь с описанием того, как правильно создать сообщение со средой выполнения websphere на стр. 119 в Руководстве по веб-сервисам IBM WebSphere Application Server V7.0 (md = javax.xml.ws.Service.create (serviceName). createDispatch (portName, SOAPMessage.class, Service.Mode.MESSAGE); ((SOAPBinding) ((BindingProvider) md) .getBinding ()). getMessageFactory ();).
Решение
Решение, которое нашел мой коллега Ян Над, состоит в том, чтобы заставить JRE использовать реализацию SOAP / SAAJ, предоставленную Axis , что-то вроде:
java -Djavax.xml.soap.SOAPFactory=org.apache.axis.soap.SOAPFactoryImpl -Djavax.xml.soap.MessageFactory=org.apache.axis.soap.MessageFactoryImpl -Djavax.xml.soap.SOAPConnectionFactory=org.apache.axis.soap.SOAPConnectionFactoryImpl example.MainClass
Это также описано в выпуске AXIS-2777 .
Проверьте детали процесса поиска в SOAPFactory.newInstance () JavaDoc .