Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Hi, On Wed, 2005-12-14 at 20:39 +0100, Guilhem Lavaux wrote: Mark, actually I don't see what benefit we could get of moving some Array.sort copy to getSerialPersistentFields. So I have not done it for the moment. No problem, I just hoped we could safe some duplicate code, but I didn't actually check whether that could actually be done. + + if (fields == ObjectStreamClass.INVALID_FIELDS) + throw new InvalidClassException(serialPersistentFields in class + osc.getName() + is invalid); + Better to use the 2 argument constructor InvalidClassException(String classname, String message) here. Also try to keep line under 80 chars. Cheers, Mark signature.asc Description: This is a digitally signed message part ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Hi, I have just commited the attached patch which is just a slight modification of what I have already sent with some documentation. Mark, actually I don't see what benefit we could get of moving some Array.sort copy to getSerialPersistentFields. So I have not done it for the moment. Cheers, Guilhem. Mark Wielaard wrote: Hi Stuart, On Sun, 2005-12-11 at 21:42 -0500, Stuart Ballard wrote: Throw.uncheckedThrow(new InvalidClassException(...)); A perfectly portable illegal-exception-thrower :) It is a nice hack. But I agree with Guilhem that illegally throwing checked exceptions from methods which are not explicitly documented to do things like that should be avoided. Cheers, Mark Index: java/io/ObjectOutputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectOutputStream.java,v retrieving revision 1.63 diff -u -r1.63 ObjectOutputStream.java --- java/io/ObjectOutputStream.java 1 Nov 2005 14:54:23 - 1.63 +++ java/io/ObjectOutputStream.java 14 Dec 2005 19:37:07 - @@ -442,6 +442,10 @@ realOutput.writeByte(flags); ObjectStreamField[] fields = osc.fields; + + if (fields == ObjectStreamClass.INVALID_FIELDS) + throw new InvalidClassException(serialPersistentFields in class + osc.getName() + is invalid); + realOutput.writeShort(fields.length); ObjectStreamField field; Index: java/io/ObjectStreamClass.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectStreamClass.java,v retrieving revision 1.43 diff -u -r1.43 ObjectStreamClass.java --- java/io/ObjectStreamClass.java 16 Sep 2005 17:24:04 - 1.43 +++ java/io/ObjectStreamClass.java 14 Dec 2005 19:37:07 - @@ -63,6 +63,8 @@ public class ObjectStreamClass implements Serializable { + static final ObjectStreamField[] INVALID_FIELDS = new ObjectStreamField[0]; + /** * Returns the codeObjectStreamClass/code for codecl/code. * If codecl/code is null, or is not codeSerializable/code, @@ -71,6 +73,11 @@ * same codeObjectStreamClass/code object and no recalculation * will be done. * + * Warning: If this class contains an invalid serialPersistentField arrays + * lookup will not throw anything. However [EMAIL PROTECTED] #getFields()} will return + * an empty array and [EMAIL PROTECTED] java.io.ObjectOutputStream#writeObject} will throw an + * [EMAIL PROTECTED] java.io.InvalidClassException}. + * * @see java.io.Serializable */ public static ObjectStreamClass lookup(Class cl) @@ -148,6 +155,8 @@ * Returns the serializable (non-static and non-transient) Fields * of the class represented by this ObjectStreamClass. The Fields * are sorted by name. + * If fields were obtained using serialPersistentFields and this array + * is faulty then the returned array of this method will be empty. * * @return the fields. */ @@ -608,6 +617,28 @@ fields = getSerialPersistentFields(cl); if (fields != null) { + ObjectStreamField[] fieldsName = new ObjectStreamField[fields.length]; + System.arraycopy(fields, 0, fieldsName, 0, fields.length); + + Arrays.sort (fieldsName, new Comparator() { + public int compare(Object o1, Object o2) + { + ObjectStreamField f1 = (ObjectStreamField)o1; + ObjectStreamField f2 = (ObjectStreamField)o2; + + return f1.getName().compareTo(f2.getName()); + } + }); + + for (int i=1; i fields.length; i++) + { + if (fieldsName[i-1].getName().equals(fieldsName[i].getName())) + { + fields = INVALID_FIELDS; + return; + } + } + Arrays.sort (fields); // Retrieve field reference. for (int i=0; i fields.length; i++) ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
On 12/11/05, Guilhem Lavaux [EMAIL PROTECTED] wrote: Bah ! I would rather use a native function that will throw directly InvalidClassException. The problem is that's will be anyway hidden to the general user and that he/she may be surprised getting that sort of exception. I dunno, this seems pretty clean if it works: public class Throw { private static Throwable t; public Throw() throws Throwable {throw t;} public static synchronized void uncheckedThrow(Throwable t) { Throw.t = t; try { Throw.class.newInstance(); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } } } Throw.uncheckedThrow(new InvalidClassException(...)); A perfectly portable illegal-exception-thrower :) -- http://sab39.dev.netreach.com/ ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Hi Stuart, On Sun, 2005-12-11 at 21:42 -0500, Stuart Ballard wrote: Throw.uncheckedThrow(new InvalidClassException(...)); A perfectly portable illegal-exception-thrower :) It is a nice hack. But I agree with Guilhem that illegally throwing checked exceptions from methods which are not explicitly documented to do things like that should be avoided. Cheers, Mark signature.asc Description: This is a digitally signed message part ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Hi. Stuart Ballard wrote: I dunno, this seems pretty clean if it works: public class Throw { private static Throwable t; public Throw() throws Throwable {throw t;} public static synchronized void uncheckedThrow(Throwable t) { Throw.t = t; try { Throw.class.newInstance(); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } } } Throw.uncheckedThrow(new InvalidClassException(...)); A perfectly portable illegal-exception-thrower :) Funny! But it works. cya Robert signature.asc Description: OpenPGP digital signature ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Why not do similar and throw the InvalidClassException from ObjectStreamClass.lookup()? (But then document that clearly in our version of course.) Because we would not have the same API. ObjectStreamClass.lookup may not throw any exception (except the default ones like Error, NPE, ...). O man, it is a checked exception... How ugly. I see why you don't want to do that. This is an ugly suggestion, but it may provide a way to achieve compatibility with this particular broken part of the spec. Jeroen pointed out to me a while back that you can use generics to throw an unchecked exception: private class EvilT extends Throwable { private static void evilThrow(Throwable t) throws T { throw (T) e; // Unchecked cast, will always succeed! } } ... EvilRuntimeException.evilThrow(new InvalidClassException()); This works because EvilRuntimeException.evilThrow only declares that it will throw RuntimeException but the cast from InvalidClassException to RuntimeException is an unchecked one which disappears at runtime. So this code really will throw an InvalidClassException from a method that doesn't declare itself as throwing one. Evil! But maybe the way to go in this case? Stuart. ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Stuart Ballard wrote: Jeroen pointed out to me a while back that you can use generics to throw an unchecked exception: There's also a way to do this without using JDK 1.5 stuff, but it's even uglier :-) Construct a class (dynamically) that has a default constructor that simply throws whatever exception you want. Then invoke Class.newInstance() on the class. -Archie __ Archie Cobbs *CTO, Awarix* http://www.awarix.com ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Re: RFC: Patch for duplicate entries in serialPersistentFields
Archie Cobbs wrote: Stuart Ballard wrote: Jeroen pointed out to me a while back that you can use generics to throw an unchecked exception: There's also a way to do this without using JDK 1.5 stuff, but it's even uglier :-) Construct a class (dynamically) that has a default constructor that simply throws whatever exception you want. Then invoke Class.newInstance() on the class. Bah ! I would rather use a native function that will throw directly InvalidClassException. The problem is that's will be anyway hidden to the general user and that he/she may be surprised getting that sort of exception. Guilhem. ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches