diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 1399a55ee70f1b302731ad3139f98e86b8e39a70..a6807eccbcf14398948d4099c37314b6983a60f5 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,11 @@ +2004-09-24 Jeroen Frijters <jeroen@frijters.net> + + * java/io/ObjectInputStream.java (readObject): Delegate instantation + of Externalizable classes to ObjectStreamClass. + * java/io/ObjectStreamClass.java (newInstance): New method to + instantiate Externalizable (while ignoring the accessibility of + the constructor). (constructor): New field to cache the constructor. + 2004-09-24 Mark Wielaard <mark@klomp.org> * java/net/URL.java (systemClassLoader): New static field. diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java index 809e9b1c94120be4ed46384cb62643a1c3c01d7c..b9bba27b09bd6b07fcadfe7b0adfdf551c6a9968 100644 --- a/libjava/java/io/ObjectInputStream.java +++ b/libjava/java/io/ObjectInputStream.java @@ -291,29 +291,7 @@ public class ObjectInputStream extends InputStream if (osc.realClassIsExternalizable) { - Externalizable obj = null; - - try - { - obj = (Externalizable)clazz.newInstance(); - } - catch (InstantiationException e) - { - throw new ClassNotFoundException - ("Instance of " + clazz + " could not be created"); - } - catch (IllegalAccessException e) - { - throw new ClassNotFoundException - ("Instance of " + clazz + " could not be created because class or " - + "zero-argument constructor is not accessible"); - } - catch (NoSuchMethodError e) - { - throw new ClassNotFoundException - ("Instance of " + clazz - + " could not be created because zero-argument constructor is not defined"); - } + Externalizable obj = osc.newInstance(); int handle = assignNewHandle(obj); diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java index 08576cd1f7a05def26da07865c7fed0e9c84d248..050ed3d7bac0ad932b540baa9e6f48d7fdc00392 100644 --- a/libjava/java/io/ObjectStreamClass.java +++ b/libjava/java/io/ObjectStreamClass.java @@ -811,6 +811,54 @@ outer: return fieldsArray; } + /** + * Returns a new instance of the Class this ObjectStreamClass corresponds + * to. + * Note that this should only be used for Externalizable classes. + * + * @return A new instance. + */ + Externalizable newInstance() throws InvalidClassException + { + synchronized(this) + { + if (constructor == null) + { + try + { + final Constructor c = clazz.getConstructor(new Class[0]); + + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + c.setAccessible(true); + return null; + } + }); + + constructor = c; + } + catch(NoSuchMethodException x) + { + throw new InvalidClassException(clazz.getName(), + "No public zero-argument constructor"); + } + } + } + + try + { + return (Externalizable)constructor.newInstance(null); + } + catch(Throwable t) + { + throw (InvalidClassException) + new InvalidClassException(clazz.getName(), + "Unable to instantiate").initCause(t); + } + } + public static final ObjectStreamField[] NO_FIELDS = {}; private static Hashtable classLookupTable = new Hashtable(); @@ -840,6 +888,7 @@ outer: boolean realClassIsExternalizable; ObjectStreamField[] fieldMapping; Class firstNonSerializableParent; + private Constructor constructor; // default constructor for Externalizable boolean isProxyClass = false;