1 7 15 16 package com.sun.corba.se.impl.io; 17 18 import java.security.MessageDigest ; 19 import java.security.NoSuchAlgorithmException ; 20 import java.security.DigestOutputStream ; 21 import java.security.AccessController ; 22 import java.security.PrivilegedExceptionAction ; 23 import java.security.PrivilegedActionException ; 24 import java.security.PrivilegedAction ; 25 26 import java.lang.reflect.Modifier ; 27 import java.lang.reflect.Array ; 28 import java.lang.reflect.Field ; 29 import java.lang.reflect.Member ; 30 import java.lang.reflect.Method ; 31 import java.lang.reflect.Constructor ; 32 import java.lang.reflect.Proxy ; 33 import java.lang.reflect.InvocationTargetException ; 34 35 import java.io.IOException ; 36 import java.io.DataOutputStream ; 37 import java.io.ByteArrayOutputStream ; 38 import java.io.InvalidClassException ; 39 import java.io.Serializable ; 40 41 import java.util.Arrays ; 42 import java.util.Comparator ; 43 import java.util.Hashtable ; 44 45 import com.sun.corba.se.impl.util.RepositoryId; 46 47 import sun.misc.SoftCache; 48 49 import org.omg.CORBA.ValueMember ; 50 51 import sun.corba.Bridge; 52 53 65 public class ObjectStreamClass implements java.io.Serializable { 66 private static final boolean DEBUG_SVUID = false ; 67 68 public static final long kDefaultUID = -1; 69 70 private static Object noArgsList[] = {}; 71 private static Class noTypesList[] = {}; 72 73 private static Hashtable translatedFields; 74 75 private static final Bridge bridge = 76 (Bridge)AccessController.doPrivileged( 77 new PrivilegedAction () { 78 public Object run() { 79 return Bridge.get() ; 80 } 81 } 82 ) ; 83 84 88 static final ObjectStreamClass lookup(Class cl) 89 { 90 ObjectStreamClass desc = lookupInternal(cl); 91 if (desc.isSerializable() || desc.isExternalizable()) 92 return desc; 93 return null; 94 } 95 96 100 static ObjectStreamClass lookupInternal(Class cl) 101 { 102 105 ObjectStreamClass desc = null; 106 synchronized (descriptorFor) { 107 108 desc = (ObjectStreamClass)descriptorFor.get(cl); 109 if (desc == null) { 110 111 boolean serializable = classSerializable.isAssignableFrom(cl); 112 113 116 ObjectStreamClass superdesc = null; 117 if (serializable) { 118 Class superclass = cl.getSuperclass(); 119 if (superclass != null) 120 superdesc = lookup(superclass); 121 } 122 123 127 boolean externalizable = false; 128 if (serializable) { 129 externalizable = 130 ((superdesc != null) && superdesc.isExternalizable()) || 131 classExternalizable.isAssignableFrom(cl); 132 if (externalizable) { 133 serializable = false; 134 } 135 } 136 137 140 desc = new ObjectStreamClass(cl, superdesc, 141 serializable, externalizable); 142 } 143 144 desc.init(); 159 } 160 161 return desc; 162 } 163 164 167 public final String getName() { 168 return name; 169 } 170 171 177 public static final long getSerialVersionUID( java.lang.Class clazz) { 178 ObjectStreamClass theosc = ObjectStreamClass.lookup( clazz ); 179 if( theosc != null ) 180 { 181 return theosc.getSerialVersionUID( ); 182 } 183 return 0; 184 } 185 186 192 public final long getSerialVersionUID() { 193 return suid; 194 } 195 196 202 public final String getSerialVersionUIDStr() { 203 if (suidStr == null) 204 suidStr = Long.toHexString(suid).toUpperCase(); 205 return suidStr; 206 } 207 208 211 public static final long getActualSerialVersionUID( java.lang.Class clazz ) 212 { 213 ObjectStreamClass theosc = ObjectStreamClass.lookup( clazz ); 214 if( theosc != null ) 215 { 216 return theosc.getActualSerialVersionUID( ); 217 } 218 return 0; 219 } 220 221 224 public final long getActualSerialVersionUID() { 225 return actualSuid; 226 } 227 228 231 public final String getActualSerialVersionUIDStr() { 232 if (actualSuidStr == null) 233 actualSuidStr = Long.toHexString(actualSuid).toUpperCase(); 234 return actualSuidStr; 235 } 236 237 241 public final Class forClass() { 242 return ofClass; 243 } 244 245 252 public ObjectStreamField[] getFields() { 253 if (fields.length > 0) { 255 ObjectStreamField[] dup = new ObjectStreamField[fields.length]; 256 System.arraycopy(fields, 0, dup, 0, fields.length); 257 return dup; 258 } else { 259 return fields; 260 } 261 } 262 263 public boolean hasField(ValueMember field) 264 { 265 try { 266 for (int i = 0; i < fields.length; i++) { 267 if (fields[i].getName().equals(field.name)) { 268 if (fields[i].getSignature().equals( 269 ValueUtility.getSignature(field))) 270 return true; 271 } 272 } 273 } catch (Exception exc) { 274 } 277 278 return false; 279 } 280 281 282 final ObjectStreamField[] getFieldsNoCopy() { 283 return fields; 284 } 285 286 291 public final ObjectStreamField getField(String name) { 292 294 for (int i = fields.length-1; i >= 0; i--) { 295 if (name.equals(fields[i].getName())) { 296 return fields[i]; 297 } 298 } 299 return null; 300 } 301 302 public Serializable writeReplace(Serializable value) { 303 if (writeReplaceObjectMethod != null) { 304 try { 305 return (Serializable ) writeReplaceObjectMethod.invoke(value,noArgsList); 306 } catch(Throwable t) { 307 throw new RuntimeException (t); 308 } 309 } 310 else return value; 311 } 312 313 public Object readResolve(Object value) { 314 if (readResolveObjectMethod != null) { 315 try { 316 return readResolveObjectMethod.invoke(value,noArgsList); 317 } catch(Throwable t) { 318 throw new RuntimeException (t); 319 } 320 } 321 else return value; 322 } 323 324 327 public final String toString() { 328 StringBuffer sb = new StringBuffer (); 329 330 sb.append(name); 331 sb.append(": static final long serialVersionUID = "); 332 sb.append(Long.toString(suid)); 333 sb.append("L;"); 334 return sb.toString(); 335 } 336 337 341 private ObjectStreamClass(java.lang.Class cl, ObjectStreamClass superdesc, 342 boolean serial, boolean extern) 343 { 344 ofClass = cl; 345 346 if (Proxy.isProxyClass(cl)) { 347 forProxyClass = true; 348 } 349 350 name = cl.getName(); 351 superclass = superdesc; 352 serializable = serial; 353 if (!forProxyClass) { 354 externalizable = extern; 356 } 357 358 363 descriptorFor.put(cl, this); 364 365 370 } 371 372 379 380 381 private void init() { 382 synchronized (lock) { 383 384 if (initialized) 386 return; 387 388 final Class cl = ofClass; 389 390 if (!serializable || 391 externalizable || 392 forProxyClass || 393 name.equals("java.lang.String")) { 394 fields = NO_FIELDS; 395 } else if (serializable) { 396 398 AccessController.doPrivileged(new PrivilegedAction () { 399 public Object run() { 400 404 try { 405 Field pf = cl.getDeclaredField("serialPersistentFields"); 406 pf.setAccessible(true); 409 java.io.ObjectStreamField [] f = 412 (java.io.ObjectStreamField [])pf.get(cl); 413 int mods = pf.getModifiers(); 414 if ((Modifier.isPrivate(mods)) && 415 (Modifier.isStatic(mods)) && 416 (Modifier.isFinal(mods))) 417 { 418 fields = (ObjectStreamField[])translateFields((Object [])pf.get(cl)); 419 } 420 } catch (NoSuchFieldException e) { 421 fields = null; 422 } catch (IllegalAccessException e) { 423 fields = null; 424 } catch (IllegalArgumentException e) { 425 fields = null; 426 } catch (ClassCastException e) { 427 430 fields = null; 431 } 432 433 434 if (fields == null) { 435 443 Field [] actualfields = cl.getDeclaredFields(); 444 445 int numFields = 0; 446 ObjectStreamField[] tempFields = 447 new ObjectStreamField[actualfields.length]; 448 for (int i = 0; i < actualfields.length; i++) { 449 Field fld = actualfields[i] ; 450 int modifiers = fld.getModifiers(); 451 if (!Modifier.isStatic(modifiers) && 452 !Modifier.isTransient(modifiers)) { 453 fld.setAccessible(true) ; 454 tempFields[numFields++] = new ObjectStreamField(fld); 455 } 456 } 457 458 fields = new ObjectStreamField[numFields]; 459 System.arraycopy(tempFields, 0, fields, 0, numFields); 460 461 } else { 462 for (int j = fields.length-1; j >= 0; j--) { 466 try { 467 Field reflField = cl.getDeclaredField(fields[j].getName()); 468 if (fields[j].getType() == reflField.getType()) { 469 reflField.setAccessible(true); 470 fields[j].setField(reflField); 471 } 472 } catch (NoSuchFieldException e) { 473 } 475 } 476 } 477 return null; 478 } 479 }); 480 481 if (fields.length > 1) 482 Arrays.sort(fields); 483 484 485 computeFieldInfo(); 486 } 487 488 494 if (isNonSerializable()) { 495 suid = 0L; 496 } else { 497 AccessController.doPrivileged(new PrivilegedAction () { 499 public Object run() { 500 if (forProxyClass) { 501 suid = 0L; 503 } else { 504 try { 505 final Field f = cl.getDeclaredField("serialVersionUID"); 506 int mods = f.getModifiers(); 507 if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) { 509 f.setAccessible(true); 510 suid = f.getLong(cl); 511 } else { 514 suid = _computeSerialVersionUID(cl); 515 } 518 } catch (NoSuchFieldException ex) { 519 suid = _computeSerialVersionUID(cl); 520 } catch (IllegalAccessException ex) { 523 suid = _computeSerialVersionUID(cl); 524 } 525 } 526 527 writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl, 528 "writeReplace", noTypesList, Object .class); 529 530 readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl, 531 "readResolve", noTypesList, Object .class); 532 533 if (externalizable) 534 cons = getExternalizableConstructor(cl) ; 535 else 536 cons = getSerializableConstructor(cl) ; 537 538 if (serializable && !forProxyClass) { 539 543 writeObjectMethod = getPrivateMethod( cl, "writeObject", 544 new Class [] { java.io.ObjectOutputStream .class }, Void.TYPE ) ; 545 readObjectMethod = getPrivateMethod( cl, "readObject", 546 new Class [] { java.io.ObjectInputStream .class }, Void.TYPE ) ; 547 } 548 return null; 549 } 550 }); 551 } 552 553 actualSuid = ObjectStreamClass.computeStructuralUID(this, cl); 555 556 if (hasWriteObject()) 560 rmiiiopOptionalDataRepId = computeRMIIIOPOptionalDataRepId(); 561 562 initialized = true; 564 } 565 } 566 567 572 private static Method getPrivateMethod(Class cl, String name, 573 Class [] argTypes, 574 Class returnType) 575 { 576 try { 577 Method meth = cl.getDeclaredMethod(name, argTypes); 578 meth.setAccessible(true); 579 int mods = meth.getModifiers(); 580 return ((meth.getReturnType() == returnType) && 581 ((mods & Modifier.STATIC) == 0) && 582 ((mods & Modifier.PRIVATE) != 0)) ? meth : null; 583 } catch (NoSuchMethodException ex) { 584 return null; 585 } 586 } 587 588 598 private String computeRMIIIOPOptionalDataRepId() { 599 600 StringBuffer sbuf = new StringBuffer ("RMI:org.omg.custom."); 601 sbuf.append(RepositoryId.convertToISOLatin1(this.getName())); 602 sbuf.append(':'); 603 sbuf.append(this.getActualSerialVersionUIDStr()); 604 sbuf.append(':'); 605 sbuf.append(this.getSerialVersionUIDStr()); 606 607 return sbuf.toString(); 608 } 609 610 613 public final String getRMIIIOPOptionalDataRepId() { 614 return rmiiiopOptionalDataRepId; 615 } 616 617 623 ObjectStreamClass(String n, long s) { 624 name = n; 625 suid = s; 626 superclass = null; 627 } 628 629 private static Object [] translateFields(Object objs[]) 630 throws NoSuchFieldException { 631 try{ 632 java.io.ObjectStreamField fields[] = (java.io.ObjectStreamField [])objs; 633 Object translation[] = null; 634 635 if (translatedFields == null) 636 translatedFields = new Hashtable (); 637 638 translation = (Object [])translatedFields.get(fields); 639 640 if (translation != null) 641 return translation; 642 else { 643 Class osfClass = Class.forName("com.sun.corba.se.impl.io.ObjectStreamField"); 644 translation = (Object [])java.lang.reflect.Array.newInstance(osfClass, objs.length); 645 Object arg[] = new Object [2]; 646 Class types[] = {String .class, Class .class}; 647 Constructor constructor = osfClass.getDeclaredConstructor(types); 648 for (int i = fields.length -1; i >= 0; i--){ 649 arg[0] = fields[i].getName(); 650 arg[1] = fields[i].getType(); 651 652 translation[i] = constructor.newInstance(arg); 653 } 654 translatedFields.put(fields, translation); 655 656 } 657 658 return (Object [])translation; 659 } 660 catch(Throwable t){ 661 NoSuchFieldException nsfe = new NoSuchFieldException (); 662 nsfe.initCause( t ) ; 663 throw nsfe ; 664 } 665 } 666 667 673 final void setClass(Class cl) throws InvalidClassException { 674 675 if (cl == null) { 676 localClassDesc = null; 677 ofClass = null; 678 computeFieldInfo(); 679 return; 680 } 681 682 localClassDesc = lookupInternal(cl); 683 if (localClassDesc == null) 684 throw new InvalidClassException (cl.getName(), 686 "Local class not compatible"); 687 if (suid != localClassDesc.suid) { 688 689 690 691 694 boolean addedSerialOrExtern = 695 isNonSerializable() || localClassDesc.isNonSerializable(); 696 697 705 706 boolean arraySUID = (cl.isArray() && ! cl.getName().equals(name)); 707 708 if (! arraySUID && ! addedSerialOrExtern ) { 709 throw new InvalidClassException (cl.getName(), 711 "Local class not compatible:" + 712 " stream classdesc serialVersionUID=" + suid + 713 " local class serialVersionUID=" + localClassDesc.suid); 714 } 715 } 716 717 718 if (! compareClassNames(name, cl.getName(), '.')) 719 throw new InvalidClassException (cl.getName(), 721 "Incompatible local class name. " + 722 "Expected class name compatible with " + 723 name); 724 725 728 729 737 if ((serializable != localClassDesc.serializable) || 738 (externalizable != localClassDesc.externalizable) || 739 (!serializable && !externalizable)) 740 741 throw new InvalidClassException (cl.getName(), 743 "Serialization incompatible with Externalization"); 744 745 758 759 ObjectStreamField[] destfield = 760 (ObjectStreamField[])localClassDesc.fields; 761 ObjectStreamField[] srcfield = 762 (ObjectStreamField[])fields; 763 764 int j = 0; 765 nextsrc: 766 for (int i = 0; i < srcfield.length; i++ ) { 767 768 for (int k = j; k < destfield.length; k++) { 769 if (srcfield[i].getName().equals(destfield[k].getName())) { 770 771 if (srcfield[i].isPrimitive() && 772 !srcfield[i].typeEquals(destfield[k])) { 773 throw new InvalidClassException (cl.getName(), 775 "The type of field " + 776 srcfield[i].getName() + 777 " of class " + name + 778 " is incompatible."); 779 } 780 781 782 j = k; 783 784 srcfield[i].setField(destfield[j].getField()); 785 continue nextsrc; 787 } 788 } 789 } 790 791 792 computeFieldInfo(); 793 794 795 ofClass = cl; 796 797 800 readObjectMethod = localClassDesc.readObjectMethod; 801 readResolveObjectMethod = localClassDesc.readResolveObjectMethod; 802 } 803 804 813 static boolean compareClassNames(String streamName, 814 String localName, 815 char pkgSeparator) { 816 817 int streamNameIndex = streamName.lastIndexOf(pkgSeparator); 818 if (streamNameIndex < 0) 819 streamNameIndex = 0; 820 821 int localNameIndex = localName.lastIndexOf(pkgSeparator); 822 if (localNameIndex < 0) 823 localNameIndex = 0; 824 825 return streamName.regionMatches(false, streamNameIndex, 826 localName, localNameIndex, 827 streamName.length() - streamNameIndex); 828 } 829 830 834 final boolean typeEquals(ObjectStreamClass other) { 835 return (suid == other.suid) && 836 compareClassNames(name, other.name, '.'); 837 } 838 839 842 final void setSuperclass(ObjectStreamClass s) { 843 superclass = s; 844 } 845 846 849 final ObjectStreamClass getSuperclass() { 850 return superclass; 851 } 852 853 856 final boolean hasReadObject() { 857 return readObjectMethod != null; 858 } 859 860 863 final boolean hasWriteObject() { 864 return writeObjectMethod != null ; 865 } 866 867 873 final boolean isCustomMarshaled() { 874 return (hasWriteObject() || isExternalizable()) 875 || (superclass != null && superclass.isCustomMarshaled()); 876 } 877 878 904 boolean hasExternalizableBlockDataMode() { 905 return hasExternalizableBlockData; 906 } 907 908 917 Object newInstance() 918 throws InstantiationException , InvocationTargetException , 919 UnsupportedOperationException 920 { 921 if (cons != null) { 922 try { 923 return cons.newInstance(new Object [0]); 924 } catch (IllegalAccessException ex) { 925 InternalError ie = new InternalError (); 927 ie.initCause( ex ) ; 928 throw ie ; 929 } 930 } else { 931 throw new UnsupportedOperationException (); 932 } 933 } 934 935 940 private static Constructor getExternalizableConstructor(Class cl) { 941 try { 942 Constructor cons = cl.getDeclaredConstructor(new Class [0]); 943 cons.setAccessible(true); 944 return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ? 945 cons : null; 946 } catch (NoSuchMethodException ex) { 947 return null; 948 } 949 } 950 951 956 private static Constructor getSerializableConstructor(Class cl) { 957 Class initCl = cl; 958 while (Serializable .class.isAssignableFrom(initCl)) { 959 if ((initCl = initCl.getSuperclass()) == null) { 960 return null; 961 } 962 } 963 try { 964 Constructor cons = initCl.getDeclaredConstructor(new Class [0]); 965 int mods = cons.getModifiers(); 966 if ((mods & Modifier.PRIVATE) != 0 || 967 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && 968 !packageEquals(cl, initCl))) 969 { 970 return null; 971 } 972 cons = bridge.newConstructorForSerialization(cl, cons); 973 cons.setAccessible(true); 974 return cons; 975 } catch (NoSuchMethodException ex) { 976 return null; 977 } 978 } 979 980 983 final ObjectStreamClass localClassDescriptor() { 984 return localClassDesc; 985 } 986 987 990 boolean isSerializable() { 991 return serializable; 992 } 993 994 997 boolean isExternalizable() { 998 return externalizable; 999 } 1000 1001 boolean isNonSerializable() { 1002 return ! (externalizable || serializable); 1003 } 1004 1005 1010 private void computeFieldInfo() { 1011 primBytes = 0; 1012 objFields = 0; 1013 1014 for (int i = 0; i < fields.length; i++ ) { 1015 switch (fields[i].getTypeCode()) { 1016 case 'B': 1017 case 'Z': 1018 primBytes += 1; 1019 break; 1020 case 'C': 1021 case 'S': 1022 primBytes += 2; 1023 break; 1024 1025 case 'I': 1026 case 'F': 1027 primBytes += 4; 1028 break; 1029 case 'J': 1030 case 'D' : 1031 primBytes += 8; 1032 break; 1033 1034 case 'L': 1035 case '[': 1036 objFields += 1; 1037 break; 1038 } 1039 } 1040 } 1041 1042 private static void msg( String str ) 1043 { 1044 System.out.println( str ) ; 1045 } 1046 1047 1053 1054 public static final int CLASS_MASK = Modifier.PUBLIC | Modifier.FINAL | 1055 Modifier.INTERFACE | Modifier.ABSTRACT ; 1056 public static final int FIELD_MASK = Modifier.PUBLIC | Modifier.PRIVATE | 1057 Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL | 1058 Modifier.TRANSIENT | Modifier.VOLATILE ; 1059 public static final int METHOD_MASK = Modifier.PUBLIC | Modifier.PRIVATE | 1060 Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL | 1061 Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.ABSTRACT | 1062 Modifier.STRICT ; 1063 1064 1069 private static long _computeSerialVersionUID(Class cl) { 1070 if (DEBUG_SVUID) 1071 msg( "Computing SerialVersionUID for " + cl ) ; 1072 ByteArrayOutputStream devnull = new ByteArrayOutputStream (512); 1073 1074 long h = 0; 1075 try { 1076 MessageDigest md = MessageDigest.getInstance("SHA"); 1077 DigestOutputStream mdo = new DigestOutputStream (devnull, md); 1078 DataOutputStream data = new DataOutputStream (mdo); 1079 1080 if (DEBUG_SVUID) 1081 msg( "\twriteUTF( \"" + cl.getName() + "\" )" ) ; 1082 data.writeUTF(cl.getName()); 1083 1084 int classaccess = cl.getModifiers(); 1085 classaccess &= (Modifier.PUBLIC | Modifier.FINAL | 1086 Modifier.INTERFACE | Modifier.ABSTRACT); 1087 1088 1095 Method [] method = cl.getDeclaredMethods(); 1096 if ((classaccess & Modifier.INTERFACE) != 0) { 1097 classaccess &= (~Modifier.ABSTRACT); 1098 if (method.length > 0) { 1099 classaccess |= Modifier.ABSTRACT; 1100 } 1101 } 1102 1103 classaccess &= CLASS_MASK ; 1105 1106 if (DEBUG_SVUID) 1107 msg( "\twriteInt( " + classaccess + " ) " ) ; 1108 data.writeInt(classaccess); 1109 1110 1115 if (!cl.isArray()) { 1116 1122 1123 Class interfaces[] = cl.getInterfaces(); 1124 Arrays.sort(interfaces, compareClassByName); 1125 1126 for (int i = 0; i < interfaces.length; i++) { 1127 if (DEBUG_SVUID) 1128 msg( "\twriteUTF( \"" + interfaces[i].getName() + "\" ) " ) ; 1129 data.writeUTF(interfaces[i].getName()); 1130 } 1131 } 1132 1133 1134 Field [] field = cl.getDeclaredFields(); 1135 Arrays.sort(field, compareMemberByName); 1136 1137 for (int i = 0; i < field.length; i++) { 1138 Field f = field[i]; 1139 1140 1143 int m = f.getModifiers(); 1144 if (Modifier.isPrivate(m) && 1145 (Modifier.isTransient(m) || Modifier.isStatic(m))) 1146 continue; 1147 1148 if (DEBUG_SVUID) 1149 msg( "\twriteUTF( \"" + f.getName() + "\" ) " ) ; 1150 data.writeUTF(f.getName()); 1151 1152 m &= FIELD_MASK ; 1154 1155 if (DEBUG_SVUID) 1156 msg( "\twriteInt( " + m + " ) " ) ; 1157 data.writeInt(m); 1158 1159 if (DEBUG_SVUID) 1160 msg( "\twriteUTF( \"" + getSignature(f.getType()) + "\" ) " ) ; 1161 data.writeUTF(getSignature(f.getType())); 1162 } 1163 1164 if (hasStaticInitializer(cl)) { 1165 if (DEBUG_SVUID) 1166 msg( "\twriteUTF( \"<clinit>\" ) " ) ; 1167 data.writeUTF("<clinit>"); 1168 1169 if (DEBUG_SVUID) 1170 msg( "\twriteInt( " + Modifier.STATIC + " )" ) ; 1171 data.writeInt(Modifier.STATIC); 1173 if (DEBUG_SVUID) 1174 msg( "\twriteUTF( \"()V\" )" ) ; 1175 data.writeUTF("()V"); 1176 } 1177 1178 1183 1184 MethodSignature[] constructors = 1185 MethodSignature.removePrivateAndSort(cl.getDeclaredConstructors()); 1186 for (int i = 0; i < constructors.length; i++) { 1187 MethodSignature c = constructors[i]; 1188 String mname = "<init>"; 1189 String desc = c.signature; 1190 desc = desc.replace('/', '.'); 1191 if (DEBUG_SVUID) 1192 msg( "\twriteUTF( \"" + mname + "\" )" ) ; 1193 data.writeUTF(mname); 1194 1195 int modifier = c.member.getModifiers() & METHOD_MASK ; 1197 1198 if (DEBUG_SVUID) 1199 msg( "\twriteInt( " + modifier + " ) " ) ; 1200 data.writeInt( modifier ) ; 1201 1202 if (DEBUG_SVUID) 1203 msg( "\twriteUTF( \"" + desc+ "\" )" ) ; 1204 data.writeUTF(desc); 1205 } 1206 1207 1210 MethodSignature[] methods = 1211 MethodSignature.removePrivateAndSort(method); 1212 for (int i = 0; i < methods.length; i++ ) { 1213 MethodSignature m = methods[i]; 1214 String desc = m.signature; 1215 desc = desc.replace('/', '.'); 1216 1217 if (DEBUG_SVUID) 1218 msg( "\twriteUTF( \"" + m.member.getName()+ "\" )" ) ; 1219 data.writeUTF(m.member.getName()); 1220 1221 int modifier = m.member.getModifiers() & METHOD_MASK ; 1223 1224 if (DEBUG_SVUID) 1225 msg( "\twriteInt( " + modifier + " ) " ) ; 1226 data.writeInt( modifier ) ; 1227 1228 if (DEBUG_SVUID) 1229 msg( "\twriteUTF( \"" + desc + "\" )" ) ; 1230 data.writeUTF(desc); 1231 } 1232 1233 1236 data.flush(); 1237 byte hasharray[] = md.digest(); 1238 for (int i = 0; i < Math.min(8, hasharray.length); i++) { 1239 h += (long)(hasharray[i] & 255) << (i * 8); 1240 } 1241 } catch (IOException ignore) { 1242 1243 h = -1; 1244 } catch (NoSuchAlgorithmException complain) { 1245 SecurityException se = new SecurityException () ; 1246 se.initCause( complain ) ; 1247 throw se ; 1248 } 1249 1250 return h; 1251 } 1252 1253 private static long computeStructuralUID(com.sun.corba.se.impl.io.ObjectStreamClass osc, Class cl) { 1254 ByteArrayOutputStream devnull = new ByteArrayOutputStream (512); 1255 1256 long h = 0; 1257 try { 1258 1259 if ((!java.io.Serializable .class.isAssignableFrom(cl)) || 1260 (cl.isInterface())){ 1261 return 0; 1262 } 1263 1264 if (java.io.Externalizable .class.isAssignableFrom(cl)) { 1265 return 1; 1266 } 1267 1268 MessageDigest md = MessageDigest.getInstance("SHA"); 1269 DigestOutputStream mdo = new DigestOutputStream (devnull, md); 1270 DataOutputStream data = new DataOutputStream (mdo); 1271 1272 Class parent = cl.getSuperclass(); 1274 if ((parent != null)) 1275 { 1280 data.writeLong(computeStructuralUID(lookup(parent), parent)); 1282 } 1283 1284 if (osc.hasWriteObject()) 1285 data.writeInt(2); 1286 else 1287 data.writeInt(1); 1288 1289 ObjectStreamField[] field = osc.getFields(); 1293 if (field.length > 1) { 1294 Arrays.sort(field, compareObjStrFieldsByName); 1295 } 1296 1297 for (int i = 0; i < field.length; i++) { 1300 data.writeUTF(field[i].getName()); 1301 data.writeUTF(field[i].getSignature()); 1302 } 1303 1304 1307 data.flush(); 1308 byte hasharray[] = md.digest(); 1309 for (int i = 0; i < Math.min(8, hasharray.length); i++) { 1313 h += (long)(hasharray[i] & 255) << (i * 8); 1314 } 1315 } catch (IOException ignore) { 1316 1317 h = -1; 1318 } catch (NoSuchAlgorithmException complain) { 1319 SecurityException se = new SecurityException (); 1320 se.initCause( complain ) ; 1321 throw se ; 1322 } 1323 return h; 1324 } 1325 1326 1329 static String getSignature(Class clazz) { 1330 String type = null; 1331 if (clazz.isArray()) { 1332 Class cl = clazz; 1333 int dimensions = 0; 1334 while (cl.isArray()) { 1335 dimensions++; 1336 cl = cl.getComponentType(); 1337 } 1338 StringBuffer sb = new StringBuffer (); 1339 for (int i = 0; i < dimensions; i++) { 1340 sb.append("["); 1341 } 1342 sb.append(getSignature(cl)); 1343 type = sb.toString(); 1344 } else if (clazz.isPrimitive()) { 1345 if (clazz == Integer.TYPE) { 1346 type = "I"; 1347 } else if (clazz == Byte.TYPE) { 1348 type = "B"; 1349 } else if (clazz == Long.TYPE) { 1350 type = "J"; 1351 } else if (clazz == Float.TYPE) { 1352 type = "F"; 1353 } else if (clazz == Double.TYPE) { 1354 type = "D"; 1355 } else if (clazz == Short.TYPE) { 1356 type = "S"; 1357 } else if (clazz == Character.TYPE) { 1358 type = "C"; 1359 } else if (clazz == Boolean.TYPE) { 1360 type = "Z"; 1361 } else if (clazz == Void.TYPE) { 1362 type = "V"; 1363 } 1364 } else { 1365 type = "L" + clazz.getName().replace('.', '/') + ";"; 1366 } 1367 return type; 1368 } 1369 1370 1373 static String getSignature(Method meth) { 1374 StringBuffer sb = new StringBuffer (); 1375 1376 sb.append("("); 1377 1378 Class [] params = meth.getParameterTypes(); for (int j = 0; j < params.length; j++) { 1380 sb.append(getSignature(params[j])); 1381 } 1382 sb.append(")"); 1383 sb.append(getSignature(meth.getReturnType())); 1384 return sb.toString(); 1385 } 1386 1387 1390 static String getSignature(Constructor cons) { 1391 StringBuffer sb = new StringBuffer (); 1392 1393 sb.append("("); 1394 1395 Class [] params = cons.getParameterTypes(); for (int j = 0; j < params.length; j++) { 1397 sb.append(getSignature(params[j])); 1398 } 1399 sb.append(")V"); 1400 return sb.toString(); 1401 } 1402 1403 static private SoftCache descriptorFor = new SoftCache() ; 1404 1405 private static Field [] getDeclaredFields(final Class clz) { 1406 return (Field []) AccessController.doPrivileged(new PrivilegedAction () { 1407 public Object run() { 1408 return clz.getDeclaredFields(); 1409 } 1410 }); 1411 } 1412 1413 1414 1417 private String name; 1418 1419 1422 private ObjectStreamClass superclass; 1423 1424 1427 private boolean serializable; 1428 private boolean externalizable; 1429 1430 1434 private ObjectStreamField[] fields; 1435 1436 1439 private Class ofClass; 1440 1441 1444 boolean forProxyClass; 1445 1446 1447 1450 private long suid = kDefaultUID; 1451 private String suidStr = null; 1452 1453 1456 private long actualSuid = kDefaultUID; 1457 private String actualSuidStr = null; 1458 1459 1463 int primBytes; 1464 int objFields; 1465 1466 1472 private boolean initialized = false; 1473 1474 1475 private Object lock = new Object (); 1476 1477 1483 private boolean hasExternalizableBlockData; 1484 Method writeObjectMethod; 1485 Method readObjectMethod; 1486 private Method writeReplaceObjectMethod; 1487 private Method readResolveObjectMethod; 1488 private Constructor cons ; 1489 1490 1498 private String rmiiiopOptionalDataRepId = null; 1499 1500 1503 private ObjectStreamClass localClassDesc; 1504 1505 1506 private static Method hasStaticInitializerMethod = null; 1507 1511 private static boolean hasStaticInitializer(Class cl) { 1512 if (hasStaticInitializerMethod == null) { 1513 Class classWithThisMethod = null; 1514 1515 try { 1516 try { 1517 classWithThisMethod = Class.forName("sun.misc.ClassReflector"); 1524 } catch (ClassNotFoundException cnfe) { 1525 } 1529 if (classWithThisMethod == null) 1530 classWithThisMethod = java.io.ObjectStreamClass .class; 1531 1532 hasStaticInitializerMethod = 1533 classWithThisMethod.getDeclaredMethod("hasStaticInitializer", 1534 new Class [] { Class .class }); 1535 } catch (NoSuchMethodException ex) { 1536 } 1537 1538 if (hasStaticInitializerMethod == null) { 1539 throw new InternalError ("Can't find hasStaticInitializer method on " 1541 + classWithThisMethod.getName()); 1542 } 1543 hasStaticInitializerMethod.setAccessible(true); 1544 } 1545 1546 try { 1547 Boolean retval = (Boolean ) 1548 hasStaticInitializerMethod.invoke(null, new Object [] { cl }); 1549 return retval.booleanValue(); 1550 } catch (Exception ex) { 1551 InternalError ie = new InternalError ( "Error invoking hasStaticInitializer" ) ; 1553 ie.initCause( ex ) ; 1554 throw ie ; 1555 } 1556 } 1557 1558 1559 1560 private static Class classSerializable = null; 1561 private static Class classExternalizable = null; 1562 1563 1566 static { 1567 try { 1568 classSerializable = Class.forName("java.io.Serializable"); 1569 classExternalizable = Class.forName("java.io.Externalizable"); 1570 } catch (Throwable e) { 1571 System.err.println("Could not load java.io.Serializable or java.io.Externalizable."); 1572 } 1573 } 1574 1575 1576 private static final long serialVersionUID = -6120832682080437368L; 1577 1578 1582 public static final ObjectStreamField[] NO_FIELDS = 1583 new ObjectStreamField[0]; 1584 1585 1589 private static class ObjectStreamClassEntry { 1591 ObjectStreamClassEntry(ObjectStreamClass c) { 1592 this.c = c; 1594 } 1595 ObjectStreamClassEntry next; 1596 1597 public Object get() 1598 { 1599 return c; 1600 } 1601 private ObjectStreamClass c; 1602 } 1603 1604 1607 private static Comparator compareClassByName = 1608 new CompareClassByName(); 1609 1610 private static class CompareClassByName implements Comparator { 1611 public int compare(Object o1, Object o2) { 1612 Class c1 = (Class )o1; 1613 Class c2 = (Class )o2; 1614 return (c1.getName()).compareTo(c2.getName()); 1615 } 1616 } 1617 1618 1621 private final static Comparator compareObjStrFieldsByName 1622 = new CompareObjStrFieldsByName(); 1623 1624 private static class CompareObjStrFieldsByName implements Comparator { 1625 public int compare(Object o1, Object o2) { 1626 ObjectStreamField osf1 = (ObjectStreamField)o1; 1627 ObjectStreamField osf2 = (ObjectStreamField)o2; 1628 1629 return osf1.getName().compareTo(osf2.getName()); 1630 } 1631 } 1632 1633 1636 private static Comparator compareMemberByName = 1637 new CompareMemberByName(); 1638 1639 private static class CompareMemberByName implements Comparator { 1640 public int compare(Object o1, Object o2) { 1641 String s1 = ((Member )o1).getName(); 1642 String s2 = ((Member )o2).getName(); 1643 1644 if (o1 instanceof Method ) { 1645 s1 += getSignature((Method )o1); 1646 s2 += getSignature((Method )o2); 1647 } else if (o1 instanceof Constructor ) { 1648 s1 += getSignature((Constructor )o1); 1649 s2 += getSignature((Constructor )o2); 1650 } 1651 return s1.compareTo(s2); 1652 } 1653 } 1654 1655 1657 private static class MethodSignature implements Comparator { 1658 Member member; 1659 String signature; 1661 1663 1665 static MethodSignature[] removePrivateAndSort(Member [] m) { 1666 int numNonPrivate = 0; 1667 for (int i = 0; i < m.length; i++) { 1668 if (! Modifier.isPrivate(m[i].getModifiers())) { 1669 numNonPrivate++; 1670 } 1671 } 1672 MethodSignature[] cm = new MethodSignature[numNonPrivate]; 1673 int cmi = 0; 1674 for (int i = 0; i < m.length; i++) { 1675 if (! Modifier.isPrivate(m[i].getModifiers())) { 1676 cm[cmi] = new MethodSignature(m[i]); 1677 cmi++; 1678 } 1679 } 1680 if (cmi > 0) 1681 Arrays.sort(cm, cm[0]); 1682 return cm; 1683 } 1684 1685 1687 public int compare(Object o1, Object o2) { 1688 1689 if (o1 == o2) 1690 return 0; 1691 1692 MethodSignature c1 = (MethodSignature)o1; 1693 MethodSignature c2 = (MethodSignature)o2; 1694 1695 int result; 1696 if (isConstructor()) { 1697 result = c1.signature.compareTo(c2.signature); 1698 } else { result = c1.member.getName().compareTo(c2.member.getName()); 1700 if (result == 0) 1701 result = c1.signature.compareTo(c2.signature); 1702 } 1703 return result; 1704 } 1705 1706 final private boolean isConstructor() { 1707 return member instanceof Constructor ; 1708 } 1709 private MethodSignature(Member m) { 1710 member = m; 1711 if (isConstructor()) { 1712 signature = ObjectStreamClass.getSignature((Constructor )m); 1713 } else { 1714 signature = ObjectStreamClass.getSignature((Method )m); 1715 } 1716 } 1717 } 1718 1719 1727 private static Method getInheritableMethod(Class cl, String name, 1728 Class [] argTypes, 1729 Class returnType) 1730 { 1731 Method meth = null; 1732 Class defCl = cl; 1733 while (defCl != null) { 1734 try { 1735 meth = defCl.getDeclaredMethod(name, argTypes); 1736 break; 1737 } catch (NoSuchMethodException ex) { 1738 defCl = defCl.getSuperclass(); 1739 } 1740 } 1741 1742 if ((meth == null) || (meth.getReturnType() != returnType)) { 1743 return null; 1744 } 1745 meth.setAccessible(true); 1746 int mods = meth.getModifiers(); 1747 if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) { 1748 return null; 1749 } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) { 1750 return meth; 1751 } else if ((mods & Modifier.PRIVATE) != 0) { 1752 return (cl == defCl) ? meth : null; 1753 } else { 1754 return packageEquals(cl, defCl) ? meth : null; 1755 } 1756 } 1757 1758 1764 private static boolean packageEquals(Class cl1, Class cl2) { 1765 Package pkg1 = cl1.getPackage(), pkg2 = cl2.getPackage(); 1766 return ((pkg1 == pkg2) || ((pkg1 != null) && (pkg1.equals(pkg2)))); 1767 } 1768} 1769 | Popular Tags |