Удалена левая угловая скобка при отправке SOAP-сообщения из Spring -WS-клиент на Java7 на сервер на Java 6

Меня это сильно расстроило, поэтому я попытаюсь объяснить, что я знаю, а что нет. Пожалуйста, следите за моими обновлениями внизу поста.

Во-первых, у нас есть война, которая использует Spring -WS для обработки сообщений. У нас также есть клиент, который использует WebServiceTemplate для отправки сообщений. Мы используем Tomcat 7.

В нашей текущей среде разработки сервер Tomcat 7 использует JRE 6u24. Локально я запускаю ту же версию, когда использую клиент для отправки сообщения SOAP. Все работает так, как ожидалось.

Когда я создаю свою локальную JRE 7u04, я получаю ответ 500, а сервер видит следующую ошибку:

[2012-05-05 20:19:13,179] DEBUG - org.springframework.web.servlet.FrameworkServlet.processRequest(671) | Could not complete request
org.springframework.ws.soap.saaj.SaajSoapEnvelopeException: Could not access envelope: Unable to create envelope from given source: ; nested exception is com.sun.xml.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source:
        at org.springframework.ws.soap.saaj.SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:260)
        at org.springframework.ws.soap.saaj.SaajSoapMessage.getImplementation(SaajSoapMessage.java:342)
        at org.springframework.ws.soap.saaj.SaajSoapMessage.<init>(SaajSoapMessage.java:117)
        at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:184)
        at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:58)
        at org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:90)
        at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:86)
        at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
        at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:222)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
        at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)
        at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)
        at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
        at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)
        at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:417)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
        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: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source:
        at com.sun.xml.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:127)
        at com.sun.xml.messaging.saaj.soap.ver1_2.SOAPPart1_2Impl.createEnvelopeFromSource(SOAPPart1_2Impl.java:84)
        at com.sun.xml.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:150)
        at org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion(SaajUtils.java:155)
        at org.springframework.ws.soap.saaj.SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:257)
       ... 39 more
Caused by: javax.xml.transform.TransformerException: org.xml.sax.SAXParseException: The markup in the document preceding the root element must be well-formed.
        at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:501)
        at com.sun.xml.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:414)
        at com.sun.xml.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:118)
       ... 43 more
Caused by: org.xml.sax.SAXParseException: The markup in the document preceding the root element must be well-formed.
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
        at org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:333)
        at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:484)
       ... 45 more

Я столкнулся с множеством потенциальных проблем. Тем не менее, я думаю, что в некотором отношении я сузил это до вопроса SAAJ.

В классе SaajSoapMessageFactory для Spring -WS есть метод, который начинается с:

public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
        MimeHeaders mimeHeaders = parseMimeHeaders(inputStream);
        try {
            inputStream = checkForUtf8ByteOrderMark(inputStream);
            SOAPMessage saajMessage = messageFactory.createMessage(mimeHeaders, inputStream);
            postProcess(saajMessage);
            return new SaajSoapMessage(saajMessage, langAttributeOnSoap11FaultString, messageFactory);
        }

Когда я отправляю с помощью клиента с JRE 6, inputStream ПОСЛЕ вызова createMessage начинается как :

[60, 101, 110, 118, 58, 69, 110, 118, 101, 108, 111, 112, 101, 32, 120, 109, 108, 110, 115, 58, 101, 110, 118, 61, 34, 104, 116

, который преобразуется в:<env:Envelope... и т.д.

Однако, когда я отправляю с помощью клиента с JRE 7, inputStream после вызова createMessage начинается как:

[101, 110, 118, 58, 69, 110, 118, 101, 108, 111, 112, 101, 32, 120, 109, 108, 110, 115, 58, 101, 110, 118, 61, 34, 104, 116

Как вы можете видеть, первый байт, левая угловая скобка, пропал. Я пытался отладить его, но мне не хватает источников com.sun.xml.internal, чтобы действительно сделать это эффективно.

Также следует отметить, что в JRE 6 поток PushbackInputStream ПОСЛЕ вызова checkForUtf8ByteOrderMark на самом деле выглядит как окончательный массив байтов:

[60, 101, 110, 118, 58, 69, 110, 118, 101, 108, 111, 112, 101, 32, 120, 109, 108, 110, 115, 58, 101, 110, 118, 61, 34, 104, 116,и т. д.

Но при отправке с использованием JRE 7 он выглядит так:

[60, 0, 0, 0, 0, 0, 0, 0, 0и т. д.

Теперь сам метод, кажется, следует тому же потоку, проверяя отсутствие спецификации, а затем возвращая то, что было снято, чтобы проверить это (, по крайней мере,так мне кажется ).

Итак, у меня два вопроса:

1 )Кто-нибудь знает, что происходит? Здесь есть что-нибудь, что звонит в колокол?

2 )Как я могу получить исходный код этих пакетов com.sun.xml.internal?

Должен отметить, что я могу запускать это локально на Tomcat в Eclipse и, кажется, не иметь никаких проблем, но я знаю, что там, вероятно, происходит какая-то странная загрузка классов.

Обновление 1:

Мне удалось связать некоторый источник с кодом, и я попал в этот метод в SOAPPart1. _2Impl:

   public void setContent(Source source) throws SOAPException {
        try {
            if (source instanceof StreamSource) {
                InputStream is = ((StreamSource) source).getInputStream();
                Reader rdr = ((StreamSource) source).getReader();

                if (is != null) {
                    this.source = new JAXMStreamSource(is);
                } else if (rdr != null) {
                    this.source = new JAXMStreamSource(rdr);
                } else {
                    log.severe("SAAJ0544.soap.no.valid.reader.for.src");
                    throw new SOAPExceptionImpl("Source does not have a valid Reader or InputStream");
                }
            }

Теперь он выбирает первый путь установки InputStream. Что очень интересно, так это то, что когда это сделано, источник имеет ByteInputStream, который начинается как таковой:

[60, 0, 0, 101, 110, 118, 58, 69, 110, 118, 101, 108, 111, 112, 101, 32, 120, 109, 108, 110, 115, 58, 101,и т. д.

Меня это очень смущает. Я попытаюсь выяснить, что именно происходит с этими первыми тремя символами --, возможно, есть какой-то побочный эффект в методе checkForUtf8ByteOrderMark.

Обновление 2:

Хорошо, теперь я действительно кое-что понял. Я изучил этот класс JAXMStreamSource, и это приводит к классу ByteOutputStream, который имеет метод:

public void write(InputStream in) throws IOException {
    if (in instanceof ByteArrayInputStream) {
        int size = in.available();
        ensureCapacity(size);
        count += in.read(buf,count,size);
        return;
    }
    while(true) {
        int cap = buf.length-count;
        int sz = in.read(buf,count,cap);
        if(sz<0)    return;     // hit EOS

        count += sz;
        if(cap==sz)
            // the buffer filled up. double the buffer
            ensureCapacity(count);
    }
}

в строке «int sz = in.read (buf,count,cap );» где два нуля после 60 добавляются. Я все еще пытаюсь понять, почему и почему клиент, использующий 1.7, мог иметь такой эффект.

5
задан AHungerArtist 6 May 2012 в 02:38
поделиться