Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在发送无效xml时修复websphere上的java堆空间_Java_Web Services_Websphere - Fatal编程技术网

如何在发送无效xml时修复websphere上的java堆空间

如何在发送无效xml时修复websphere上的java堆空间,java,web-services,websphere,Java,Web Services,Websphere,当我将无效xml发送到websphere server上的web服务时,我会得到java堆空间: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"> <soap:Header/> <soap:Body> <MyElement

当我将无效xml发送到websphere server上的web服务时,我会得到java堆空间:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/">
   <soap:Header/>
   <soap:Body>
       <MyElementsomething</MyElement>

   </soap:Body>
</soap:Envelope>
由于
WebServiceMessageReceiveObjectSupport.class

86            WebServiceMessage request = connection.receive(getMessageFactory()); // here occurs out of memory
87            MessageContext messageContext = new DefaultMessageContext(request, getMessageFactory());
88            receiver.receive(messageContext); // and in this method are interceptor which validate request
PS2:

当我尝试将堆空间从2gb增加到4gb时,在同一点上还有另一个异常:

java.lang.IndexOutOfBoundsException
        at java.io.PushbackInputStream.read(PushbackInputStream.java:181) ~[?:1.7.0]
        at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[?:1.7.0]
        at com.ibm.ws.webservices.utils.WebServicesInputSource$FilterIS.read(WebServicesInputSource.java:805) ~[com.ibm.ws.runtime.jar:?]
        at com.ibm.ws.webservices.utils.BAIS.create(BAIS.java:77) ~[com.ibm.ws.runtime.jar:?]
PS3:

这是sun java的正确行为:

Caused by: org.xml.sax.SAXParseException: The element type "urn:ZadostInfo" must be terminated by the matching end-tag "</urn:ZadostInfo>".
        at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) ~[?:?]
        at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) ~[?:?]
        at org.xml.sax.helpers.XMLFilterImpl.parse(Unknown Source) ~[?:?]
        at org.apache.xalan.transformer.TransformerIdentityImpl.transform(Unknown Source) ~[?:?]
        at com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:411) ~[?:1.7.0]
        at com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:115) ~[?:1.7.0]
        at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java:80) ~[?:1.7.0]
        at com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:140) ~[?:1.7.0]
        at org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion(SaajUtils.java:155) ~[spring-ws-core-2.1.2.RELEASE.jar:?]
由以下原因引起:org.xml.sax.SAXParseException:元素类型“urn:ZadostInfo”必须由匹配的结束标记“”终止。
在org.apache.xerces.parsers.AbstractSAXParser.parse(未知源)~[?:?]
位于org.apache.xerces.jaxp.saxpasserimpl$JAXPSAXParser.parse(未知源)~[?:?]
在org.xml.sax.helpers.XMLFilterImpl.parse(未知源)~[?:?]
在org.apache.xalan.transformer.TransformerIdentityImpl.transform(未知源)~[?:?]
在com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:411)~[?:1.7.0]
在com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:115)~[?:1.7.0]
在com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java:80)~[?:1.7.0]
在com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:140)~[?:1.7.0]
在org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion(SaajUtils.java:155)~[spring-ws-core-2.1.2.RELEASE.jar:?]

最好的方法是使用spring payloadinterceptor根据xml模式验证传入的xml,然后再对其进行进一步解析。。。 示例代码:

bean id="validatingInterceptor"
    class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="schema" value="/WEB-INF/conf/MyElement.xsd"/>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="false"/>
bean id=“validatingInterceptor”
class=“org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor”>


有关更多详细信息,请阅读spring,您刚刚发现一个bug。请报告错误。因为这与解析有关。你可以做两件事

首先,您可以进行内存转储。只需转储内存(或使用visualvm对此进行配置并运行内存配置文件)。这样你就能理解是什么污染了记忆

其次,您可以纠正发现的问题。我一直使用第三方代码。因此,在他们开始解析代码段之前,您需要执行另一个步骤,在不检查shema的情况下评估xml是否正确。只需在不涉及shema的情况下运行解析器

为了提供修改后的实现,请使用源代码,如果源代码不可用,请对其进行反编译或重命名该类,并提供由此扩展的新实现类。如果它是您需要访问的私有方法或功能,只需修改字节码即可

为了注入您的版本,只需将您的类添加到类路径(或websphere的类路径)并将其放在前面。通常,您的代码在任何库代码之前。这样,只要控制类路径(通常通过在java.exe中设置它),就可以覆盖任何库的每个实现细节

因此,在发布这个有缺陷的版本之前,只需添加一个额外的正确性测试,并报告该缺陷,并在博客上发布相关信息


如果您有问题或需要工具建议,请提问。我经常这样做。使用开源和非开源软件。对于扩展功能等其他方面也很有用。

我尝试自己解决这个问题。我检查了spring ws如何验证xml,并尝试在websphere之前进行验证。下面是代码。我测试了它,它对我有用。

public class SaajSoapMessageValidatorFactory extends SaajSoapMessageFactory {

    @Override
    public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
        InputStream original;

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, baos);

            original = new ByteArrayInputStream(baos.toByteArray());
            InputStream validate = new ByteArrayInputStream(baos.toByteArray());

            try {
                ValidatorResources validator = new XmlValidatorResources(validate);
                validator.process();
            } catch (Exception parseException) {
                throw new InvalidXmlException("Could not parse XML", parseException);
            } finally {
                IOUtils.closeQuietly(validate);
            }
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        return super.createWebServiceMessage(original);
    }
}



public class XmlValidatorResources extends ValidatorResources {

    private static final long serialVersionUID = 1L;

    public XmlValidatorResources(InputStream in) throws IOException, SAXException {
        Digester digester = new Digester();
        digester.push(this);
        digester.parse(in);
    }

}
在spring上下文中,我添加了:

<bean id="messageFactory" class="cz.isvs.ais3.ws.validator.SaajSoapMessageValidatorFactory" />

在Martin建议之后,我尝试反编译ibm代码,我认为问题出在这个过程中:

private SOAPEnvelope _getSOAPEnvelope()
    throws WebServicesFault
{
    SOAPEnvelope soapEnvelope = _getCachedSOAPEnvelope();
    if(soapEnvelope == null)
        if(currentForm == 4)
        {
            soapEnvelope = (SOAPEnvelope)getCurrentMessage();
        } else
        {
            if(log.isDebugEnabled())
                log.debug("Converting " + formNames[currentForm] + " to " + formNames[4]);
            MessageContext mc = getMessage().getMessageContext();
            if(mc != null)
                if(mc.isHighFidelity())
                {
                    if(originalContent == null)
                        originalContent = _getCachedWebServicesInputSource();
                } else
                {
                    originalContent = null;
                }
            WebServicesInputSource wsis = _getWebServicesInputSource();
            if(log.isDebugEnabled())
                log.debug("Parsing inputSource " + wsis.dumpStats());
            String encoding = getMessage().getCharacterEncoding();
            if(encoding != null)
                wsis.setEncoding(encoding);
            DeserializationContext dser = new DeserializationContextImpl(wsis, getMessage().getMessageContext(), getMessage().getMessageType(), getMessage().getSOAPConstants(), Utils._isSAAJ13Enabled());
            try
            {
                dser.parse();
            }
            catch(SAXException e)
            {
                FFDCFilter.processException(e, "com.ibm.ws.webservices.engine.SOAPPart.getSOAPEnvelope", "964", this);
                Exception real = e.getException();
                wsis.reset();
                if(real instanceof WebServicesFault)
                    throw (WebServicesFault)real;
                if(originalContent == null)
                    originalContent = wsis;
问题部分:

                if(originalContent == null)// I am not sure but I think this will never happend. So to fix it I will delete this condition and  throw this 
exception not the second one where it want to display message
                        throw WebServicesFault.makeFault("To see the message containing the parsing error in the log, either enable web service engine tracing or set MessageContext.setHighFidelity(true).", ((Throwable) (real == null ? ((Throwable) (e)) : ((Throwable) (real)))));
                    else
                        throw WebServicesFault.makeFault("Message being parsed: " + originalContent.getString(), ((Throwable) (real == null ? ((Throwable) (e)) : ((Throwable) (real)))));
                }
                if(log.isDebugEnabled())
                    log.debug("Done parsing inputSource.");
                originalParseLength = wsis.getContentLength();
                soapEnvelope = dser.getEnvelope();
                setCurrentForm(soapEnvelope, 4);
                String messageProtocol = getMessage().getSOAPConstants().getSOAPProtocol();
                String factoryProtocol = soapEnvelope.getSOAPFactory().getSOAPConstants().getSOAPProtocol();
                String envelopeProtocol = "SOAP 1.1 Protocol";
                String ns = soapEnvelope.getNamespaceURI();
                if(soapEnvelope.getNamespaceURI().equals("http://schemas.xmlsoap.org/soap/envelope/"))
                    envelopeProtocol = "SOAP 1.2 Protocol";
                if(messageProtocol.equals("Dynamic Protocol"))
                {
                    getMessage().setSOAPConstants(soapEnvelope.getSOAPFactory().getSOAPConstants());
                    messageProtocol = getMessage().getSOAPConstants().getSOAPProtocol();
                }
                if(envelopeProtocol.equals(factoryProtocol) && factoryProtocol.equals(messageProtocol))
                {
                    if(log.isDebugEnabled())
                        log.debug("The protocol is: " + envelopeProtocol);
                } else
                if(log.isDebugEnabled())
                {
                    log.debug("The SOAPEnvelope protocol is: " + envelopeProtocol);
                    log.debug("The SOAPFactory protocol is: " + factoryProtocol);
                    log.debug("The SOAPMessage protocol is: " + messageProtocol);
                }
            }
        return soapEnvelope;
    }

