[jsr330-eg] Please try the JSR-330 TCK.

78 views
Skip to first unread message

Bob Lee

unread,
Sep 29, 2009, 1:38:30 PM9/29/09
to atin...@googlegroups.com
Late last night, we submitted the final materials for JSR-330, including the TCK and RI. If we're lucky, it will go on the ballot today. If not, it will go on the ballot next Tuesday. The final vote takes two weeks.

Thank you very much to EG member Jesse Wilson for his hard work on the TCK and RI!

The TCK relies on JUnit. To integrate the TCK with your injector, simply create a JUnit test suite class that passes an injected Car instance to Tck:

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 */);
  }
}

The static suite method that returns a Test is a JUnit convention. Feel free to run the returned tests in other ways. The Javadoc on Tck.testsFor() contains instructions for configuring the injector. For example, see how Guice integrates with the TCK.

Static and private member injection support is optional, but if your injector supports those features, you must pass those tests. 

Use your favorite JUnit tool to run the tests. I ran them in my IDE, but you can also use JUnit's command line runner:

java -cp javax.inject-tck.jar:junit.jar:myinjector.jar junit.textui.TestRunner MyTck
 
Overridden methods will probably be the trickiest thing to get right. For a working example, see InjectionPoint.forInstanceMethodsAndFields() in Guice.

We may only have two weeks. I'd like for these tests to pass two additional injector implementations by that time. Please try it soon so we have time to address any bugs or coverage gaps that may surface. 

Thanks,
Bob


javax.inject-tck-javadoc.zip
javax.inject-tck-src.zip
javax.inject-tck.jar

Boris Bokowski

unread,
Sep 29, 2009, 6:02:46 PM9/29/09
to atin...@googlegroups.com

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

Bob Lee

unread,
Sep 29, 2009, 6:09:45 PM9/29/09
to atin...@googlegroups.com
On Tue, Sep 29, 2009 at 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.
;-)

Yay!!! You could just throw it up on Google Code. Can't wait to see it.

Bob


Jesse Wilson

unread,
Sep 29, 2009, 9:17:16 PM9/29/09
to atin...@googlegroups.com

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...



Bob Lee

unread,
Sep 30, 2009, 1:07:27 AM9/30/09
to atin...@googlegroups.com
It's on the ballot!

Bob


Pete Muir

unread,
Sep 30, 2009, 10:27:13 AM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com, Gavin King
I am trying to run JSR-330 TCK for the JSR-299 RI and I suspect I have
run into an incompatiblity. For example

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.

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).
> <javax.inject-tck-javadoc.zip><javax.inject-tck-
> src.zip><javax.inject-tck.jar>

Jesse Wilson

unread,
Sep 30, 2009, 11:45:05 AM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com, Gavin King
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.

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.

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.

Bob Lee

unread,
Sep 30, 2009, 12:41:44 PM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com, Gavin King
On Wed, Sep 30, 2009 at 9:27 AM, Pete Muir <pm...@bleepbleep.org.uk> wrote:
public class Convertible implements Car {

    @Inject DriversSeat driversSeatA;
    @Inject DriversSeat driversSeatB;

     ....

requires that a dependency of type DriversSeat is available whilst

Thanks for fixing this Jesse.
 
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.

Jesse, please make this rule explicit in the docs on Tck.testsFor(), i.e "Seat must be injected for Seat."
 
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).

You'll probably need to use @Nonbinding.

We tried not to overly-constrain injector implementations, but a TCK is allowed to enforce a minimum standard of quality, which 299 clearly exceeds.

Once your impl has passed, I'll send an updated TCK to the JCP.

Thanks,
Bob

Gavin King

unread,
Sep 30, 2009, 1:38:06 PM9/30/09
to Bob Lee, atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com

No, this is clearly a bug in the TCK that must be fixed. The TCK may
not enforce rules that are not required by the actual 330 specification.

In 299, the second injection point is considered ambiguous since 2
different beans satisfy the required type and qualifiers, and thus an
error is reported at startup. This is desirable behavior. On the other
hand, 330 is silent on the behavior that is expected here, and
therefore the TCK can not enforce any particular behavior.


Sent from my iPhone

On Sep 30, 2009, at 11:41 AM, Bob Lee <crazy...@gmail.com> wrote:

>


Bob Lee

unread,
Sep 30, 2009, 2:15:19 PM9/30/09
to Gavin King, atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com
Point taken. Interface-based dependencies also aren't explicitly covered in the spec, so we should take those out, too. Actually, the spec doesn't impose any requirements on what types an injector must be able to inject, so I conclude that, like JSR-250, we can't have a TCK. This is OK. It means you can have purpose-built injectors that only support a fixed set of built-in types.

I would like to at least test that members are injected in the correct order and that method overriding is adhered to. We specify constructor injection already. Should I add a sentence to the @Inject spec requiring injectors to be able to handle deps on injectable classes? Of course, we wouldn't be able to test qualifiers. Or, we could forego the TCK for 330. More strict downstream specs would be able to reuse the current TCK. 

Thoughts?

Bob

Bob Lee

unread,
Sep 30, 2009, 2:31:22 PM9/30/09
to Gavin King, atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com
I have an idea: we can at least test injection of parameterless constructors and methods. This will enable us to test the default constructor and a constructor with @Inject (with various accessibility levels). We can ensure that parent class methods are injected before child class methods (for both static and instance). We can test that method overriding is respected. We can't test field injection or @Singleton, but it's better than nothing.

Bob

Bob Lee

unread,
Sep 30, 2009, 3:36:43 PM9/30/09
to Gavin King, atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com
I spoke with Jesse. We're going to go with my original suggestion of making the rule explicit in the docs on Tck.testsFor(), i.e "An instance of Seat but not a subclass must be injected for Seat."

The spec will impose a minimum requirement on injectors. I'll add the following to the spec for @Inject:

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.  

Sounds good?

Thanks,
Bob

Bob Lee

unread,
Sep 30, 2009, 5:19:17 PM9/30/09
to atin...@googlegroups.com
OK, I added this rule to the spec and fixed the omission in the testsFor() Javadoc. I also took the opportunity to improve the Tck Javadocs and add a test case that mixes package-private with overriding.


I'll send this to the JCP as soon as your done.

Thanks,
Bob


Bob Lee

unread,
Sep 30, 2009, 5:25:32 PM9/30/09
to atin...@googlegroups.com
I almost forgot. You'll find the updated TCK and spec attached.

Thanks,
Bob


javax.inject-tck.zip
javax.inject.zip

Bob Lee

unread,
Sep 30, 2009, 5:52:51 PM9/30/09
to atin...@googlegroups.com
I passed along the updated spec and TCK to the JCP. Thanks for the feedback, everyone!

Bob


Pete Muir

unread,
Sep 30, 2009, 6:34:54 PM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback
Thanks for the speedy fix.

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;

Bob Lee

unread,
Sep 30, 2009, 6:59:12 PM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback
Peter,

On Wed, Sep 30, 2009 at 3:34 PM, Pete Muir <pm...@bleepbleep.org.uk> wrote:
I found another such case: @Inject SpareTire spareTire; in Convertible
should be @Inject @Named("spare") Tire AFAICT. 

I addressed this by adding SpareTire to the list of classes that can be injected. The updated TCK docs are attached.

Thanks,
Bob 
javax.inject-tck.zip

Pete Muir

unread,
Sep 30, 2009, 7:17:59 PM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback

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

Bob Lee

unread,
Sep 30, 2009, 7:24:59 PM9/30/09
to atinject...@googlegroups.com, JSR-299 Feedback
On Wed, Sep 30, 2009 at 4:17 PM, Pete Muir <pm...@bleepbleep.org.uk> wrote:
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.

There must be some way to configure a 299 injector to inject Tire (and not SpareTire) for Tire.

Bob 

Gavin King

unread,
Oct 1, 2009, 12:15:26 AM10/1/09
to Bob Lee, atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com
No, this change is definitely not acceptable to us, since it is
different to the rule specified in JSR-299.

--
Gavin King
gavin...@gmail.com
http://in.relation.to/Bloggers/Gavin
http://hibernate.org
http://seamframework.org

Gavin King

unread,
Oct 1, 2009, 12:16:13 AM10/1/09
to atin...@googlegroups.com

Please roll back this unacceptable change.

Gavin King

unread,
Oct 1, 2009, 12:18:19 AM10/1/09
to atinject...@googlegroups.com, JSR-299 Feedback

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.

Gavin King

unread,
Oct 1, 2009, 12:23:21 AM10/1/09
to Bob Lee, atinject...@googlegroups.com, JSR-299 Feedback, atin...@googlegroups.com
On Wed, Sep 30, 2009 at 2:15 PM, Bob Lee <crazy...@gmail.com> wrote:
> Point taken. Interface-based dependencies also aren't explicitly covered in
> the spec, so we should take those out, too. Actually, the spec doesn't
> impose any requirements on what types an injector must be able to inject, so
> I conclude that, like JSR-250, we can't have a TCK. This is OK. It means you
> can have purpose-built injectors that only support a fixed set of built-in
> types.

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.

Boris Bokowski

unread,
Oct 1, 2009, 11:48:48 AM10/1/09
to atin...@googlegroups.com

Hi Bob,

The code of my injector implementation is now available from
eclipse.org (licensed under EPL), you can get it as follows:

cvs -d :pserver:anon...@dev.eclipse.org:/cvsroot/eclipse co -d
org.eclipse.e4.core.di
e4/org.eclipse.e4.runtime/bundles/org.eclipse.e4.core.di

A comment in Injector.java shows how to run the TCK against the
injector implementation.

Looking forward to comments!

Boris

Werner Keil

