From 73eb130916f39f689a0c6089e4ee699d89f85907 Mon Sep 17 00:00:00 2001
From: Jeroen Frijters <jeroen@frijters.net>
Date: Fri, 24 Sep 2004 09:05:10 +0000
Subject: [PATCH] ObjectInputStream.java (readObject): Delegate instantation of
 Externalizable classes to ObjectStreamClass.

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.

From-SVN: r88019
---
 libjava/ChangeLog                      |  8 +++++
 libjava/java/io/ObjectInputStream.java | 24 +------------
 libjava/java/io/ObjectStreamClass.java | 49 ++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 1399a55ee70f..a6807eccbcf1 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 809e9b1c9412..b9bba27b09bd 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 08576cd1f7a0..050ed3d7bac0 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;
 
-- 
GitLab