这看起来像一个Websphere错误。使用Spring WS,我得到了一些错误:

java.lang.OutOfMemoryError:java堆空间 位于com.ibm.ws.webservices.utils.BAIS.create(BAIS.java:74)

我设法以这种方式解决了这个问题:放入/AppServer/lib/ext这个库:axis2-saaj-1.6.2.jar(在WebSphereV8.5和SpringWSV2.2.0上为我工作,但您可能需要更改版本)

解释

当SpringWS请求javax.xml.soap.MessageFactory实现时,它会得到一个com.ibm.WS.webservices.engine.soap.messagefactorympl实例(来自Websphere运行时),而不是一个com.sun.xml.internal.messaging.saaj.soap.messagefactorympl实例(来自JVM),这导致了上述错误。 axis2 saaj库还包含一个javax.xml.soap.MessageFactory实现:org.apache.axis2.saaj.MessageFactoryImpl。现在,当axis2 saaj位于lib/ext文件夹中且错误消失时(我还配置了父类路径,不知道这是否重要)

更新


@hudi您的解决方案是正确的,我刚刚测试了它。遗憾的是,我无法给您投票。

客户在SDK 1.7中使用WebSphere 8.5.5.x,并在Spring frmae work中使用SAAJ,在发送具有无效请求的SOAP请求时可能会遇到OutOfMemoryError。这是由于SDK 1.7和更高版本中出现了修复

IBM已通过IBM SDK APAR IV73614修复了此问题

bug修复的详细信息在以后的版本中发布

JAVA.IO.PACKEDINPUTSTREAM.AVAILABLE() RETURNS INTEGER.MAX_VALUE I.E., 2147483647 ON EMPTY STREAM IN JAVA 7

