< prev index next >

src/java.base/share/classes/java/io/ObjectStreamClass.java

Print this page

  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodType;
  31 import java.lang.ref.Reference;
  32 import java.lang.ref.ReferenceQueue;
  33 import java.lang.ref.SoftReference;
  34 import java.lang.ref.WeakReference;
  35 import java.lang.reflect.Constructor;
  36 import java.lang.reflect.Field;

  37 import java.lang.reflect.InvocationTargetException;
  38 import java.lang.reflect.RecordComponent;
  39 import java.lang.reflect.UndeclaredThrowableException;
  40 import java.lang.reflect.Member;
  41 import java.lang.reflect.Method;
  42 import java.lang.reflect.Modifier;
  43 import java.lang.reflect.Proxy;
  44 import java.security.AccessControlContext;
  45 import java.security.AccessController;
  46 import java.security.MessageDigest;
  47 import java.security.NoSuchAlgorithmException;
  48 import java.security.PermissionCollection;
  49 import java.security.Permissions;
  50 import java.security.PrivilegedAction;
  51 import java.security.PrivilegedActionException;
  52 import java.security.PrivilegedExceptionAction;
  53 import java.security.ProtectionDomain;
  54 import java.util.ArrayList;
  55 import java.util.Arrays;
  56 import java.util.Collections;

 486             return entry;
 487         }
 488 
 489         /**
 490          * Returns the thread that created this EntryFuture.
 491          */
 492         Thread getOwner() {
 493             return owner;
 494         }
 495     }
 496 
 497     /**
 498      * Creates local class descriptor representing given class.
 499      */
 500     @SuppressWarnings("removal")
 501     private ObjectStreamClass(final Class<?> cl) {
 502         this.cl = cl;
 503         name = cl.getName();
 504         isProxy = Proxy.isProxyClass(cl);
 505         isEnum = Enum.class.isAssignableFrom(cl);

 506         isRecord = cl.isRecord();
 507         serializable = Serializable.class.isAssignableFrom(cl);
 508         externalizable = Externalizable.class.isAssignableFrom(cl);
 509 
 510         Class<?> superCl = cl.getSuperclass();
 511         superDesc = (superCl != null) ? lookup(superCl, false) : null;
 512         localDesc = this;
 513 
 514         if (serializable) {
 515             AccessController.doPrivileged(new PrivilegedAction<>() {
 516                 public Void run() {
 517                     if (isEnum) {
 518                         suid = 0L;
 519                         fields = NO_FIELDS;
 520                         return null;
 521                     }
 522                     if (cl.isArray()) {
 523                         fields = NO_FIELDS;
 524                         return null;
 525                     }

 557                     readResolveMethod = getInheritableMethod(
 558                         cl, "readResolve", null, Object.class);
 559                     return null;
 560                 }
 561             });
 562         } else {
 563             suid = 0L;
 564             fields = NO_FIELDS;
 565         }
 566 
 567         try {
 568             fieldRefl = getReflector(fields, this);
 569         } catch (InvalidClassException ex) {
 570             // field mismatches impossible when matching local fields vs. self
 571             throw new InternalError(ex);
 572         }
 573 
 574         if (deserializeEx == null) {
 575             if (isEnum) {
 576                 deserializeEx = new ExceptionInfo(name, "enum type");


 577             } else if (cons == null && !isRecord) {
 578                 deserializeEx = new ExceptionInfo(name, "no valid constructor");
 579             }
 580         }
 581         if (isRecord && canonicalCtr == null) {
 582             deserializeEx = new ExceptionInfo(name, "record canonical constructor not found");
 583         } else {
 584             for (int i = 0; i < fields.length; i++) {
 585                 if (fields[i].getField() == null) {
 586                     defaultSerializeEx = new ExceptionInfo(
 587                         name, "unmatched serializable field(s) declared");
 588                 }
 589             }
 590         }
 591         initialized = true;
 592     }
 593 
 594     /**
 595      * Creates blank class descriptor which should be initialized via a
 596      * subsequent call to initProxy(), initNonProxy() or readNonProxy().

1543         ObjectStreamClass desc = new ObjectStreamClass();
1544         if (isProxy) {
1545             desc.initProxy(cl, null, superDesc);
1546         } else {
1547             desc.initNonProxy(this, cl, null, superDesc);
1548         }
1549         return desc;
1550     }
1551 
1552     /**
1553      * Returns public no-arg constructor of given class, or null if none found.
1554      * Access checks are disabled on the returned constructor (if any), since
1555      * the defining class may still be non-public.
1556      */
1557     private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
1558         try {
1559             Constructor<?> cons = cl.getDeclaredConstructor((Class<?>[]) null);
1560             cons.setAccessible(true);
1561             return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
1562                 cons : null;
1563         } catch (NoSuchMethodException ex) {
1564             return null;
1565         }
1566     }
1567 
1568     /**
1569      * Returns subclass-accessible no-arg constructor of first non-serializable
1570      * superclass, or null if none found.  Access checks are disabled on the
1571      * returned constructor (if any).
1572      */
1573     private static Constructor<?> getSerializableConstructor(Class<?> cl) {
1574         return reflFactory.newConstructorForSerialization(cl);
1575     }
1576 
1577     /**
1578      * Returns the canonical constructor for the given record class, or null if
1579      * the not found ( which should never happen for correctly generated record
1580      * classes ).
1581      */
1582     @SuppressWarnings("removal")
1583     private static MethodHandle canonicalRecordCtr(Class<?> cls) {

1872             Method[] methods = cl.getDeclaredMethods();
1873             if ((classMods & Modifier.INTERFACE) != 0) {
1874                 classMods = (methods.length > 0) ?
1875                     (classMods | Modifier.ABSTRACT) :
1876                     (classMods & ~Modifier.ABSTRACT);
1877             }
1878             dout.writeInt(classMods);
1879 
1880             if (!cl.isArray()) {
1881                 /*
1882                  * compensate for change in 1.2FCS in which
1883                  * Class.getInterfaces() was modified to return Cloneable and
1884                  * Serializable for array classes.
1885                  */
1886                 Class<?>[] interfaces = cl.getInterfaces();
1887                 String[] ifaceNames = new String[interfaces.length];
1888                 for (int i = 0; i < interfaces.length; i++) {
1889                     ifaceNames[i] = interfaces[i].getName();
1890                 }
1891                 Arrays.sort(ifaceNames);

1892                 for (int i = 0; i < ifaceNames.length; i++) {
1893                     dout.writeUTF(ifaceNames[i]);

1894                 }
1895             }
1896 
1897             Field[] fields = cl.getDeclaredFields();
1898             MemberSignature[] fieldSigs = new MemberSignature[fields.length];
1899             for (int i = 0; i < fields.length; i++) {
1900                 fieldSigs[i] = new MemberSignature(fields[i]);
1901             }
1902             Arrays.sort(fieldSigs, new Comparator<>() {
1903                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1904                     return ms1.name.compareTo(ms2.name);
1905                 }
1906             });
1907             for (int i = 0; i < fieldSigs.length; i++) {
1908                 MemberSignature sig = fieldSigs[i];
1909                 int mods = sig.member.getModifiers() &
1910                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1911                      Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
1912                      Modifier.TRANSIENT);
1913                 if (((mods & Modifier.PRIVATE) == 0) ||

  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodType;
  31 import java.lang.ref.Reference;
  32 import java.lang.ref.ReferenceQueue;
  33 import java.lang.ref.SoftReference;
  34 import java.lang.ref.WeakReference;
  35 import java.lang.reflect.Constructor;
  36 import java.lang.reflect.Field;
  37 import java.lang.reflect.InaccessibleObjectException;
  38 import java.lang.reflect.InvocationTargetException;
  39 import java.lang.reflect.RecordComponent;
  40 import java.lang.reflect.UndeclaredThrowableException;
  41 import java.lang.reflect.Member;
  42 import java.lang.reflect.Method;
  43 import java.lang.reflect.Modifier;
  44 import java.lang.reflect.Proxy;
  45 import java.security.AccessControlContext;
  46 import java.security.AccessController;
  47 import java.security.MessageDigest;
  48 import java.security.NoSuchAlgorithmException;
  49 import java.security.PermissionCollection;
  50 import java.security.Permissions;
  51 import java.security.PrivilegedAction;
  52 import java.security.PrivilegedActionException;
  53 import java.security.PrivilegedExceptionAction;
  54 import java.security.ProtectionDomain;
  55 import java.util.ArrayList;
  56 import java.util.Arrays;
  57 import java.util.Collections;

 487             return entry;
 488         }
 489 
 490         /**
 491          * Returns the thread that created this EntryFuture.
 492          */
 493         Thread getOwner() {
 494             return owner;
 495         }
 496     }
 497 
 498     /**
 499      * Creates local class descriptor representing given class.
 500      */
 501     @SuppressWarnings("removal")
 502     private ObjectStreamClass(final Class<?> cl) {
 503         this.cl = cl;
 504         name = cl.getName();
 505         isProxy = Proxy.isProxyClass(cl);
 506         isEnum = Enum.class.isAssignableFrom(cl);
 507         boolean isPrimitiveClass = cl.isPrimitiveClass();
 508         isRecord = cl.isRecord();
 509         serializable = Serializable.class.isAssignableFrom(cl);
 510         externalizable = Externalizable.class.isAssignableFrom(cl);
 511 
 512         Class<?> superCl = cl.getSuperclass();
 513         superDesc = (superCl != null) ? lookup(superCl, false) : null;
 514         localDesc = this;
 515 
 516         if (serializable) {
 517             AccessController.doPrivileged(new PrivilegedAction<>() {
 518                 public Void run() {
 519                     if (isEnum) {
 520                         suid = 0L;
 521                         fields = NO_FIELDS;
 522                         return null;
 523                     }
 524                     if (cl.isArray()) {
 525                         fields = NO_FIELDS;
 526                         return null;
 527                     }

 559                     readResolveMethod = getInheritableMethod(
 560                         cl, "readResolve", null, Object.class);
 561                     return null;
 562                 }
 563             });
 564         } else {
 565             suid = 0L;
 566             fields = NO_FIELDS;
 567         }
 568 
 569         try {
 570             fieldRefl = getReflector(fields, this);
 571         } catch (InvalidClassException ex) {
 572             // field mismatches impossible when matching local fields vs. self
 573             throw new InternalError(ex);
 574         }
 575 
 576         if (deserializeEx == null) {
 577             if (isEnum) {
 578                 deserializeEx = new ExceptionInfo(name, "enum type");
 579             } else if (isPrimitiveClass && writeReplaceMethod == null) {
 580                 deserializeEx = new ExceptionInfo(name, "primitive class");
 581             } else if (cons == null && !isRecord) {
 582                 deserializeEx = new ExceptionInfo(name, "no valid constructor");
 583             }
 584         }
 585         if (isRecord && canonicalCtr == null) {
 586             deserializeEx = new ExceptionInfo(name, "record canonical constructor not found");
 587         } else {
 588             for (int i = 0; i < fields.length; i++) {
 589                 if (fields[i].getField() == null) {
 590                     defaultSerializeEx = new ExceptionInfo(
 591                         name, "unmatched serializable field(s) declared");
 592                 }
 593             }
 594         }
 595         initialized = true;
 596     }
 597 
 598     /**
 599      * Creates blank class descriptor which should be initialized via a
 600      * subsequent call to initProxy(), initNonProxy() or readNonProxy().

1547         ObjectStreamClass desc = new ObjectStreamClass();
1548         if (isProxy) {
1549             desc.initProxy(cl, null, superDesc);
1550         } else {
1551             desc.initNonProxy(this, cl, null, superDesc);
1552         }
1553         return desc;
1554     }
1555 
1556     /**
1557      * Returns public no-arg constructor of given class, or null if none found.
1558      * Access checks are disabled on the returned constructor (if any), since
1559      * the defining class may still be non-public.
1560      */
1561     private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
1562         try {
1563             Constructor<?> cons = cl.getDeclaredConstructor((Class<?>[]) null);
1564             cons.setAccessible(true);
1565             return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
1566                 cons : null;
1567         } catch (NoSuchMethodException | InaccessibleObjectException ex) {
1568             return null;
1569         }
1570     }
1571 
1572     /**
1573      * Returns subclass-accessible no-arg constructor of first non-serializable
1574      * superclass, or null if none found.  Access checks are disabled on the
1575      * returned constructor (if any).
1576      */
1577     private static Constructor<?> getSerializableConstructor(Class<?> cl) {
1578         return reflFactory.newConstructorForSerialization(cl);
1579     }
1580 
1581     /**
1582      * Returns the canonical constructor for the given record class, or null if
1583      * the not found ( which should never happen for correctly generated record
1584      * classes ).
1585      */
1586     @SuppressWarnings("removal")
1587     private static MethodHandle canonicalRecordCtr(Class<?> cls) {

1876             Method[] methods = cl.getDeclaredMethods();
1877             if ((classMods & Modifier.INTERFACE) != 0) {
1878                 classMods = (methods.length > 0) ?
1879                     (classMods | Modifier.ABSTRACT) :
1880                     (classMods & ~Modifier.ABSTRACT);
1881             }
1882             dout.writeInt(classMods);
1883 
1884             if (!cl.isArray()) {
1885                 /*
1886                  * compensate for change in 1.2FCS in which
1887                  * Class.getInterfaces() was modified to return Cloneable and
1888                  * Serializable for array classes.
1889                  */
1890                 Class<?>[] interfaces = cl.getInterfaces();
1891                 String[] ifaceNames = new String[interfaces.length];
1892                 for (int i = 0; i < interfaces.length; i++) {
1893                     ifaceNames[i] = interfaces[i].getName();
1894                 }
1895                 Arrays.sort(ifaceNames);
1896                 // Skip IdentityObject to keep the computed SVUID the same.
1897                 for (int i = 0; i < ifaceNames.length; i++) {
1898                     if (!"java.lang.IdentityObject".equals(ifaceNames[i]))
1899                         dout.writeUTF(ifaceNames[i]);
1900                 }
1901             }
1902 
1903             Field[] fields = cl.getDeclaredFields();
1904             MemberSignature[] fieldSigs = new MemberSignature[fields.length];
1905             for (int i = 0; i < fields.length; i++) {
1906                 fieldSigs[i] = new MemberSignature(fields[i]);
1907             }
1908             Arrays.sort(fieldSigs, new Comparator<>() {
1909                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1910                     return ms1.name.compareTo(ms2.name);
1911                 }
1912             });
1913             for (int i = 0; i < fieldSigs.length; i++) {
1914                 MemberSignature sig = fieldSigs[i];
1915                 int mods = sig.member.getModifiers() &
1916                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1917                      Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
1918                      Modifier.TRANSIENT);
1919                 if (((mods & Modifier.PRIVATE) == 0) ||
< prev index next >