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
>