Index: main/java/org/apache/harmony/pack200/Segment.java =================================================================== --- main/java/org/apache/harmony/pack200/Segment.java (revision 637154) +++ main/java/org/apache/harmony/pack200/Segment.java (working copy) @@ -127,29 +127,44 @@ int i = fullName.lastIndexOf("/") + 1; // if lastIndexOf==-1, then // -1+1=0, so str.substring(0) // == str - AttributeLayout SOURCE_FILE = attrDefinitionBands.getAttributeDefinitionMap() - .getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE, - AttributeLayout.CONTEXT_CLASS); - if (SOURCE_FILE.matches(classBands.getClassFlags()[classNum])) { - int firstDollar = SegmentUtils.indexOfFirstDollar(fullName); - String fileName = null; - if(firstDollar > -1 && (i <= firstDollar)) { - fileName = fullName.substring(i, firstDollar) + ".java"; - } else { - fileName = fullName.substring(i) + ".java"; - } - classFile.attributes = new Attribute[] { (Attribute) cp - .add(new SourceFileAttribute(cpBands.cpUTF8Value(fileName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ))) }; - } else { - classFile.attributes = new Attribute[] {}; - } - + // Get the source file attribute + ArrayList classAttributes = classBands.getClassAttributes()[classNum]; + SourceFileAttribute sourceFileAttribute = null; + for(int index=0; index < classAttributes.size(); index++) { + if(((Attribute)classAttributes.get(index)).isSourceFileAttribute()) { + sourceFileAttribute = ((SourceFileAttribute)classAttributes.get(index)); + } + } + + if(sourceFileAttribute == null) { + // If we don't have a source file attribute yet, we need + // to infer it from the class. + AttributeLayout SOURCE_FILE = attrDefinitionBands.getAttributeDefinitionMap() + .getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE, + AttributeLayout.CONTEXT_CLASS); + if (SOURCE_FILE.matches(classBands.getClassFlags()[classNum])) { + int firstDollar = SegmentUtils.indexOfFirstDollar(fullName); + String fileName = null; + + if(firstDollar > -1 && (i <= firstDollar)) { + fileName = fullName.substring(i, firstDollar) + ".java"; + } else { + fileName = fullName.substring(i) + ".java"; + } + sourceFileAttribute = new SourceFileAttribute(cpBands.cpUTF8Value(fileName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ)); + classFile.attributes = new Attribute[] { (Attribute) cp + .add(sourceFileAttribute) }; + } else { + classFile.attributes = new Attribute[] {}; + } + } else { + classFile.attributes = new Attribute[] { (Attribute) cp.add(sourceFileAttribute)}; + } + // If we see any class attributes, add them to the class's attributes that will // be written out. Keep SourceFileAttributes out since we just - // did them above. (One of the computations for SourceFileAttribute - // may be redundant.) - ArrayList classAttributes = classBands.getClassAttributes()[classNum]; + // did them above. ArrayList classAttributesWithoutSourceFileAttribute = new ArrayList(); for(int index=0; index < classAttributes.size(); index++) { Attribute attrib = (Attribute)classAttributes.get(index); @@ -200,11 +215,23 @@ // add inner class attribute (if required) boolean addInnerClassesAttr = false; + // TODO: remove the debug info below +// String debugClass = getClassBands().getClassThis()[classNum]; +// SegmentUtils.debug("buildClassFile: class is " + debugClass); +// if("com/ibm/collaboration/realtime/application/RTCMainPlugin".equals(foo)) { +// SegmentUtils.debug("self halt"); +// } IcTuple[] ic_local = getClassBands().getIcLocal()[classNum]; boolean ic_local_sent = false; if(ic_local != null) { ic_local_sent = true; } + // TODO: remove the debug code below +// if(ic_local_sent) { +// for(int xx = 0; xx < ic_local.length; xx++) { +// SegmentUtils.debug("ic_local[" + xx + "]=" + ic_local[xx]); +// } +// } InnerClassesAttribute innerClassesAttribute = new InnerClassesAttribute("InnerClasses"); IcTuple[] ic_relevant = getIcBands().getRelevantIcTuples(fullName, cp); IcTuple[] ic_stored = computeIcStored(ic_local, ic_relevant); Index: main/java/org/apache/harmony/pack200/IcBands.java =================================================================== --- main/java/org/apache/harmony/pack200/IcBands.java (revision 637154) +++ main/java/org/apache/harmony/pack200/IcBands.java (working copy) @@ -92,7 +92,14 @@ int allTuplesSize = allTuples.length; for(int index=0; index < allTuplesSize; index++) { if(allTuples[index].outerClassString().equals(className)) { - relevantTuples.add(allTuples[index]); + // Originally I added all classes (anonymous and not anonymous). + // That yielded bad results on some classes. Adding just + // the non-anonymous classes (which is not what the + // spec specifies) seems to fix up a number of cases + // where the classes are otherwise mismatched. + if(!allTuples[index].isAnonymous()) { + relevantTuples.add(allTuples[index]); + } } } Index: main/java/org/apache/harmony/pack200/IcTuple.java =================================================================== --- main/java/org/apache/harmony/pack200/IcTuple.java (revision 637154) +++ main/java/org/apache/harmony/pack200/IcTuple.java (working copy) @@ -182,4 +182,35 @@ result.append(')'); return result.toString(); } + + public boolean nullSafeEquals(String stringOne, String stringTwo) { + if(null==stringOne) { + return null==stringTwo; + } + return stringOne.equals(stringTwo); + } + + public boolean equals(Object object) { + if(object.getClass() != this.getClass()) { + return false; + } + IcTuple compareTuple = (IcTuple)object; + + if(!nullSafeEquals(this.C, compareTuple.C)) { + return false; + } + + if(!nullSafeEquals(this.C2, compareTuple.C2)) { + return false; + } + + if(!nullSafeEquals(this.N, compareTuple.N)) { + return false; + } + return true; + } + + public int hashCode() { + return 17 + C.hashCode() + C2.hashCode() + N.hashCode(); + } }