You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kato-spec@incubator.apache.org by Stuart Monteith <st...@stoo.me.uk> on 2009/05/13 10:41:54 UTC

API changes

Hello All,
    I'd like to start a discussion on changes to the API we should make 
before the Early Draft Review of the API.

One change to make would be to replace the Iterators with Lists. Steve 
has expressed a strong desire to do so as it will enable more useful 
ways to access the API.
Connected with this is the exception handling. Just now we return 
CorruptData objects, but these don't work when the Lists are strongly 
typed using generics.
Carmine has suggested always returning objects of the appropriate type, 
but instead have dummy objects of the appropriate type also implement 
the CorruptData interface.

As I see it it would look like so:

interface JavaHeap {
    List<JavaObject> getObjects();
}

Then we'd ordinarily return at least an object like so:

class JavaObjectImpl implements JavaObject {
}

and in error cases:

class JavaObjectCorruptImpl implements JavaObject, CorruptData {
    public ImagePointer getAddress() {
       return badAddress;
    }

    public String toString() {
       return badMessage;
    }

    public boolean isArray() {
       throw new RuntimeException("This object is corrupt.");
    }
}

so we would do something like the following:

JavaHeap heap = runtime.getHeap();

List<JavaObject> objects = heap.getObjects();

for (JavaObject obj : objects) {
    if (obj instanceof CorruptData) {
       System.err.println("Corrupt object: @ "+ 
((CorruptData)obj).getAddress()+":\""+obj+"\"");
       continue;
    }

    try{
        System.out.println("Instance: "+obj.getID()+" instanceof 
"+obj.getJavaClass().getName());
    }catch (CorruptDataException e){
       e.printStackTrace();
    }
}


Does this look sensible? More importantly, is this an improvement?

I don't like the idea of using a runtime exception within the corrupt 
object, I'd much prefer to return a CorruptDataException, with it 
perhaps returning itself.
Of course, this means adding CorruptDataException to every method, but 
at least that way we're not catching out our callers.
An even more friendly means of dealing with this problem is to use 
Steve's idea of having sensible defaults. Having said that, I don't like 
the idea of defaults messing up the statistics that may be being collected.

Looking forward to your thoughts and comments,
    Stuart


Re: API changes

Posted by Stuart Monteith <st...@stoo.me.uk>.
Comments below...

Adam Pilkington wrote:
> Implementing a CorruptedData interface looks like a sensible way of
> allowing the API to present strongly typed interfaces to the outside
> world. However I would add that I prefer the approach of coding
> runtime exceptions into the dummy object which is returned when the
> data is corrupted. I don't see this as catching out callers as our
> documentation should state something along the lines of "when
> retrieving objects through a list (or other collection) interface, you
> will need to perform a check to see if it implements the
> CorruptedData" interface. I would see the runtime exception as an
> approach to ensure that data is not accessed inadvertently from a
> corrupt object (either through bad coding or the return of default
> values), and is better than having every method declare that it throws
> CorruptDataException. This has a knock on effect in that I can pass
> objects that I know are not corrupt to other functions without having
>   
The assumption here is that CorruptData object are checked deeply for 
whether or not they are entirely correct. Normally, CorruptData on an 
Iterator should be returned if there was a problem retrieving the 
object, not that all of its information is correct. I think that 
practically, object that are not CorruptData objects might still be able 
to throw CorruptDataExceptions.
For example, you might be able to retrieve a JavaClass successfully (no 
CorruptData), but getName() throws a CorruptDataException as the pointer 
to the name is corrupt.
The Iterator, or rather List, wouldn't check the name before returning it.
> that function either declare that it throws CorruptDataException or
> handle it internally when that is never going to be the case.
>
> I've also had a play around with the example For loop that Stuart
> posted to see how things might work in either case.
>
>
> JavaHeap heap = runtime.getHeap();
>
> List<JavaObject> objects = heap.getObjects();
>
> for (JavaObject obj : objects) {
>   if (obj instanceof CorruptData) {
>      System.err.println("Corrupt object: @ "+
> ((CorruptData)obj).getAddress()+":\""+obj+"\"");
>   } else {
>      JavaClass clazz = obj.getJavaClass();
>   
My assumption was that the CorruptData implementations were only 
returned by Lists. When they are being returned by methods directly, you 
will then need to check the type of everything returned by the API that 
is not a primitive or a type outwith the API. In which case, you will 
have to catch CorruptDataExceptions where there is a String or primitive 
returned. That might not be true if there are sensible defaults.
>      if (clazz instanceof CorruptData) {
>        System.err.println("Corrupt object: @ "+
> ((CorruptData)clazz).getAddress()+":\""+obj+"\"");
>        System.out.println("Instance: "+obj.getID()+" has a corrupt Java class");
>      } else {
>
>        System.out.println("Instance: "+obj.getID()+" instanceof
> "+obj.getJavaClass().getName());
>      }
>   }
> }
>
>
> for (JavaObject obj : objects) {
>
>   try{
>     System.out.println("Instance: "+obj.getID()+" instanceof
> "+obj.getJavaClass().getName());
>   }catch (CorruptDataRuntimeException e){
>     e.printStackTrace();            //can explicity catch the runtime
> exception but this still has a problem, see next example
>   }
> }
>
>
>
> for (JavaObject obj : objects) {
>
>   try{
>     System.out.println("Instance: "+obj.getID()+" instanceof
> "+obj.getJavaClass().getName());
>   }catch (CorruptDataException e){
>     e.printStackTrace();            //OK, but we have to look at the
> stack trace to see which objec was corrupt
>   
Somehow, it has to be reported. e.getCorruptData() would return the 
presumably the same CorruptData as you'd two examples previously.
>   }
> }
>
>
> for (JavaObject obj : objects) {
>   try{
>     JavaClass clazz = obj.getJavaClass();
>
>   }catch (CorruptDataException e){
>     e.printStackTrace();
>     continue;                //cannot proceed with processing if I
> can't get a JavaClass object
>   }
>   try{
>     System.out.println("Instance: "+obj.getID()+" instanceof
> "+obj.getJavaClass().getName());
>   } catch (CorruptDataException e) {
>     System.out.println("Instance: "+obj.getID()+" has a corrupt Java class");
>     e.printStackTrace();
>   }
> }
>
>
> 2009/5/13 Stuart Monteith <st...@stoo.me.uk>
>   
>> Hello All,
>>   I'd like to start a discussion on changes to the API we should make before the Early Draft Review of the API.
>>
>> One change to make would be to replace the Iterators with Lists. Steve has expressed a strong desire to do so as it will enable more useful ways to access the API.
>> Connected with this is the exception handling. Just now we return CorruptData objects, but these don't work when the Lists are strongly typed using generics.
>> Carmine has suggested always returning objects of the appropriate type, but instead have dummy objects of the appropriate type also implement the CorruptData interface.
>>
>> As I see it it would look like so:
>>
>> interface JavaHeap {
>>   List<JavaObject> getObjects();
>> }
>>
>> Then we'd ordinarily return at least an object like so:
>>
>> class JavaObjectImpl implements JavaObject {
>> }
>>
>> and in error cases:
>>
>> class JavaObjectCorruptImpl implements JavaObject, CorruptData {
>>   public ImagePointer getAddress() {
>>      return badAddress;
>>   }
>>
>>   public String toString() {
>>      return badMessage;
>>   }
>>
>>   public boolean isArray() {
>>      throw new RuntimeException("This object is corrupt.");
>>   }
>> }
>>
>> so we would do something like the following:
>>
>> JavaHeap heap = runtime.getHeap();
>>
>> List<JavaObject> objects = heap.getObjects();
>>
>> for (JavaObject obj : objects) {
>>   if (obj instanceof CorruptData) {
>>      System.err.println("Corrupt object: @ "+ ((CorruptData)obj).getAddress()+":\""+obj+"\"");
>>      continue;
>>   }
>>
>>   try{
>>       System.out.println("Instance: "+obj.getID()+" instanceof "+obj.getJavaClass().getName());
>>   }catch (CorruptDataException e){
>>      e.printStackTrace();
>>   }
>> }
>>
>>
>> Does this look sensible? More importantly, is this an improvement?
>>
>> I don't like the idea of using a runtime exception within the corrupt object, I'd much prefer to return a CorruptDataException, with it perhaps returning itself.
>> Of course, this means adding CorruptDataException to every method, but at least that way we're not catching out our callers.
>> An even more friendly means of dealing with this problem is to use Steve's idea of having sensible defaults. Having said that, I don't like the idea of defaults messing up the statistics that may be being collected.
>>
>> Looking forward to your thoughts and comments,
>>   Stuart
>>
>>     
>
>
>
> --
> Regards
>
> Adam Pilkington
>   

Re: API changes

Posted by Adam Pilkington <pi...@googlemail.com>.
Implementing a CorruptedData interface looks like a sensible way of
allowing the API to present strongly typed interfaces to the outside
world. However I would add that I prefer the approach of coding
runtime exceptions into the dummy object which is returned when the
data is corrupted. I don't see this as catching out callers as our
documentation should state something along the lines of "when
retrieving objects through a list (or other collection) interface, you
will need to perform a check to see if it implements the
CorruptedData" interface. I would see the runtime exception as an
approach to ensure that data is not accessed inadvertently from a
corrupt object (either through bad coding or the return of default
values), and is better than having every method declare that it throws
CorruptDataException. This has a knock on effect in that I can pass
objects that I know are not corrupt to other functions without having
that function either declare that it throws CorruptDataException or
handle it internally when that is never going to be the case.

I've also had a play around with the example For loop that Stuart
posted to see how things might work in either case.


JavaHeap heap = runtime.getHeap();

List<JavaObject> objects = heap.getObjects();

for (JavaObject obj : objects) {
  if (obj instanceof CorruptData) {
     System.err.println("Corrupt object: @ "+
((CorruptData)obj).getAddress()+":\""+obj+"\"");
  } else {
     JavaClass clazz = obj.getJavaClass();
     if (clazz instanceof CorruptData) {
       System.err.println("Corrupt object: @ "+
((CorruptData)clazz).getAddress()+":\""+obj+"\"");
       System.out.println("Instance: "+obj.getID()+" has a corrupt Java class");
     } else {

       System.out.println("Instance: "+obj.getID()+" instanceof
"+obj.getJavaClass().getName());
     }
  }
}


for (JavaObject obj : objects) {

  try{
    System.out.println("Instance: "+obj.getID()+" instanceof
"+obj.getJavaClass().getName());
  }catch (CorruptDataRuntimeException e){
    e.printStackTrace();            //can explicity catch the runtime
exception but this still has a problem, see next example
  }
}



for (JavaObject obj : objects) {

  try{
    System.out.println("Instance: "+obj.getID()+" instanceof
"+obj.getJavaClass().getName());
  }catch (CorruptDataException e){
    e.printStackTrace();            //OK, but we have to look at the
stack trace to see which objec was corrupt
  }
}


for (JavaObject obj : objects) {
  try{
    JavaClass clazz = obj.getJavaClass();

  }catch (CorruptDataException e){
    e.printStackTrace();
    continue;                //cannot proceed with processing if I
can't get a JavaClass object

  }
  try{
    System.out.println("Instance: "+obj.getID()+" instanceof
"+obj.getJavaClass().getName());
  } catch (CorruptDataException e) {
    System.out.println("Instance: "+obj.getID()+" has a corrupt Java class");
    e.printStackTrace();
  }
}


2009/5/13 Stuart Monteith <st...@stoo.me.uk>
>
> Hello All,
>   I'd like to start a discussion on changes to the API we should make before the Early Draft Review of the API.
>
> One change to make would be to replace the Iterators with Lists. Steve has expressed a strong desire to do so as it will enable more useful ways to access the API.
> Connected with this is the exception handling. Just now we return CorruptData objects, but these don't work when the Lists are strongly typed using generics.
> Carmine has suggested always returning objects of the appropriate type, but instead have dummy objects of the appropriate type also implement the CorruptData interface.
>
> As I see it it would look like so:
>
> interface JavaHeap {
>   List<JavaObject> getObjects();
> }
>
> Then we'd ordinarily return at least an object like so:
>
> class JavaObjectImpl implements JavaObject {
> }
>
> and in error cases:
>
> class JavaObjectCorruptImpl implements JavaObject, CorruptData {
>   public ImagePointer getAddress() {
>      return badAddress;
>   }
>
>   public String toString() {
>      return badMessage;
>   }
>
>   public boolean isArray() {
>      throw new RuntimeException("This object is corrupt.");
>   }
> }
>
> so we would do something like the following:
>
> JavaHeap heap = runtime.getHeap();
>
> List<JavaObject> objects = heap.getObjects();
>
> for (JavaObject obj : objects) {
>   if (obj instanceof CorruptData) {
>      System.err.println("Corrupt object: @ "+ ((CorruptData)obj).getAddress()+":\""+obj+"\"");
>      continue;
>   }
>
>   try{
>       System.out.println("Instance: "+obj.getID()+" instanceof "+obj.getJavaClass().getName());
>   }catch (CorruptDataException e){
>      e.printStackTrace();
>   }
> }
>
>
> Does this look sensible? More importantly, is this an improvement?
>
> I don't like the idea of using a runtime exception within the corrupt object, I'd much prefer to return a CorruptDataException, with it perhaps returning itself.
> Of course, this means adding CorruptDataException to every method, but at least that way we're not catching out our callers.
> An even more friendly means of dealing with this problem is to use Steve's idea of having sensible defaults. Having said that, I don't like the idea of defaults messing up the statistics that may be being collected.
>
> Looking forward to your thoughts and comments,
>   Stuart
>



--
Regards

Adam Pilkington

Re: API changes

Posted by Steve Poole <sp...@googlemail.com>.
On Wed, May 13, 2009 at 1:14 PM, Andrew Johnson
<an...@uk.ibm.com>wrote:

> Stuart Monteith <st...@stoo.me.uk> wrote on 13/05/2009 11:41:54:
> >
> > Hello All,
> >     I'd like to start a discussion on changes to the API we should make
> > before the Early Draft Review of the API.
> >
> > One change to make would be to replace the Iterators with Lists. Steve
> > has expressed a strong desire to do so as it will enable more useful
> > ways to access the API.
>

The basic need I have is to be able to access an element directly by
index.   I don't want all the semantics of a list -  I just want  size() and
get(index)  capabilities.


> > Connected with this is the exception handling. Just now we return
> > CorruptData objects, but these don't work when the Lists are strongly
> > typed using generics.
> > Carmine has suggested always returning objects of the appropriate type,
> > but instead have dummy objects of the appropriate type also implement
> > the CorruptData interface.
> >
>
> I think that using Lists for JavaObjects from the heap is going to be
> unworkable if it implies having all the objects in the heap present in the
> list.
>
Thats true - but is the same for iterators.   What the list gives you is an
idea on quantity and the ability access an object directly.


> Is the list modifiable? That would imply having a new copy each time,
> which could also be hard. You need to allow an implementation to
> prohibiting add, addAll, clear, remove, removeAll, retainAll, set. That
> way the list can be shared.
> E.g. Collections.unmodifiableList().
>

yep agree I dont want a modifiable list!

>
> You might be able to make the list for objects from the heap by wrapping
> the heap and getting an iterator when needed.
>
> E.g. implement methods as follows
> contains - get a new iterator, go along entire heap
> containsAll - iterate twice?
> get - iterate to get to required index
>
> listIterator - could be tricky as the iterator can go backward which might
> be hard when traversing the heap.
>
> You could easily have some expensive operations.
>
> List l<JavaObject> = heap.getObjects();
> if (l.subList(1,l.size).containsAll(l.subList(1,l.size-1))
> l.toArray();
> Collections.shuffle(l);
>
> If JavaObjects can't be done as Lists then it seem strange to allow others
> as Lists.
>
> Lists imply ordering, which makes things predictable, but also allow
> duplicates. Would a Set be sufficient? This prohibits duplicates, and also
> doesn't have the tricky listIterator. The set could dynamically get its
> elements as needed from the heap. Is it worth enforcing a predictable
> ordering from the iterator?
>
The DTFJ/PHD reader included here:
> http://www.ibm.com/developerworks/java/jdk/tools/dtfj.html
> has classes such as
> class PHDCorruptJavaObject implements JavaObject, CorruptData
> and PHDJavaHeap
>        public Iterator<JavaObject> getObjects()
>
> so the idea of using generics does work.
>
> Andrew Johnson
>
>
>
>
>
>
> Unless stated otherwise above:
> IBM United Kingdom Limited - Registered in England and Wales with number
> 741598.
> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
>
>
>
>
>
>
>

Re: API changes

Posted by Andrew Johnson <an...@uk.ibm.com>.
Stuart Monteith <st...@stoo.me.uk> wrote on 13/05/2009 11:41:54:
> 
> Hello All,
>     I'd like to start a discussion on changes to the API we should make 
> before the Early Draft Review of the API.
> 
> One change to make would be to replace the Iterators with Lists. Steve 
> has expressed a strong desire to do so as it will enable more useful 
> ways to access the API.
> Connected with this is the exception handling. Just now we return 
> CorruptData objects, but these don't work when the Lists are strongly 
> typed using generics.
> Carmine has suggested always returning objects of the appropriate type, 
> but instead have dummy objects of the appropriate type also implement 
> the CorruptData interface.
> 

I think that using Lists for JavaObjects from the heap is going to be 
unworkable if it implies having all the objects in the heap present in the 
list.

Is the list modifiable? That would imply having a new copy each time, 
which could also be hard. You need to allow an implementation to 
prohibiting add, addAll, clear, remove, removeAll, retainAll, set. That 
way the list can be shared.
E.g. Collections.unmodifiableList().

You might be able to make the list for objects from the heap by wrapping 
the heap and getting an iterator when needed.

E.g. implement methods as follows
contains - get a new iterator, go along entire heap
containsAll - iterate twice?
get - iterate to get to required index

listIterator - could be tricky as the iterator can go backward which might 
be hard when traversing the heap.

You could easily have some expensive operations.

List l<JavaObject> = heap.getObjects();
if (l.subList(1,l.size).containsAll(l.subList(1,l.size-1))
l.toArray();
Collections.shuffle(l);

If JavaObjects can't be done as Lists then it seem strange to allow others 
as Lists.

Lists imply ordering, which makes things predictable, but also allow 
duplicates. Would a Set be sufficient? This prohibits duplicates, and also 
doesn't have the tricky listIterator. The set could dynamically get its 
elements as needed from the heap. Is it worth enforcing a predictable 
ordering from the iterator?

The DTFJ/PHD reader included here:
http://www.ibm.com/developerworks/java/jdk/tools/dtfj.html
has classes such as
class PHDCorruptJavaObject implements JavaObject, CorruptData
and PHDJavaHeap
        public Iterator<JavaObject> getObjects()

so the idea of using generics does work.

Andrew Johnson






Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 
741598. 
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU