< prev index next >

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

Print this page




 350             future = (EntryFuture) entry;
 351             if (future.getOwner() == Thread.currentThread()) {
 352                 /*
 353                  * Handle nested call situation described by 4803747: waiting
 354                  * for future value to be set by a lookup() call further up the
 355                  * stack will result in deadlock, so calculate and set the
 356                  * future value here instead.
 357                  */
 358                 entry = null;
 359             } else {
 360                 entry = future.get();
 361             }
 362         }
 363         if (entry == null) {
 364             try {
 365                 entry = new ObjectStreamClass(cl);
 366             } catch (Throwable th) {
 367                 entry = th;
 368             }
 369             if (future.set(entry)) {
 370                 Caches.localDescs.put(key, new SoftReference<Object>(entry));
 371             } else {
 372                 // nested lookup call already set future
 373                 entry = future.get();
 374             }
 375         }
 376 
 377         if (entry instanceof ObjectStreamClass) {
 378             return (ObjectStreamClass) entry;
 379         } else if (entry instanceof RuntimeException) {
 380             throw (RuntimeException) entry;
 381         } else if (entry instanceof Error) {
 382             throw (Error) entry;
 383         } else {
 384             throw new InternalError("unexpected entry: " + entry);
 385         }
 386     }
 387 
 388     /**
 389      * Placeholder used in class descriptor and field reflector lookup tables
 390      * for an entry in the process of being initialized.  (Internal) callers


 413             this.entry = entry;
 414             notifyAll();
 415             return true;
 416         }
 417 
 418         /**
 419          * Returns the value contained by this EntryFuture, blocking if
 420          * necessary until a value is set.
 421          */
 422         synchronized Object get() {
 423             boolean interrupted = false;
 424             while (entry == unset) {
 425                 try {
 426                     wait();
 427                 } catch (InterruptedException ex) {
 428                     interrupted = true;
 429                 }
 430             }
 431             if (interrupted) {
 432                 AccessController.doPrivileged(
 433                     new PrivilegedAction<Void>() {
 434                         public Void run() {
 435                             Thread.currentThread().interrupt();
 436                             return null;
 437                         }
 438                     }
 439                 );
 440             }
 441             return entry;
 442         }
 443 
 444         /**
 445          * Returns the thread that created this EntryFuture.
 446          */
 447         Thread getOwner() {
 448             return owner;
 449         }
 450     }
 451 
 452     /**
 453      * Creates local class descriptor representing given class.
 454      */
 455     private ObjectStreamClass(final Class<?> cl) {
 456         this.cl = cl;
 457         name = cl.getName();
 458         isProxy = Proxy.isProxyClass(cl);
 459         isEnum = Enum.class.isAssignableFrom(cl);
 460         serializable = Serializable.class.isAssignableFrom(cl);
 461         externalizable = Externalizable.class.isAssignableFrom(cl);
 462 
 463         Class<?> superCl = cl.getSuperclass();
 464         superDesc = (superCl != null) ? lookup(superCl, false) : null;
 465         localDesc = this;
 466 
 467         if (serializable) {
 468             AccessController.doPrivileged(new PrivilegedAction<Void>() {
 469                 public Void run() {
 470                     if (isEnum) {
 471                         suid = Long.valueOf(0);
 472                         fields = NO_FIELDS;
 473                         return null;
 474                     }
 475                     if (cl.isArray()) {
 476                         fields = NO_FIELDS;
 477                         return null;
 478                     }
 479 
 480                     suid = getDeclaredSUID(cl);
 481                     try {
 482                         fields = getSerialFields(cl);
 483                         computeFieldOffsets();
 484                     } catch (InvalidClassException e) {
 485                         serializeEx = deserializeEx =
 486                             new ExceptionInfo(e.classname, e.getMessage());
 487                         fields = NO_FIELDS;
 488                     }


1716                  * compensate for change in 1.2FCS in which
1717                  * Class.getInterfaces() was modified to return Cloneable and
1718                  * Serializable for array classes.
1719                  */
1720                 Class<?>[] interfaces = cl.getInterfaces();
1721                 String[] ifaceNames = new String[interfaces.length];
1722                 for (int i = 0; i < interfaces.length; i++) {
1723                     ifaceNames[i] = interfaces[i].getName();
1724                 }
1725                 Arrays.sort(ifaceNames);
1726                 for (int i = 0; i < ifaceNames.length; i++) {
1727                     dout.writeUTF(ifaceNames[i]);
1728                 }
1729             }
1730 
1731             Field[] fields = cl.getDeclaredFields();
1732             MemberSignature[] fieldSigs = new MemberSignature[fields.length];
1733             for (int i = 0; i < fields.length; i++) {
1734                 fieldSigs[i] = new MemberSignature(fields[i]);
1735             }
1736             Arrays.sort(fieldSigs, new Comparator<MemberSignature>() {
1737                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1738                     return ms1.name.compareTo(ms2.name);
1739                 }
1740             });
1741             for (int i = 0; i < fieldSigs.length; i++) {
1742                 MemberSignature sig = fieldSigs[i];
1743                 int mods = sig.member.getModifiers() &
1744                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1745                      Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
1746                      Modifier.TRANSIENT);
1747                 if (((mods & Modifier.PRIVATE) == 0) ||
1748                     ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0))
1749                 {
1750                     dout.writeUTF(sig.name);
1751                     dout.writeInt(mods);
1752                     dout.writeUTF(sig.signature);
1753                 }
1754             }
1755 
1756             if (hasStaticInitializer(cl)) {
1757                 dout.writeUTF("<clinit>");
1758                 dout.writeInt(Modifier.STATIC);
1759                 dout.writeUTF("()V");
1760             }
1761 
1762             Constructor<?>[] cons = cl.getDeclaredConstructors();
1763             MemberSignature[] consSigs = new MemberSignature[cons.length];
1764             for (int i = 0; i < cons.length; i++) {
1765                 consSigs[i] = new MemberSignature(cons[i]);
1766             }
1767             Arrays.sort(consSigs, new Comparator<MemberSignature>() {
1768                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1769                     return ms1.signature.compareTo(ms2.signature);
1770                 }
1771             });
1772             for (int i = 0; i < consSigs.length; i++) {
1773                 MemberSignature sig = consSigs[i];
1774                 int mods = sig.member.getModifiers() &
1775                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1776                      Modifier.STATIC | Modifier.FINAL |
1777                      Modifier.SYNCHRONIZED | Modifier.NATIVE |
1778                      Modifier.ABSTRACT | Modifier.STRICT);
1779                 if ((mods & Modifier.PRIVATE) == 0) {
1780                     dout.writeUTF("<init>");
1781                     dout.writeInt(mods);
1782                     dout.writeUTF(sig.signature.replace('/', '.'));
1783                 }
1784             }
1785 
1786             MemberSignature[] methSigs = new MemberSignature[methods.length];
1787             for (int i = 0; i < methods.length; i++) {
1788                 methSigs[i] = new MemberSignature(methods[i]);
1789             }
1790             Arrays.sort(methSigs, new Comparator<MemberSignature>() {
1791                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1792                     int comp = ms1.name.compareTo(ms2.name);
1793                     if (comp == 0) {
1794                         comp = ms1.signature.compareTo(ms2.signature);
1795                     }
1796                     return comp;
1797                 }
1798             });
1799             for (int i = 0; i < methSigs.length; i++) {
1800                 MemberSignature sig = methSigs[i];
1801                 int mods = sig.member.getModifiers() &
1802                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1803                      Modifier.STATIC | Modifier.FINAL |
1804                      Modifier.SYNCHRONIZED | Modifier.NATIVE |
1805                      Modifier.ABSTRACT | Modifier.STRICT);
1806                 if ((mods & Modifier.PRIVATE) == 0) {
1807                     dout.writeUTF(sig.name);
1808                     dout.writeInt(mods);
1809                     dout.writeUTF(sig.signature.replace('/', '.'));
1810                 }