From javacore stack indicate following 4XESTACKTRACE at com/ibm/ws/webservices/utils/BAIS.create(BAIS.java:74) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getBAISContent(WebServicesInputSource.java:744) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getByteArrayContent(WebServicesInputSource.java:710) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getStringContent(WebServicesInputSource.java:674) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getString(WebServicesInputSource.java:425(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/webservices/engine/SOAPPart._getSOAPEnvelope(SOAPPart.java:1090(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/webservices/engine/SOAPPart.getAsSOAPEnvelope(SOAPPart.java:628(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/webservices/engine/SOAPPart.getEnvelope(SOAPPart.java:656(Compiled Code)) 4XESTACKTRACE at org/springframework/ws/soap/saaj/support/SaajUtils.getSaajVersion(SaajUtils.java:155) 4XESTACKTRACE at org/springframework/ws/soap/saaj/SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:257) 4XESTACKTRACE at org/springframework/ws/soap/saaj/SaajSoapMessage.getImplementation(SaajSoapMessage.java:342(Compiled Code))

请参阅IBM开发人员工作日志


您解决了这个问题吗?我也遇到了同样的问题。没有。您是否已经尝试扩展JVM设置的堆sace?还没有,因为当我发送有效的xml时,我看不出它工作的原因message@ZeusNet尝试过但没有成功I am validation xml但是websphere的东西在这个validation之前你能描述吗如何验证?您想描述什么?我有类似于您发布的验证如果您已经定义了验证拦截器,那么应该在调用基于websphere的库来实际解析消息之前调用此拦截器…因此,如果xml无效,处理应该在消费者出现SOAP错误的情况下停止….做一件事,定义ne用户定义的自定义拦截器和
private SOAPEnvelope _getSOAPEnvelope()
    throws WebServicesFault
{
    SOAPEnvelope soapEnvelope = _getCachedSOAPEnvelope();
    if(soapEnvelope == null)
        if(currentForm == 4)
        {
            soapEnvelope = (SOAPEnvelope)getCurrentMessage();
        } else
        {
            if(log.isDebugEnabled())
                log.debug("Converting " + formNames[currentForm] + " to " + formNames[4]);
            MessageContext mc = getMessage().getMessageContext();
            if(mc != null)
                if(mc.isHighFidelity())
                {
                    if(originalContent == null)
                        originalContent = _getCachedWebServicesInputSource();
                } else
                {
                    originalContent = null;
                }
            WebServicesInputSource wsis = _getWebServicesInputSource();
            if(log.isDebugEnabled())
                log.debug("Parsing inputSource " + wsis.dumpStats());
            String encoding = getMessage().getCharacterEncoding();
            if(encoding != null)
                wsis.setEncoding(encoding);
            DeserializationContext dser = new DeserializationContextImpl(wsis, getMessage().getMessageContext(), getMessage().getMessageType(), getMessage().getSOAPConstants(), Utils._isSAAJ13Enabled());
            try
            {
                dser.parse();
            }
            catch(SAXException e)
            {
                FFDCFilter.processException(e, "com.ibm.ws.webservices.engine.SOAPPart.getSOAPEnvelope", "964", this);
                Exception real = e.getException();
                wsis.reset();
                if(real instanceof WebServicesFault)
                    throw (WebServicesFault)real;
                if(originalContent == null)
                    originalContent = wsis;
                if(originalContent == null)// I am not sure but I think this will never happend. So to fix it I will delete this condition and  throw this 
exception not the second one where it want to display message
                        throw WebServicesFault.makeFault("To see the message containing the parsing error in the log, either enable web service engine tracing or set MessageContext.setHighFidelity(true).", ((Throwable) (real == null ? ((Throwable) (e)) : ((Throwable) (real)))));
                    else
                        throw WebServicesFault.makeFault("Message being parsed: " + originalContent.getString(), ((Throwable) (real == null ? ((Throwable) (e)) : ((Throwable) (real)))));
                }
                if(log.isDebugEnabled())
                    log.debug("Done parsing inputSource.");
                originalParseLength = wsis.getContentLength();
                soapEnvelope = dser.getEnvelope();
                setCurrentForm(soapEnvelope, 4);
                String messageProtocol = getMessage().getSOAPConstants().getSOAPProtocol();
                String factoryProtocol = soapEnvelope.getSOAPFactory().getSOAPConstants().getSOAPProtocol();
                String envelopeProtocol = "SOAP 1.1 Protocol";
                String ns = soapEnvelope.getNamespaceURI();
                if(soapEnvelope.getNamespaceURI().equals("http://schemas.xmlsoap.org/soap/envelope/"))
                    envelopeProtocol = "SOAP 1.2 Protocol";
                if(messageProtocol.equals("Dynamic Protocol"))
                {
                    getMessage().setSOAPConstants(soapEnvelope.getSOAPFactory().getSOAPConstants());
                    messageProtocol = getMessage().getSOAPConstants().getSOAPProtocol();
                }
                if(envelopeProtocol.equals(factoryProtocol) && factoryProtocol.equals(messageProtocol))
                {
                    if(log.isDebugEnabled())
                        log.debug("The protocol is: " + envelopeProtocol);
                } else
                if(log.isDebugEnabled())
                {
                    log.debug("The SOAPEnvelope protocol is: " + envelopeProtocol);
                    log.debug("The SOAPFactory protocol is: " + factoryProtocol);
                    log.debug("The SOAPMessage protocol is: " + messageProtocol);
                }
            }
        return soapEnvelope;
    }
JAVA.IO.PACKEDINPUTSTREAM.AVAILABLE() RETURNS INTEGER.MAX_VALUE I.E., 2147483647 ON EMPTY STREAM IN JAVA 7

From javacore stack indicate following 4XESTACKTRACE at com/ibm/ws/webservices/utils/BAIS.create(BAIS.java:74) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getBAISContent(WebServicesInputSource.java:744) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getByteArrayContent(WebServicesInputSource.java:710) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getStringContent(WebServicesInputSource.java:674) 4XESTACKTRACE at com/ibm/ws/webservices/utils/WebServicesInputSource.getString(WebServicesInputSource.java:425(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/webservices/engine/SOAPPart._getSOAPEnvelope(SOAPPart.java:1090(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/webservices/engine/SOAPPart.getAsSOAPEnvelope(SOAPPart.java:628(Compiled Code)) 4XESTACKTRACE at com/ibm/ws/webservices/engine/SOAPPart.getEnvelope(SOAPPart.java:656(Compiled Code)) 4XESTACKTRACE at org/springframework/ws/soap/saaj/support/SaajUtils.getSaajVersion(SaajUtils.java:155) 4XESTACKTRACE at org/springframework/ws/soap/saaj/SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:257) 4XESTACKTRACE at org/springframework/ws/soap/saaj/SaajSoapMessage.getImplementation(SaajSoapMessage.java:342(Compiled Code))