classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Object serialization and final fields


From: Guilhem Lavaux
Subject: Re: Object serialization and final fields
Date: Fri, 02 Apr 2004 21:52:27 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030630

Hi,

Here is the real patch for object serialization. I've added new static methods to VMObjectStreamClass and changed the methods called in ObjectStreamField accordingly. Note that we need to check all exceptions now as the native functions may fail for some other obscure reasons.

ChangeLog entry:

2004-04-02  Guilhem Lavaux <address@hidden>

        * java/io/ObjectStreamField.java
        (setBooleanField, setCharField, setByteField, setShortField,
        setIntField, setLongField, setFloatField, setDoubleField): Use
        native methods directly to be able to set final fields.

        * vm/reference/java/io/VMObjectStreamClass.java
        (setBooleanNative, setCharNative, setByteNative, setShortNative,
        setIntNative, setLongNative, setFloatNative, setDoubleNative):
        New methods for serialization to be able to set final fields.

        * native/jni/java-io/java_io_VMObjectStreamClass.c:
        Implemented new native methods of java.io.VMObjectStreamClass
        accordingly.

Cheers,

Guilhem.

P.S.: If nobody is against, I'll check it in on sunday.
Index: java/io/ObjectStreamField.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/io/ObjectStreamField.java,v
retrieving revision 1.14
diff -u -b -B -r1.14 ObjectStreamField.java
--- java/io/ObjectStreamField.java      26 Feb 2004 07:53:15 -0000      1.14
+++ java/io/ObjectStreamField.java      2 Apr 2004 19:42:15 -0000
@@ -38,9 +38,9 @@
 
 package java.io;
 
+import gnu.java.lang.reflect.TypeSignature;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import gnu.java.lang.reflect.TypeSignature;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -64,7 +64,6 @@
   {
     this (field.getName(), field.getType());
     this.field = field;
-    toset = !Modifier.isFinal(field.getModifiers());
   }
 
   /**
@@ -357,9 +356,9 @@
   {
     try
       {
-       field.setBoolean(obj, val);
+       VMObjectStreamClass.setBooleanNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -369,9 +368,9 @@
   {
     try
       {
-       field.setByte(obj, val);
+       VMObjectStreamClass.setByteNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -381,9 +380,9 @@
   {
     try
       {
-       field.setChar(obj, val);
+       VMObjectStreamClass.setCharNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -393,9 +392,9 @@
   {
     try
       {
-       field.setShort(obj, val);
+       VMObjectStreamClass.setShortNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -405,9 +404,9 @@
   {
     try
       {
-       field.setInt(obj, val);
+       VMObjectStreamClass.setIntNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -417,9 +416,9 @@
   {
     try
       {
-       field.setLong(obj, val);
+       VMObjectStreamClass.setLongNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -429,9 +428,9 @@
   {
     try
       {
-       field.setFloat(obj, val);
+       VMObjectStreamClass.setFloatNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
@@ -441,21 +440,22 @@
   {
     try
       {
-       field.setDouble(obj, val);
+       VMObjectStreamClass.setDoubleNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
   }
   
+  
   final void setObjectField(Object obj, Object val)
   { 
     try
       {
-       field.set(obj, val);
+       VMObjectStreamClass.setObjectNative(field, obj, val);
       }
-    catch(IllegalAccessException x)
+    catch(Exception x)
       {
        throw new InternalError(x.getMessage());
       }
Index: native/jni/java-io/java_io_VMObjectStreamClass.c
===================================================================
RCS file: 
/cvsroot/classpath/classpath/native/jni/java-io/java_io_VMObjectStreamClass.c,v
retrieving revision 1.3
diff -u -b -B -r1.3 java_io_VMObjectStreamClass.c
--- native/jni/java-io/java_io_VMObjectStreamClass.c    29 Mar 2004 07:07:27 
-0000      1.3
+++ native/jni/java-io/java_io_VMObjectStreamClass.c    2 Apr 2004 19:42:17 
-0000
@@ -59,3 +59,195 @@
     }
   return JNI_TRUE;
 }
+
+static jfieldID getFieldReference(JNIEnv *env, jobject field, jobject object, 
const char *type)
+{
+  jclass fieldClass;
+  jclass objectClass;
+  jfieldID fid;
+  const jbyte *field_name;
+  jmethodID mid;
+  jstring name;
+
+  fieldClass = (*env)->GetObjectClass(env, field);
+
+  mid = (*env)->GetMethodID(env, fieldClass, "getName", 
"()Ljava/lang/String;");
+  if (mid == NULL)
+    return NULL;
+
+  name = (*env)->CallObjectMethod(env, field, mid);
+  field_name = (*env)->GetStringUTFChars(env, name, NULL);
+  
+  objectClass = (*env)->GetObjectClass(env, object);
+  fid = (*env)->GetFieldID(env, objectClass, field_name, type);
+  if (fid == NULL)
+      return NULL;
+  (*env)->ReleaseStringUTFChars(env, name, field_name);
+  
+  return fid;
+}
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setBooleanNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setBooleanNative( JNIEnv * env,
+                                                  jclass vmosklass,
+                                                  jobject field,
+                                                  jobject object,
+                                                  jboolean value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "Z");
+
+  if (fid != NULL)
+    (*env)->SetBooleanField(env, object, fid, value);
+}
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setCharNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;C)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setCharNative( JNIEnv * env,
+                                               jclass vmosklass,
+                                               jobject field,
+                                               jobject object,
+                                               jchar value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "C");
+
+  if (fid != NULL)
+    (*env)->SetCharField(env, object, fid, value);
+}
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setByteNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;B)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setByteNative( JNIEnv * env,
+                                               jclass vmosklass,
+                                               jobject field,
+                                               jobject object,
+                                               jbyte value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "B");
+
+  if (fid != NULL)
+    (*env)->SetByteField(env, object, fid, value);
+}
+
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setShortNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;S)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setShortNative( JNIEnv * env,
+                                                jclass vmosklass,
+                                                jobject field,
+                                                jobject object,
+                                                jshort value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "S");
+
+  if (fid != NULL)
+    (*env)->SetShortField(env, object, fid, value);
+}
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setIntNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setIntNative( JNIEnv * env,
+                                              jclass vmosklass,
+                                              jobject field,
+                                              jobject object,
+                                              jint value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "I");
+
+  if (fid != NULL)
+    (*env)->SetIntField(env, object, fid, value);
+}
+
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setLongNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;J)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setLongNative( JNIEnv * env,
+                                              jclass vmosklass,
+                                              jobject field,
+                                              jobject object,
+                                              jlong value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "J");
+
+  if (fid != NULL)
+    (*env)->SetLongField(env, object, fid, value);
+}
+
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setFloatNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;F)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setFloatNative( JNIEnv * env,
+                                                jclass vmosklass,
+                                                jobject field,
+                                                jobject object,
+                                                jfloat value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "F");
+
+  if (fid != NULL)
+    (*env)->SetFloatField(env, object, fid, value);
+}
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setDoubleNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;D)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setDoubleNative( JNIEnv * env,
+                                                jclass vmosklass,
+                                                jobject field,
+                                                jobject object,
+                                                jdouble value )
+{
+  jfieldID fid = getFieldReference (env, field, object, "D");
+
+  if (fid != NULL)
+    (*env)->SetDoubleField(env, object, fid, value);
+}
+
+/*
+ * Class:     java_io_VMObjectOutputStream
+ * Method:    setObjectNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setObjectNative( JNIEnv * env,
+                                                jclass vmosklass,
+                                                jobject field,
+                                                jobject object,
+                                                jobject value )
+{
+  jfieldID fid = getFieldReference (env, field, object, NULL);
+
+  if (fid != NULL)
+    (*env)->SetObjectField(env, object, fid, value);
+}
Index: vm/reference/java/io/VMObjectStreamClass.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/java/io/VMObjectStreamClass.java,v
retrieving revision 1.1
diff -u -b -B -r1.1 VMObjectStreamClass.java
--- vm/reference/java/io/VMObjectStreamClass.java       17 Jan 2003 16:45:29 
-0000      1.1
+++ vm/reference/java/io/VMObjectStreamClass.java       2 Apr 2004 19:42:17 
-0000
@@ -38,7 +38,7 @@
 
 package java.io;
 
-import java.lang.reflect.Method;
+import java.lang.reflect.Field;
 
 final class VMObjectStreamClass
 {
@@ -47,4 +47,111 @@
     * (a.k.a. <clinit>).
     */
   static native boolean hasClassInitializer (Class clazz);