unread,
Oct 1, 2009, 6:46:44 AM10/1/09
to atinject-observer
I was wondering, if package naming for the TCK had to follow any
common standard?

"atinject.org" is not owned by any EG member or other company. It says
to be "parked" by GoDaddy.

Is that widely accepted, or what would happen, if any company buys
that domain?

Thanks,
Werner

Werner Keil

unread,
Oct 1, 2009, 6:30:35 AM10/1/09
to atinject-observer
@Gavin, I guess this partially goes in the same direction that I
critizised in the EG ballot.
Your rep Mark mentioned, he only missed a "yes" vote, but backing your
remarks he probably should have mentioned some of that there, too ?;-)

@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.

Werner

Werner Keil

unread,
Oct 1, 2009, 5:43:02 AM10/1/09
to atinject-observer
Under which project at eclipse.org?

Boris Bokowski

unread,
Oct 1, 2009, 12:05:33 PM10/1/09
to atinject...@googlegroups.com
Hi Werner,

That would be the e4 project. Let me know if you need instructions for
getting the code into the Eclipse IDE.

Boris

Bob Lee

unread,
Oct 1, 2009, 12:25:02 PM10/1/09
to atinject...@googlegroups.com
Werner,

On Thu, Oct 1, 2009 at 5:46 AM, Werner Keil <werne...@gmail.com> wrote:
"atinject.org" is not owned by any EG member or other company. It says
to be "parked" by GoDaddy.

There's a tool named "whois". If you run it against atinject.org, you'll see that I own it.
 
On Thu, Oct 1, 2009 at 5:30 AM, Werner Keil <werne...@gmail.com> wrote:
@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.

If you can't be constructive, you will not be allowed to post to this list. I expect more of an EC member.

Bob

Boris Bokowski

unread,
Oct 1, 2009, 12:54:23 PM10/1/09
to atin...@googlegroups.com

Gavin,

Which rule in 299 are you referring to?

Boris

Pete Muir

unread,
Oct 1, 2009, 1:29:43 PM10/1/09
to atinject...@googlegroups.com, JSR-299 Feedback
Whilst we resolve this issue, I thought it would be useful to report
that the JSR-299 RI is now passing the JSR-330 TCK with the
modification I proposed to the JSR-330 TCK. FYI I have attached that
modification as a patch, I don't believe it alters the semantics of
the TCK in any way (beside removing the requirement that a 330-
compliant injector should be able to be configured to inject the
supertype, and not some subtype of the type specified at the injection
point). I would welcome any corrections!

330-tck.patch

Jesse Wilson

unread,
Oct 1, 2009, 1:55:24 PM10/1/09
to atinject...@googlegroups.com, JSR-299 Feedback
Looks Good To Me.

Jesse Wilson

unread,
Oct 1, 2009, 2:02:08 PM10/1/09
to atinject...@googlegroups.com, JSR-299 Feedback


On Thu, Oct 1, 2009 at 10:55 AM, Jesse Wilson <je...@swank.ca> wrote:

... and rolled back: http://code.google.com/p/atinject/source/detail?r=49

I'd forgotten that we'd updated the spec to address this, so changing the TCK should be unnecessary.

Boris Bokowski

unread,
Oct 1, 2009, 2:35:29 PM10/1/09
to atinject...@googlegroups.com
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?)
 (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

Gavin King

unread,
Oct 1, 2009, 3:33:54 PM10/1/09
to atinject...@googlegroups.com, JSR-299 Feedback
Sorry, we have not agreed to that change in the specification.

And to be very clear. The 299 group agreed to adopt the 330
annotations, under the agreement that the 330 spec said what it said
in the revisions that we saw. Sorry, but it is now far too late for
330 to be adding additional semantics and requirements that are
contrary to what 299 specifies and to what was agreed between the two
expert groups.

You'll need to remove this new requirement. Sorry.

Pete Muir

unread,
Oct 1, 2009, 4:52:08 PM10/1/09
to atinject...@googlegroups.com
Hi 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

Roberto Chinnici

unread,
Oct 1, 2009, 5:56:46 PM10/1/09
to atin...@googlegroups.com

I agree with Gavin.

This is not the right time to change the spec. Clearly the sentence that
got added is significant, as the case of 299 trying to pass the 330 TCK
shows.

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.

--Roberto

Bob Lee

unread,
Oct 1, 2009, 6:21:56 PM10/1/09
to atin...@googlegroups.com
On Thu, Oct 1, 2009 at 2:56 PM, Roberto Chinnici <Roberto....@sun.com> wrote:
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.

The added sentence ratifies a rule that has been implicit in the spec all along. Now, before 330 and 299 have gone final, is the perfect time to address this problem. The fact that 299 gives me a Properties object when I ask for a Hashtable or a LinkedHashMap when I ask for a HashMap is a deficiency we should fix now, before we've gone final, not ignore. Dropping the rule would defeat our ability to test our specification; it isn't an option. I have no doubt that the 299 EG can address this issue in an elegant fashion.

Bob


Michael Keith

unread,
Oct 1, 2009, 6:23:02 PM10/1/09
to atinject...@googlegroups.com
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 the
injection 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... :-)
 
