river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject Re: correctness, generics, and spaces
Date Thu, 02 Jun 2011 01:19:27 GMT
The argument for generics in remote interfaces is to reduce boilerplate 
code, the argument against is, it introduces unchecked type casts.  (See 
earlier discussion)

Is there another way to reduce the boilerplate code, using annotations 

Or perhaps generics in combination with an annotation, then we can use 
ASM to weave in type cast checks.

A developer writing code, might not know what type of object T is, but 
after compilation, it will be declared as a specific type in bytecode.  
The weaved bytecode can simply throw an exception that extends 
RemoteException, perhaps called RemoteTypeCastException.

This way the client is protected from a malicious service, designed to 
create runtime exceptions using class cast exceptions.

Unfortunately I don't have the time right now to write such a tool, but 
it would make the use of Generics in remote interfaces typesafe.   I'm 
willing to help where possible if someone has the desire to take up the 
cause and get it started.  At some stage we will probably support 
Generics, at this point it's just easier to tell users that Generics are 
still experimental.

Perhaps annotations and ASM could be used to simply proxy verification 
boilerplate code too.



James Grahn wrote:
> On Tue, May 31, 2011 at 10:51 PM, Shay Hassidim <shay@gigaspaces.com> wrote:
>> James,
>> In case this helps - After similar debates over the years we at GigaSpaces end up
>> <T> T read(T template)
>> <T> T take(T template)
>> write(T entry)
> Quite interesting.   This is exists presently in the experimental
> generics branch, except the type is <T extends Entry>.
> I take this to mean you did not address the corner case that worried
> many on this list?   Does it simply prove to not be an issue in your
> experience?
>> See more here:
>> http://www.gigaspaces.com/docs/JavaDoc8.0/org/openspaces/core/GigaSpace.html
>> Please note we support POJO as well with our implementation as space classes and
not just Classes implementing the Entry interface.
>> This works very well for us.
> Entry, of course, is just a marker interface.   When you say "POJO",
> though you mean Java objects without any requirements upon them?
> (e.g. no requirement of a public, no-arg constructor, no need for
> public fields, etc.)
> The inclusion of asynchronous calls using Futures is also quite
> noteworthy, as is your treatment of "snapshot".   I was about to start
> poking the mailing list about snapshot myself, albeit with a different
> proposal than yours.
> I am now wondering: is the Gigaspaces code available?   Under what
> license?   And is anyone there interested in contributing?
>> Shay Hassidim
>> Deputy CTO
> By the way, welcome!   If nothing else, your feedback in discussions
> will prove valuable, I'm sure.
> james
>> -----Original Message-----
>> From: James Grahn [mailto:grahnian@gmail.com]
>> Sent: Tuesday, May 31, 2011 7:05 PM
>> To: dev@river.apache.org
>> Subject: correctness, generics, and spaces
>> Hello all,
>> I've been doing some pondering on the question of generics in spaces again.
>> ==Background==
>> To refresh those who've forgotten prior discussion, the proposal was to replace methods
like this:
>> Entry read(Entry)
>> With this:
>> <T extends Entry> T read(T)
>> This change was desired because:
>> 1) it reduces boilerplate code (mandatory casting of objects returned from space)
>> 2) it is a more precise statement of the contract by which these methods operate:
i.e. the return type _should be_ the same as the type of the template.
>> Some opposed this change because they felt any use of generics would be seen an implicit
guarantee that there are no corner cases with
>> generics.   Meanwhile, it was hoped, a lack of generics in the
>> interface would be seen as an implicit warning that no guarantees were
>> made about interactions with generics.   Regardless of the API, the
>> current specification does contain corner cases wherein the behavior is potentially
>> Specifically, this corner case was brought up: If an Entry implementation determines
the type of one of its members through a type variable, the returned generic type from a read/take
operation would not be guaranteed to be correct if that variable were wildcarded using "null"
in a javaspace template search.
>> Given:
>> class Box<A extends Serializable> implements Entry{
>>   public A member;
>> }
>> With the generic implementation of spaces:
>> Box<Integer> value = read(new Box<Integer>(5)); //correct Box<Integer>
value2 = read(new Box<Integer>(null)); //potentially incorrect, inconsistent failures.
>> Box<Object> value3 = read(new Box<Object>(null)); //correct, but unhelpful.
>> With the non-generic implementation of spaces:
>> Box<Integer> value = (Box<Integer>) read(new Box<Integer>(5));
//correct Box<Integer> value2 = (Box<Integer>) read(new Box<Integer>(null));
//potentially incorrect, inconsistent failures.
>> Box<?> value3 = (Box<?>) read(new Box<Integer>(null)); //correct,
but unhelpful.
>> Note that regardless of whether the implementation includes generic methods, both
cases require careful thought in the usage of generics to avoid errors. Because of this, a
recommendation was made that Entry objects should probably not have a parameterized types
in general.
>> == Proposal ==
>> What I finally realized: we can actually require Entries to not contain any unassigned
type parameters.
>> Because it is a bad practice regardless, why not do that?
>> Costs:
>> 1) People who are familiar with generics and would always properly handle corner
cases will not be able to do exactly as they please; they would need to provide a fully specified
wrapper class for what would otherwise be their Entry class.
>> 2) An additional runtime check of an Entry's class would slow the execution time
of Javaspace methods (slightly).
>> Benefits:
>> 1) If this clears the opposition for using generics in the Javaspace interface, see
the above mentioned benefits.
>> 2) Prevents violation of the principle of least surprise in using generics with space
(regardless of implementation).
>> == Implementation Detail ==
>> At the interface level, we would need to add a line to the documentation of Entry,
stating that any class implementing Entry may not include type parameters. Entry implementations
already have several requirements which can't be enforced at compile time, so adding another
is not the worst thing in the world.
>> At the implementation level, we'd add enforcement in outrigger's EntryRep.ensureValidClass,
checking to confirm that the Entry that Outrigger is given has no type parameters via reflection.
>> Shouldn't take long to edit the existing generics branch to do this.
>> == Questions ==
>> So here are my questions:
>> 1) Is there a problem transforming this from a bad practice to a forbidden practice?
>> 2) Does this address concerns with the generics? Are there any corner cases this
will not cover?
>> 3) Any other concerns? Anything I'm not seeing?
>> jamesG

View raw message