[cdi-dev] CDI and generics
Marko Lukša
marko.luksa at gmail.com
Mon Jul 15 18:15:36 EDT 2013
Actually, it will never be the same instance, since all beans with a
parameterized bean class must be @Dependent scoped.
Marko
On 15.7.2013 23:46, Arne Limburg wrote:
> No, I understood you right ;-)
> In Java the same instance cannot be MyClass<String> and
> MyClass<Integer> at the same time.
> We would do exactly that, if we had two injection points like
> @Inject
> MyClass<String> myStringClass;
> @Inject
> MyClass<Integer> myIntegerClass;
> In plain java this could never be the same instances without heavy
> (compile-time) casting, thus this should not be the same instances in CDI.
>
> Cheers,
> Arne
>
> Von: Romain Manni-Bucau <rmannibucau at gmail.com
> <mailto:rmannibucau at gmail.com>>
> Datum: Montag, 15. Juli 2013 23:41
> An: Arne Limburg <arne.limburg at openknowledge.de
> <mailto:arne.limburg at openknowledge.de>>
> Cc: Mark Struberg <struberg at yahoo.de <mailto:struberg at yahoo.de>>,
> Martin Kouba <mkouba at redhat.com <mailto:mkouba at redhat.com>>,
> "cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>"
> <cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>>
> Betreff: Re: [cdi-dev] CDI and generics
>
> hmm think you misunderstood what i said (sorry if it was unclear)
>
> basically my point was a generic bean or produced bean should be
> injectable everywhere so MyClass<T> should match @Inject
> MyClass<String>. In plain java we do: new MyClass<String>().
>
> /Romain Manni-Bucau/
> /Twitter: @rmannibucau <https://twitter.com/rmannibucau>/
> /Blog: //http://rmannibucau.wordpress.com//
> /LinkedIn: //_http://fr.linkedin.com/in/rmannibucau_/
> /Github: https://github.com/rmannibucau/
>
>
>
> 2013/7/15 Arne Limburg <arne.limburg at openknowledge.de
> <mailto:arne.limburg at openknowledge.de>>
>
> Hi Romain,
>
> In plain old java the behavior would depend on where the type
> variable is declared.
> See the following samples:
>
> public class MyClass<T> {
>
> List<T> myList = new ArrayList<T>();
>
> List<String> myStringList = myList;
> }
>
> public class MyClass {
>
> <T> List<T> myList() {
> return new ArrayList<T>();
> }
>
> List<String> myStringList = myList();
> }
>
> The first example does not work and the second works.
>
> And even, if you would access myList from outside, the first
> example just works, if you instantiate myClass with the type argument:
>
> List<String> myStringList = new MyClass<String>().myList;
>
> To transfer this to CDI: We would need an instance of Bean MyClass
> with MyClass<String> in the type closure. And we would have to do
> this for every type argument that can be found within the
> injection points, i.e., if we had the injection points
> @Inject
> MyClass<String> myStringClass;
> @Inject
> MyClass<Integer> myIntegerClass;
> either the type closure of my class would have to contain
> MyClass<String> AND MyClass<Integer> or we would need to have
> different beans for both types. I think, we cannot do either.
>
> I suggest to handle TypeVariables declared at class level
> different than TypeVariables declared at (producer-)method level.
> Thus we could handle Mark Strubergs case and leave the rest like
> it is in plain old java.
>
> I suggest to change the fourth bullet point of chapter 5.2.4:
> "the required type parameter is an actual type, the bean type
> parameter is a type variable that is declared at class level and
> the actual type is assignable from the upper bound of the type
> variable,"
> and add another bullet point:
> "the required type parameter is an actual type, the bean type
> parameter is a type variable that is declared at method level and
> the actual type is assignable to the upper bound of the type
> variable, or"
> And add a footnote: "If no explicit upper bound is defined, the
> implicit upper bound java.lang.Object is assumed"
>
> BTW. Should we create a spec issue for that?
>
> WDYT?
> Regards,
> Arne
>
> P.S.: I don't think this is a backward compatibility issue, just
> because Weld and OpenWebBeans implemented it differently in the
> past. It just was not clear in 1.0 and is not in 1.1. The
> misleading part is the "if any" in the fourth bullet point. A
> TypeVariable ALWAYS has an upper bound. "If no bound is given for
> a type variable, Object is assumed" (Java Lang Spec 4.4)
>
> Von: Romain Manni-Bucau <rmannibucau at gmail.com
> <mailto:rmannibucau at gmail.com>>
> Datum: Montag, 15. Juli 2013 07:55
> An: Mark Struberg <struberg at yahoo.de <mailto:struberg at yahoo.de>>
> Cc: Martin Kouba <mkouba at redhat.com <mailto:mkouba at redhat.com>>,
> Arne Limburg <arne.limburg at openknowledge.de
> <mailto:arne.limburg at openknowledge.de>>, "cdi-dev at lists.jboss.org
> <mailto:cdi-dev at lists.jboss.org>" <cdi-dev at lists.jboss.org
> <mailto:cdi-dev at lists.jboss.org>>
> Betreff: Re: [cdi-dev] CDI and generics
>
> +1, if we are no more aligned on something so simple in plain java
> we are useless i fear :(
>
> (i used and saw it used in a lot of real apps)
>
>
> /Romain Manni-Bucau/
> /Twitter: @rmannibucau <https://twitter.com/rmannibucau>/
> /Blog: //http://rmannibucau.wordpress.com//
> /LinkedIn: //_http://fr.linkedin.com/in/rmannibucau_/
> /Github: https://github.com/rmannibucau/
>
>
>
> 2013/7/14 Mark Struberg <struberg at yahoo.de <mailto:struberg at yahoo.de>>
>
> folks, this breaks backward compatibility
>
>
> In CDI 1.0 it was perfectly fine to do the following
>
> @Produces
> @Dependent
> public <KEY, VALUE extends Serializable> Cache<KEY, VALUE>
> getDefaultCache(InjectionPoint injectionPoint) {
> Type ipType = injectionPoint.getType();
> String cacheName = null;
>
> if (ipType instanceof ParameterizedType) {
> ParameterizedType generic = (ParameterizedType)
> ipType;
> Type[] paramTypes = generic.getActualTypeArguments();
> if (paramTypes == null || paramTypes.length != 2) {
> throw new RuntimeException("illegal param
> types for generic type " + ipType);
> }
>
> if (paramTypes[1] instanceof Class) {
> cacheName = ((Class)
> paramTypes[1]).getSimpleName();
> }
> else {
> cacheName = paramTypes[1].toString();
> }
> }
>
> return getCache(cacheName);
> }
>
>
>
> usage:
>
>
> @Inject
> private Cache<String, IdmUser> userCache;
>
>
> With your new interpretation you basically trash this, right?
> For having a generic producer you would need to create a
> distinct producer method for each and every usage. This just
> doesn't work out in practice...
>
>
>
> LieGrue,
> strub
>
>
>
>
>
> ----- Original Message -----
> From: Martin Kouba <mkouba at redhat.com <mailto:mkouba at redhat.com>>
> To: Arne Limburg <arne.limburg at openknowledge.de
> <mailto:arne.limburg at openknowledge.de>>
> Cc: "cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>"
> <cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>>
> Sent: Wednesday, 10 July 2013, 14:01
> Subject: Re: [cdi-dev] CDI and generics
>
> No, it's not necessary. We'll fix this within CDITCK-349 [1].
> Leave a
> comment if you wish :-)
>
> Thanks
> Martin
>
> [1]
> https://issues.jboss.org/browse/CDITCK-349
>
>
> Dne 10.7.2013 13:52, Arne Limburg napsal(a):
> > OK, so shall I create a TCK issue for that?
> >
> >
> > Cheers,
> > Arne
> >
> > Am 10.07.13 13:50 schrieb "Martin Kouba" unter
> <mkouba at redhat.com <mailto:mkouba at redhat.com>>:
> >
> >> Hi Arne,
> >>
> >> I think so (except the required type is Baz<List<Qux>>) -
> there is no
> >> bean with assignable bean type for this IP (according to
> CDI 1.1 rules
> >> of course).
> >>
> >> Martin
> >>
> >> Dne 10.7.2013 13:16, Arne Limburg napsal(a):
> >>> Hi Martin,
> >>>
> >>> So, which bean should be injected into
> >>> @Inject
> >>> private Baz<List<T2>> t2BazList;
> >>> ?
> >>>
> >>> Baz<T> is also not assignable to Baz<List<String>>,
> because List<String>
> >>> is also not assignable from Object.
> >>>
> >>>
> >>> Am I right, that the test should throw an
> >>> UnsatisfiedResolutionException?
> >>>
> >>> Cheers,
> >>> Arne
> >>>
> >>> Am 08.07.13 12:17 schrieb "Martin Kouba" unter
> <mkouba at redhat.com <mailto:mkouba at redhat.com>>:
> >>>
> >>>> Re Arne's question:
> >>>> Yes, Baz is a managed bean and
> AmbiguousResolutionException should not
> >>>> be thrown because Qux is not a managed bean (doesn't have
> a public
> >>>> no-arg constructor).
> >>>>
> >>>> Re Marko's findings:
> >>>> Yes, the TCK assertions are not up to date and Baz<T> is
> not assignable
> >>>> to Baz<String>, because String is not assignable from
> Object (no bound
> >>>> is defined -> Object is assumed; see JSL 4.4). So I
> confirm a TCK
> >>>> issue.
> >>>>
> >>>> IMO this would deserve a proper cleanup...
> >>>>
> >>>> Martin
> >>>>
> >>>> Dne 8.7.2013 01:22, Marko Lukša napsal(a):
> >>>>> I'd say it's a bug. While Baz indeed is a managed bean,
> it shouldn't
> >>>>> be
> >>>>> injected into injection point with type Baz<String> nor
> >>>>> Baz<List<Qux>>.
> >>>>> So I believe you're right in saying that this test
> should fail with
> >>>>> UnsatisfiedResolutionException.
> >>>>>
> >>>>> There was a change made to the spec way back in 2010
> (see [1]), but
> >>>>> the
> >>>>> TCK apparently wasn't updated then. I've filed an issue
> in the TCK
> >>>>> jira
> >>>>> [2].
> >>>>>
> >>>>> The problem isn't only in the TCK, but also in the spec
> itself. Some
> >>>>> of
> >>>>> the examples in section 5.2.4 don't conform to the rules
> defined in
> >>>>> the
> >>>>> same section (according to the rules, bean Dao<T extends
> Persistent>
> >>>>> shouldn't be eligible for injection into Dao<Order> or
> Dao<User>). I
> >>>>> remember asking about this a year ago ([3]), but I
> didn't articulate
> >>>>> the
> >>>>> problem properly.
> >>>>>
> >>>>> [1]
> >>>>>
> >>>>>
> >>>>>
> https://github.com/cdi-spec/cdi/commit/b32243350ace6a0bba337f91a35f5fd0
> >>>>> 5c
> >>>>> 151f14
> >>>>> [2] https://issues.jboss.org/browse/CDITCK-349
> >>>>> [3]
> http://lists.jboss.org/pipermail/cdi-dev/2012-April/001742.html
> >>>>>
> >>>>> Marko
> >>>>>
> >>>>> On 7.7.2013 16:04, Arne Limburg wrote:
> >>>>>> Hi all,
> >>>>>>
> >>>>>> At the OpenWebBeans list we are currently discussing
> handling of
> >>>>>> generics in CDI.
> >>>>>> I found a test in the CDI 1.1 TCK, which imho has a
> bug. The test
> >>>>>> is
> >>>>>>
> >>>>>>
> org.jboss.cdi.tck.tests.inheritance.generics.MemberLevelInheritanceTes
> >>>>>> t
> >>>>>> and the (simplified) deployment scenario is the following:
> >>>>>>
> >>>>>> public class Baz<T> {
> >>>>>> }
> >>>>>>
> >>>>>> public class Qux extends Baz<String> {
> >>>>>> }
> >>>>>>
> >>>>>> @Vetoed
> >>>>>> public class Bar<T1, T2> {
> >>>>>> @Inject
> >>>>>> private Baz<T1> baz;
> >>>>>> @Inject
> >>>>>> private Baz<List<T2>> t2BazList;
> >>>>>> }
> >>>>>>
> >>>>>> @RequestScoped
> >>>>>> public class Foo extends Bar<String, Qux> {
> >>>>>> }
> >>>>>>
> >>>>>> public class Producer {
> >>>>>> @Produces
> >>>>>> @Amazing
> >>>>>> public String produceString() {
> >>>>>> return "ok";
> >>>>>> }
> >>>>>>
> >>>>>> @Produces
> >>>>>> public String[] produceStringArray() {
> >>>>>> return new String[0];
> >>>>>> }
> >>>>>>
> >>>>>> @Produces
> >>>>>> public Baz<Baz<Qux>> produceBazBazQux() {
> >>>>>> return new Baz();
> >>>>>> }
> >>>>>> }
> >>>>>>
> >>>>>> The class Bar has some more injection points, but that
> does not
> >>>>>> matter.
> >>>>>> Due to the TCK this deployment should work, but I don't
> know how.
> >>>>>> Question: Is Baz a Bean (I suppose so) and may it be
> injected into
> >>>>>> Bean Foo, more precisely into the second injection
> point of class
> >>>>>> Bar?
> >>>>>> - If yes, it also should be injected into the first
> injection
> >>>>>> point, right? This would lead to an
> AmbiguousResolutionException
> >>>>>> since
> >>>>>> Qux may also be injected into the first injection point.
> >>>>>> - If no, the deployment should fail with a
> >>>>>> UnsatisfiedResolutionException since there is no Bean
> that can be
> >>>>>> injected into that injection point.
> >>>>>>
> >>>>>> Is this a bug in the TCK and if not, how is this
> supposed to work?
> >>>>>>
> >>>>>> Cheers,
> >>>>>> Arne
> >>>>>>
> >>>>>>
> >>>>>> _______________________________________________
> >>>>>> cdi-dev mailing list
> >>>>>> cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>
> >>>>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>>>
> >>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> cdi-dev mailing list
> >>>>> cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>
> >>>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>>>
> >>>> _______________________________________________
> >>>> cdi-dev mailing list
> >>>> cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>
> >>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>
> >
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org <mailto:cdi-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
>
>
>
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/cdi-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/cdi-dev/attachments/20130716/fa9d20fe/attachment-0001.html
More information about the cdi-dev
mailing list