Thanks,
-Mike

Bob Lee

unread,
Oct 1, 2009, 6:46:44 PM10/1/09
to atinject...@googlegroups.com
On Thu, Oct 1, 2009 at 3:23 PM, Michael Keith <MICHAE...@oracle.com> wrote:
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 the
injection 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... :-)

The test should remain until we've resolved this issue. The test covers this sentence: "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." We're open to alternate solutions, but removing this sentence entirely removes our ability to test this specification, not to mention any hope of application portability. Ideally, we'd address this deficiency in 299 before it goes final.

Thanks,
Bob

Roberto Chinnici

unread,
Oct 1, 2009, 6:53:02 PM10/1/09
to atin...@googlegroups.com
Given that we disagree, it cannot have been implicit all along.

Certainly the intent of the bean author is to have an object of a compatible type injected, but there may well be restrictions in the injector regarding what specific types are allowed to be injected in a given context. Since we never went into the details of how injectors work and how they are configured, this behavior should be allowed.

This does not imply declawing the TCK. The proposed changes are minor and leave us with a decent amount of tests, all while avoiding a problematic case.



Larry Cable

unread,
Oct 1, 2009, 7:16:53 PM10/1/09
to atin...@googlegroups.com, atinject...@googlegroups.com
Hey Bob,
       I think it's unfortunate that we have tripped up over an undiscovered implicit 'rule' at this point in time, but it's no one's fault, simply a function of the environment in which 330 and 299
are working, but we need to address it.

From a procedural point of view, I do not think it is appropriate for this to be changed unilaterally without discussion within the 330 EG and between it and the 299 EG also. Simply amending the
spec thus causing 299 to transition from "compliant" to "non-compliant" then tossing it over the wall for them to fix seems "uncooperative"... and not in the spirit of the JCP and this collaboration.

I think we should approach this discussion from the perspective of what level of specificity would a developer using 330/299 desire (that we can deliver in the constraints we are operating with)

Regards

- Larry


Michael Keith

unread,
Oct 1, 2009, 7:17:58 PM10/1/09
to atinject...@googlegroups.com
But you just added that sentence to the spec now. It was never there throughout the entire process
of reconciliation between 299 and 330, or it could have been discussed. In fact, 330 has not outlined
any of the inheritance issues around injectable classes. Don't you think it is a little late to be adding
a statement about inheritance that is so controversial and deserves a lot more discussion than what
can be undertaken mere days before the spec is final?
 
I think the TCK should stay away from inheritance because up to this point the spec has not defined it.
-----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.

Larry Cable

unread,
Oct 1, 2009, 7:20:05 PM10/1/09
to atin...@googlegroups.com, atinject...@googlegroups.com
Actually I think that the sentence should be backed out until the 330 EG has an opportunity to discuss and agree to it's inclusion...

Ideally, we'd address this deficiency in 299 before it goes final.

agreed we need to normalize this woth 330 and 299 before either go final.

Thanks,
Bob






Bob Lee

unread,
Oct 1, 2009, 7:31:20 PM10/1/09
to atin...@googlegroups.com
I take full responsibility for overlooking the omission of this sentence up until now. I'm sorry. Don't get hung up on the current state of the spec. It's not final yet, and as always, everything is up for discussion. Let's focus on the way forward. Shipping the spec without a sufficient TCK is not an option. Specific suggestions for alternate prose are welcome. 

Bob


Boris Bokowski

unread,
Oct 1, 2009, 7:32:36 PM10/1/09
to atinject...@googlegroups.com
If JSR-299 requires an injector to "give up" in ambiguous situations,
and also that qualifiers be added to fix ambiguities, then it seems to
be that JSR-299 is at odds with modular development practices. I think
we should be glad that this issue has come up before 299 and 330 are
finalized.

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

Boris Bokowski

unread,
Oct 1, 2009, 7:33:20 PM10/1/09
to atinject...@googlegroups.com
s/seems to be/seems to me/

Bob Lee

unread,
Oct 1, 2009, 11:44:15 PM10/1/09
to atin...@googlegroups.com
Thank you, Boris.

Experts, please note that the spec on the ballot does not have the contentious sentence. The TCK currently on the ballot requires injection of Tire (!SpareTire). We all agree that this is an invalid combination, but we can't change it now. Let's please work together to resolve this issue in time to submit a new spec/TCK combination for next Tuesday's ballot.

Thanks,
Bob 


Pete Muir

unread,
Oct 2, 2009, 5:41:36 AM10/2/09
to atinject...@googlegroups.com

On 2 Oct 2009, at 01:31, Bob Lee wrote:

> 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.

Bob Lee