2147                 if (ref != null) {
2148                     entry = ref.get();
2149                 }
2150             } while (ref != null && entry == null);
2151             if (entry == null) {
2152                 future = newEntry;
2153             }
2154         }
2155 
2156         if (entry instanceof FieldReflector) {  // check common case first
2157             return (FieldReflector) entry;
2158         } else if (entry instanceof EntryFuture) {
2159             entry = ((EntryFuture) entry).get();
2160         } else if (entry == null) {
2161             try {
2162                 entry = new FieldReflector(matchFields(fields, localDesc));
2163             } catch (Throwable th) {
2164                 entry = th;
2165             }
2166             future.set(entry);
2167             Caches.reflectors.put(key, new SoftReference<Object>(entry));
2168         }
2169 
2170         if (entry instanceof FieldReflector) {
2171             return (FieldReflector) entry;
2172         } else if (entry instanceof InvalidClassException) {
2173             throw (InvalidClassException) entry;
2174         } else if (entry instanceof RuntimeException) {
2175             throw (RuntimeException) entry;
2176         } else if (entry instanceof Error) {
2177             throw (Error) entry;
2178         } else {
2179             throw new InternalError("unexpected entry: " + entry);
2180         }
2181     }
2182 
2183     /**
2184      * FieldReflector cache lookup key.  Keys are considered equal if they
2185      * refer to the same class and equivalent field formats.
2186      */
2187     private static class FieldReflectorKey extends WeakReference<Class<?>> {




 350             future = (EntryFuture) entry;
 351             if (future.getOwner() == Thread.currentThread()) {
 352                 /*
 353                  * Handle nested call situation described by 4803747: waiting
 354                  * for future value to be set by a lookup() call further up the
 355                  * stack will result in deadlock, so calculate and set the
 356                  * future value here instead.
 357                  */
 358                 entry = null;
 359             } else {
 360                 entry = future.get();
 361             }
 362         }
 363         if (entry == null) {
 364             try {
 365                 entry = new ObjectStreamClass(cl);
 366             } catch (Throwable th) {
 367                 entry = th;
 368             }
 369             if (future.set(entry)) {
 370                 Caches.localDescs.put(key, new SoftReference<>(entry));
 371             } else {
 372                 // nested lookup call already set future
 373                 entry = future.get();
 374             }
 375         }
 376 
 377         if (entry instanceof ObjectStreamClass) {
 378             return (ObjectStreamClass) entry;
 379         } else if (entry instanceof RuntimeException) {
 380             throw (RuntimeException) entry;
 381         } else if (entry instanceof Error) {
 382             throw (Error) entry;
 383         } else {
 384             throw new InternalError("unexpected entry: " + entry);
 385         }
 386     }
 387 
 388     /**
 389      * Placeholder used in class descriptor and field reflector lookup tables
 390      * for an entry in the process of being initialized.  (Internal) callers


 413             this.entry = entry;
 414             notifyAll();
 415             return true;
 416         }
 417 
 418         /**
 419          * Returns the value contained by this EntryFuture, blocking if
 420          * necessary until a value is set.
 421          */
 422         synchronized Object get() {
 423             boolean interrupted = false;
 424             while (entry == unset) {
 425                 try {
 426                     wait();
 427                 } catch (InterruptedException ex) {
 428                     interrupted = true;
 429                 }
 430             }
 431             if (interrupted) {
 432                 AccessController.doPrivileged(
 433                     new PrivilegedAction<>() {
 434                         public Void run() {
 435                             Thread.currentThread().interrupt();
 436                             return null;
 437                         }
 438                     }
 439                 );
 440             }
 441             return entry;
 442         }
 443 
 444         /**
 445          * Returns the thread that created this EntryFuture.
 446          */
 447         Thread getOwner() {
 448             return owner;
 449         }
 450     }
 451 
 452     /**
 453      * Creates local class descriptor representing given class.
 454      */
 455     private ObjectStreamClass(final Class<?> cl) {
 456         this.cl = cl;
 457         name = cl.getName();
 458         isProxy = Proxy.isProxyClass(cl);
 459         isEnum = Enum.class.isAssignableFrom(cl);
 460         serializable = Serializable.class.isAssignableFrom(cl);
 461         externalizable = Externalizable.class.isAssignableFrom(cl);
 462 
 463         Class<?> superCl = cl.getSuperclass();
 464         superDesc = (superCl != null) ? lookup(superCl, false) : null;
 465         localDesc = this;
 466 
 467         if (serializable) {
 468             AccessController.doPrivileged(new PrivilegedAction<>() {
 469                 public Void run() {
 470                     if (isEnum) {
 471                         suid = Long.valueOf(0);
 472                         fields = NO_FIELDS;
 473                         return null;
 474                     }
 475                     if (cl.isArray()) {
 476                         fields = NO_FIELDS;
 477                         return null;
 478                     }
 479 
 480                     suid = getDeclaredSUID(cl);
 481                     try {
 482                         fields = getSerialFields(cl);
 483                         computeFieldOffsets();
 484                     } catch (InvalidClassException e) {
 485                         serializeEx = deserializeEx =
 486                             new ExceptionInfo(e.classname, e.getMessage());
 487                         fields = NO_FIELDS;
 488                     }


1716                  * compensate for change in 1.2FCS in which
1717                  * Class.getInterfaces() was modified to return Cloneable and
1718                  * Serializable for array classes.
1719                  */
1720                 Class<?>[] interfaces = cl.getInterfaces();
1721                 String[] ifaceNames = new String[interfaces.length];
1722                 for (int i = 0; i < interfaces.length; i++) {
1723                     ifaceNames[i] = interfaces[i].getName();
1724                 }
1725                 Arrays.sort(ifaceNames);
1726                 for (int i = 0; i < ifaceNames.length; i++) {
1727                     dout.writeUTF(ifaceNames[i]);
1728                 }
1729             }
1730 
1731             Field[] fields = cl.getDeclaredFields();
1732             MemberSignature[] fieldSigs = new MemberSignature[fields.length];
1733             for (int i = 0; i < fields.length; i++) {
1734                 fieldSigs[i] = new MemberSignature(fields[i]);
1735             }
1736             Arrays.sort(fieldSigs, new Comparator<>() {
1737                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1738                     return ms1.name.compareTo(ms2.name);
1739                 }
1740             });
1741             for (int i = 0; i < fieldSigs.length; i++) {
1742                 MemberSignature sig = fieldSigs[i];
1743                 int mods = sig.member.getModifiers() &
1744                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1745                      Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
1746                      Modifier.TRANSIENT);
1747                 if (((mods & Modifier.PRIVATE) == 0) ||
1748                     ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0))
1749                 {
1750                     dout.writeUTF(sig.name);
1751                     dout.writeInt(mods);
1752                     dout.writeUTF(sig.signature);
1753                 }
1754             }
1755 
1756             if (hasStaticInitializer(cl)) {
1757                 dout.writeUTF("<clinit>");
1758                 dout.writeInt(Modifier.STATIC);
1759                 dout.writeUTF("()V");
1760             }
1761 
1762             Constructor<?>[] cons = cl.getDeclaredConstructors();
1763             MemberSignature[] consSigs = new MemberSignature[cons.length];
1764             for (int i = 0; i < cons.length; i++) {
1765                 consSigs[i] = new MemberSignature(cons[i]);
1766             }
1767             Arrays.sort(consSigs, new Comparator<>() {
1768                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1769                     return ms1.signature.compareTo(ms2.signature);
1770                 }
1771             });
1772             for (int i = 0; i < consSigs.length; i++) {
1773                 MemberSignature sig = consSigs[i];
1774                 int mods = sig.member.getModifiers() &
1775                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1776                      Modifier.STATIC | Modifier.FINAL |
1777                      Modifier.SYNCHRONIZED | Modifier.NATIVE |
1778                      Modifier.ABSTRACT | Modifier.STRICT);
1779                 if ((mods & Modifier.PRIVATE) == 0) {
1780                     dout.writeUTF("<init>");
1781                     dout.writeInt(mods);
1782                     dout.writeUTF(sig.signature.replace('/', '.'));
1783                 }
1784             }
1785 
1786             MemberSignature[] methSigs = new MemberSignature[methods.length];
1787             for (int i = 0; i < methods.length; i++) {
1788                 methSigs[i] = new MemberSignature(methods[i]);
1789             }
1790             Arrays.sort(methSigs, new Comparator<>() {
1791                 public int compare(MemberSignature ms1, MemberSignature ms2) {
1792                     int comp = ms1.name.compareTo(ms2.name);
1793                     if (comp == 0) {
1794                         comp = ms1.signature.compareTo(ms2.signature);
1795                     }
1796                     return comp;
1797                 }
1798             });
1799             for (int i = 0; i < methSigs.length; i++) {
1800                 MemberSignature sig = methSigs[i];
1801                 int mods = sig.member.getModifiers() &
1802                     (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
1803                      Modifier.STATIC | Modifier.FINAL |
1804                      Modifier.SYNCHRONIZED | Modifier.NATIVE |
1805                      Modifier.ABSTRACT | Modifier.STRICT);
1806                 if ((mods & Modifier.PRIVATE) == 0) {
1807                     dout.writeUTF(sig.name);
1808                     dout.writeInt(mods);
1809                     dout.writeUTF(sig.signature.replace('/', '.'));
1810                 }


2147                 if (ref != null) {
2148                     entry = ref.get();
2149                 }
2150             } while (ref != null && entry == null);
2151             if (entry == null) {
2152                 future = newEntry;
2153             }
2154         }
2155 
2156         if (entry instanceof FieldReflector) {  // check common case first
2157             return (FieldReflector) entry;
2158         } else if (entry instanceof EntryFuture) {
2159             entry = ((EntryFuture) entry).get();
2160         } else if (entry == null) {
2161             try {
2162                 entry = new FieldReflector(matchFields(fields, localDesc));
2163             } catch (Throwable th) {
2164                 entry = th;
2165             }
2166             future.set(entry);
2167             Caches.reflectors.put(key, new SoftReference<>(entry));
2168         }
2169 
2170         if (entry instanceof FieldReflector) {
2171             return (FieldReflector) entry;
2172         } else if (entry instanceof InvalidClassException) {
2173             throw (InvalidClassException) entry;
2174         } else if (entry instanceof RuntimeException) {
2175             throw (RuntimeException) entry;
2176         } else if (entry instanceof Error) {
2177             throw (Error) entry;
2178         } else {
2179             throw new InternalError("unexpected entry: " + entry);
2180         }
2181     }
2182 
2183     /**
2184      * FieldReflector cache lookup key.  Keys are considered equal if they
2185      * refer to the same class and equivalent field formats.
2186      */
2187     private static class FieldReflectorKey extends WeakReference<Class<?>> {


< prev index next >