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<?>> {
|