Uploaded image for project: 'Batik'
  1. Batik
  2. BATIK-954

NPE in EventListenerList (Concurrency)

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Resolution: Unresolved
    • Affects Version/s: 1.7
    • Fix Version/s: None
    • Component/s: SVG DOM
    • Labels:
      None
    • Environment:
      Operating System: Windows XP
      Platform: PC

      Description

      not repeatable, not clearly reproducable. bug occurs frequently in our Jemmy application GUI tests.

      java.lang.NullPointerException
      at org.apache.batik.dom.events.EventListenerList.removeListener(EventListenerList.java:88)
      at org.apache.batik.dom.events.EventSupport.removeEventListenerNS(EventSupport.java:180)
      at org.apache.batik.dom.AbstractNode.removeEventListenerNS(AbstractNode.java:991)
      at org.apache.batik.dom.svg.SVGOMDocument.removeCSSNavigableDocumentListener(SVGOMDocument.java:473)
      at org.apache.batik.css.engine.CSSEngine.removeEventListeners(CSSEngine.java:487)
      at org.apache.batik.css.engine.CSSEngine.dispose(CSSEngine.java:516)
      at org.apache.batik.bridge.BridgeContext.removeDOMListeners(BridgeContext.java:1291)
      at org.apache.batik.bridge.BridgeContext.dispose(BridgeContext.java:1444)
      at org.apache.batik.swing.svg.AbstractJSVGComponent.installSVGDocument(AbstractJSVGComponent.java:721)
      at org.apache.batik.swing.JSVGCanvas.installSVGDocument(JSVGCanvas.java:591)
      at org.apache.batik.swing.svg.AbstractJSVGComponent$2.run(AbstractJSVGComponent.java:679)

      I guess it's because we do call AbstractJSVGComponent's setSVGDocument frequently. I assume while one call of setSVGDocument still processes its installSVGDocument, another thread also tries to remove listeners.

      Code in EventListenerList, which causes NPE, is eht "else if" condition:

      else if (head != null
      && (namespaceURI != null && namespaceURI.equals(head.namespaceURI)

      namespaceURI == null && head.namespaceURI == null)
      && listener == head.listener) { head = head.next; }

      The only reason for NPE that I can figure out is, that the member "head" in thread A passes the "head != null" condition, then thread B already processes head=head.next (what may set head = NULL), and then thread A resumes with accessing head.namecpaceURI or head.listener -> NPE.

      What about assigning head to a local variable before entering the IF condition; and using the local variable for the conditions (and as source for assignment)?

        Attachments

          Activity

            People

            • Assignee:
              batik-dev@xmlgraphics.apache.org Batik Developer's Mailing list
              Reporter:
              christoph.bimminger@systema.info Christoph Bimminger
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: