0

enter image description hereWe are analyzing our springboot MQ listner application in order to evaluate performances. During method hotspots analysis we notice JAXB library spends 60% in lock time calling Constructor.newInstance.

We use this code in order to create constructur and to unmarshal our input bytes

    JAXBContext context = JAXBContext.newInstance(ApplicationData.class);
        ApplicationData aData = (ApplicationData) context.createUnmarshaller()
                .unmarshal(new StringReader(new String(input)));

We call this code snippet every time we read a new message from our MQ queue. It should be a singleton by design, but: shoulde we create it once and use the same context? Maybe in a static way?

Thanks to all.

Pietro Fragnito
  • 327
  • 1
  • 4
  • 18
  • 1
    I would strongly suggest to use the `Jaxb2Marshaller` from Spring as that does some caching. But if you don't want, reuse the `JAXBContext`, create it once and reuse. It is thread safe (the `Unmarshaller` isn't) so you can just create it once (in the constructor for instance) and reuse it. Creating a `JAXBContext` is quite a heavy operation and therefor should be as limited as possible. Also why not let Spring handle this and just let it unmarshall for you (all the Spring `@*Listener` support this, and instead of a `byte[]` use `ApplicationData` in your method signature. – M. Deinum Nov 16 '19 at 10:01
  • Thanks @M.Deinum: we are working for. Generally we are firstly evaluating for a singleton. In a next step we'll migrate to the Jaxb2 libs: we found [this example](https://stackoverflow.com/questions/44676532/how-to-use-spring-to-marshal-and-unmarshal-xml) but we have some problems in autowiring the Jaxb2marshall state variable. By the way thanks for you tip. – Pietro Fragnito Nov 19 '19 at 07:53

1 Answers1

0

I post the solution.

We solve the lock time performace using JAXBContext as a singleton

public class JAXBContextCustom {

     private static JAXBContext instance;

     private static Logger logger = LoggerFactory.getLogger(JAXBContextCustom .class);

        private JAXBContextCustom () {
        }

        public static synchronized JAXBContext initContext() {
            try {
                if (instance == null)
                    instance = JAXBContext.newInstance(ApplicationData.class);
            } catch (JAXBException e) {
                e.printStackTrace();
                logger.error("Error instantiating JAXB context");
            }
            return instance;
        }
}

In a second stage, as suggested by @M.Deinum, we will try to use Spring Jaxb2 to handle unmarshalling.

Pietro Fragnito
  • 327
  • 1
  • 4
  • 18