unread,
Oct 2, 2009, 10:45:43 AM10/2/09
to atinject...@googlegroups.com
On Fri, Oct 2, 2009 at 4:41 AM, Pete Muir <pm...@bleepbleep.org.uk> wrote:
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.

Nice work, Pete! That sounds like a decent compromise.

Since we have a little more time, let's keep working and try to find an even more ideal compromise. The original rule still has the advantages of being simpler and addressing Boris's use case. This is a now or never thing; we can't make the rules more strict after we've shipped because it would break backward compatibility.

What if 299 added an @Exports annotation?

@Exports public class SpareTire {
  ...
}

@Exports overrides 299's default behavior of exporting every type in the hierarchy. Instead, it exports only the specified types. It would be defined something like this:

public @interface Exports {
  Class<?>[] types {};
}  

If types is empty (the default), 299 exports only the bottom-most type. If types are specified, 299 verifies that the bean implements all of those types and exports them

Thanks,
Bob 

Boris Bokowski

unread,
Oct 2, 2009, 11:05:51 AM10/2/09
to atinject...@googlegroups.com
> 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?

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

Michael Keith

unread,
Oct 2, 2009, 11:51:46 AM10/2/09
to atinject...@googlegroups.com
 
This is a interesting idea. Two things occurred to me, though:
 
- 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
-----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.

Michael Keith

unread,
Oct 2, 2009, 11:58:25 AM10/2/09
to atinject...@googlegroups.com

> -----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...

Bob Lee

unread,
Oct 2, 2009, 12:09:20 PM10/2/09
to atinject...@googlegroups.com
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.

- The class resolution would be context-specific, so I would expect a qualifier at the injection site is the correct place to disabiguate

You 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. 

Bob

larry...@oracle.com

unread,
Oct 2, 2009, 12:29:09 PM10/2/09
to atinject...@googlegroups.com, atin...@googlegroups.com

+1

Michael Keith

unread,
Oct 2, 2009, 12:45:43 PM10/2/09
to atinject...@googlegroups.com
-----Original Message-----
From: Bob Lee [mailto:crazy...@gmail.com]
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 disabiguate

You 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 class
to 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

Boris Bokowski

unread,
Oct 2, 2009, 1:09:45 PM10/2/09
to atinject...@googlegroups.com
2009/10/2 Michael Keith <MICHAE...@oracle.com>:

> 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 class to 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?

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

Bob Lee

unread,
Oct 2, 2009, 1:11:46 PM10/2/09
to atinject...@googlegroups.com
On Fri, Oct 2, 2009 at 11:45 AM, Michael Keith <MICHAE...@oracle.com> wrote:
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 class
to 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.
Agreed.
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.

Thanks,
Bob 

Bob Lee

unread,
Oct 2, 2009, 1:12:57 PM10/2/09
to atinject...@googlegroups.com
On Fri, Oct 2, 2009 at 12:11 PM, Bob Lee <crazy...@gmail.com> wrote:
This sounds like a question for the 299 EG, but we would love it if they could address it before both JSRs go final.

Actually, they just need to agree to address it before 330 goes final.

Thanks,
Bob 

Michael Keith

unread,
Oct 2, 2009, 1:49:42 PM10/2/09
to atinject...@googlegroups.com

> -----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.

Bob Lee

unread,
Oct 2, 2009, 2:02:16 PM10/2/09
to atinject...@googlegroups.com
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 enough
defined 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.

I don't want to step on the 299 EG's toes, so please leave the specifics up to them.

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.

Bob

larry...@oracle.com

unread,
Oct 2, 2009, 2:20:32 PM10/2/09
to atinject...@googlegroups.com
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?

Michael Keith

unread,
Oct 2, 2009, 2:27:29 PM10/2/09
to atinject...@googlegroups.com
-----Original Message-----
From: Bob Lee [mailto:crazy...@gmail.com]
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 enough
defined 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

Pete Muir

unread,
Oct 2, 2009, 2:43:35 PM10/2/09
to atinject...@googlegroups.com, JSR-299 Feedback

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.

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...

Michael Keith

unread,
Oct 2, 2009, 3:01:06 PM10/2/09
to atinject...@googlegroups.com, JSR-299 Feedback

> -----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.

Bob Lee

unread,
Oct 2, 2009, 4:29:48 PM10/2/09
to atinject...@googlegroups.com
On Fri, Oct 2, 2009 at 11:27 AM, Michael Keith <MICHAE...@oracle.com> wrote:
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?
The rule says a user should be able to specify which subtype (out of any subtype) gets injected. An injector is not allowed to prevent a user from injecting a specific subtype. The test JSR-299 fails covers this. If you translate this to real life, without this rule, classes that work fine with Guice won't work with 299 unless I add qualifiers to the injected code. This is not acceptable.  
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 ;-)
We unintentionally uncovered an inadequacy in 299 that needs to be addressed. I already apologized for not catching it sooner. While you all didn't think this was part of the spec, it should be clear from the TCK design that we did. The path forward is all that matters now.
Not sure what you mean by leaving the specifics to them.
While I'm happy to make suggestions, it would be presumptuous to start designing features for 299. 
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. 
We'll have to wait to hear from Gavin. It should be clear by now that we've considered his input. Now, we have to find a path forward that fits within the parameters I've laid out.

Bob

Bob Lee

unread,
Oct 2, 2009, 4:53:41 PM10/2/09
to atinject...@googlegroups.com
On Fri, Oct 2, 2009 at 11:20 AM, <larry...@oracle.com> wrote:
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?

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  

Jesse Wilson

unread,
Oct 3, 2009, 12:27:16 AM10/3/09
to atinject...@googlegroups.com

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...

Bob Lee

unread,
Oct 3, 2009, 1:48:17 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
Pete,


On Fri, Oct 2, 2009 at 11:43 AM, Pete Muir <pm...@bleepbleep.org.uk> wrote:
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.

Are you saying you can use 299's meta-data API to pass the 330 TCK? If so, problem solved. We can keep the sentence and no changes to 299 will be necessary.

Bob


 

Mark Struberg

unread,
Oct 3, 2009, 5:27:32 AM10/3/09
to atinject...@googlegroups.com
I'm note sure if 330 should change much for this case, because that would be against the spirit of 330. The definitely wrong thing (as Pete pointed out) is to force rules in the TCK which have not been specified in the spec.

Please also remind that that there is additional ways to override the annotated injections with external configuration (e.g. via XML) with most DI frameworks. And this is a huge win for large projects where we simply don't know which of the subclasses will be used at runtime.

Most time there is a very good reason to have specialised subclasses: because they define a functionality which is _really_ needed. So simply injecting the least common denominator aka baseclass simply will not work for most projects and should definitely not get defined in 330 this way.

And even worse: for different customers/installations we have to inject either the base class or different subclasses (which gets picked up from another jar which is not even on the compilepath of the base poject). How the hack should I add qualifiers for that? Maybe I don't get it but imho we are discussing things which cannot always be resolved with annotations anyway.

LieGrue,
strub

--- On Fri, 10/2/09, larry...@oracle.com <larry...@oracle.com> wrote:

> From: larry...@oracle.com <larry...@oracle.com>
> Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.

Michael Keith

unread,
Oct 3, 2009, 10:21:14 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
The problem really boils down not to what 299 does or doesn't do, but that there is a TCK test that
exists and expects a certain injection even though that injection is not required by the 330 spec.
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.
This makes the Tire test appear to be beyond the spec and puts it at risk for a TCK challenge,
which we generally want to avoid if we can since they are an incredible time drain for everyone
(especially if they escalate to the PMO).
-----Original Message-----
From: Bob Lee [mailto:crazy...@gmail.com]
Sent: Saturday, October 03, 2009 1:48 AM
To: atinject...@googlegroups.com
Cc: JSR-299 Feedback
Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.

Bob Lee

unread,
Oct 3, 2009, 10:39:24 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
On Sat, Oct 3, 2009 at 7:21 AM, Michael Keith <MICHAE...@oracle.com> wrote:
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.

It's not supposed to require a superclass of T... and we don't require that.

Does this rephrasing help your understanding? "For a given type T and optional qualifier, an injector must be able to inject a user-specified class that a) is assignable compatible with T and b) has an injectable constructor." That's more precise.

The point is simple: an injector should be able to inject whatever subtype (including the type T itself) the user asks to be injected. In our case, the TCK is the user, and it's asking the injector to inject Tire for Tire.

Thanks,
Bob

Bob Lee

unread,
Oct 3, 2009, 10:57:05 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
On Sat, Oct 3, 2009 at 7:39 AM, Bob Lee <crazy...@gmail.com> wrote:
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.

Ah, by "superclass T" you mean "T itself, not one of its subtypes." The rephrasing should make this clearer.

Bob

Bob Lee

unread,
Oct 3, 2009, 11:06:33 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
Also, that should be "assignment compatible." I originally wrote "assignable" and went back and added "compatible" but forgot to s/assignable/assignment/. :-)

Thanks,
Bob

Michael Keith

unread,
Oct 3, 2009, 11:33:53 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
I don't see how the rephrasing makes it any more explicit.
 
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.
Basically, I agree with your statement:
 
The point is simple: an injector should be able to inject whatever subtype (including the type T itself) the user asks to be injected.
 
I just don't see how you can then move on to saying that:
 
In our case, the TCK is the user, and it's asking the injector to inject Tire for Tire.
 
The test is not necessarily asking for Tire since the spec does not say how to do so.
It is simply specifying an injection target of type Tire, which by the rule may be of type Tire or a some subclass of Tire.
 
Perhaps, the test is already not assuming that the injection is of concrete type Tire, but allows for some subclass anyway?
If this is the case then we are done.
-----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.

Bob Lee

unread,
Oct 3, 2009, 11:37:41 AM10/3/09
to atinject...@googlegroups.com, JSR-299 Feedback
On Sat, Oct 3, 2009 at 8:33 AM, Michael Keith <MICHAE...@oracle.com> wrote:
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.

The configuration instructions in the TCK explicitly say that Tire must be injected for Tire. This is equivalent to a user asking for the same.
 
Bob

Gavin King

unread,
Oct 3, 2009, 10:51:35 PM10/3/09
to atinject...@googlegroups.com
On Thu, Oct 1, 2009 at 7:32 PM, Boris Bokowski <boko...@gmail.com> wrote:
>
> If JSR-299 requires an injector to "give up" in ambiguous situations,
> and also that qualifiers be added to fix ambiguities, then it seems to
> be that JSR-299 is at odds with modular development practices.

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

Gavin King

unread,
Oct 3, 2009, 10:53:18 PM10/3/09
to atinject...@googlegroups.com

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.

Bob Lee

unread,
Oct 3, 2009, 10:57:34 PM10/3/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 9:53 PM, Gavin King <gavin...@gmail.com> wrote:
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?
 
Ha ha! For one, you're not supposed to drive more than 50mph on a spare tire. ;-)

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.

Bob

Gavin King

unread,
Oct 3, 2009, 11:28:11 PM10/3/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 10:57 PM, Bob Lee <crazy...@gmail.com> wrote:
> On Sat, Oct 3, 2009 at 9:53 PM, Gavin King <gavin...@gmail.com> wrote:
>>
>> 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?
>
>
> Ha ha! For one, you're not supposed to drive more than 50mph on a spare
> tire. ;-)

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.

Bob Lee

unread,
Oct 3, 2009, 11:57:51 PM10/3/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 10:28 PM, Gavin King <gavin...@gmail.com> wrote:
Ahah! So, in fact, you are not specifying that you want just any old tire!

Correct. An injector can pick any Tire implementation it likes by default, but it must also support injection of a user-specified Tire implementation.

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. Should you later introduce a second implementation of that type, you shouldn't have to go back and retrofit the existing injection points.
 
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.

Bob

Gavin King

unread,
Oct 4, 2009, 12:01:48 AM10/4/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 11:57 PM, Bob Lee <crazy...@gmail.com> wrote:

>> 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.

Bob Lee

unread,
Oct 4, 2009, 12:06:36 AM10/4/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 11:01 PM, Gavin King <gavin...@gmail.com> wrote:
On Sat, Oct 3, 2009 at 11:57 PM, Bob Lee <crazy...@gmail.com> wrote:

>> 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.

Ha ha. Nice try. ;-)

Bob

Gavin King

unread,
Oct 4, 2009, 12:15:57 AM10/4/09
to atinject...@googlegroups.com

"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...

Bob Lee

unread,
Oct 4, 2009, 12:32:19 AM10/4/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 11:15 PM, Gavin King <gavin...@gmail.com> wrote:
"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...

Ha ha. If you're seriously proposing an additional restriction, we will consider it.

Bob

Gavin King

unread,
Oct 4, 2009, 12:42:52 AM10/4/09
to atinject...@googlegroups.com

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.

Gavin King

unread,
Oct 4, 2009, 12:47:43 AM10/4/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 11:57 PM, Bob Lee <crazy...@gmail.com> wrote:

>> 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.

Bob Lee

unread,
Oct 4, 2009, 12:52:22 AM10/4/09
to atinject...@googlegroups.com
On Sat, Oct 3, 2009 at 11:47 PM, Gavin King <gavin...@gmail.com> wrote:
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.
 
What does 299 do? If it still injects Tire, an impl should pass the TCK with no problem. If it injects SpareTire, it changes the behavior of existing code.

Bob

Jesse Wilson

unread,
Oct 4, 2009, 2:26:24 AM10/4/09
to atinject...@googlegroups.com
I've got technical concerns with JSR-299's approach to modular configuration. Although it "includes explicit support for modularity", Gavin made this concession:

On Sat, Oct 3, 2009 at 9:34 PM, Gavin King <gavin...@gmail.com> wrote:
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.

In the projects I've been involved with, broad functionality gets repurposed, reused and refactored.

Here's a hypothetical example.
Suppose that the location module from Google Maps is adopted for geotagging in Picasa. Both Maps and Picasa use ImageCacher to make downloads faster. Picasa uses the base class, which maximizes image privacy. Maps uses a subclass, ContentDeliveryNetworkImageCacher, which sends images to a public content delivery network. When we add Maps functionality to Picasa, we effectively merge their giant codebases. When introducing a subclass changes behaviour, in this scenario Picasa would leak private user data.

So ultimately, modularity requires encapsulation. Does JSR-299 address problems of this scale?

Pete Muir

unread,
Oct 4, 2009, 8:11:37 AM10/4/09
to atinject...@googlegroups.com

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.

Gavin King

