Looking at [1] again, I see the mistake now:
while MediumClass is assignable to SmallClass, ArrayList<MediumClass> is
NOT assignable to ArrayList<SmallClass> (this is a common mistake - see
[2]).
So, given the following:
/>/
@Produces ... ArrayList<T> m1()
/>/
/>/ @Inject ... ArrayList<SmallClass> s1;
/>/ @Inject ... ArrayList<BigClass> b1;/
s1 needs an object that is exactly an ArrayList<SmallClass> and b1 needs
exactly ArrayList<BigClass>.
The producer method is able to produce ArrayList<MediumClass> and
ArrayList<BigClass>. It is NOT able to produce ArrayList<SmallClass>.
Therefore s1 cannot be satisfied.
The original wording in the CDI 1.0 spec was correct:
"/- the required type parameter is an actual type, the bean type
parameter is a type variable and the actual type is assignable *to* the
upper bound, if any, of the type variable/"
s1: the required type parameter is the actual type SmallClass, the bean
type parameter is a type variable with upper bound MediumClass. The
actual type is not assignable to the upper bound (SmallClass is not
assignable to MediumClass), therefore s1 cannot be satisfied.
b1: the required type parameter is the actual type BigClass, the bean
type parameter is a type variable with upper bound MediumClass. The
actual type IS assignable to the upper bound (BigClass is assignable to
MediumClass), therefore b1 can be satisfied.
[1]
no no, what i say is CDI could handle generic beans as template it
would duplicate as many time as needed to match all instances. the
same as for @Dependent but with the scope you want. there is no
technical blocking point.
/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/16 Marko Lukša <marko.luksa(a)gmail.com
<mailto:marko.luksa@gmail.com>>
Yes, you'd need an extension that registers multiple beans. But
that's how it needs to be.
It's not sad. This simply can't work. If you inject the same
instance into both @Inject List<String> stringList and @Inject
List<Integer> integerList, then the user can do this:
stringList.add("some string");
integerList.add(15);
for (String str : stringList) {
System.out.println(str);
}
which would result in a ClassCastException, right?
Marko
On 16.7.2013 9:23, Romain Manni-Bucau wrote:
> hmm, and if you don't want a @Dependent? it is doable through an
> extension but not through declaration, that's sad IMO
>
> /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/16 Marko Lukša <marko.luksa(a)gmail.com
> <mailto:marko.luksa@gmail.com>>
>
> What Arne was concerned about is that we cannot inject the
> same instance into two different typed injection points. We
> can't have an object that is a list of strings and a list of
> integers at the same time. We would need such an object if we
> wanted to inject it into both @Inject List<String> and
> @Inject List<Integer>.
>
> What I pointed out is that CDI has this covered, as it
> requires all beans with a parameterized bean class to be
> dependent scoped and by definition not sharable across
> multiple injection points. CDI will create a _new instance_
> for each injection point, therefore it actually can inject
> bean MyClass<T> into both @Inject MyClass<String> and @Inject
> MyClass<Integer>, since it injects two different instances.
> There is no need to have a custom extension and register
> MyClass<T> multiple times (as MyClass<String>,
> MyClass<Integer>, etc.).
>
> So this means the change at [1] was a mistake.
>
> [1]
>
https://github.com/cdi-spec/cdi/commit/b32243350ace6a0bba337f91a35f5fd05c...
>
> Marko
>
>
> On 16.7.2013 7:17, Romain Manni-Bucau wrote:
>>
>> Hmm not sure i get the Dependent limit. Using a custom
>> extension you'll register the same bean as many times as
>> needed but using different values for parameters and the
>> scope you want.
>>
>> Why CDI wouldnt be able of it out of the box?
>>
>> It is really something basic in 2013 and find really sad
>> that's look so complicated. Please explain me what i'm
>> missing if so.
>>
>> Le 16 juil. 2013 00:15, "Marko Lukša"
<marko.luksa(a)gmail.com
>> <mailto:marko.luksa@gmail.com>> a écrit :
>>
>> 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(a)gmail.com
>>> <mailto:rmannibucau@gmail.com>>
>>> Datum: Montag, 15. Juli 2013 23:41
>>> An: Arne Limburg <arne.limburg(a)openknowledge.de
>>> <mailto:arne.limburg@openknowledge.de>>
>>> Cc: Mark Struberg <struberg(a)yahoo.de
>>> <mailto:struberg@yahoo.de>>, Martin Kouba
>>> <mkouba(a)redhat.com <mailto:mkouba@redhat.com>>,
>>> "cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>"
>>> <cdi-dev(a)lists.jboss.org
<mailto:cdi-dev@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(a)openknowledge.de
>>> <mailto:arne.limburg@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(a)gmail.com
>>> <mailto:rmannibucau@gmail.com>>
>>> Datum: Montag, 15. Juli 2013 07:55
>>> An: Mark Struberg <struberg(a)yahoo.de
>>> <mailto:struberg@yahoo.de>>
>>> Cc: Martin Kouba <mkouba(a)redhat.com
>>> <mailto:mkouba@redhat.com>>, Arne Limburg
>>> <arne.limburg(a)openknowledge.de
>>> <mailto:arne.limburg@openknowledge.de>>,
>>> "cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>"
>>> <cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@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(a)yahoo.de
>>> <mailto:struberg@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(a)redhat.com
>>> <mailto:mkouba@redhat.com>>
>>> To: Arne Limburg <arne.limburg(a)openknowledge.de
>>> <mailto:arne.limburg@openknowledge.de>>
>>> Cc: "cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>"
>>> <cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@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(a)redhat.com
>>> <mailto:mkouba@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(a)redhat.com
>>> <mailto:mkouba@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(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>
>>> >>>>>>
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>> >>>>>
>>> >>>>>
>>> >>>>>
>>> >>>>>
_______________________________________________
>>> >>>>> cdi-dev mailing list
>>> >>>>> cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>
>>> >>>>>
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>> >>>>>
>>> >>>>
_______________________________________________
>>> >>>> cdi-dev mailing list
>>> >>>> cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>
>>> >>>>
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>> >>>
>>> >
>>>
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev(a)lists.jboss.org
>>> <mailto:cdi-dev@lists.jboss.org>
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev(a)lists.jboss.org <mailto:cdi-dev@lists.jboss.org>
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>
>>
>> _______________________________________________
>> cdi-dev mailing list
>> cdi-dev(a)lists.jboss.org <mailto:cdi-dev@lists.jboss.org>
>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>
>
>