Question

So I have an EAR that reads messages from a JMS queue. As per requirement the messages are XML data. I read the data from queue, unmarshall it using JAXB and save the xml data into database. But this whole process takes 90-95% usage of my CPU. I followed up the changes suggested in this link so as to reduce my CPU usage. But even after implementing those it still uses 90% of mu CPU till all messages in queue are processed.

Note that I have created a separate hibernatePersistance.jar which is where I have implemented the JAXB unmarshalling. The hibernate.cfg.xml file is also inside the jar. Is this what I think might be the problems for high usage?

Does having a separate jar for persistence establishes and closes database connections each time the save() function is called which might be causing high CPU usage or its something else?

Here is the code

**MDB Listener Class**

/**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message message) {
        try {
            if (message instanceof BytesMessage) {
                BytesMessage bytesMessage = (BytesMessage) message;
                StringBuffer buffer = new StringBuffer();
                for (int i = 0; i < (int) bytesMessage.getBodyLength(); i++) {
                    buffer.append((char) bytesMessage.readByte());
                }
                String cbeXml = buffer.toString().trim();
                persistAuditMessage(cbeXml);
            } else if (message instanceof TextMessage) {
                TextMessage textMessage = (TextMessage) message;
                persistAuditMessage(textMessage.getText());
            }

        } catch (JMSException e) {
            e.printStackTrace();
        } catch (Exception jmse) {
            jmse.printStackTrace();
        }
    }

    private void persistAuditMessage(String auditMessage) {
        // for without Session Bean Call
        count++;
        if (auditMessage != null && auditMessage.trim().length() != 0) {
            MarshalImpl impl = new MarshalImpl();
            impl.saveCbeXml(auditMessage);

        }


    }

Class inside Persistence JAR

public class MarshalImpl extends AbstractHibernateLayar<BaseEvent, Long> implements Marshal {

    private static Logger logger = LoggerFactory.getLogger(MarshalImpl.class);
    private static JAXBContext context = null;

    public static synchronized JAXBContext createJAXBContext() throws JAXBException {
        if (context == null) {
            System.out.println("Creating jaxb context");
            context = JAXBContext.newInstance(BaseEvents.class.getPackage().getName());
        }
        return context;
    }




    public MarshalImpl() {
        super();
    }


    @Override
    public void saveCbeXml(String auditMessage) {
        try {



            Unmarshaller unmarshaller = createJAXBContext().createUnmarshaller();
        @SuppressWarnings("unchecked")
        JAXBElement<BaseEvents> root = (JAXBElement<BaseEvents>) unmarshaller.unmarshal(new StreamSource(new StringReader(auditMessage)));
        List<BaseEvent> baseEvent = root.getValue().getCommonBaseEvent();
            // Persist BaseEvent one by one
            for (BaseEvent event : baseEvent) {
                event.setSequenceNumber(new Long(1));// Indicate Working Flag
                event.setCreationTimeItem(new Date());
                save(event);

            }

        } catch (Exception e) {
            logger.error("MarshalImpl::saveCbeXml::CBE Records not inserted!!::" + e.getMessage(), e);
        } finally {
            System.gc();

        }
    }
Was it helpful?

Solution

Well what do you know... I got the answer to my question in question itself. The comments in the bloglink mentioned in the question also told that I needed to have particular jaxb jar.

Comment that gave my answer

FYI this problem does not happen with jaxb-impl 2.2.4 and newer (though not sure in which version exactly it was changed).So now you can either use latest JDK 7u7 (which should contain jaxb-impl 2.2.4) or add jaxb-impl 2.2.6 to your project. It still happens with JDK 6u35 (which has 2.1.10 according to http://jaxb.java.net/guide/Which_JAXB_RI_is_included_in_which_JDK_.html). Last info it does not happen on JBoss 7.1.1 which bundles jaxb-impl 2.2.4). Then you can use old way and no need to implement any cache for JAXBContext to avoid repeated class loading.

I was using jaxb2.2.4 jar..So including jaxb2.2.6 jar solved my problem and guess what.. It reduced my CPU usage to mere 30% and it processed 500 queue messages in just less than 1 min:)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top