unread,
Oct 4, 2009, 10:18:41 AM10/4/09
to atinject...@googlegroups.com
On Sun, Oct 4, 2009 at 2:26 AM, Jesse Wilson <je...@swank.ca> wrote:

> 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.

Gavin King

unread,
Oct 4, 2009, 10:21:25 AM10/4/09
to atinject...@googlegroups.com
On Sun, Oct 4, 2009 at 10:18 AM, Gavin King <gavin...@gmail.com> wrote:
> On Sun, Oct 4, 2009 at 2:26 AM, Jesse Wilson <je...@swank.ca> wrote:
>
>> 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.

Pete Muir

unread,
Oct 4, 2009, 11:49:01 AM10/4/09
to atinject...@googlegroups.com, JSR-299 Feedback

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 ;-):

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

Bes,t

Pete


Bob Lee

unread,
Oct 4, 2009, 11:57:23 AM10/4/09
to atinject...@googlegroups.com, JSR-299 Feedback
On Sun, Oct 4, 2009 at 10:49 AM, Pete Muir <pm...@bleepbleep.org.uk> wrote:
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

Nice work, Pete! 
It's a good thing this is open source. It's certainly better than arbitrarily "modularizing" an app with ears.

Bob 

Jesse Wilson

unread,
Oct 4, 2009, 4:18:30 PM10/4/09
to atinject...@googlegroups.com, JSR-299 Feedback
Pete,

This is fantastic. I agree that in this form, the BeanDisambiguator seems too tightly-coupled to implementation details within the TCK.

Would it be reasonable to create a helper class, say, AbstractBeanDisambiguator, to make it easier to address problems of this form? I'm imagining something like this:

public class PlainTireMapper
    extends AbstractInjectionMapper {

  @Override protected Mapping getMapping() {
    return new Mapping(Tire.class, null, Tire.class, Plain.class, new AnnotationLiteral<Plain>() {});
  }
}

This instruct the 299 injector to interpret each injection of an unannotated Tire as a @Plain Tire. This helper API would address the specific TCK problem, and also the other potential problems that we've raised regarding 299.

The AbstractBeanDisambiguator class would be functionally similar to your BeanDisambiguator. But it would figure out which injections to remap by discovery instead of requiring them to be explicitly listed in the code.

Cheers,
Jesse

PS - technical and political discussions tend to frustrate, but decisions need to be made. I'm very happy to see much constructive technical work from our community.

Mark Struberg

unread,
Oct 5, 2009, 4:03:54 AM10/5/09
to atinject...@googlegroups.com, JSR-299 Feedback
JFTR this will not work in OpenWebBeans!

LieGrue,
strub

--- On Sun, 10/4/09, Pete Muir <pm...@bleepbleep.org.uk> wrote:

> From: Pete Muir <pm...@bleepbleep.org.uk>
> Subject: [jsr330-observer] Re: [jsr330-eg] Please try the JSR-330 TCK.
> To: atinject...@googlegroups.com

Pete Muir

unread,
Oct 5, 2009, 5:50:34 AM10/5/09
to atinject...@googlegroups.com, JSR-299 Feedback
Hi Jesse,

On 4 Oct 2009, at 21:18, Jesse Wilson wrote:

> Pete,
>
> This is fantastic. I agree that in this form, the BeanDisambiguator
> seems too tightly-coupled to implementation details within the TCK.

Agreed.

Historically, 299 added this metamodel SPI to allow portable
extensions to be built, which could include XML configuration,
programmatic configuration (like you propose) etc. (Mike Keith pointed
out to me that you could easily do this disambiguation work via the
XML config that was originally in the 299 spec, and will likely be a
portable extension in the future).

However, I decided for a couple of reasons to take this approach.
First, we are on a tight schedule ;-) Second, for reference purposes,
keeping this as close to the 299 APIs as possible seemed sensible.
Maybe, once we have some of these portable extensions, we'll revisit :-)

Pete

Mark Struberg

unread,
Oct 5, 2009, 6:01:29 AM10/5/09
to atinject...@googlegroups.com, JSR-299 Feedback
Pete convinced me that we can do the same thing for Apache OpenWebBeans also. I'm still not a big fan of this approach but at least it's no showstopper any more.

LieGrue,
strub

--- On Mon, 10/5/09, Mark Struberg <stru...@yahoo.de> wrote:

Werner Keil

unread,
Oct 5, 2009, 1:14:31 PM10/5/09
to atinject-observer
I do know "whois" btw, and GoDaddy has a rather dubious reputation
towards hosting spam strongholds like "000webhost.com" (check their
"whois", but it'll lead to little result now, I did so before they
covered their traces ;-)

What makes it particularly interesting for Google is that some of
these guys openly promote and attempt organised "click-theft" and
nobody really cares about them or tries to shut them down.

Of course this has no direct relation to the JSR, I just wanted to
mention it together with "whois"

Werner
Reply all
Reply to author
Forward
0 new messages