Index: main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (revision 633719) +++ main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (working copy) @@ -101,9 +101,18 @@ ArrayList nestedEntries = new ArrayList(); nestedEntries.add(getAttributeName()); nestedEntries.addAll(byteCodes); - // TODO: Is this the right place to add code attribute - // attributes? nestedEntries.addAll(attributes); + // Don't forget to add the ExceptionTable catch_types + for (Iterator iter = exceptionTable.iterator(); iter.hasNext();) { + ExceptionTableEntry entry = (ExceptionTableEntry) iter.next(); + CPClass catchType = entry.getCatchType(); + // If the catch type is null, this is a finally + // block. If it's not null, we need to add the + // CPClass to the list of nested class file entries. + if(catchType != null) { + nestedEntries.add(catchType); + } + } ClassFileEntry[] nestedEntryArray = new ClassFileEntry[nestedEntries .size()]; nestedEntries.toArray(nestedEntryArray); Index: main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java =================================================================== --- main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java (revision 633719) +++ main/java/org/apache/harmony/pack200/bytecode/ExceptionTableEntry.java (working copy) @@ -32,6 +32,22 @@ private int handlerPcRenumbered; private int catchTypeIndex; + /** + * Create a new ExceptionTableEntry. Exception tables are + * of two kinds: either a normal one (with a Throwable as + * the catch_type) or a finally clause (which has no + * catch_type). In the class file, the finally clause is + * represented as catch_type == 0. + * + * To create a finally clause with this method, pass in + * null for the catchType. + * + * @param startPC int + * @param endPC int + * @param handlerPC int + * @param catchType CPClass (if it's a normal catch) or null + * (if it's a finally clause). + */ public ExceptionTableEntry(int startPC, int endPC, int handlerPC, CPClass catchType) { this.startPC = startPC; this.endPC = endPC; @@ -54,7 +70,17 @@ handlerPcRenumbered = ((Integer)byteCodeOffsets.get(handlerPcIndex)).intValue(); } + public CPClass getCatchType() { + return catchType; + } + public void resolve(ClassConstantPool pool) { + if(catchType == null) { + // If the catch type is a finally clause + // the index is always 0. + catchTypeIndex = 0; + return; + } catchType.resolve(pool); catchTypeIndex = pool.indexOf(catchType); } Index: main/java/org/apache/harmony/pack200/BcBands.java =================================================================== --- main/java/org/apache/harmony/pack200/BcBands.java (revision 633719) +++ main/java/org/apache/harmony/pack200/BcBands.java (working copy) @@ -386,7 +386,13 @@ if(handlerCount != null) { for (int j = 0; j < handlerCount[i]; j++) { String handlerClass = handlerClassTypes[i][j]; - CPClass cpHandlerClass = segment.getCpBands().cpClassValue(handlerClass); + CPClass cpHandlerClass = null; + if(handlerClass != null) { + // The handlerClass will be null if the + // catch is a finally (that is, the + // exception table catch_type should be 0 + cpHandlerClass = segment.getCpBands().cpClassValue(handlerClass); + } ExceptionTableEntry entry = new ExceptionTableEntry( handlerStartPCs[i][j], handlerEndPCs[i][j], handlerCatchPCs[i][j], cpHandlerClass);