当我向websphere服务器上的web服务发送无效的xml时,我得到了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>
使用元素
<MyElement>something</MyElement>
一切正常
例外:
java.lang.OutOfMemoryError: Java heap space
at com.ibm.ws.webservices.utils.BAIS.create(BAIS.java:74) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.utils.WebServicesInputSource.getBAISContent(WebServicesInputSource.java:744) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.utils.WebServicesInputSource.getByteArrayContent(WebServicesInputSource.java:710) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.utils.WebServicesInputSource.getStringContent(WebServicesInputSource.java:674) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.utils.WebServicesInputSource.getString(WebServicesInputSource.java:425) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.engine.SOAPPart._getSOAPEnvelope(SOAPPart.java:1090) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.engine.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:628) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.webservices.engine.SOAPPart.getEnvelope(SOAPPart.java:656) ~[com.ibm.ws.runtime.jar:?]
at org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion(SaajUtils.java:155) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.soap.saaj.SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:257) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.soap.saaj.SaajSoapMessage.getImplementation(SaajSoapMessage.java:342) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.soap.saaj.SaajSoapMessage.<init>(SaajSoapMessage.java:117) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:186) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:60) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:90) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:86) ~[spring-ws-core-2.1.0.RELEASE.jar:?]
编辑:
没人知道?
PS:弹簧验证没有帮助,因为它是在websphere之后。当我发送无效的xml agains xsd(例如字符串而不是数字)时,它可以工作:
2015-02-18 10:12:46.128 [WebContainer : 8] WARN cz.isvs.ais3.ws.interceptor.ServerPayloadValidatingInterceptor - XML validation error on request: cvc-datatype-valid.1.2.1: 'b' is not a valid value for 'integer'.
2015-02-18 10:12:46.128 [WebContainer : 8] WARN cz.isvs.ais3.ws.interceptor.ServerPayloadValidatingInterceptor - XML validation error on request: cvc-type.3.1.3: The value 'b' of element 'urn1:Ais' is not valid.
因为WebServiceMessageReceiverObjectSupport.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:?]
答案 0 :(得分:2)
最好的方法是使用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"/>
有关详细信息,请阅读spring documentation
答案 1 :(得分:2)
你刚发现了一个错误。请报告错误。因为这与解析有关。你可以做两件事。
首先,您可以进行内存转储。只需转储内存(或使用visualvm进行配置文件并运行内存配置文件)。通过这种方式,您可以了解内存的监控行为。
其次,您可以更正找到的问题。我用第三方代码一直这样做。因此,在他们进入解析代码段之前,您需要执行另一个步骤来评估xml是否正确而不检查shema。只需使用一个没有涉及shema的解析器运行。
为了提供修改后的实现,请使用源代码,如果不可用,请对其进行反编译或重命名,并提供一个新的实现类。如果它是私有方法或功能,则只需修改字节代码即可访问。
为了注入你的版本,只需将你的类添加到你的类路径(或websphere的类路径)中,然后将它放在它前面。通常,您的代码都适用于任何库代码。这样,只要您控制类路径(通常通过在java.exe中设置它),您就可以覆盖任何库的每个实现细节。
因此,在发布此错误版本之前,只需添加一个额外的测试以确保正确性。并报告错误以及博客。
如果您有疑问或需要工具建议,请询问。我经常这样做。使用开源和非开源软件。也适用于扩展功能等其他功能。
答案 2 :(得分:2)
在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;
}
答案 3 :(得分:2)
这看起来像是一个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(在Websphere v8.5和Spring-WS v2.2.0上为我工作,但你可以必须改变版本。)
<强>解释强>
当Spring-WS请求javax.xml.soap.MessageFactory实现时,它会获取com.ibm.ws.webservices.engine.soap.MessageFactoryImpl实例(来自Websphere运行时)而不是com.sun.xml.internal .messaging.saaj.soap.MessageFactoryImpl实例(来自JVM),导致上述错误。 axis2-saaj库还包含javax.xml.soap.MessageFactory实现:org.apache.axis2.saaj.MessageFactoryImpl。当axis2-saaj在lib / ext文件夹中时,现在使用了这个,并且错误消失了(我还配置了PARENT LAST类路径,不知道这里是否重要)
<强>更新强>
@hudi你的解决方案是正确的,我只是测试了它。可悲的是,不能投票给你。
答案 4 :(得分:2)
请参阅IBM developer wroks post
答案 5 :(得分:1)
我试图通过自己解决这个问题。我检查了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);
}
}
在春天的上下文中我添加:
<bean id="messageFactory" class="cz.isvs.ais3.ws.validator.SaajSoapMessageValidatorFactory" />
答案 6 :(得分:1)
在发送具有无效请求的SOAP请求时,使用WebSphere 8.5.5.x和SDK 1.7并将SAAJ与Spring frmae工作一起使用的客户可能会遇到OutOfMemoryError。这是因为bug修复了SDK 1.7及更高版本。
IBM已通过IBM SDK APAR IV73614修复了此问题。
错误修复的详细信息在以后的版本中进行了
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))