lundi 4 mai 2015

Incorrect CDI/EJB injection in JBoss EAP 6.2

In highly concurrent environment on JBoss EAP 6.2 I have noticed errors while marshaling entities:

java.lang.ArrayIndexOutOfBoundsException: -1
    at com.sun.xml.bind.v2.util.CollisionCheckStack.pushNocheck(CollisionCheckStack.java:132)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:487)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:323)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:251)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:74)

Exception above is caused by concurrent use of javax.xml.bind.Marshaller, but according to service implementation, there no such possibility. Here are samples of source code:

This EJB bean is used by client:

@Stateless
public class CustomXmlConverter implements XmlConverter {

    @Inject
    private ConverterWrapper converterWrapper;

    public Result convertMessage(Message m){
        return converterWrapper.convert(m);
    }
...

Implementation of converter that in my opinion should not be shared, but probably is...

@Named
public class ConverterWrapperImpl implements ConverterWrapper {

    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    @PostConstruct
    public void init() throws JAXBException {
        unmarshaller = JAXBContext.newInstance(XmlObjectFactory.class, ObjectFactory.class).createUnmarshaller();
        marshaller = JAXBContext.newInstance(XmlObjectFactory.class, ObjectFactory.class).createMarshaller();
        marshaller.setProperty("jaxb.formatted.output", true);
    }

    public String convert(Message m) throws JAXBException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            marshaller.marshal(obj, os);
            return new String(os.toByteArray(), "UTF-8");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                os.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
...

Exception occurence is non-deterministic, on invocation of:

 marshaller.marshal(obj, os);

What could be the reason of concurrent usage of method, if EJB is stateless and CDI bean is in scope dependent?

Aucun commentaire:

Enregistrer un commentaire