[seam-dev] CDI with generic class and the hell of type erasure.
José Rodolfo Freitas
joserodolfo.freitas at gmail.com
Wed Dec 7 07:21:10 EST 2011
Ales and All,
when
@Inject
GenericQuery<String> gqs;
my producer do:
new GenericQuery(clazz)
And then @Inject inside GenericQuery does not work (since I'm using new).
What's the best approach in this situation?
Using BeanManagerProvider.getInstance() inside GenericQuery constructor to
provide instances for the objects I want to inject?
On Tue, Dec 6, 2011 at 9:29 PM, José Rodolfo Freitas <
joserodolfo.freitas at gmail.com> wrote:
> that´s an awesome solution Ales!
> I didn´t thought that I could obtain the parametizedType that way!
> Testing this will be my first task tomorrow morning.
>
> thank you all for your ideas.
>
>
> On Tue, Dec 6, 2011 at 8:55 PM, Jason Porter <lightguard.jp at gmail.com>wrote:
>
>> Nice solution Ales, wish I'd thought of it :)
>>
>>
>> On Tue, Dec 6, 2011 at 15:45, Ales Justin <ales.justin at gmail.com> wrote:
>>
>>> You could do something like this:
>>>
>>> @SuppressWarnings({"unchecked"})
>>> @Produces
>>> public GenericQuery injectClass(InjectionPoint ip) {
>>> Annotated annotated = ip.getAnnotated();
>>> Class clazz = Object.class;
>>> Type type = annotated.getBaseType();
>>> if (type instanceof ParameterizedType) {
>>> ParameterizedType pt = (ParameterizedType) type;
>>> clazz = (Class) pt.getActualTypeArguments()[0];
>>> }
>>> return new GenericQuery(clazz);
>>> }
>>>
>>> --
>>>
>>> @Inject
>>> GenericQuery<String> gqs;
>>> @Inject
>>> GenericQuery<Number> gqn;
>>>
>>> --
>>>
>>> System.out.println("GQS: " + gqs.getClazz());
>>> System.out.println("GQN: " + gqn.getClazz());
>>>
>>> --
>>>
>>> GQS: class java.lang.String
>>> GQN: class java.lang.Number
>>>
>>> --
>>>
>>>
>>> https://github.com/alesj/cdi-arq-workshop/commit/64860f15197be40a7714dfd8a7da931c1db11411
>>>
>>> HTH
>>>
>>> -Ales
>>>
>>> Hey guys, how you doing?
>>>
>>> I'm trying to achieve something that might be impossible, but before
>>> concluding that, I'd like to ask you, CDI gurus!
>>>
>>> I have the following class:
>>>
>>> public class Foo<T> {
>>>
>>> public TypedQuery<T> getQuery(){
>>>
>>> }
>>>
>>> }
>>>
>>> As you can Imagine, inside my getQuery method, I'd have to use "T.class"
>>> to make it TypedQuery. which is impossible due java generics type erasure.
>>>
>>> so I'd have to build a private field to hold the t.class for me.
>>>
>>> public class Foo<T> {
>>>
>>> private Class<T> klass;
>>>
>>> public TypedQuery<T> getQuery(){
>>>
>>> }
>>>
>>> public void setKlass(Class<T> klass){
>>> this.klass = klass;
>>> }
>>> }
>>>
>>> The problem is that forcing this 'setKlass' feels very ugly to the api,
>>> and it's not very error prone, since one could easily forget to set this
>>> configuration.
>>>
>>> So I had an Idea: force the setKlass inside the constructor:
>>>
>>> public class Foo<T> {
>>>
>>> private Class<T> klass;
>>>
>>> public Foo(Class<T> klass){
>>> this.klass = klass;
>>> }
>>>
>>> public TypedQuery<T> getQuery(){
>>>
>>> }
>>>
>>> }
>>>
>>> Unfortunatelly, this breaks cdi, since it cannot inject it anymore. At
>>> least AFAIK.
>>>
>>> So, is there a way out of this? maybe using a secret solder feature?
>>> _______________________________________________
>>> seam-dev mailing list
>>> seam-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/seam-dev
>>>
>>>
>>>
>>> _______________________________________________
>>> seam-dev mailing list
>>> seam-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/seam-dev
>>>
>>>
>>
>>
>> --
>> Jason Porter
>> http://lightguard-jp.blogspot.com
>> http://twitter.com/lightguardjp
>>
>> Software Engineer
>> Open Source Advocate
>> Author of Seam Catch - Next Generation Java Exception Handling
>>
>> PGP key id: 926CCFF5
>> PGP key available at: keyserver.net, pgp.mit.edu
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/seam-dev/attachments/20111207/30f7bb8a/attachment-0001.html
More information about the seam-dev
mailing list