dev@glassfish.java.net

Re: Suggestions for improvements: AMX (generics)

From: Lloyd L Chambers <Lloyd.Chambers_at_Sun.COM>
Date: Fri, 21 Jul 2006 08:29:43 -0700

Kohsuke,

I think it would be great if you would file RFEs for any API
shortcomings you find.

You are correct that in general it cannot be assumed uniform types
for getResourceSet(), and that "? extends J2EEResource" would be a
simpler and better choice.

AMX was originally designed without generics, and I must admit I was
learning as I adapted it to them. No doubt I made more than one
mistake, though I did talk directly with Gilad Bracha about some of
the issues.

Thank you,
Lloyd Chambers
Sun AppServer team

On Jul 20, 2006, at 5:20 PM, Kohsuke Kawaguchi wrote:

> Lloyd L Chambers wrote:
>> The way most methods are defined, it is possible to write code
>> that doesn't require casts. The alternative requires casts for
>> every call. In some cases, compatibility prevented use of
>> improved method signatures including a "Class<T>: parameter.
>> Using JNDIResource as a generic example, one can write the following:
>> Set<JNDIResource> s = server.getResourceSet();
>> TypeCast.checkSet( s, JNDIResource.class ); // optional, throws
>> ClassCastException if elements are not all JNDIResource
>> for( JNDIResource jndi : s ) {
>> }
>
> I guess the part that I don't understand is why a developer can
> assume that this server only has JNDIResources (as opposed to, say,
> FooBarResource?) Is that somehow implied by the type of the
> "server" variable? If so, maybe what you wanted was co-variant
> return type?
>
> Because if it's incorrect for me to assume that the set is really
> actually Set<JNDIResource>s, then your cast elimination just ends
> up masking the problem, because that cast should have made a
> programmer think about "am I really always getting JNDIResource here?"
>
>
>> I completely agree that getResourceSet( Class<T> type) is far
>> better, but that would have been an incompatible change (which we
>> wished to avoid), or an additional method. And getContaineeMap()
>> already provides such functionality, though for compatibility
>> reasons the type passed is String and not Class<T>.
>
> Yeah, compatibility always bites us.
>
>
>>> <T1 extends Serializable,T2 extends Serializable>
>>> void startDeploy(Object deployID,
>>> Map<String,T1> source,
>>> Map<String,T2> plan,
>>> Map<String,String> options)
>>>
>>> ... which should have been just:
>>>
>>> void startDeploy(Object deployID,
>>> Map<String,? extends Serializable> source,
>>> Map<String,? extends Serializable> plan,
>>> Map<String,String> options)
>>>
>> I believe you are correct that the "? extends Serializable"
>> choice would be preferable in this case. The T1/T2 construct
>> enforces uniformity of type (though plain 'Serializable' would
>> suffice also).
>
> To the best of my knowledge, those two type signatures are
> identical. If you are not convinced, I've heard that Effective Java
> reloaded explains this better.
>
> --
> Kohsuke Kawaguchi
> Sun Microsystems kohsuke.kawaguchi_at_sun.com