Skip to content
This repository has been archived by the owner on Jul 11, 2019. It is now read-only.

DefinitionException for CommandBus producer #21

Open
hwellmann opened this issue Oct 1, 2018 · 3 comments
Open

DefinitionException for CommandBus producer #21

hwellmann opened this issue Oct 1, 2018 · 3 comments

Comments

@hwellmann
Copy link

Using the following producer method for CommandBus

    @Produces
    @Typed(CommandBus.class)
    @ApplicationScoped
    public CommandBus commandBus(Configuration configuration) {
        CommandBus commandBus = configuration.commandBus();
        commandBus.registerDispatchInterceptor(new BeanValidationInterceptor<>());
        return commandBus;
    }

my application fails to start with a DefinitionException

Caused by: org.jboss.weld.exceptions.DefinitionException: Exception List with 1 exceptions:
Exception 0 :
org.jboss.weld.exceptions.IllegalArgumentException: WELD-001456: Argument resolvedBean must not be null
	at org.jboss.weld.util.Preconditions.checkArgumentNotNull(Preconditions.java:40)
	at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:752)
	at org.jboss.weld.injection.ParameterInjectionPointImpl.getValueToInject(ParameterInjectionPointImpl.java:76)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.getParameterValues(StaticMethodInjectionPoint.java:134)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:85)
	at org.jboss.weld.injection.producer.ProducerMethodProducer.produce(ProducerMethodProducer.java:103)
	at org.jboss.weld.injection.producer.AbstractMemberProducer.produce(AbstractMemberProducer.java:161)
	at org.axonframework.cdi.AxonCdiExtension.produce(AxonCdiExtension.java:896)
	at org.axonframework.cdi.AxonCdiExtension.afterBeanDiscovery(AxonCdiExtension.java:535)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:95)
	at org.jboss.weld.injection.MethodInvocationStrategy$SpecialParamPlusBeanManagerStrategy.invoke(MethodInvocationStrategy.java:144)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:330)
	at org.jboss.weld.event.ExtensionObserverMethodImpl.sendEvent(ExtensionObserverMethodImpl.java:123)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:308)
	at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:286)
	at javax.enterprise.inject.spi.ObserverMethod.notify(ObserverMethod.java:124)
	at org.jboss.weld.util.Observers.notify(Observers.java:166)
	at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:285)
	at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:273)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:177)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:171)
	at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:53)
	at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:44)
	at org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl.fire(AfterBeanDiscoveryImpl.java:75)
	at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:456)
	at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:86)
	at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:97)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1736)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1698)
	at org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1556)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
	at java.lang.Thread.run(Thread.java:748)

	at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:46)
	at org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl.fire(AfterBeanDiscoveryImpl.java:75)
	at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:456)
	at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:86)
	at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:97)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1736)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1698)
	... 6 more

This is one of the issues I mentioned in #7. The CommandBus producer method should not be invoked explicitly by the extension. The invocation fails since the Configuration bean to be injected is not yet available at this stage.

@m-reza-rahman m-reza-rahman self-assigned this Oct 1, 2018
@zambrovski
Copy link

@hwellmann - I observed this too. Is there a way to use a CDI concept (I thought this should be a Producer, but I seem to be mistaken) to mark methods that should produce instances?

An alternative is to let the container produce beans and and retrieve the beans using the BeanManager. This would mean, that the entire Axon Configuration startup needs to be executed after the CDI is up and running. In doing so, the portable extension would only collect the annotated producer methods and provide defaults in case there are none and the entire wiring must happen AFTER the CDI is up and running using some late application event.

Does this make sence, then?

(Just to explain the idea behind current code: in Spring it is ok to hook up into the BeanFactory and call producer methods...)

@m-reza-rahman
Copy link
Contributor

Simon, what you suggested is indeed one of the very approaches I am trying to pursue. Unfortunately it is not that simple since we need to make some beans injectable ourselves including repositories and saga factories that are not just static definitions but dynamic, with a parameterized type and inside a loop. In addition, we need to actually build or start the configuration before we an make the beans injectable. It is a tough circular reference situation that hopefully can be solved. I am trying to unravel it, but PRs solving the issue are welcome.

In the worst case, we may need to say that for some types of customizations like the command bus, you must also supply and manage your own configuration reference. Hopefully it won't come to that.

@bert-laverman
Copy link
Contributor

Sorry to be late to this party, but I think this discussion can be solved as follows:

The recursive dependency issue (also commented on by Mark in AxonDefaultConfiguration) is caused by the idea that e.g. the CommandBus is produced by retrieving it from the configuration, which is not true. The CommandBus bean is the object you want to inject into the configuration. A default producer for it should return a SimpleCommandBus or a AxonServerCommandBus, to be used for injection into the configurer. This is how it works in Spring-land as well.

Now applications can add producers for a customized command bus, which will be picked up by the CDI extension, without referring to the configuration-to-be. Then remains the problem of ensuring that it is a singleton, but that is an issue for the BeanManager, which we are currently circumventing by calling the producer directly in CdiExtension::produce(). We need something like the BeanBuilder and BeanProvider classes from Apache DeltaSpike instead.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants