1

The answer of this question describes that it is possible to sort CDI events with the @Priority annotation.

Execution order of different CDI Events in same transaction

Since CDI 2.0 (check here, Chapter 10.5.2), you may define an order using the @Priority annotation and specifying a number as its value. Observers with smaller priority values are called first and observers with no @Priority annotation gets de default priority (Priority.APPLICATION + 500). As with CDI 1.2, observers with same priority does not have any previously defined order and may be called by CDI container in any order.

CDI 2.0 observer ordering does not apply to asynchronous observer methods (per spec), as it's expected that observer methods get called as soon as it is possible and in different contexts. If you need some kind of ordering in you use case, you should make your asynchronous observer trigger the next event, instead of calling it from your "main" method.

So even if i fire Two different Event-Objects the order is not specified? – Noixes Jul 22 '20 at 6:45

Yes. Unless you are using CDI 2 and defining different priorities, the order is unspecified. You must realize that you may "discover" the order of a given implementation in such cases, but it is not recommended to rely on it because a future version of the same implementation may change it without colliding with the spec. –

But it doesn't work in my example:

@Stateless
public class EventTest {

  @Inject
  @QualifierA
  private Event<String> eventA;

  @Inject
  @QualifierB
  private Event<String> eventB;


  @Test
  public void test() throws VerarbeitungsException {
    eventB.fire("B");
    eventA.fire("A");
  }

  public void observerA(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 1) @QualifierA String xml) {
    send(xml);
  }

  public void observerB(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 2) @QualifierB String xml) {
    send(xml);
  }

  private void send(String xml){
    System.out.println(xml);
  }
}

In my testclass I fire event B and then A. The test log show B/A but I woud expact A/B as defined with @Priority. Im using WildFly14 with CDI 2.0. Does sorting of Events only work for observer for the same event/qualifier?

NF117
  • 13
  • 3

2 Answers2

1

The ordering is between observers of the same event. But you defined two events, with different qualifiers.

To properly test the priority you should fire only one event, and set two observers for that event.

For example:

@Stateless
public class EventTest {

  @Inject
  @QualifierA
  private Event<String> eventA;


  @Test
  public void test() throws VerarbeitungsException {
    eventA.fire("A");
  }

  public void observerA(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 1) @QualifierA String xml) {
    send("A: " + xml);
  }

  public void observerB(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 2) @QualifierB String xml) {
    send("B: " + xml);
  }

  private void send(String xml){
    System.out.println(xml);
  }
}
areus
  • 2,880
  • 2
  • 7
  • 17
  • Thank you for your confirmation. I find the spec: [CDI 2.0 observer_ordering](https://docs.jboss.org/cdi/spec/2.0-PRD/cdi-spec.html#observer_ordering) Before the actual observer notification, the container determines an order in which the observer methods for a **certain** event are invoked. – NF117 Aug 18 '21 at 15:50
0

Event qualifiers

The event qualifiers act as topic selectors, allowing the consumer to narrow the set of events it observes. An event qualifier may be an instance of any qualifier type. Observer methods

An observer method allows the application to receive and respond synchronously to event notifications. And an async observer method allows the application to receive and respond asynchronously to event notifications. they both act as event consumers, observing events of a specific type, with a specific set of qualifiers. Any Java type may be observed by an observer method.

An observer method is a method of a bean class or extension with a parameter annotated @Observes or @ObservesAsync.

An observer method will be notified of an event if:

the event object is assignable to the type observed by the observer method,
the observer method has all the event qualifiers of the event, and
either the event is not a container lifecycle event, or the observer method belongs to an extension.

Blockquote

In your code, you are specifically requesting that it observes events with different qualifiers. The ordering will not not be enforced.

Change it to and try:

  public void observesFirst(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 1) String xml) {
    send(xml);
  }

  public void observesSecond(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 2) String xml) {
    send(xml);
  }
JCompetence
  • 6,997
  • 3
  • 19
  • 26
  • Ok @Priority is only helpful to control the order of several observer for same event. In my application I want to control the order in which the messages are sent. If I define two observers for the same event every message sent twice. – NF117 Aug 18 '21 at 15:32