What type literal must I use to have CDI's Instance::select method work properly?
cdi, java
Solution
Creating a `TypeLiteral` to capture generic parameters only works if those parameters are known at compile time, so `new TypeLiteral<Converter<Integer>>(){}`.
If the type parameter is not known at compile time then a TypeLiteral cannot capture the parameter information because that information has been removed due to type erasure. So creating a `new TypeLiteral<Converter<T>>(){}` actually just creates a `new TypeLiteral<Converter<object>>(){}`.
This means your `select(typeLiteral)` will not work as expected since it will receive the type literal for `Converter<object>`.
Problem
Suppose I have an interface like this: ``` public interface Converter<T> { /*...*/ } ``` And suppose in a CDI environment I have successfully done this: ``` @Inject @Any private Instance<Converter<?>> converters; ``` (By "successfully" I mean that I can do the following and see several converters in the output, so beans are being discovered and supplied properly: ``` for (final Object o : converters) { System.out.println("*** converter: " + o); } ``` …so bean discovery is not the issue.) And now suppose that given `Integer.class`, I'd like to do this: ``` final TypeLiteral<Converter<Integer>> typeLiteral = new TypeLiteral<Converter<Integer>>(){}; final Instance<Converter<Integer>> subInstance = converters.select(typeLiteral); final Converter<Integer> converter = subInstance.get(); ``` This works fine. Now, in my actual code, `Integer.class` is passed in, as a value fulfilling a parameter declared as `Class<T>`, so what I really have is this: ``` final TypeLiteral<Converter<T>> typeLiteral = new TypeLiteral<Converter<T>>(){}; final Instance<Converter<T>> subInstance = converters.select(typeLiteral); final Converter<T> converter = subInstance.get(); // this does not work ``` The `get()` call fails with a stack trace that starts with something that looks like the following: ``` org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type Converter<T> with qualifiers @Any at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:105) ``` What must I do to make this selection succeed? One thing I notice is that the stack is reporting that a `Converter<T>` cannot be found. This looks suspicious: I would have expected it to talk in terms of `Converter<Integer>` instead, since the `T` "slot" is being "filled" with `Integer.class` at runtime, although, to be fair, I did indeed supply a `new TypeLiteral<Converter<T>>(){}`, not `new TypeLiteral<Converter<Integer>>(){}`. Anyway, all this tells me that `TypeLiteral<T>` is using `T` as the type to look for, not the actual value "filling" the `T` "slot", and indeed, there is no converter declared as `implements Converter<T>`, only a converter declared as `implements Converter<Integer>`, and so I'm worried that what I'd like to do here is fundamentally impossible.