import junit.framework.Test;
import org.atinject.tck.Tck;
import org.atinject.tck.auto.Car;
public class MyTck {
public static Test suite() {
Car car = new MyInjector().getInstance(Car.class);
return Tck.testsFor(car,
true /* supportsStatic */,
true /* supportsPrivate */);
}
}
java -cp javax.inject-tck.jar:junit.jar:myinjector.jar junit.textui.TestRunner MyTck
Hi Bob,
It took me a few hours to write a toy implementation that passes
Tck.testsFor(car, false /* supportsStatic */, true /* supportsPrivate
*/).
I'll try to make the code available publicly (probably at
eclipse.org), hope it doesn't take me more time than writing the code.
;-)
A couple hours? Dude, you rockstar. That makes me feel great about the complexity of this spec...
On Sep 29, 2009 3:02 PM, "Boris Bokowski" <boko...@gmail.com> wrote:
Hi Bob,
It took me a few hours to write a toy implementation that passes
Tck.testsFor(car, false /* supportsStatic */, true /* supportsPrivate
*/).
I'll try to make the code available publicly (probably at
eclipse.org), hope it doesn't take me more time than writing the code.
;-)
Boris
On Tue, Sep 29, 2009 at 1:38 PM, Bob Lee <craz...@crazybob.org> wrote: > Late last night, we submi...
IOW the 330 TCK requires that a dependency of type Seat and of type
DriversSeat is available, which leads me to assume that the 330 TCK
requires that the supertypes of a dependency are not considered when
identifying the implementation to inject. Studying the GuiceTck
appears to support this understanding
Firstly, is this correct, or have I misunderstood the TCK/configured
it wrongly for the JSR-299 RI?
If this is correct, it is at odds with the resolution rules specified
in JSR-299 (namely 2.2 Bean Types and 5.3 Typesafe Resolution).
public class Convertible implements Car {
@Inject DriversSeat driversSeatA;
@Inject DriversSeat driversSeatB;
....
requires that a dependency of type DriversSeat is available whilst
public class Convertible implements Car {
....
@Inject Seat fieldPlainSeat;
...
public void testFieldInjectionWithValues() {
assertFalse("Expected unqualified value",
car.fieldPlainSeat instanceof DriversSeat);
....
requires that a dependency of type Seat (and not a subtype) is injected.
If this is correct, it is at odds with the resolution rules specified
in JSR-299 (namely 2.2 Bean Types and 5.3 Typesafe Resolution).
For a given type T and optional qualifier, an injector must be able to inject a user-specified subclass of T that has an injectable constructor.
I found another such case: @Inject SpareTire spareTire; in Convertible
should be @Inject @Named("spare") Tire AFAICT.
After fixing this locally, I see mainly tests relating to overriding
failing (which doesn't surprise me). I intend to work on this
tomorrow, and will let you know if I find any more issues.
On 30 Sep 2009, at 16:45, Jesse Wilson wrote:
> On Wed, Sep 30, 2009 at 7:27 AM, Pete Muir <pm...@bleepbleep.org.uk>
> wrote:
> IOW the 330 TCK requires that a dependency of type Seat and of type
> DriversSeat is available, which leads me to assume that the 330 TCK
> requires that the supertypes of a dependency are not considered when
> identifying the implementation to inject. Studying the GuiceTck
> appears to support this understanding
>
> Firstly, is this correct, or have I misunderstood the TCK/configured
> it wrongly for the JSR-299 RI?
>
> If this is correct, it is at odds with the resolution rules specified
> in JSR-299 (namely 2.2 Bean Types and 5.3 Typesafe Resolution).
>
> Yes, the TCK is constraining the injector more than it should. The
> code should have been written like so:
> @Inject @Drivers Seat driversSeatA;
> @Inject @Drivers Seat driversSeatB;
> @Inject Seat fieldPlainSeat;
> Will JSR-299 be able to satisfy these such that fieldPlainSeat is
> not a DriversSeat? Otherwise I need a mechanism other than the
> injected type to verify that qualifiers are honoured. The injection
> of DriversSeat is just a plain old bug in the TCK that I will fix.
Yes.
> Aside: can external configuration be used with JSR 299 to satisfy
> the current-but-limited TCK? One strategy that seems reasonable is
> injecting some subtype of Seat when it is injected unqualified. Ie.
> create a PlainSeat class to satisfy the unannotated Seat injections.
No, because the injection point type is Seat, both DriversSeat and
Seat are resolved for injection at Seat, with no qualifiers. Once we
remove the requirement that DriversSeat is available for injection
(and make it @Inject @Drivers Seat), there is now only one
implementation of Seat with no qualifiers (Seat).
> If it isn't possible, it seems like an unfortuante limitation in
> 299's injector. I can imagine client code injecting say, an
> unqualified ThreadPoolExecutors and unqualified
> ScheduledThreadPoolExecutor, with the desire to configure different
> implementations for each. Or perhaps I'm underestimating the
> prevalence of qualifiers in JSR-299ified applications.
You would need to use a qualifier here:
@Inject @Scheduled ThreadPoolExecutor;
@Inject ThreadPoolExecutor;
I found another such case: @Inject SpareTire spareTire; in Convertible
should be @Inject @Named("spare") Tire AFAICT.
Unfortunately this fix has the effect of causing an ambiguous
dependency in 299, for example the injection point tireB on Engine:
@Inject public void injectQualifiers(@Drivers Seat seatA, Seat seatB,
@Named("spare") Tire tireA, Tire tireB) as both Tire and SpareTire
resolve to an unqualified injection point with type Tire.
Best,
Pete
dependency in 299, for example the injection point tireB on Engine:Unfortunately this fix has the effect of causing an ambiguous
@Inject public void injectQualifiers(@Drivers Seat seatA, Seat seatB,
@Named("spare") Tire tireA, Tire tireB) as both Tire and SpareTire
resolve to an unqualified injection point with type Tire.
--
Gavin King
gavin...@gmail.com
http://in.relation.to/Bloggers/Gavin
http://hibernate.org
http://seamframework.org
Of course. You specify a qualifier.
The idea that a SpareTire is not a Tire is frankly absurd, and totally
inconsistent with the Java model of assignability and polymorphism.
Any injector that is not able to recognize that a SpareTire is a Tire
is broken, IMO.
Right, so you finally see the point that I have been trying to make
for the past several months, that JSR-330 is totally underspecified
and leaves most of the interesting semantics undefined. And that
because of everything left undefined, 330 provides no reasonable level
of portability for applications.
Sorry Bob, but you can't just go checking a bunch of unspecified (by
the spec), but assumed (by you but not necessarily by anyone else)
semantics in the TCK. That's not how it works.
"atinject.org" is not owned by any EG member or other company. It says
to be "parked" by GoDaddy.
@Bob I like the dynamic form of updating spec, RI and TCK here, but
hopefully at the end we get a "frozen" piece as Josh also said he
wouldn't want a "dynamic" spec out here in forums like this instead of
a real archive or document.
Checked in here: http://code.google.com/p/atinject/source/detail?r=48
Gavin King wrote:
> Bob Lee wrote:
>> There must be some way to configure a 299 injector to inject Tire (and not
>> SpareTire) for Tire.
Let's see if I understand this correctly: We have client code that
looks like this:
@Inject public void injectQualifiers(@Drivers Seat seatA, Seat seatB,
@Named("spare") Tire tireA, Tire tireB) { ... }
The method is annotated with @Inject but there is no qualifier on "Tire tireB".
Assuming that both Tire and SpareTire are available to the injector,
the injector could:
(1) give up and complain about the ambiguity (is this what the
JSR-299 RI does?)
(2) inject an instance according to built-in heuristics (e.g. exact
match wins - this is what my injector implementation does)
(3) based on how it is configured for this case, inject Tire or SpareTire
I would argue that (3) should be possible for any injector
implementation, i.e. I agree with Bob on this.
>> There must be some way to configure a 299 injector to inject Tire (and not
>> SpareTire) for Tire.
> Of course. You specify a qualifier.
Are you saying that every time you add a new subclass, and make it
available to the injector, that you need to go back to your code that
used to work and add qualifiers where there were none? That doesn't
sound right to me.
> The idea that a SpareTire is not a Tire is frankly absurd, and totally
> inconsistent with the Java model of assignability and polymorphism.
> Any injector that is not able to recognize that a SpareTire is a Tire
> is broken, IMO.
Gavin, not sure if this rant is helping. Nobody claimed that a SpareTire is
not a Tire. We are arguing that an injector should be configurable
such that you can tell it whether to inject a Tire or a SpareTire when
asked to inject a Tire.
Boris
On 1 Oct 2009, at 20:35, Boris Bokowski wrote:
>
> Gavin, Pete,
>
> Gavin King wrote:
>> Bob Lee wrote:
>>> There must be some way to configure a 299 injector to inject Tire
>>> (and not
>>> SpareTire) for Tire.
>
> Let's see if I understand this correctly: We have client code that
> looks like this:
>
> @Inject public void injectQualifiers(@Drivers Seat seatA, Seat seatB,
> @Named("spare") Tire tireA, Tire tireB) { ... }
>
> The method is annotated with @Inject but there is no qualifier on
> "Tire tireB".
>
> Assuming that both Tire and SpareTire are available to the injector,
> the injector could:
> (1) give up and complain about the ambiguity (is this what the
> JSR-299 RI does?)
This is what JSR-299 requires an implementation to do, yes. This
isn't about how a 299 implementation itself behaves, but how 330 is
used by the 299 specification.
> (2) inject an instance according to built-in heuristics (e.g. exact
> match wins - this is what my injector implementation does)
> (3) based on how it is configured for this case, inject Tire or
> SpareTire
>
> I would argue that (3) should be possible for any injector
> implementation, i.e. I agree with Bob on this.
Yes, however as 299 builds upon 330, and 299 specifies behaviour (1),
there is a mismatch :-) As Gavin said, a change this large in the 330
requirements needs to have come much earlier, not after the PFD is
published and the TCK is passed to the JCP. I know this seems like
proceduralism over correctness (but there is a lot of stuff being
built on top of 330 that needs time to react).
I'll get back to implementing now :-)
Pete
Pete Muir had suggested a small change to the TCK that solves the
problem. We should go with that instead of adding a new requirement.
Jesse, why would you roll back the fix that worked for both 330 and 299?Bob, are you able to help out, here, to resolve this?I am a little surprised that tests like these are in the TCK since 330 does not outline theinjection semantics to this degree of specificity. Even using the qualifiers is stretching the spec,somewhat, I suppose, since they are application-defined and not semantically specified by 330.However, I understand that this is not an average spec... :-)
-----Original Message-----
From: Bob Lee [mailto:crazy...@gmail.com]
Sent: Thursday, October 01, 2009 6:47 PM
To: atinject...@googlegroups.com
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
Ideally, we'd address this deficiency in 299 before it goes final.
Thanks,Bob
Consider the following example:
Assume a common class Tire, and the following code components, having
been developed by independent teams:
-begin component 1-
public class Car {
@Inject Tire frontTire;
@Inject Tire rearTire;
}
-end component 1-
-begin component 2-
public class SpareTire extends Tire {
}
class Trunk {
@Inject SpareTire spareTire;
}
-end component 2-
Independently, these pieces work wonderfully, and independently, an
injector can produce an instance of Car, or an instance of SpareTire,
without any problems.
However, if I understand the JSR-299 model correctly, you will run
into problems when you try to combine the two
pieces as follows:
-begin component 3-
public class CarWithTrunk extends Car {
@Inject Trunk trunk;
}
-end component 3-
At this point, you would have to go back to piece 2 and add qualifiers
if you want a JSR-299 injector to be able to produce an instance of
CarWithTrunk.
Or am I missing something?
Boris
> Specific suggestions for alternate prose are welcome.
How about this, which is compatible with both the current 299 and 330
specs, and reduces the constraints placed on injectors:
> For a given type T and optional qualifier, an injector must be able
> to inject a subtype of T that has an injectable constructor. To
> portably select which subtype is injected, a qualifier must be used.
> Beyond that, which values are injected depend upon the injector
> implementation and its configuration.
How about this, which is compatible with both the current 299 and 330specs, and reduces the constraints placed on injectors:
> to inject a subtype of T that has an injectable constructor. To
> For a given type T and optional qualifier, an injector must be able
> portably select which subtype is injected, a qualifier must be used.
> Beyond that, which values are injected depend upon the injector
> implementation and its configuration.
@Exports public class SpareTire {...}
public @interface Exports {Class<?>[] types {};}
So you are saying that client code, to be portable across different
injector implementations, would have to add qualifiers everywhere?
Rather than reducing constraints placed on injectors, how about we try
to come up with a solution that reduces the constraints on client
code?
Boris
-----Original Message-----
From: Bob Lee [mailto:crazy...@gmail.com]
Sent: Friday, October 02, 2009 10:46 AM
To: atinject...@googlegroups.com
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
> -----Original Message-----
> From: Boris Bokowski [mailto:boko...@gmail.com]
> Sent: Friday, October 02, 2009 11:06 AM
> To: atinject...@googlegroups.com
> Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
>
>
>
> > How about this, which is compatible with both the current
> 299 and 330
> > specs, and reduces the constraints placed on injectors:
> >
> >> For a given type T and optional qualifier, an injector must be able
> >> to inject a subtype of T that has an injectable constructor. To
> >> portably select which subtype is injected, a qualifier
> must be used.
> >> Beyond that, which values are injected depend upon the injector
> >> implementation and its configuration.
>
> So you are saying that client code, to be portable across different
> injector implementations, would have to add qualifiers everywhere?
To be portable across injectors then qualifiers would need to be added when
the target type is ambiguous (for some definition of ambiguous).
> Rather than reducing constraints placed on injectors, how about we try
> to come up with a solution that reduces the constraints on client
> code?
Hmm. That is usually where the config comes in. Maybe this is just a config issue...
- Export seems to be a global setting, which makes unexported classes not injectable everywhere (even when there is no ambiguity)
- The class resolution would be context-specific, so I would expect a qualifier at the injection site is the correct place to disabiguate
Sent: Friday, October 02, 2009 12:09 PM
To: atinject...@googlegroups.com
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
On Fri, Oct 2, 2009 at 10:51 AM, Michael Keith <MICHAE...@oracle.com> wrote:
- Export seems to be a global setting, which makes unexported classes not injectable everywhere (even when there is no ambiguity)The same is true for all of the JSR-299 annotations, i.e. changes to the annotations on a bean apply everywhere the bean is used.
Well, yes, for the most part (ignoring binding types), that is why I don't think a bean annotation is the best approach.
- The class resolution would be context-specific, so I would expect a qualifier at the injection site is the correct place to disabiguateYou still want to be able to use the base type without qualifiers. If I start off with just Tire, and I later introduce SpareTire, I don't want to go back and add @Normal to all of my Tire injection points.
Right, this is the case that Boris was bringing up. But couldn't it also be argued that if you later introduced a SpareTire then you might want that classto be injected instead? That is part of what injection frameworks are supposed to give you. Change the configuration and cause different objects to be injected. If you are coding in such a way that you don't *want* a subclass to be injected then maybe a reserved @Concrete or @NoSubclass qualifier should be added. If you don't care or have not specified and then you define another subclass then it would be ambiguous. How does that sound?Bob
I would expect injectors to follow the principle of least astonishment
- that is, I would expect an injector to pick Tire over SpareTire in
an ambiguous situation like that, without having to add a @Concrete or
@NoSubclass qualifier. Of course, if only SpareTire is available
(through configuration of the injector or otherwise), it's not
ambiguous, and SpareTire should be injected.
Boris
Right, this is the case that Boris was bringing up. But couldn't it also be argued that if you later introduced a SpareTire then you might want that classto be injected instead? That is part of what injection frameworks are supposed to give you. Change the configuration and cause different objects to be injected.
If you are coding in such a way that you don't *want* a subclass to be injected then maybe a reserved @Concrete or @NoSubclass qualifier should be added. If you don't care or have not specified and then you define another subclass then it would be ambiguous. How does that sound?
This sounds like a question for the 299 EG, but we would love it if they could address it before both JSRs go final.
> -----Original Message-----
> From: Boris Bokowski [mailto:boko...@gmail.com]
> Sent: Friday, October 02, 2009 1:10 PM
> To: atinject...@googlegroups.com
> Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
>
Then I suppose different people have different ways of being astonished :-)
The most useful reason to use Tire, IMO, is because I want to be able
to handle all of the subclasses, not because I prefer the superclass.
That gets into a separate, but perhaps related philosophical discussion
about using concrete superclasses that we shouldn't really get started on,
but I don't think it is the most expected behavior to inject an instance of
Tire just because it is concrete.
BTW, I still think the rules around inheritance are just not well enough
defined at this point. What happens if Tire is abstract and there exists two
concrete subclasses SpareTire and InstalledTire? You would consider that
ambiguous wouldn't you? What if InstalledTire was also abstract, but had a
concrete BalancedTire subclass? Would you expect the least or most derived
concrete child? I know that the 299 group gave a lot of thought to the
resolution rules, and I am not sure if they got them completely right or not,
but it seems to me that this kind of thing is dependent more on external
configuration than on code annotations. I would prefer to see this as a
configuration issue rather than a spec issue.
BTW, I still think the rules around inheritance are just not well enoughdefined at this point.
For a given type T and optional qualifier, an injector must be able to inject a user-specified subtype of T that has an injectable constructor.
Sent: Friday, October 02, 2009 2:02 PM
To: atinject...@googlegroups.com
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
On Fri, Oct 2, 2009 at 12:49 PM, Michael Keith <MICHAE...@oracle.com> wrote:
BTW, I still think the rules around inheritance are just not well enoughdefined at this point.Are you talking about the inheritance rules in JSR-330? If so, I disagree and think 330 is very well specified. Here's the rule again:For a given type T and optional qualifier, an injector must be able to inject a user-specified subtype of T that has an injectable constructor.This accepts the fact that we can't know what a user wants in every situation. JSR-330 doesn't try to guess. It requires an injector to let the user select the subtype, but it puts no restrictions on how an injector does this.
Then aren't we agreeing that 330 does not try to specify how injection works in the face of inheritance hierarchies? To me this statement just says that inheritance must work. It doesn't define how it works. The problem surfaced when the 330 TCK test had an injection point that was part of an inheritance hierarchy but expected a specific behavior without specifying a qualifier, which still seems to disagree with the statement that you added (it doesn't qualify that a given type in the hierarchy must be injected if it exists). What am I missing?
I don't want to step on the 299 EG's toes, so please leave the specifics up to them.
I believe they think you already did step on their toes by introducing a rule at the last minute that broke their tests ;-)Not sure what you mean by leaving the specifics to them. Do you mean that you would prefer to discuss this directly with Gavin without any impartial observers in the way, or do you just mean that this is their problem and they should find a way to get past it? The last time he posted I think he was in violent disagreement with your rule, so I am not sure if leaving this to 299 to figure out is going to achieve what we want, here.
Do we all agree that this is the path forward? If so, we can resubmit the current spec on Tuesday (if that's not allowed from a process perspective, I'll figure something else out). It's clear that the 299 EG should be able to address this problem with little risk before they submit their own final draft.
I don't know what this path is, but I thought your previous messages were that we should discuss it all together and settle on semantics.Bob
>> I don't want to step on the 299 EG's toes, so please leave the
>> specifics up to them.
> I believe they think you already did step on their toes by
> introducing a rule at the last minute that broke their tests ;-)
The issue isn't that the 299 RI can't pass the 330 TCK (I can see a
number of ways to solve this, such as adding optional heuristics to
the code, using the metadata apis to add additional metadata to
SpareTire, or the ambiguous injection points etc.) but that the
default resolution algorithm of 299 isn't compatible with 330 atm.
But, this does raise the question. Should a 299 implementation be
required to pass the 330 TCK using the APIs (rather than SPIs) that
299 offers - I strongly believe it should, as it verifies that the 299
semantics are compatible (in their default state) with 330. Perhaps
this is a question better directed at the 299 EG...
> -----Original Message-----
> From: Pete Muir [mailto:pm...@bleepbleep.org.uk]
> Sent: Friday, October 02, 2009 2:44 PM
> To: atinject...@googlegroups.com
> Cc: JSR-299 Feedback
> Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
>
> On 2 Oct 2009, at 20:27, Michael Keith wrote:
>
> >> I don't want to step on the 299 EG's toes, so please leave the
> >> specifics up to them.
> > I believe they think you already did step on their toes by
> > introducing a rule at the last minute that broke their tests ;-)
>
> The issue isn't that the 299 RI can't pass the 330 TCK (I can see a
> number of ways to solve this, such as adding optional heuristics to
> the code, using the metadata apis to add additional metadata to
> SpareTire, or the ambiguous injection points etc.) but that the
> default resolution algorithm of 299 isn't compatible with 330 atm.
I was going to ask you why you didn't just do that (ie add some external
metadata to configure it).
To be resolution rule compatible I think 299 would have to add a rule
that says that if the injection point specifies a concrete injectable
class that matches the resolution rules then it is not ambiguous, but
can be resolved to that class. Additional config metadata would allow
subclasses to be injected.
> But, this does raise the question. Should a 299 implementation be
> required to pass the 330 TCK using the APIs (rather than SPIs) that
> 299 offers - I strongly believe it should, as it verifies
> that the 299
> semantics are compatible (in their default state) with 330. Perhaps
> this is a question better directed at the 299 EG...
Most TCKs require some amount of external configuration, so it is
certainly reasonable to expect an accompanying XML file.
Then aren't we agreeing that 330 does not try to specify how injection works in the face of inheritance hierarchies? To me this statement just says that inheritance must work. It doesn't define how it works. The problem surfaced when the 330 TCK test had an injection point that was part of an inheritance hierarchy but expected a specific behavior without specifying a qualifier, which still seems to disagree with the statement that you added (it doesn't qualify that a given type in the hierarchy must be injected if it exists). What am I missing?
I don't want to step on the 299 EG's toes, so please leave the specifics up to them.I believe they think you already did step on their toes by introducing a rule at the last minute that broke their tests ;-)
Not sure what you mean by leaving the specifics to them.
Do you mean that you would prefer to discuss this directly with Gavin without any impartial observers in the way, or do you just mean that this is their problem and they should find a way to get past it? The last time he posted I think he was in violent disagreement with your rule, so I am not sure if leaving this to 299 to figure out is going to achieve what we want, here.
Perhaps what we need are some additional words about disambiguation as it relates to specified and implementation
specific behavior that would accomodate 299's current behavior?
Since 299 can be configured to pass the TCK, I think the best way forward is to do that work. Whether doing so uses the defaults or it needs configuration is quite inconsequential. Guice certainly needs several lines of configuration, and I anticipate this will be the norm.
When app developers adopt 299, either they'll run into Tire vs. SpareTire problems or they won't. If it's a common problem, it can be addressed by tools, helper APIs, or a revision to the spec. If it's uncommon, then 299 will retain its current simplicity.
On Oct 2, 2009 1:53 PM, "Bob Lee" <crazy...@gmail.com> wrote:On Fri, Oct 2, 2009 at 11:20 AM, <larry...@oracle.com> wrote: > > Perhaps what we need are some a...
330 has no notion of ambiguous types, so it's hard to talk about them. You'd have to talk about the context you're looking for types in, etc (The classpath? The injectors configuration? The module? We haven't defined any of that).I also think it would be a mistake to compromise compatibility to accommodate one consumer, a spec that has yet to go final itself.Thanks,Bob
--~--~---------~--~----~------------~-------~--~----~ You received this message because you are su...
The issue isn't that the 299 RI can't pass the 330 TCK (I can see a
number of ways to solve this, such as adding optional heuristics to
the code, using the metadata apis to add additional metadata to
SpareTire, or the ambiguous injection points etc.) but that the
default resolution algorithm of 299 isn't compatible with 330 atm.
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
There is nothing inherently wrong with the statement:For a given type T and optional qualifier, an injector must be able to inject a user-specified subtype of T that has an injectable constructor.but I just don't see how this statement defines a required behavior of injecting the superclass T.
but I just don't see how this statement defines a required behavior of injecting the superclass T.
It's not supposed to require a superclass of T... and we don't require that.
-----Original Message-----
From: Bob Lee [mailto:crazy...@gmail.com]
Sent: Saturday, October 03, 2009 10:57 AM
To: atinject...@googlegroups.com
Cc: JSR-299 Feedback
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
To me it seems like the TCK can't assume that T is injected because this rule still allows a subclass of T to be injected instead.
Rrmmm, no, 299 (unlike 330), includes explicit support for modularity.
--
Gavin King
gavin...@gmail.com
http://in.relation.to/Bloggers/Gavin
http://hibernate.org
http://seamframework.org
That may not astonish you, but it would certainly astonish me if an
injector behaved this way. On what rational basis does Tire satisfy
the stated requirements any better than SpareTire does?
I'm afraid that the principle of not astonishing people requires that
the injector warn the user instead of going off and applying arbitrary
rules like this.
That may not astonish you, but it would certainly astonish me if aninjector behaved this way. On what rational basis does Tire satisfy
the stated requirements any better than SpareTire does?
I'm afraid that the principle of not astonishing people requires that
the injector warn the user instead of going off and applying arbitrary
rules like this.
Ahah! So, in fact, you are not specifying that you want just any old tire!
What you are really trying to say is that you want an Tire that will
@GoTheDistance! So say that, explicitly, using a qualifier.
>> I'm afraid that the principle of not astonishing people requires that
>> the injector warn the user instead of going off and applying arbitrary
>> rules like this.
>
> FWIW, Guice has no arbitrary rules.
The Boris-proposed rule that the least-derived class should be
prefered is, indeed, arbitrary. It can not be arrived at from
reasoning about Java's type system.
Ahah! So, in fact, you are not specifying that you want just any old tire!
What you are really trying to say is that you want an Tire that will
@GoTheDistance! So say that, explicitly, using a qualifier.
The Boris-proposed rule that the least-derived class should beprefered is, indeed, arbitrary. It can not be arrived at from
reasoning about Java's type system.
>> The Boris-proposed rule that the least-derived class should be
>> prefered is, indeed, arbitrary. It can not be arrived at from
>> reasoning about Java's type system.
>
> OK. Are you now proposing that 330 be more restrictive? It's too late.
Errr, sorry? I did not propose any new restriction. You proposed a new
restriction. I agree that it is too late to add this new restriction.
On Sat, Oct 3, 2009 at 11:57 PM, Bob Lee <crazy...@gmail.com> wrote:Errr, sorry? I did not propose any new restriction. You proposed a new
>> The Boris-proposed rule that the least-derived class should be
>> prefered is, indeed, arbitrary. It can not be arrived at from
>> reasoning about Java's type system.
>
> OK. Are you now proposing that 330 be more restrictive? It's too late.
restriction. I agree that it is too late to add this new restriction.
"Nice try"?
So hold on a sec. "It's too late" is a good argument when deployed by
you, but not when deployed by me?
Well, I understand that "a foolish consistency is the hobgoblin of
little minds", but this is ridiculous...
"Nice try"?
So hold on a sec. "It's too late" is a good argument when deployed by
you, but not when deployed by me?
Well, I understand that "a foolish consistency is the hobgoblin of
little minds", but this is ridiculous...
I propose that the new rule not be added, and that the original TCK
patch proposed by Pete be applied.
And then we can all go back to our normal lives.
>> What you are really trying to say is that you want an Tire that will
>> @GoTheDistance! So say that, explicitly, using a qualifier.
>
> No thanks. The majority of the time, you don't need a qualifier because you
> only have one implementation of a type.
I totally agree. But in this case, we have two implementations of the
same type. So be explicit about which you want.
> Should you later introduce a second
> implementation of that type, you shouldn't have to go back and retrofit the
> existing injection points.
And 299 doesn't require that you do that, as I've repeatedly
explained. Instead, you put the qualifier on the *new* injection
points that should match to SpareTire.
You do not need to add any qualifier to existing injection points of type Tire.
And 299 doesn't require that you do that, as I've repeatedlyexplained. Instead, you put the qualifier on the *new* injection
points that should match to SpareTire.
You do not need to add any qualifier to existing injection points of type Tire.
Indeed, it is possible to break code in 299 just by adding a subclass.But the breakage is detected immediately and trivially fixable (by
adding a qualifier to the new subclass). We think that it's better
that the injector force the user to be clear and unambiguous in these
cased, rather than have it silently go off and do things that are
"subtle" and perhaps not what the user wants.
Right, the issue is that we cannot alter the TCK code in anyway. If we
could, this could be easily resolved by adding a custom qualifier to
SpareTire. You would of course need to use that qualifier at any
injection point which has type SpareTire.
I believe this does address the "modularity issue" discussed, as
SpareTire has been later added to the system, and so any injection
points with type SpareTire will have been added at that point.
Pete
PS. As you will see from the metamodel approach, this is essentially
what I will do, but without touching the actual TCK classes.
> So ultimately, modularity requires encapsulation. Does JSR-299 address
> problems of this scale?
From the situation you just described, it sounds like you have
multiple modules at play, in which case my comment does not apply.
i.e. ContentDeliveryNetworkImageCacher is a subclass that is only
visible in and used in the Maps module and not available for injection
into the other modules.
As I discussed above, and offline with Bob and Gavin, here is a way in
which any 299 impl can pass the 330 TCK without modifying the TCK
code, and only using 299 APIs.
Here, we specify which classes to use for the TCK, and boot the
container (ok, this bit is container specific ;-):
And here, using only 299 APIs, we adjust the TCK classes to not have
any ambiguities:
Bes,t
Pete
Here, we specify which classes to use for the TCK, and boot the
container (ok, this bit is container specific ;-):
http://anonsvn.jboss.org/repos/webbeans/ri/trunk/inject-tck-runner/src/test/java/org/jboss/webbeans/atinject/tck/AtInjectTCK.java
And here, using only 299 APIs, we adjust the TCK classes to not have
any ambiguities:
http://anonsvn.jboss.org/repos/webbeans/ri/trunk/inject-tck-runner/src/test/java/org/jboss/webbeans/atinject/tck/BeanDisambiguator.java
public class PlainTireMapperextends AbstractInjectionMapper {@Override protected Mapping getMapping() {return new Mapping(Tire.class, null, Tire.class, Plain.class, new AnnotationLiteral<Plain>() {});}}