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 <
*Blog: **http://rmannibucau.wordpress.com/*<http://rmannibucau.wordpress.com/>
*LinkedIn: **http://fr.linkedin.com/in/rmannibucau*
*Github:
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>
Datum: Montag, 15. Juli 2013 07:55
An: Mark Struberg <struberg(a)yahoo.de>
Cc: Martin Kouba <mkouba(a)redhat.com>, Arne Limburg <
arne.limburg(a)openknowledge.de>, "cdi-dev(a)lists.jboss.org" <
cdi-dev(a)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/*<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>
> 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>
> To: Arne Limburg <arne.limburg(a)openknowledge.de>
> Cc: "cdi-dev(a)lists.jboss.org" <cdi-dev(a)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>:
> >
> >> 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>:
> >>>
> >>>> 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
> >>>>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>>>
> >>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> cdi-dev mailing list
> >>>>> cdi-dev(a)lists.jboss.org
> >>>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>>>
> >>>> _______________________________________________
> >>>> cdi-dev mailing list
> >>>> cdi-dev(a)lists.jboss.org
> >>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>
> >
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>