Reputation: 61538
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.
Upvotes: 12
Views: 10736
Reputation: 47163
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.
Upvotes: 17
Reputation: 14636
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?
Upvotes: 2