The JSR-299 specification states in §3.1:
If the managed bean class is a generic type, it must have scope @Dependent. If a managed bean with a parameterized bean class declares any scope other than @Dependent, the container automatically detects the problem and treats it as a definition error.
Effectively meaning that you can't do this:
@Named
@SessionScoped or @RequestScoped or similar
public class MyProducer<T> {...}
What are the technical reasons for this decision?
Will it be remedied in an upcoming version of CDI by any chance?
Is there a best practice for dealing with /working around this?
Thank you
EDIT - a workaround I can often use is to inject a generic POJO-bean into a bean with the needed scope. Often, but not always.
Here's a generic, non-dependent bean class:
@ApplicationScoped
public class FavouriteChooser<T> {
public T getFavourite() {
// ...
}
}
How many instances of this bean will there be in the application?
Here is an injection site:
@Inject
private FavouriteChooser<String> favouriteWord;
And here's another:
@Inject
private FavouriteChooser<Integer> favouriteNumber;
Would you like to change your answer? :D
Ooh, and here's another:
@Inject
private FavouriteChooser<CharSequence> favouriteLetters;
EDIT. If you want a solution, i would suggest making your generic class abstract, and adding concrete subclasses which bind the type. So:
public abstract class MyProducer<T> {...}
@Named
@SessionScoped
public class MyStringProducer extends MyProducer<String> {}
@Named
@SessionScoped
public class MyIntegerProducer extends MyProducer<Integer> {}
It's boilerplate, but it's only three lines per type. Bear in mind that would give you one instance per session per type, which you might not want.
All non-dependent scoped beans have to be proxied - AFAIK this is not possible with generic types.
UPDATE:
I'd love to be able to explain that in more detail, but I'm not ;-) Weld uses javassist, and they state that proxying generic types is possible in principle - though not directly supported by the toplevel API. But we are talking about the specification, not the implementation of Weld...
Maybe someone else can fill the gap?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With