Index: working_classlib/modules/misc/src/main/native/accessors/shared/org_apache_harmony_misc_accessors_ObjectAccessorImpl.c =================================================================== --- working_classlib/modules/misc/src/main/native/accessors/shared/org_apache_harmony_misc_accessors_ObjectAccessorImpl.c (revision 649000) +++ working_classlib/modules/misc/src/main/native/accessors/shared/org_apache_harmony_misc_accessors_ObjectAccessorImpl.c (working copy) @@ -307,8 +307,13 @@ */ JNIEXPORT jobject JNICALL Java_org_apache_harmony_misc_accessors_ObjectAccessor_newInstance__Ljava_lang_Class_2J_3Ljava_lang_Object_2 (JNIEnv *env, jobject accessorObj, jclass clss, jlong ctorID, jobjectArray args) { - jvalue* pargs = jarrayToValues(env, args); - jobject res = (*env)->NewObjectA(env, clss, (jmethodID)(intptr_t)ctorID, pargs); + jvalue *pargs = NULL; + jobject res; + + if (args != NULL) { + pargs = jarrayToValues(env, args); + } + res = (*env)->NewObjectA(env, clss, (jmethodID)(intptr_t)ctorID, pargs); free(pargs); return res; } Index: working_classlib/modules/luni/src/main/java/java/io/ObjectInputStream.java =================================================================== --- working_classlib/modules/luni/src/main/java/java/io/ObjectInputStream.java (revision 649000) +++ working_classlib/modules/luni/src/main/java/java/io/ObjectInputStream.java (working copy) @@ -495,25 +495,6 @@ } /** - * Create and return a new instance of class instantiationClass - * but running the constructor defined in class - * constructorClass (same as instantiationClass - * or a superclass). - * - * Has to be native to avoid visibility rules and to be able to have - * instantiationClass not the same as - * constructorClass (no such API in java.lang.reflect). - * - * @param instantiationClass - * The new object will be an instance of this class - * @param constructorClass - * The empty constructor to run will be in this class - * @return the object created from instantiationClass - */ - private static native Object newInstance(Class instantiationClass, - Class constructorClass); - - /** * Return the next int handle to be used to indicate cyclic * references being loaded from the stream. * @@ -1860,51 +1841,9 @@ return Integer.valueOf(input.readInt()); } - /** - * Read a new object from the stream. It is assumed the object has not been - * loaded yet (not a cyclic reference). Return the object read. - * - * If the object implements Externalizable its - * readExternal is called. Otherwise, all fields described by - * the class hierarchy are loaded. Each class can define how its declared - * instance fields are loaded by defining a private method - * readObject - * - * @param unshared - * read the object unshared - * @return the object read - * - * @throws IOException - * If an IO exception happened when reading the object. - * @throws OptionalDataException - * If optional data could not be found when reading the object - * graph - * @throws ClassNotFoundException - * If a class for one of the objects could not be found - */ - private Object readNewObject(boolean unshared) - throws OptionalDataException, ClassNotFoundException, IOException { - ObjectStreamClass classDesc = readClassDesc(); + private Class resolveConstructorClass(Class objectClass, boolean wasSerializable, boolean wasExternalizable) + throws OptionalDataException, ClassNotFoundException, IOException { - if (classDesc == null) { - throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$ - } - - Integer newHandle = Integer.valueOf(nextHandle()); - - // Note that these values come from the Stream, and in fact it could be - // that the classes have been changed so that the info below now - // conflicts with the newer class - boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0; - boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0; - - // Maybe we should cache the values above in classDesc ? It may be the - // case that when reading classDesc we may need to read more stuff - // depending on the values above - Class objectClass = classDesc.forClass(); - - Object result, registeredResult = null; - if (objectClass != null) { // The class of the instance may not be the same as the class of the // constructor to run // This is the constructor to run if Externalizable @@ -1964,9 +1903,66 @@ } } + return constructorClass; + } + + /** + * Read a new object from the stream. It is assumed the object has not been + * loaded yet (not a cyclic reference). Return the object read. + * + * If the object implements Externalizable its + * readExternal is called. Otherwise, all fields described by + * the class hierarchy are loaded. Each class can define how its declared + * instance fields are loaded by defining a private method + * readObject + * + * @param unshared + * read the object unshared + * @return the object read + * + * @throws IOException + * If an IO exception happened when reading the object. + * @throws OptionalDataException + * If optional data could not be found when reading the object + * graph + * @throws ClassNotFoundException + * If a class for one of the objects could not be found + */ + private Object readNewObject(boolean unshared) + throws OptionalDataException, ClassNotFoundException, IOException { + ObjectStreamClass classDesc = readClassDesc(); + + if (classDesc == null) { + throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$ + } + + Integer newHandle = Integer.valueOf(nextHandle()); + + // Note that these values come from the Stream, and in fact it could be + // that the classes have been changed so that the info below now + // conflicts with the newer class + boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0; + boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0; + + + // Maybe we should cache the values above in classDesc ? It may be the + // case that when reading classDesc we may need to read more stuff + // depending on the values above + Class objectClass = classDesc.forClass(); + + Object result, registeredResult = null; + if (objectClass != null) { + + long constructor = classDesc.getConstructor(); + if (constructor == ObjectStreamClass.CONSTRUCTOR_IS_NOT_RESOLVED) { + constructor = accessor.getMethodID(resolveConstructorClass(objectClass, wasSerializable, wasExternalizable), null, new Class[0]); + classDesc.setConstructor(constructor); + } + // Now we know which class to instantiate and which constructor to // run. We are allowed to run the constructor. - result = newInstance(objectClass, constructorClass); + result = accessor.newInstance(objectClass, constructor, null); + registerObjectRead(result, newHandle, unshared); registeredResult = result; Index: working_classlib/modules/luni/src/main/java/java/io/ObjectStreamClass.java =================================================================== --- working_classlib/modules/luni/src/main/java/java/io/ObjectStreamClass.java (revision 649000) +++ working_classlib/modules/luni/src/main/java/java/io/ObjectStreamClass.java (working copy) @@ -58,6 +58,8 @@ // Name of the field that contains the SUID value (if present) private static final String UID_FIELD_NAME = "serialVersionUID"; //$NON-NLS-1$ + static final long CONSTRUCTOR_IS_NOT_RESOLVED = -1; + private static final int CLASS_MODIFIERS_MASK; private static final int FIELD_MODIFIERS_MASK; @@ -174,6 +176,17 @@ // Array of ObjectStreamField describing the serialized fields of this class private transient ObjectStreamField[] loadFields; + // MethodID for deserialization constructor + private transient long constructor = CONSTRUCTOR_IS_NOT_RESOLVED; + + void setConstructor(long newConstructor) { + constructor = newConstructor; + } + + long getConstructor() { + return constructor; + } + /* * If an ObjectStreamClass describes an Externalizable class, it (the * descriptor) should not have field descriptors (ObjectStreamField) at all. Index: working_classlib/modules/luni/src/main/native/luni/unix/makefile =================================================================== --- working_classlib/modules/luni/src/main/native/luni/unix/makefile (revision 649000) +++ working_classlib/modules/luni/src/main/native/luni/unix/makefile (working copy) @@ -27,7 +27,7 @@ BUILDFILES = \ $(SHAREDSUB)luni_copyright.o $(SHAREDSUB)file.o procimpl.o \ $(SHAREDSUB)nethelp.o \ - $(SHAREDSUB)floatbits.o $(SHAREDSUB)ois.o \ + $(SHAREDSUB)floatbits.o \ helpers.o $(SHAREDSUB)math.o $(SHAREDSUB)luniglob.o \ $(SHAREDSUB)proxy.o \ $(SHAREDSUB)cbigint.o $(SHAREDSUB)dblparse.o $(SHAREDSUB)fltparse.o \ Index: working_classlib/modules/luni/src/main/native/luni/shared/ois.c =================================================================== --- working_classlib/modules/luni/src/main/native/luni/shared/ois.c (revision 645928) +++ working_classlib/modules/luni/src/main/native/luni/shared/ois.c (working copy) @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "jni.h" - -JNIEXPORT jobject JNICALL -Java_java_io_ObjectInputStream_newInstance (JNIEnv * env, jclass clazz, - jobject instantiationClass, - jobject constructorClass) -{ - jmethodID mid = - (*env)->GetMethodID (env, constructorClass, "", "()V"); - - if (mid == 0) - { - /* Cant newInstance,No empty constructor... */ - return (jobject) 0; - } - else - { - /* Instantiate an object of a given class and construct it using - the constructor of the other class. */ - jobject obj; - obj = (*env)->AllocObject(env, instantiationClass); - if (obj != NULL) { - (*env)->CallNonvirtualVoidMethod(env, obj, constructorClass, mid); - } - return obj; - } - -} - Index: working_classlib/modules/luni/src/main/native/luni/windows/makefile =================================================================== --- working_classlib/modules/luni/src/main/native/luni/windows/makefile (revision 649000) +++ working_classlib/modules/luni/src/main/native/luni/windows/makefile (working copy) @@ -28,7 +28,7 @@ BUILDFILES = \ $(SHAREDSUB)luni_copyright.obj $(SHAREDSUB)file.obj procimpl.obj \ $(SHAREDSUB)nethelp.obj $(SHAREDSUB)floatbits.obj \ - $(SHAREDSUB)ois.obj helpers.obj $(SHAREDSUB)math.obj \ + helpers.obj $(SHAREDSUB)math.obj \ $(SHAREDSUB)luniglob.obj $(SHAREDSUB)proxy.obj $(SHAREDSUB)netif.obj \ $(SHAREDSUB)cbigint.obj $(SHAREDSUB)dblparse.obj $(SHAREDSUB)fltparse.obj \ $(SHAREDSUB)process.obj $(SHAREDSUB)bigint.obj $(SHAREDSUB)osc.obj \