В нашем приложении мы используем Apache Camel с компонентом camel-cdi
в среде JBoss EAP 7.1. После обновления Apache Camel до актуальной версии приложение стало некорректно работать при параллельном выполнении.
Я обнаружил, что компонент компонента всегда вызывает один и тот же экземпляр. Насколько я понимаю, bean-компонент с областью действия @Dependent
всегда должен быть свежим экземпляром для каждого поиска CDI.
Я пробовал параметр конечной точки cache=false
, который должен быть значением по умолчанию, но поведение остается прежним. Также попытался указать @Dependent
, что также должно быть по умолчанию.
Присоединение MCVE, которое не работает на Apache Camel 2.20.0
и новее. Хорошо работает с 2.19.5
и старше. Полностью воспроизводимый проект на Github .
@ApplicationScoped
@Startup
@ContextName("cdi-context")
public class MainRouteBuilder extends RouteBuilder {
public void configure() throws Exception {
from("timer:test")
.to("bean:someDependentBean?cache=false");
}
}
@Named
//@Dependent //Dependent is default
public class SomeDependentBean implements Processor {
private int numOfInvocations = 0;
private static Logger log = LoggerFactory.getLogger(SomeDependentBean.class);
public void process(Exchange exchange) throws Exception {
log.info("This is: "+toString());
numOfInvocations++;
if (numOfInvocations!=1){
throw new IllegalStateException(numOfInvocations+"!=1");
} else {
log.info("OK");
}
}
}
Что я могу сделать в нашем приложении, чтобы изменить это поведение и использовать актуальную версию Apache Camel?
EDIT:
Удаление тегов camel-cdi
и jboss-weld
. Я создал модульный тест, чтобы смоделировать эту ситуацию без зависимостей от camel-cdi и Weld. Этот тест содержит утверждение для проверки JndiRegistry#lookup
, который возвращает правильный экземпляр. В соответствии с этим тестом, я считаю, проблема заключается в самом компоненте бобов. Сбой с версией> = 2.20.0
и передачей с <= <code>2.19.5
public class CamelDependentTest extends CamelTestSupport {
private Context context;
private JndiRegistry registry;
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:in")
.to("bean:something?cache=false");
}
};
}
@Override
protected JndiRegistry createRegistry() throws Exception {
JndiRegistry registry = super.createRegistry();
registry.bind("something", new SomeDependentBean());
this.context = registry.getContext();
this.registry = registry;
return registry;
}
@Test
public void testFreshBeanInContext() throws Exception{
SomeDependentBean originalInstance = registry.lookup("something", SomeDependentBean.class);
template.sendBody("direct:in",null);
context.unbind("something");
context.bind("something", new SomeDependentBean()); //Bind new instance to Context
Assert.assertNotSame(registry.lookup("something"), originalInstance); //Passes, the issue is not in JndiRegistry.
template.sendBody("direct:in",null); //fails, uses cached instance of SameDependentBean
}
}