3

MSSQL サーバーで dao の更新/挿入用のアプリを実行するために EJB3 を使用する JBoss Web サービス (5.1) があります。

アプリのセットアップの一部にはカスタム SOAPHandler が含まれています。これは、ByteArray[Output/Input]Stream 内のメッセージから xml を解析し、それをサーバー ログに出力するために使用されます。

ほとんどの場合、これで問題なく動作しますが、最近、大量のデータを送信している新しいクライアントを引き受けました。予算が少ない (事実上存在しない) ため、古い PC でテスト/統合サービスを実行する必要があります。 (私を信じてください、私はしたくありませんでした)。

案の定、やがて私は遭遇しました:

    2012-11-21 14:20:40,128 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]. *removed* -5) Servlet.service() for servlet *MyIface* threw exception
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.write(UTF8XmlOutput.java:394)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.write(UTF8XmlOutput.java:386)
    at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.endTag(UTF8XmlOutput.java:273)
    at com.sun.xml.bind.v2.runtime.output.NamespaceContextImpl$Element.endElement(NamespaceContextImpl.java:493)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.endElement(XMLSerializer.java:310)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
    at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
    at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)

ここでチャンク解析に関するヒントを教えてください。とりわけこのスレッドを確認しましたが、私の問題はこれに似ていますが、使用する API/アプローチがわかりません。

ここに私のハンドラがあります:

@SuppressWarnings("rawtypes")
public class MyHandler extends GenericSOAPHandler {

    private void print(InputStream input, OutputStream out) throws Exception {
        try {
            DocumentBuilder parser;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newDocumentBuilder();
            Document document = parser.parse(input);
            Transformer serializer = TransformerFactory.newInstance().newTransformer();
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            serializer.transform(new DOMSource(document), new StreamResult(out));
        } catch (TransformerException e) {
            // A fatal error occurred
            throw new Exception(e);
        }
    }


    @Override
    protected boolean handleInbound(MessageContext msgContext) {
        SOAPMessageContext soapMessageCtx = (SOAPMessageContext) msgContext;
        SOAPMessage soapMessage = soapMessageCtx.getMessage();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            soapMessage.writeTo(outputStream);
            byte[] array = outputStream.toByteArray();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(array);
            System.out.println("SOAP request message:\n");
            print(inputStream, System.out);
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    protected boolean handleOutbound(MessageContext msgContext) {
        SOAPMessageContext soapMessageCtx = (SOAPMessageContext) msgContext;
        SOAPMessage soapMessage = soapMessageCtx.getMessage();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            soapMessage.writeTo(outputStream);
            byte[] array = outputStream.toByteArray();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(array);
            System.out.println("SOAP response message:\n");
            print(inputStream, System.out);
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

}

ありがとうございました

4

0 に答える 0