1

Using Arquillian JUnit (version 1.1.1 respectively 4.11) to setup my CDI (1.0.0.CR7 on Weld 1.1.13.Final) embedded with JDK 1.7.25....

Got the following classes:

public class Receiver {
  private String message;

  public void catching(@Observes DummyEvent event) {
    System.out.println(String.format("message [%s], hash [%d]", event.getMessage(), hashCode()));
    this.message = event.getMessage();
  }

  public String getMessage() {
    return this.message;
  }
}

public class Sender {
  @Inject @Any
  Event<DummyEvent> e;

  public void fire(String message) {
    System.out.println(String.format("fire message [%s], hash [%d]", message, hashCode()));

    DummyEvent de = new DummyEvent;
    de.setMessage(message);
    e.fire(de);
  }
}

@RunWith(Arquillian.class)
public class Example {
  @Deployment
  public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class).addClasses(Example .class, Receiver.class, Sender.class)
         .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
  }

  @Inject
  Receiver receiver;

  @Inject
  Sender sender;

  @Test
  public void dummy() {
    System.out.println(String.format("sender hash [%d]", sender.hashCode()));
    sender.fire("Hello from me");

    System.out.println(String.format("message [%s], receiver hash: [%d]",
    receiver.getMessage(), receiver.hashCode()));
  }
}

What gets printed is the following:

sender hash [785714873]
firing event [value: Hello from me], hash [785714873]
message [Hello from me], hash [632925108]
message [null], receiver hash: [1085786565]

What I don't get is why the receiver hash codes differ and the event is NOT propagated to the injected Receiver bean in the Example JUnit. Rather the event is sent to some OTHER receiver bean.

Has this something to do with scope (which should be the default @Dependent)?

Matthew Campbell
  • 1,864
  • 3
  • 24
  • 51
  • Tried with weld-se (using a WeldJUnit4Runner) and got the same results (i.e. not an Arquillian issue). – Matthew Campbell Dec 20 '13 at 09:01
  • Adding @ApplicationScoped to the Receiver and adding "notifyObserver=Reception.IF_EXISTS" to the Observes annotation stops the propagation of the event to the "OTHER" bean. Noticed that with non-conditional observation (Reception.ALWAYS) that a Receiver bean is created for every event. Not at all what I expected. – Matthew Campbell Dec 20 '13 at 09:17
  • Adding @Singleton to the Receiver gives the correct behavior but would love not to be restricted to a Singleton. Any ideas? – Matthew Campbell Dec 20 '13 at 09:36

1 Answers1

2

It looks like Receiver and Sender have no scoped defined. As a result, they'll get @Dependent as their scope. When you use @Dependent a new instance is injected at every injection point.

John Ament
  • 11,595
  • 1
  • 36
  • 45
  • Adding any scope above dependent should work for you (RequestScoped, ApplicationScoped, etc). – John Ament Jan 06 '14 at 16:16
  • John, yes-box except this questions is a spin-off from http://stackoverflow.com/questions/20050437/cdi-extension-altering-processed-type where the targeted annotated type likely with have it's own scope. And as far as I know you'll can have multiple scopes on the same managed bean (ex. if I mixed in a custom scope). – Matthew Campbell Jan 06 '14 at 21:10