+
+  /**
+   * Sets the value of the specified field. This method handles "double".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setDoubleNative(Field field, Object obj, double val);
+
+  /**
+   * Sets the value of the specified field. This method handles "float".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setFloatNative(Field field, Object obj, float val);
+
+  /**
+   * Sets the value of the specified field. This method handles "long".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setLongNative(Field field, Object obj, long val);
+  
+  /**
+   * Sets the value of the specified field. This method handles "int".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setIntNative(Field field, Object obj, int val) 
+    throws IllegalAccessException;
+  
+  /**
+   * Sets the value of the specified field. This method handles "short".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setShortNative(Field field, Object obj, short val) 
+    throws IllegalAccessException;
+
+  /**
+   * Sets the value of the specified field. This method handles "char".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setCharNative(Field field, Object obj, char val) 
+    throws IllegalAccessException;
+
+  /**
+   * Sets the value of the specified field. This method handles "byte".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setByteNative(Field field, Object obj, byte val) 
+    throws IllegalAccessException;
+
+  /**
+   * Sets the value of the specified field. This method handles "boolean".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setBooleanNative(Field field, Object obj, boolean val) 
+    throws IllegalAccessException;
+
+  /**
+   * Sets the value of the specified field. This method handles "object".
+   * Warning ! The types are not truely checked here and final values may be
+   * assigned.
+   *
+   * @param field Field to set the value.
+   * @param obj Instance which will have its field set.
+   * @param val Value to put in the field.
+   */
+  static native void setObjectNative(Field field, Object obj, Object val) 
+    throws IllegalAccessException;
+  
 }
+

Attachment: pgp5yy2u89Ckz.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]