EventGateway not injected depending on handler method access modifiers

I noticed some very strange (and unexplainable for me) behaviour.

Consider the following snippet.

@Component
public class SomeEventHandler {

	@Autowired(required = true)
	private EventGateway events;

    @QueryHandler
    private List<SomeObject> query(SomeQuery query) {
        ...
    }

	@EventHandler
	public void on(SomeEvent event) {
		events.publish(new NewEvent(...);
	}

When I change the access modifier of the EventHandler method to private, the EventGateway will not be injected resulting in a NULL value. With the public access modifier, the dependency gets injected as supposed.

Removing the QueryHandler annotation and setting the access modifier (on the event handler method) to private also results in the resource being correctly injected.

Why am I not allowed to make annotated event handler methods private preventing them from being called directly by instantiating the class. Since Axon Framework is able to call any correctly annotated method, I would expect it to be a good practise to “hide” handler methods from the class’ public API. I am not sure this is Axon related or is just the way Spring behaves…

Thanks for your comment/remarks/explanation.

This seems very odd to me, @KDW.
At the moment this sounds like a potential bug to me.

So, firstly, thanks for sharing.
Secondly, to the predicament at hand, I have some questions:

  • What Java version do you use?
  • What Spring version(s) do you use?
  • What Axon version(s) do you use?
  • Do you use Spring AOP perchance?
  • Do you use Spring Boot Devtools perchance?

Thirdly, and more of a side note, I personally tend to make the entire class package private, leaving the internals accessible to everything within the class.

What Java version do you use? JDK 11.0.12
What Spring version(s) do you use? Spring Boot Starter 2.5.6
What Axon version(s) do you use? 4.5.4
Do you use Spring AOP perchance? No
Do you use Spring Boot Devtools perchance? No

Additional dependencies that could be of any interest:

  • spring-boot-starter-security (2.5.6)
  • keycloak-spring-boot-starter (18.0.0)
  • spring-boot-starter-webflux (2.5.6)
  • spring-boot-starter-validation (2.5.6)
  • hibernate-validator (6.2.0.Final)

Hey @KDW,

Quick question to try to narrow down the problem… If you do injection through constructor (making the field final and not using @Autowired), does it work?

KR,

@lfgcampos

I did the following modification in the code.

//    @Autowired
    private final EventGateway events;
	
//    @Autowired
    private final QueryGateway queries;
	
    public ProvisioningHandler(EventGateway events, QueryGateway queries) {
        this.events = events;
        this.queries = queries;
    }

    @QueryHandler
    private List<SomeObject> query(SomeQuery query) {
        ...
    }

    @EventHandler
    public void on(SomeEvent event) {
        events.publish(new NewEvent(...);
    }

Breakpoint in the constructor indicates that both the EventGateway and QueryGateway are non-NULL. As soon as the event handler method is called, events and queries variables are NULL again…

That is super strange … do you perhaps has a sample project?

@lfgcampos I uploaded a sample project to GitLab and sent you an invite to access the repository. If all went well, you should be able to find the source code.

Thanks in advance for taking a look at it :slight_smile: