samagra-comms / outbound

0 stars 8 forks source link

Getting NullPointerException When Trying to Convert XMessage Object to XML (Outbound - FCM) #24

Closed pankajjangid05 closed 1 year ago

pankajjangid05 commented 1 year ago

We are converting the XMessage object data to XML using these dependencies javax.xml.bind.JAXBContext, Marshaller, and Unmarshaller for conversions we are getting multiple exceptions while sending the notification.

Getting Below Exceptions :

  1. java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 16 at com.sun.xml.bind.v2.util.CollisionCheckStack.pushNocheck(CollisionCheckStack.java:102) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:457) at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:298) at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:226) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:101) at messagerosa.core.model.XMessage.toXML(XMessage.java:118)

  2. java.lang.NullPointerException at com.sun.xml.bind.v2.runtime.output.NamespaceContextImpl$Element.startElement(NamespaceContextImpl.java:466) at com.sun.xml.bind.v2.runtime.XMLSerializer.endNamespaceDecls(XMLSerializer.java:258) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:653) at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:128) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:329) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:563) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:310) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:464) at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:298) at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:226) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:101) at messagerosa.core.model.XMessage.toXML(XMessage.java:118)

  3. java.util.EmptyStackException at java.base/java.util.Stack.peek(Stack.java:102) at java.base/java.util.Stack.pop(Stack.java:84) at com.sun.xml.bind.marshaller.DataWriter.endElement(DataWriter.java:252) at com.sun.xml.bind.v2.runtime.output.SAXOutput.endTag(SAXOutput.java:102) at com.sun.xml.bind.v2.runtime.output.NamespaceContextImpl$Element.endElement(NamespaceContextImpl.java:477) at com.sun.xml.bind.v2.runtime.XMLSerializer.endElement(XMLSerializer.java:285) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:311) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:464) at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:298) at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:226) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:101) at messagerosa.core.model.XMessage.toXML(XMessage.java:118)

pankajjangid05 commented 1 year ago

This is because Marshaller and Unmarshaller are not thread-safe. So when we send the notification using reactive and reactive create multiple threads to convert XMessage to XML and currently, we are creating one object of marshaller. So I think threads are changing the value or stack empty that's why we are getting these exceptions.

Solution : JAXBContext - is thread-safe and can (and must) be a singleton. Creation is an expensive operation.

Marshaller and Unmarshaller are not thread safe! You must create them every time. Creation is not expensive and takes almost no time (less than 1 millisecond).

Need to discuss with Karan & Chakshu on it.

chinmoy12c commented 1 year ago

https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#other-miscellaneous-topics-performance-and-thread-safety This documentation states that: The JAXBContext class is thread safe, but the Marshaller, Unmarshaller, and Validator classes are not thread safe.

This means that currently, the only safe way is to create a new instance of marshaller for every XML convert method call.

karntrehan commented 1 year ago

@ChakshuGautam what should be the resolution here?

My suggestion was to try to make the code block synchronised or make the parser class a singleton object.

ChakshuGautam commented 1 year ago

Hey let's create new instances and see if that solves the problem. I see that it should.

pankajjangid05 commented 1 year ago

Changes are done.

ChakshuGautam commented 1 year ago

Why is there no PR on this?

karntrehan commented 1 year ago

PR was missed here. Everything from now on would be PR - @pankajjangid05

850 notifications were triggered. 2 errors seen yesterday post deployment.