`

java stax xml解析出现的一个死循环

    博客分类:
  • java
 
阅读更多

    public OfferInfo parseXml(String content) throws NumberFormatException, XMLStreamException {
        if (content == null || content.isEmpty()) {
            return null;
        }
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = null;
        try {
            reader = factory.createXMLStreamReader(new StringReader(content));
        } catch (XMLStreamException e1) {
            return null;
        }

        if (reader == null) {
            return null;
        }

        OfferInfo offerInfo = new OfferInfo();
        while (reader.hasNext()) {
            int event = 0;
            try {
                event = reader.nextTag();
            } catch (Exception e) {
            }
            switch (event) {
                case XMLStreamConstants.START_ELEMENT:
                    if (reader.getLocalName().equalsIgnoreCase(OFFER_ID)) {
                        offerInfo.setOfferId(Long.parseLong(reader.getElementText()));
                    } else if (reader.getLocalName().equalsIgnoreCase(MEMBER_ID)) {
                        offerInfo.setMemberId(reader.getElementText());
                    } else if (reader.getLocalName().equalsIgnoreCase(ACTION)) {
                        offerInfo.setAction(reader.getElementText());
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break;
            }
            //如果已经解析完需要的字段,则跳过剩余xml内容的解析,提高性能
            if(offerInfo.getOfferId() != null && offerInfo.getMemberId() != null && offerInfo.getAction() != null){
                return offerInfo;
            }
        }
        return offerInfo;

    }

 这段代码的

  try {
                event = reader.nextTag();
            } catch (Exception e) {
            }
 居然能搞出一个死循环,导致cpu跟load飙升,yonggc非常频繁

 

 

初步诊断如下:

stax在调用reader的nextTag方法时,因为格式不对,导致抛异常,本来我是只需要xml内容的三个字段,我认为如果是其他字段解析有问题,我直接忽略,所以我没打印日志,也没有跳出xml解析,而是直接解析,因为对nextTag可能不熟悉,我要的功能跟nextTag提供的不匹配,导致抛出异常之后,我又调用了该方法,然后因为nextTag抛出异常之后没有忽略当前有问题的xml内容,导致下次调用时又回到有问题的xml起始位置继续处理,重复抛出异常,这样就成为死循环了。

 

之前两个多月应用一直没问题,由于没有打印日志所以也扑捉不到当时xml的内容。

这里需要做两个教训:1.打印日志,2调用API时一定要了解API的详细处理过程,避免错误调用API导致问题;3.对于出错时event初始参数可以进行判断是否出错了,进行处理。

 

从jstack里面打印出来10几个这样的线程信息

"ActiveMQ Session Task" prio=10 tid=0x00000000451b3000 nid=0x7db7 runnable [0x00000000429ff000]
   java.lang.Thread.State: RUNNABLE
	at java.util.Arrays.copyOf(Arrays.java:2882)
	at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
	at java.lang.StringBuilder.append(StringBuilder.java:119)
	at javax.xml.stream.XMLStreamException.<init>(XMLStreamException.java:61)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:594)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1235)
	at com.alibaba.china.industry.brand.napoli.OfferNewReceiverWorker.parseXml(OfferNewReceiverWorker.java:195)
 "ActiveMQ Session Task" prio=10 tid=0x0000000046892000 nid=0x7baf runnable [0x0000000040a72000]
   java.lang.Thread.State: RUNNABLE
	at java.lang.StringBuffer.toString(StringBuffer.java:585)
	- locked <0x000000078890bc10> (a java.lang.StringBuffer)
	at java.text.MessageFormat.makeFormat(MessageFormat.java:1337)
	at java.text.MessageFormat.applyPattern(MessageFormat.java:458)
	at java.text.MessageFormat.<init>(MessageFormat.java:350)
	at java.text.MessageFormat.format(MessageFormat.java:811)
	at com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter.formatMessage(XMLMessageFormatter.java:85)
	at com.sun.xml.internal.stream.StaxErrorReporter.reportError(StaxErrorReporter.java:95)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanCDATASection(XMLDocumentFragmentScannerImpl.java:1690)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2985)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:554)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1235)
 
0
0
分享到:
评论

相关推荐

    java基础.zip

    - Java中的解析XML的库,如DOM、SAX和StAX解析器。 - JSON对象和JSON数组的Java表示,如JSONObject和JSONArray类(来自org.json库)。 - 将Java对象序列化为JSON和反序列化为Java对象的方法。 通过学习这些文档...

    华为java面试题

    - **知识点解析**:在Java中,每个源代码文件编译后都会生成一个对应的`.class`文件。这个过程是由Java编译器完成的。`.class`文件包含了类的字节码,这些字节码可以在Java虚拟机(JVM)上运行。因此,可以判断此说法...

    java 面试题 总结

    Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,...

    超级有影响力霸气的Java面试题大全文档

     Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,...

    JAVA程序员-中远面试题目

    11. **XML解析**:DOM、SAX和StAX是三种解析方式,DOM一次性加载整个文档,适合小文件;SAX事件驱动,只读取所需部分,适合大文件;StAX是流式解析,允许前后移动。 12. **权限控制**:Java的public、protected、...

    java面试题综合

    35. XML解析:DOM、SAX和StAX,XML约束如DTD、XSD。 36. SQL查询:使用子查询或窗口函数(如RANK())获取部门前两名员工。 37. 面向对象特征:封装、继承、多态。 38. Math.round():向上或向下取整,11.5变为12...

    阿里巴巴 面经

    XML解析方式** - **DOM**(Document Object Model):将XML文档解析为树形结构。 - **SAX**(Simple API for XML):逐行解析XML文档。 - **StAX**(Streaming API for XML):流式解析XML文档。 **50. Statement...

Global site tag (gtag.js) - Google Analytics