Java JBoss EAP 6.2中不正确的CDI/EJB注入
在JBoss EAP 6.2上的高度并发环境中,我注意到封送实体时出现错误:Java JBoss EAP 6.2中不正确的CDI/EJB注入,java,jakarta-ee,jboss,java-ee-6,Java,Jakarta Ee,Jboss,Java Ee 6,在JBoss EAP 6.2上的高度并发环境中,我注意到封送实体时出现错误: 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(XMLSerializ
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)
上述异常是由于并发使用javax.xml.bind.Marshaller造成的,但根据服务实现,不存在这种可能性。以下是源代码示例:
此EJB bean由客户端使用:
@Stateless
public class CustomXmlConverter implements XmlConverter {
@Inject
private ConverterWrapper converterWrapper;
public Result convertMessage(Message m){
return converterWrapper.convert(m);
}
...
我认为转换器的实现不应该共享,但可能是
@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);
}
}
}
...
调用时,异常发生是不确定的:
marshaller.marshal(obj, os);
如果EJB是无状态的,CDIBean依赖于作用域,那么并发使用方法的原因可能是什么?我假设如果ConverterRapper有默认CDI作用域(依赖),那么一个EJB总是会有一个实例,对吗?如果你说的是对的,那么池化EJB实例的意义是什么?如何使用非线程安全的CDIBean?它不违反EJB规范吗?无论如何,将ConverterRapperImpl更改为@RequestScoped bean如何?@Kayaman我不能同意您的看法,即SLSB的一个实例可以在同一时间在不同线程之间共享,您是否有任何参考资料支持此假设?