Hot questions for Using Enterprise JavaBeans in java 8

Question:

Given the following interface:

public interface MyRunnable {   
    public MyResponse run(int x);
}

It is implemented by two @Stateless beans:

@Stateless
public class Bean1 implements MyRunnable {

     public MyResponse run(int x) {
           // some logic
     }
}


@Stateless
public class Bean2 implements MyRunnable {

     public MyResponse run(int x) {
           // some logic
     }
}

Now, I want to run one bean or the other depending on a condition. What is the best way to achieve that?

This is what I tried, unsuccessfully:

@Stateless
@LocalBean
public class MainBean {

   @Inject 
   private Bean1 bean1;

   @Inject 
   private Bean2 bean2;

   public void someMethod(int y) {

          MyRunnable runnable = null;
          if (y == 1)
              runnable = bean1;
          else
              runnable = bean2;

          runnable.run(5);

   }
}

The code compiles, but it gives me (in Wildfly) a startup error:

WELD-001408: Unsatisfied dependencies for type Bean1 with qualifiers @Default

UPDATE Something that I noticed; if I remove implements MyRunnable from the beans there are no startup errors.


Answer:

Since you're implementing the same interface in Bean1 and Bean2 they are mapped to to MyRunnable (they are now @Local beans). Since Weld does not know how to resolve this you would need to specify which bean you would like to inject. The proper way would be:

@Stateless
public class MyBean {

  @EJB(beanName = "Bean1")
  MyRunnable bean1;

  @EJB(beanName = "Bean2")
  MyRunnable bean2;

  public void run() {
    MyRunnable r = Math.random() < 0.5d ? bean1 : bean2;
    r.run(10);
  }
}

Question:

In Java SE I used to call a singleton instance method this way:

MySingleton.getInstance().method();

Now, in Java EE 8 I have a @Singleton bean. How can I call a method? Do I have to inject the Singleton instance in the caller?

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class MySingletonBean {

  @Lock(LockType.WRITE)
  public void method() {
    // .....
  }

}

Answer:

Do I have to inject the Singleton instance in the caller?

Yes, that's the preferred approach.

Just do

@Inject
private MySingletonBean name;