[En] How to resolve Ambiguous error in Jakarta EE with 3 different approach ?

The problem :

Imagine that you have an interface like this

public interface Notification {
   void send(String message);
}

If you implement 2 versions of this interface like this

public class NotificationImpl implements Notification{

  @Override
  public void send(String message) {
     System.out.println(" --> " + message);
  }
}
public class NotificationImpl2 implements Notification{

  @Override
  public void send(String message) {
    System.out.println("--2 " + message);
  }
}

You could get an error like this if you don’t specify which implementation you exactly want to use

Exception during lifecycle processing
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:WELD-001409: Ambiguous dependencies for type Notification with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject com.airhacks.ping.boundary.Pingy.notification
at com.airhacks.ping.boundary.Pingy.notification(Pingy.java:0)
Possible dependencies:

 

Solution 1 – Use @Alternative

@Alternative
public class NotificationImpl implements Notification{

  @Override
  public void send(String message) {
    System.out.println(" --> " + message);
  }
}

@Alternative tag makes other implementation default

Solution 2 – Use javax.enterprise.inject.Instance

In this solution, you will call all implementations.

@Stateless
@Interceptors(CallTracer.class)
public class Pingy {

  @PersistenceContext
  EntityManager entityManager;

  @Inject
  Instance<Notification> notifications; // --> important

  @PostConstruct
  public void init() {
    System.out.println(" initilizaze...");

    System.out.println(" --> " + this.notifications.isAmbiguous());
    System.out.println(" --> " + this.notifications.isUnsatisfied());
    for (Notification notification : notifications) {
       notification.send("hey jowsal ....... "); //--> important
    }
}
....

Solution 3 – Use @Qualifier

In this solution, we will use @Qualifier within custom homemade annotations in order to increase readability.

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Age {
   Time value();

   enum Time {
     RECENT, OLD
   }
}

Usage could be like that :

@Stateless
@Interceptors(CallTracer.class)
public class Pingy {

  @PersistenceContext
  EntityManager entityManager;

  @Inject
  @Age(Age.Time.OLD) // important
  Notification notification;

  @PostConstruct
  public void init() {
    System.out.println(" initilizaze...");
    notification.send("hey jowsal");
}

Hava fun…

No Comments

Post a Comment

Comment
Name
Email
Website