Question

I use Java 1.7 and Glassfish 4.0.

There is a generic interface Service<T> with 2 implementations where the second extends the first.

public interface Service<T>{
  void serve(T t);
}

@Singleton @ServiceQualifier(type=ServiceType.DEFAULT)
public class DefaultService implements Service<MyType>{
  public void serve(MyType t){
    ...
  }
}

@Singleton @ServiceQualifier(type=ServiceType.SPECIAL)
public class SpecialService extends DefaultService{
  @Override
  public void serve(MyType t){
    ...
  }
}

In order to use CDI there is a qualifier annotation where ServiceType is a simple enum with ServiceType.DEFAULT and ServiceType.SPECIAL.

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface ServiceQualifier {
  ServiceType type();
}

If the Service is injected like this

@Inject @ServiceQualifier(type=ServiceType.DEFAULT)
private Service service;

the CDI Container throws an exception (I deploy the app to glassfish 4 if that matters.)

Error occurred during deployment: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Service] with qualifiers [@ServiceQualifier]

But if the Service is injected with the generic parameter it works.

@Inject @ServiceQualifier(type=ServiceType.DEFAULT)
private Service<MyType> service;

I am very confused now because i thought that generic parameters are removed at compile time in Java. Can someone explain why it is necessary to specify the generic parameter although it is compiled away?

Thanks in advance.

Was it helpful?

Solution

Yes, it's required as the type parameter goes into the selection. You can put the qualifier anywhere , but if it doesn't match type you won't be able to inject the bean into it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top