# HG changeset patch # User ksrini # Date 1368667576 25200 # Node ID 46864558d06823f9f3eddac9bf6b964879e07cf4 # Parent a74a13b9aa934a55fbaf44f2fdd892f59fdb2b50 8001163: [pack200] should support attributes introduced by JSR-308 Reviewed-by: jrose diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Wed May 15 18:26:16 2013 -0700 @@ -99,6 +99,7 @@ return this == def.canon; } + @Override public int compareTo(Attribute that) { return this.def.compareTo(that.def); } @@ -212,20 +213,20 @@ // Metadata. // // We define metadata using similar layouts - // for all five kinds of metadata attributes. + // for all five kinds of metadata attributes and 2 type metadata attributes // // Regular annotations are a counted list of [RSHNH[RUH(1)]][...] // pack.method.attribute.RuntimeVisibleAnnotations=[NH[(1)]][RSHNH[RUH(1)]][TB...] // // Parameter annotations are a counted list of regular annotations. - // pack.method.attribute.RuntimeVisibleParameterAnnotations=[NH[(1)]][NH[(1)]][RSHNH[RUH(1)]][TB...] + // pack.method.attribute.RuntimeVisibleParameterAnnotations=[NB[(1)]][NH[(1)]][RSHNH[RUH(1)]][TB...] // // RuntimeInvisible annotations are defined similarly... // Non-method annotations are defined similarly... // // Annotation are a simple tagged value [TB...] // pack.attribute.method.AnnotationDefault=[TB...] - // + static { String mdLayouts[] = { Attribute.normalizeLayoutString @@ -238,6 +239,9 @@ +"\n # annotations :=" +"\n [ NH[(1)] ] # forward call to annotation" +"\n " + ), + Attribute.normalizeLayoutString + ("" +"\n # annotation :=" +"\n [RSH" +"\n NH[RUH (1)] # forward call to value" @@ -259,24 +263,67 @@ +"\n ()[] ]" ) }; + /* + * RuntimeVisibleTypeAnnotation and RuntimeInvisibleTypeAnnotatation are + * similar to RuntimeVisibleAnnotation and RuntimeInvisibleAnnotation, + * a type-annotation union and a type-path structure precedes the + * annotation structure + */ + String typeLayouts[] = { + Attribute.normalizeLayoutString + ("" + +"\n # type-annotations :=" + +"\n [ NH[(1)(2)(3)] ] # forward call to type-annotations" + ), + Attribute.normalizeLayoutString + ( "" + +"\n # type-annotation :=" + +"\n [TB" + +"\n (0-1) [B] # {CLASS, METHOD}_TYPE_PARAMETER" + +"\n (16) [FH] # CLASS_EXTENDS" + +"\n (17-18) [BB] # {CLASS, METHOD}_TYPE_PARAMETER_BOUND" + +"\n (19-21) [] # FIELD, METHOD_RETURN, METHOD_RECEIVER" + +"\n (22) [B] # METHOD_FORMAL_PARAMETER" + +"\n (23) [H] # THROWS" + +"\n (64-65) [NH[PHOHH]] # LOCAL_VARIABLE, RESOURCE_VARIABLE" + +"\n (66) [H] # EXCEPTION_PARAMETER" + +"\n (67-70) [PH] # INSTANCEOF, NEW, {CONSTRUCTOR, METHOD}_REFERENCE_RECEIVER" + +"\n (71-75) [PHB] # CAST, {CONSTRUCTOR,METHOD}_INVOCATION_TYPE_ARGUMENT, {CONSTRUCTOR, METHOD}_REFERENCE_TYPE_ARGUMENT" + +"\n ()[] ]" + ), + Attribute.normalizeLayoutString + ("" + +"\n # type-path" + +"\n [ NB[BB] ]" + ) + }; Map sd = standardDefs; - String defaultLayout = mdLayouts[2]; - String annotationsLayout = mdLayouts[1] + mdLayouts[2]; + String defaultLayout = mdLayouts[3]; + String annotationsLayout = mdLayouts[1] + mdLayouts[2] + mdLayouts[3]; String paramsLayout = mdLayouts[0] + annotationsLayout; + String typesLayout = typeLayouts[0] + typeLayouts[1] + + typeLayouts[2] + mdLayouts[2] + mdLayouts[3]; + for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { - if (ctype == ATTR_CONTEXT_CODE) continue; - define(sd, ctype, - "RuntimeVisibleAnnotations", annotationsLayout); + if (ctype != ATTR_CONTEXT_CODE) { + define(sd, ctype, + "RuntimeVisibleAnnotations", annotationsLayout); + define(sd, ctype, + "RuntimeInvisibleAnnotations", annotationsLayout); + + if (ctype == ATTR_CONTEXT_METHOD) { + define(sd, ctype, + "RuntimeVisibleParameterAnnotations", paramsLayout); + define(sd, ctype, + "RuntimeInvisibleParameterAnnotations", paramsLayout); + define(sd, ctype, + "AnnotationDefault", defaultLayout); + } + } define(sd, ctype, - "RuntimeInvisibleAnnotations", annotationsLayout); - if (ctype == ATTR_CONTEXT_METHOD) { - define(sd, ctype, - "RuntimeVisibleParameterAnnotations", paramsLayout); - define(sd, ctype, - "RuntimeInvisibleParameterAnnotations", paramsLayout); - define(sd, ctype, - "AnnotationDefault", defaultLayout); - } + "RuntimeVisibleTypeAnnotations", typesLayout); + define(sd, ctype, + "RuntimeInvisibleTypeAnnotations", typesLayout); } } @@ -529,6 +576,7 @@ return canon.addContent(bytes, null); } + @Override public boolean equals(Object x) { return ( x != null) && ( x.getClass() == Layout.class ) && equals((Layout)x); @@ -538,11 +586,13 @@ && this.layout.equals(that.layout) && this.ctype == that.ctype; } + @Override public int hashCode() { return (((17 + name.hashCode()) * 37 + layout.hashCode()) * 37 + ctype); } + @Override public int compareTo(Layout that) { int r; r = this.name.compareTo(that.name); @@ -551,6 +601,7 @@ if (r != 0) return r; return this.ctype - that.ctype; } + @Override public String toString() { String str = contextName(ctype)+"."+name+"["+layout+"]"; // If -ea, print out more informative strings! @@ -698,11 +749,14 @@ // References (to a local cpMap) are embedded in the bytes. def.parse(holder, bytes, 0, bytes.length, new ValueStream() { + @Override public void putInt(int bandIndex, int value) { } + @Override public void putRef(int bandIndex, Entry ref) { refs.add(ref); } + @Override public int encodeBCI(int bci) { return bci; } @@ -716,6 +770,7 @@ return def.unparse(in, out); } + @Override public String toString() { return def +"{"+(bytes == null ? -1 : size())+"}" @@ -1309,7 +1364,7 @@ } out.putRef(bandIndex, globalRef); break; - default: assert(false); continue; + default: assert(false); } } return pos; @@ -1416,8 +1471,7 @@ int localRef; if (globalRef != null) { // It's a one-element array, really an lvalue. - fixups[0] = Fixups.add(fixups[0], null, out.size(), - Fixups.U2_FORMAT, globalRef); + fixups[0] = Fixups.addRefWithLoc(fixups[0], out.size(), globalRef); localRef = 0; // placeholder for fixups } else { localRef = 0; // fixed null value diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Wed May 15 18:26:16 2013 -0700 @@ -48,6 +48,7 @@ import java.util.Map; import java.util.jar.Pack200; import static com.sun.java.util.jar.pack.Constants.*; +import java.util.LinkedList; /** * Define the structure and ordering of "bands" in a packed file. @@ -495,6 +496,7 @@ } protected int lengthForDebug = -1; // DEBUG ONLY + @Override public String toString() { // DEBUG ONLY int length = (lengthForDebug != -1 ? lengthForDebug : length()); String str = name; @@ -518,20 +520,24 @@ super(name, regularCoding); } + @Override public int capacity() { return values == null ? -1 : values.length; } /** Declare predicted or needed capacity. */ + @Override protected void setCapacity(int cap) { assert(length <= cap); if (cap == -1) { values = null; return; } values = realloc(values, cap); } + @Override public int length() { return length; } + @Override protected int valuesRemainingForDebug() { return length - valuesDisbursed; } @@ -583,6 +589,7 @@ return true; } + @Override protected void chooseBandCodings() throws IOException { boolean canVary = canVaryCoding(); if (!canVary || !shouldVaryCoding()) { @@ -653,6 +660,7 @@ } } + @Override protected long computeOutputSize() { outputSize = getCodingChooser().computeByteSize(bandCoding, values, 0, length); @@ -668,6 +676,7 @@ return regularCoding.setD(0).getLength(X); } + @Override protected void writeDataTo(OutputStream out) throws IOException { if (length == 0) return; // nothing to write long len0 = 0; @@ -691,6 +700,7 @@ if (optDumpBands) dumpBand(); } + @Override protected void readDataFrom(InputStream in) throws IOException { length = valuesExpected(); if (length == 0) return; // nothing to read @@ -707,7 +717,6 @@ if (XB < 0) { // Do not consume this value. No alternate coding. in.reset(); - XB = _meta_default; bandCoding = regularCoding; metaCoding = noMetaCoding; } else if (XB == _meta_default) { @@ -733,6 +742,7 @@ if (optDumpBands) dumpBand(); } + @Override public void doneDisbursing() { super.doneDisbursing(); values = null; // for GC @@ -763,7 +773,10 @@ /** Disburse one value. */ protected int getValue() { assert(phase() == DISBURSE_PHASE); - assert(valuesDisbursed < length); + // when debugging return a zero if lengths are zero + if (optDebugBands && length == 0 && valuesDisbursed == length) + return 0; + assert(valuesDisbursed <= length); return values[valuesDisbursed++]; } @@ -784,9 +797,11 @@ super(name, BYTE1); } + @Override public int capacity() { return bytes == null ? -1 : Integer.MAX_VALUE; } + @Override protected void setCapacity(int cap) { assert(bytes == null); // do this just once bytes = new ByteArrayOutputStream(cap); @@ -796,27 +811,32 @@ bytes = null; } + @Override public int length() { return bytes == null ? -1 : bytes.size(); } public void reset() { bytes.reset(); } + @Override protected int valuesRemainingForDebug() { return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available(); } + @Override protected void chooseBandCodings() throws IOException { // No-op. assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0); assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0); } + @Override protected long computeOutputSize() { // do not cache return bytes.size(); } + @Override public void writeDataTo(OutputStream out) throws IOException { if (length() == 0) return; bytes.writeTo(out); @@ -834,6 +854,7 @@ } } + @Override public void readDataFrom(InputStream in) throws IOException { int vex = valuesExpected(); if (vex == 0) return; @@ -852,11 +873,13 @@ if (optDumpBands) dumpBand(); } + @Override public void readyToDisburse() { in = new ByteArrayInputStream(bytes.toByteArray()); super.readyToDisburse(); } + @Override public void doneDisbursing() { super.doneDisbursing(); if (optDumpBands @@ -882,11 +905,13 @@ // Tap the stream. bytesForDump = new ByteArrayOutputStream(); this.in = new FilterInputStream(in) { + @Override public int read() throws IOException { int ch = in.read(); if (ch >= 0) bytesForDump.write(ch); return ch; } + @Override public int read(byte b[], int off, int len) throws IOException { int nr = in.read(b, off, len); if (nr >= 0) bytesForDump.write(b, off, nr); @@ -917,6 +942,7 @@ assert(b == (b & 0xFF)); collectorStream().write(b); } + @Override public String toString() { return "byte "+super.toString(); } @@ -1184,6 +1210,7 @@ super(name, regularCoding); } + @Override public Band init() { super.init(); // This is all just to keep the asserts happy: @@ -1259,12 +1286,17 @@ int bandCount() { return bandCount; } private int cap = -1; + @Override public int capacity() { return cap; } + @Override public void setCapacity(int cap) { this.cap = cap; } + @Override public int length() { return 0; } + @Override public int valuesRemainingForDebug() { return 0; } + @Override protected void chooseBandCodings() throws IOException { // coding decision pass for (int i = 0; i < bandCount; i++) { @@ -1273,6 +1305,7 @@ } } + @Override protected long computeOutputSize() { // coding decision pass long sum = 0; @@ -1286,6 +1319,7 @@ return sum; } + @Override protected void writeDataTo(OutputStream out) throws IOException { long preCount = 0; if (outputCounter != null) preCount = outputCounter.getCount(); @@ -1303,6 +1337,7 @@ } } + @Override protected void readDataFrom(InputStream in) throws IOException { assert(false); // not called? for (int i = 0; i < bandCount; i++) { @@ -1314,6 +1349,7 @@ } } + @Override public String toString() { return "{"+bandCount()+" bands: "+super.toString()+"}"; } @@ -1335,14 +1371,17 @@ public long getCount() { return count; } public void setCount(long c) { count = c; } + @Override public void write(int b) throws IOException { count++; if (out != null) out.write(b); } + @Override public void write(byte b[], int off, int len) throws IOException { count += len; if (out != null) out.write(b, off, len); } + @Override public String toString() { return String.valueOf(getCount()); } @@ -1490,6 +1529,7 @@ CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_FieldSpecific); CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature); MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5); + MultiBand field_type_metadata_bands = field_attr_bands.newMultiBand("(field_type_metadata_bands)", UNSIGNED5); CPRefBand method_descr = class_bands.newCPRefBand("method_descr", MDELTA5, CONSTANT_NameandType); MultiBand method_attr_bands = class_bands.newMultiBand("(method_attr_bands)", UNSIGNED5); @@ -1507,6 +1547,7 @@ IntBand method_MethodParameters_NB = method_attr_bands.newIntBand("method_MethodParameters_NB", BYTE1); CPRefBand method_MethodParameters_name_RUN = method_attr_bands.newCPRefBand("method_MethodParameters_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK); IntBand method_MethodParameters_flag_FH = method_attr_bands.newIntBand("method_MethodParameters_flag_FH"); + MultiBand method_type_metadata_bands = method_attr_bands.newMultiBand("(method_type_metadata_bands)", UNSIGNED5); MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5); IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi"); @@ -1527,6 +1568,7 @@ CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK); IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H"); IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H"); + MultiBand class_type_metadata_bands = class_attr_bands.newMultiBand("(class_type_metadata_bands)", UNSIGNED5); MultiBand code_bands = class_bands.newMultiBand("(code_bands)", UNSIGNED5); ByteBand code_headers = code_bands.newByteBand("code_headers"); //BYTE1 @@ -1545,7 +1587,7 @@ IntBand code_attr_indexes = code_attr_bands.newIntBand("code_attr_indexes"); IntBand code_attr_calls = code_attr_bands.newIntBand("code_attr_calls"); - MultiBand stackmap_bands = code_attr_bands.newMultiBand("StackMapTable_bands", UNSIGNED5); + MultiBand stackmap_bands = code_attr_bands.newMultiBand("(StackMapTable_bands)", UNSIGNED5); IntBand code_StackMapTable_N = stackmap_bands.newIntBand("code_StackMapTable_N"); IntBand code_StackMapTable_frame_T = stackmap_bands.newIntBand("code_StackMapTable_frame_T",BYTE1); IntBand code_StackMapTable_local_N = stackmap_bands.newIntBand("code_StackMapTable_local_N"); @@ -1573,6 +1615,7 @@ CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8); CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature); IntBand code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot"); + MultiBand code_type_metadata_bands = code_attr_bands.newMultiBand("(code_type_metadata_bands)", UNSIGNED5); // bands for bytecodes MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)", UNSIGNED5); @@ -1678,6 +1721,14 @@ metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands; metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands; } + // Table of bands which contains type_metadata (TypeAnnotations) + protected MultiBand[] typeMetadataBands = new MultiBand[ATTR_CONTEXT_LIMIT]; + { + typeMetadataBands[ATTR_CONTEXT_CLASS] = class_type_metadata_bands; + typeMetadataBands[ATTR_CONTEXT_FIELD] = field_type_metadata_bands; + typeMetadataBands[ATTR_CONTEXT_METHOD] = method_type_metadata_bands; + typeMetadataBands[ATTR_CONTEXT_CODE] = code_type_metadata_bands; + } // Attribute layouts. public static final int ADH_CONTEXT_MASK = 0x3; // (ad_hdr & ADH_CONTEXT_MASK) @@ -1793,36 +1844,47 @@ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { MultiBand xxx_metadata_bands = metadataBands[ctype]; - if (xxx_metadata_bands == null) - continue; // no code attrs + if (ctype != ATTR_CONTEXT_CODE) { + // These arguments cause the bands to be built + // automatically for this complicated layout: + predefineAttribute(X_ATTR_RuntimeVisibleAnnotations, + ATTR_CONTEXT_NAME[ctype]+"_RVA_", + xxx_metadata_bands, + Attribute.lookup(null, ctype, + "RuntimeVisibleAnnotations")); + predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations, + ATTR_CONTEXT_NAME[ctype]+"_RIA_", + xxx_metadata_bands, + Attribute.lookup(null, ctype, + "RuntimeInvisibleAnnotations")); - // These arguments cause the bands to be built - // automatically for this complicated layout: - predefineAttribute(X_ATTR_RuntimeVisibleAnnotations, - ATTR_CONTEXT_NAME[ctype]+"_RVA_", - xxx_metadata_bands, - Attribute.lookup(null, ctype, - "RuntimeVisibleAnnotations")); - predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations, - ATTR_CONTEXT_NAME[ctype]+"_RIA_", - xxx_metadata_bands, - Attribute.lookup(null, ctype, - "RuntimeInvisibleAnnotations")); - if (ctype != ATTR_CONTEXT_METHOD) - continue; - - predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations, - "method_RVPA_", xxx_metadata_bands, - Attribute.lookup(null, ctype, - "RuntimeVisibleParameterAnnotations")); - predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, - "method_RIPA_", xxx_metadata_bands, - Attribute.lookup(null, ctype, - "RuntimeInvisibleParameterAnnotations")); - predefineAttribute(METHOD_ATTR_AnnotationDefault, - "method_AD_", xxx_metadata_bands, - Attribute.lookup(null, ctype, - "AnnotationDefault")); + if (ctype == ATTR_CONTEXT_METHOD) { + predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations, + "method_RVPA_", xxx_metadata_bands, + Attribute.lookup(null, ctype, + "RuntimeVisibleParameterAnnotations")); + predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, + "method_RIPA_", xxx_metadata_bands, + Attribute.lookup(null, ctype, + "RuntimeInvisibleParameterAnnotations")); + predefineAttribute(METHOD_ATTR_AnnotationDefault, + "method_AD_", xxx_metadata_bands, + Attribute.lookup(null, ctype, + "AnnotationDefault")); + } + } + // All contexts have these + MultiBand xxx_type_metadata_bands = typeMetadataBands[ctype]; + predefineAttribute(X_ATTR_RuntimeVisibleTypeAnnotations, + ATTR_CONTEXT_NAME[ctype] + "_RVTA_", + xxx_type_metadata_bands, + Attribute.lookup(null, ctype, + "RuntimeVisibleTypeAnnotations")); + predefineAttribute(X_ATTR_RuntimeInvisibleTypeAnnotations, + ATTR_CONTEXT_NAME[ctype] + "_RITA_", + xxx_type_metadata_bands, + Attribute.lookup(null, ctype, + "RuntimeInvisibleTypeAnnotations")); } @@ -2053,8 +2115,7 @@ Attribute.Layout def = attr.layout(); int ctype = def.ctype(); return predefineAttribute(index, ctype, - makeNewAttributeBands(bandPrefix, def, - addHere), + makeNewAttributeBands(bandPrefix, def, addHere), def.name(), def.layout()); } @@ -2539,7 +2600,7 @@ return true; } - // DEBUG ONLY: Validate next input band. + // DEBUG ONLY: Validate next input band, ensure bands are read in sequence private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException { Band p = prevForAssertMap.get(b); // Any previous band must be done reading before this one starts. @@ -2547,30 +2608,19 @@ Utils.log.warning("Previous band not done reading."); Utils.log.info(" Previous band: "+p); Utils.log.info(" Next band: "+b); - Thread.dumpStack(); assert(verbose > 0); // die unless verbose is true } String name = b.name; if (optDebugBands && !name.startsWith("(")) { + assert(bandSequenceList != null); // Verify synchronization between reader & writer: - StringBuilder buf = new StringBuilder(); - int ch; - while ((ch = in.read()) > 0) - buf.append((char)ch); - String inName = buf.toString(); + String inName = bandSequenceList.removeFirst(); + // System.out.println("Reading: " + name); if (!inName.equals(name)) { - StringBuilder sb = new StringBuilder(); - sb.append("Expected "+name+" but read: "); - inName += (char)ch; - while (inName.length() < 10) { - inName += (char) in.read(); - } - for (int i = 0; i < inName.length(); i++) { - sb.append(inName.charAt(i)); - } - Utils.log.warning(sb.toString()); + Utils.log.warning("Expected " + name + " but read: " + inName); return false; } + Utils.log.info("Read band in sequence: " + name); } return true; } @@ -2590,7 +2640,12 @@ return true; } - // DEBUG ONLY: Maybe write a debugging cookie to next output band. + /* + * DEBUG ONLY: write the bands to a list and read back the list in order, + * this works perfectly if we use the java packer and unpacker, typically + * this will work with --repack or if they are in the same jvm instance. + */ + static LinkedList bandSequenceList = null; private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException { Band p = prevForAssertMap.get(b); // Any previous band must be done writing before this one starts. @@ -2598,16 +2653,15 @@ Utils.log.warning("Previous band not done writing."); Utils.log.info(" Previous band: "+p); Utils.log.info(" Next band: "+b); - Thread.dumpStack(); assert(verbose > 0); // die unless verbose is true } String name = b.name; if (optDebugBands && !name.startsWith("(")) { + if (bandSequenceList == null) + bandSequenceList = new LinkedList<>(); // Verify synchronization between reader & writer: - for (int j = 0; j < name.length(); j++) { - out.write((byte)name.charAt(j)); - } - out.write((byte)0); + bandSequenceList.add(name); + // System.out.println("Writing: " + b); } return true; } @@ -2664,7 +2718,7 @@ buf.append("\\r"); } else { String str = "000"+Integer.toHexString(ch); - buf.append("\\u"+str.substring(str.length()-4)); + buf.append("\\u").append(str.substring(str.length()-4)); } } ps.println(buf); diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Wed May 15 18:26:16 2013 -0700 @@ -45,6 +45,7 @@ 1.5 to 1.5.X 49,0 1.6 to 1.5.x 50,0 1.7 to 1.6.x 51,0 + 1.8 to 1.7.x 52,0 */ public final static Package.Version JAVA_MIN_CLASS_VERSION = @@ -161,7 +162,9 @@ METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24, CLASS_ATTR_ClassFile_version = 24, METHOD_ATTR_AnnotationDefault = 25, - METHOD_ATTR_MethodParameters = 26, + METHOD_ATTR_MethodParameters = 26, // JDK8 + X_ATTR_RuntimeVisibleTypeAnnotations = 27, // JDK8 + X_ATTR_RuntimeInvisibleTypeAnnotations = 28, // JDK8 CODE_ATTR_StackMapTable = 0, // new in Java 6 CODE_ATTR_LineNumberTable = 1, CODE_ATTR_LocalVariableTable = 2, diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java Wed May 15 18:26:16 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.Objects; /** * Collection of relocatable constant pool references. @@ -77,8 +78,9 @@ private static final int MINBIGSIZE = 1; // cleverly share empty bigDescs: - private static int[] noBigDescs = {MINBIGSIZE}; + private static final int[] noBigDescs = {MINBIGSIZE}; + @Override public int size() { return size; } @@ -105,6 +107,7 @@ } } + @Override public void clear() { if (bytes != null) { // Clean the bytes: @@ -141,16 +144,16 @@ assert(old.equals(new ArrayList<>(this))); } - static final int LOC_SHIFT = 1; - static final int FMT_MASK = 0x1; - static final byte UNUSED_BYTE = 0; - static final byte OVERFLOW_BYTE = -1; + private static final int LOC_SHIFT = 1; + private static final int FMT_MASK = 0x1; + private static final byte UNUSED_BYTE = 0; + private static final byte OVERFLOW_BYTE = -1; // fill pointer of bigDescs array is in element [0] - static final int BIGSIZE = 0; + private static final int BIGSIZE = 0; // Format values: - public static final int U2_FORMAT = 0; - public static final int U1_FORMAT = 1; + private static final int U2_FORMAT = 0; + private static final int U1_FORMAT = 1; // Special values for the static methods. private static final int SPECIAL_LOC = 0; @@ -232,6 +235,14 @@ } } + void addU1(int pc, Entry ref) { + add(pc, U1_FORMAT, ref); + } + + void addU2(int pc, Entry ref) { + add(pc, U2_FORMAT, ref); + } + /** Simple and necessary tuple to present each fixup. */ public static class Fixup implements Comparable { @@ -248,15 +259,25 @@ public int location() { return descLoc(desc); } public int format() { return descFmt(desc); } public Entry entry() { return entry; } + @Override public int compareTo(Fixup that) { // Ordering depends only on location. return this.location() - that.location(); } + @Override public boolean equals(Object x) { if (!(x instanceof Fixup)) return false; Fixup that = (Fixup) x; return this.desc == that.desc && this.entry == that.entry; } + @Override + public int hashCode() { + int hash = 7; + hash = 59 * hash + this.desc; + hash = 59 * hash + Objects.hashCode(this.entry); + return hash; + } + @Override public String toString() { return "@"+location()+(format()==U1_FORMAT?".1":"")+"="+entry; } @@ -267,8 +288,11 @@ int index = 0; // index into entries int bigIndex = BIGSIZE+1; // index into bigDescs int next = head; // desc pointing to next fixup + @Override public boolean hasNext() { return index < size; } + @Override public void remove() { throw new UnsupportedOperationException(); } + @Override public Fixup next() { int thisIndex = index; return new Fixup(nextDesc(), entries[thisIndex]); @@ -293,17 +317,20 @@ } } + @Override public Iterator iterator() { return new Itr(); } public void add(int location, int format, Entry entry) { addDesc(makeDesc(location, format), entry); } + @Override public boolean add(Fixup f) { addDesc(f.desc, f.entry); return true; } + @Override public boolean addAll(Collection c) { if (c instanceof Fixups) { // Use knowledge of Itr structure to avoid building little structs. @@ -367,7 +394,13 @@ } /// Static methods that optimize the use of this class. - public static + static Object addRefWithBytes(Object f, byte[] bytes, Entry e) { + return add(f, bytes, 0, U2_FORMAT, e); + } + static Object addRefWithLoc(Object f, int loc, Entry entry) { + return add(f, null, loc, U2_FORMAT, entry); + } + private static Object add(Object prevFixups, byte[] bytes, int loc, int fmt, Entry e) { diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Wed May 15 18:26:16 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -259,7 +259,7 @@ byte[] bytes = new byte[2]; sfName = getRefString(obvious); Object f = null; - f = Fixups.add(f, bytes, 0, Fixups.U2_FORMAT, sfName); + f = Fixups.addRefWithBytes(f, bytes, sfName); a = attrSourceFileSpecial.addContent(bytes, f); } } else if (obvious.equals(sfName.stringValue())) { diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Wed May 15 18:26:16 2013 -0700 @@ -116,7 +116,7 @@ int nr = super.read(b, off, len); servedPos = pos; if (nr >= 0) served += nr; - assert(served <= limit || limit == -1); + //assert(served <= limit || limit == -1); return nr; } public long skip(long n) throws IOException { @@ -1500,6 +1500,7 @@ // ic_local_bands // *class_ClassFile_version_minor_H :UNSIGNED5 // *class_ClassFile_version_major_H :UNSIGNED5 + // class_type_metadata_bands // // field_attr_bands: // *field_flags :UNSIGNED5 @@ -1509,6 +1510,7 @@ // *field_Signature_RS :UNSIGNED5 (cp_Signature) // field_metadata_bands // *field_ConstantValue_KQ :UNSIGNED5 (cp_Int, etc.; see note) + // field_type_metadata_bands // // method_attr_bands: // *method_flags :UNSIGNED5 @@ -1522,6 +1524,7 @@ // *method_MethodParameters_NB: BYTE1 // *method_MethodParameters_RUN: UNSIGNED5 (cp_Utf8) // *method_MethodParameters_FH: UNSIGNED5 (flag) + // method_type_metadata_bands // // code_attr_bands: // *code_flags :UNSIGNED5 @@ -1537,6 +1540,7 @@ // *code_LocalVariableTable_name_RU :UNSIGNED5 (cp_Utf8) // *code_LocalVariableTable_type_RS :UNSIGNED5 (cp_Signature) // *code_LocalVariableTable_slot :UNSIGNED5 + // code_type_metadata_bands countAttrs(ctype, holders); readAttrs(ctype, holders); @@ -1703,8 +1707,9 @@ class_InnerClasses_outer_RCN.readFrom(in); class_InnerClasses_name_RUN.expectLength(tupleCount); class_InnerClasses_name_RUN.readFrom(in); - } else if (totalCount == 0) { - // Expect no elements at all. Skip quickly. + } else if (!optDebugBands && totalCount == 0) { + // Expect no elements at all. Skip quickly. however if we + // are debugging bands, read all bands regardless for (int j = 0; j < ab.length; j++) { ab[j].doneWithUnusedBand(); } @@ -1723,11 +1728,17 @@ assert(cbles[j].kind == Attribute.EK_CBLE); int entryCount = forwardCounts[j]; forwardCounts[j] = -1; // No more, please! - if (cbles[j].flagTest(Attribute.EF_BACK)) + if (totalCount > 0 && cbles[j].flagTest(Attribute.EF_BACK)) entryCount += xxx_attr_calls.getInt(); readAttrBands(cbles[j].body, entryCount, forwardCounts, ab); } } + // mark them read, to satisfy asserts + if (optDebugBands && totalCount == 0) { + for (int j = 0; j < ab.length; j++) { + ab[j].doneDisbursing(); + } + } } } if (!predef) break; @@ -2154,11 +2165,10 @@ if (size == 1) ldcRefSet.add(ref); int fmt; switch (size) { - case 1: fmt = Fixups.U1_FORMAT; break; - case 2: fmt = Fixups.U2_FORMAT; break; + case 1: fixupBuf.addU1(pc, ref); break; + case 2: fixupBuf.addU2(pc, ref); break; default: assert(false); fmt = 0; } - fixupBuf.add(pc, fmt, ref); buf[pc+0] = buf[pc+1] = 0; pc += size; } @@ -2193,7 +2203,7 @@ int coding = bc_initref.getInt(); // Find the nth overloading of in classRef. MemberEntry ref = pkg.cp.getOverloadingForIndex(CONSTANT_Methodref, classRef, "", coding); - fixupBuf.add(pc, Fixups.U2_FORMAT, ref); + fixupBuf.addU2(pc, ref); buf[pc+0] = buf[pc+1] = 0; pc += 2; assert(Instruction.opLength(origBC) == (pc - curPC)); @@ -2226,7 +2236,7 @@ insnMap[numInsns++] = curPC; } buf[pc++] = (byte) origBC; - fixupBuf.add(pc, Fixups.U2_FORMAT, ref); + fixupBuf.addU2(pc, ref); buf[pc+0] = buf[pc+1] = 0; pc += 2; assert(Instruction.opLength(origBC) == (pc - curPC)); @@ -2289,11 +2299,10 @@ buf[pc++] = (byte) origBC; int fmt; switch (size) { - case 1: fmt = Fixups.U1_FORMAT; break; - case 2: fmt = Fixups.U2_FORMAT; break; + case 1: fixupBuf.addU1(pc, ref); break; + case 2: fixupBuf.addU2(pc, ref); break; default: assert(false); fmt = 0; } - fixupBuf.add(pc, fmt, ref); buf[pc+0] = buf[pc+1] = 0; pc += size; if (origBC == _multianewarray) { diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/native/com/sun/java/util/jar/pack/constants.h --- a/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/constants.h Wed May 15 18:26:16 2013 -0700 @@ -133,6 +133,8 @@ X_ATTR_Deprecated = 20, X_ATTR_RuntimeVisibleAnnotations = 21, X_ATTR_RuntimeInvisibleAnnotations = 22, + X_ATTR_RuntimeVisibleTypeAnnotations = 27, + X_ATTR_RuntimeInvisibleTypeAnnotations = 28, X_ATTR_OVERFLOW = 16, X_ATTR_LIMIT_NO_FLAGS_HI = 32, X_ATTR_LIMIT_FLAGS_HI = 63, @@ -146,6 +148,8 @@ F(X_ATTR_Deprecated,Deprecated) \ F(X_ATTR_RuntimeVisibleAnnotations,RuntimeVisibleAnnotations) \ F(X_ATTR_RuntimeInvisibleAnnotations,RuntimeInvisibleAnnotations) \ + F(X_ATTR_RuntimeVisibleTypeAnnotations,RuntimeVisibleTypeAnnotations) \ + F(X_ATTR_RuntimeInvisibleTypeAnnotations,RuntimeInvisibleTypeAnnotations) \ /*F(X_ATTR_Synthetic,Synthetic)*/ \ /*(end)*/ #define CLASS_ATTR_DO(F) \ diff -r a74a13b9aa93 -r 46864558d068 jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Thu May 16 10:58:20 2013 -0700 +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp Wed May 15 18:26:16 2013 -0700 @@ -1791,7 +1791,7 @@ switch (*lp++) { case 'B': case 'H': case 'I': case 'V': // unsigned_int case 'S': // signed_int - --lp; // reparse + --lp; // reparse case 'F': lp = parseIntLayout(lp, b, EK_INT); break; @@ -2037,47 +2037,80 @@ MDL0 // annotations: #define MDL1 \ - "[NH[(1)]]" \ - "[RSHNH[RUH(1)]]" + "[NH[(1)]]" MDL1 - // member_value: - "[TB" - "(66,67,73,83,90)[KIH]" - "(68)[KDH]" - "(70)[KFH]" - "(74)[KJH]" - "(99)[RSH]" - "(101)[RSHRUH]" - "(115)[RUH]" - "(91)[NH[(0)]]" - "(64)[" - // nested annotation: - "RSH" - "NH[RUH(0)]" - "]" - "()[]" +#define MDL2 \ + "[RSHNH[RUH(1)]]" + MDL2 + // element_value: +#define MDL3 \ + "[TB" \ + "(66,67,73,83,90)[KIH]" \ + "(68)[KDH]" \ + "(70)[KFH]" \ + "(74)[KJH]" \ + "(99)[RSH]" \ + "(101)[RSHRUH]" \ + "(115)[RUH]" \ + "(91)[NH[(0)]]" \ + "(64)[" \ + /* nested annotation: */ \ + "RSH" \ + "NH[RUH(0)]" \ + "]" \ + "()[]" \ "]" + MDL3 ); const char* md_layout_P = md_layout; const char* md_layout_A = md_layout+strlen(MDL0); - const char* md_layout_V = md_layout+strlen(MDL0 MDL1); + const char* md_layout_V = md_layout+strlen(MDL0 MDL1 MDL2); assert(0 == strncmp(&md_layout_A[-3], ")]][", 4)); assert(0 == strncmp(&md_layout_V[-3], ")]][", 4)); +const char* type_md_layout( + "[NH[(1)(2)(3)]]" + // target-type + target_info + "[TB" + "(0,1)[B]" + "(16)[FH]" + "(17,18)[BB]" + "(19,20,21)[]" + "(22)[B]" + "(23)[H]" + "(64,65)[NH[PHOHH]]" + "(66)[H]" + "(67,68,69,70)[PH]" + "(71,72,73,74,75)[PHB]" + "()[]]" + // target-path + "[NB[BB]]" + // annotation + element_value + MDL2 + MDL3 +); + for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) { attr_definitions& ad = attr_defs[i]; - ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations, - "RuntimeVisibleAnnotations", md_layout_A); - ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations, - "RuntimeInvisibleAnnotations", md_layout_A); - if (i != ATTR_CONTEXT_METHOD) continue; - ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations, - "RuntimeVisibleParameterAnnotations", md_layout_P); - ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, - "RuntimeInvisibleParameterAnnotations", md_layout_P); - ad.defineLayout(METHOD_ATTR_AnnotationDefault, - "AnnotationDefault", md_layout_V); + if (i != ATTR_CONTEXT_CODE) { + ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations, + "RuntimeVisibleAnnotations", md_layout_A); + ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations, + "RuntimeInvisibleAnnotations", md_layout_A); + if (i == ATTR_CONTEXT_METHOD) { + ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations, + "RuntimeVisibleParameterAnnotations", md_layout_P); + ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, + "RuntimeInvisibleParameterAnnotations", md_layout_P); + ad.defineLayout(METHOD_ATTR_AnnotationDefault, + "AnnotationDefault", md_layout_V); + } + } + ad.defineLayout(X_ATTR_RuntimeVisibleTypeAnnotations, + "RuntimeVisibleTypeAnnotations", type_md_layout); + ad.defineLayout(X_ATTR_RuntimeInvisibleTypeAnnotations, + "RuntimeInvisibleTypeAnnotations", type_md_layout); } attr_definition_headers.readData(attr_definition_count); @@ -2433,6 +2466,7 @@ ad.readBandData(X_ATTR_RuntimeVisibleAnnotations); ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations); + CHECK; count = ad.predefCount(CLASS_ATTR_InnerClasses); class_InnerClasses_N.readData(count); @@ -2452,6 +2486,10 @@ class_ClassFile_version_minor_H.readData(count); class_ClassFile_version_major_H.readData(count); CHECK; + + ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations); + ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations); + CHECK; break; case ATTR_CONTEXT_FIELD: @@ -2467,6 +2505,10 @@ ad.readBandData(X_ATTR_RuntimeVisibleAnnotations); ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations); CHECK; + + ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations); + ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations); + CHECK; break; case ATTR_CONTEXT_METHOD: @@ -2497,6 +2539,11 @@ method_MethodParameters_name_RUN.readData(count); method_MethodParameters_flag_FH.readData(count); CHECK; + + ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations); + ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations); + CHECK; + break; case ATTR_CONTEXT_CODE: @@ -2566,18 +2613,22 @@ count = ad.predefCount(CODE_ATTR_LineNumberTable); code_LineNumberTable_N.readData(count); + CHECK; count = code_LineNumberTable_N.getIntTotal(); code_LineNumberTable_bci_P.readData(count); code_LineNumberTable_line.readData(count); + CHECK; count = ad.predefCount(CODE_ATTR_LocalVariableTable); code_LocalVariableTable_N.readData(count); + CHECK; count = code_LocalVariableTable_N.getIntTotal(); code_LocalVariableTable_bci_P.readData(count); code_LocalVariableTable_span_O.readData(count); code_LocalVariableTable_name_RU.readData(count); code_LocalVariableTable_type_RS.readData(count); code_LocalVariableTable_slot.readData(count); + CHECK; count = ad.predefCount(CODE_ATTR_LocalVariableTypeTable); code_LocalVariableTypeTable_N.readData(count); @@ -2587,6 +2638,12 @@ code_LocalVariableTypeTable_name_RU.readData(count); code_LocalVariableTypeTable_type_RS.readData(count); code_LocalVariableTypeTable_slot.readData(count); + CHECK; + + ad.readBandData(X_ATTR_RuntimeVisibleTypeAnnotations); + ad.readBandData(X_ATTR_RuntimeInvisibleTypeAnnotations); + CHECK; + break; } @@ -5151,7 +5208,7 @@ #ifndef PRODUCT int unpacker::printcr_if_verbose(int level, const char* fmt ...) { - if (verbose < level+10) return 0; + if (verbose < level) return 0; va_list vl; va_start(vl, fmt); char fmtbuf[300]; diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/AttributeTests.java --- a/jdk/test/tools/pack200/AttributeTests.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/test/tools/pack200/AttributeTests.java Wed May 15 18:26:16 2013 -0700 @@ -21,12 +21,9 @@ * questions. */ import java.io.File; -import java.nio.charset.Charset; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static java.nio.file.StandardOpenOption.*; /* * @test * @bug 6746111 8005252 8008262 @@ -58,8 +55,7 @@ scratch.add("}"); File cwd = new File("."); File javaFile = new File(cwd, javaFileName); - Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(), - CREATE, TRUNCATE_EXISTING); + Utils.createFile(javaFile, scratch); Utils.compiler(javaFile.getName(), "-parameters"); diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/BandIntegrity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/BandIntegrity.java Wed May 15 18:26:16 2013 -0700 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary test ensures the proper sequencing of bands, dump bands as well. + * @compile -XDignore.symbol.file Utils.java BandIntegrity.java + * @run main BandIntegrity + * @author ksrini + */ +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/* + * This makes use of the optDebugBands to ensure the bands are read in the + * same sequence as it was written. The caveat is that this works only with + * the java unpacker, therefore it will work only with --repack such that + * the java packer and unpacker must be called in the same java instance. + */ +public class BandIntegrity { + public static void main(String... args) throws IOException { + File testFile = new File("test.jar"); + Utils.jar("cvf", testFile.getName(), + "-C", Utils.TEST_CLS_DIR.getAbsolutePath(), + "."); + List scratch = new ArrayList<>(); + // band debugging works only with java unpacker + scratch.add("com.sun.java.util.jar.pack.disable.native=true"); + scratch.add("com.sun.java.util.jar.pack.debug.bands=true"); + // while at it, might as well exercise this functionality + scratch.add("com.sun.java.util.jar.pack.dump.bands=true"); + scratch.add("pack.unknown.attribute=error"); + File configFile = new File("pack.conf"); + Utils.createFile(configFile, scratch); + File outFile = new File("out.jar"); + Utils.repack(testFile, outFile, true, + "-v", "--config-file=" + configFile.getName()); + } +} diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/InstructionTests.java --- a/jdk/test/tools/pack200/InstructionTests.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/test/tools/pack200/InstructionTests.java Wed May 15 18:26:16 2013 -0700 @@ -21,11 +21,8 @@ * questions. */ import java.io.File; -import java.nio.charset.Charset; -import java.nio.file.Files; import java.util.ArrayList; import java.util.List; -import static java.nio.file.StandardOpenOption.*; /* * @test @@ -59,8 +56,7 @@ scratch.add("}"); File cwd = new File("."); File javaFile = new File(cwd, javaFileName); - Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(), - CREATE, TRUNCATE_EXISTING); + Utils.createFile(javaFile, scratch); // -g to compare LVT and LNT entries Utils.compiler("-g", javaFile.getName()); @@ -69,8 +65,7 @@ scratch.clear(); scratch.add("com.sun.java.util.jar.pack.class.format.error=error"); scratch.add("pack.unknown.attribute=error"); - Files.write(propsFile.toPath(), scratch, Charset.defaultCharset(), - CREATE, TRUNCATE_EXISTING); + Utils.createFile(propsFile, scratch); // jar the file up File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT); Utils.jar("cvf", testjarFile.getName(), "."); diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/Utils.java --- a/jdk/test/tools/pack200/Utils.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/test/tools/pack200/Utils.java Wed May 15 18:26:16 2013 -0700 @@ -32,6 +32,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; +import java.nio.charset.Charset; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; @@ -45,6 +46,7 @@ import java.util.zip.ZipFile; import static java.nio.file.StandardCopyOption.*; +import static java.nio.file.StandardOpenOption.*; /** * @@ -70,6 +72,7 @@ static final String JAR_FILE_EXT = ".jar"; static final File TEST_SRC_DIR = new File(System.getProperty("test.src")); + static final File TEST_CLS_DIR = new File(System.getProperty("test.classes")); static final String VERIFIER_DIR_NAME = "pack200-verifier"; static final File VerifierJar = new File(VERIFIER_DIR_NAME + JAR_FILE_EXT); @@ -86,6 +89,10 @@ return; } File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME); + if (!srcDir.exists()) { + // if not available try one level above + srcDir = new File(TEST_SRC_DIR.getParentFile(), VERIFIER_DIR_NAME); + } List javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT)); File tmpFile = File.createTempFile("javac", ".tmp"); File classesDir = new File("xclasses"); @@ -205,6 +212,10 @@ : name; } + static void createFile(File outFile, List content) throws IOException { + Files.write(outFile.getAbsoluteFile().toPath(), content, + Charset.defaultCharset(), CREATE_NEW, TRUNCATE_EXISTING); + } /* * Suppose a path is provided which consists of a full path diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java Thu May 16 10:58:20 2013 -0700 +++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java Wed May 15 18:26:16 2013 -0700 @@ -69,6 +69,9 @@ import com.sun.tools.classfile.StackMapTable_attribute.*; import com.sun.tools.classfile.StackMap_attribute; import com.sun.tools.classfile.Synthetic_attribute; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.TypeAnnotation.Position; +import static com.sun.tools.classfile.TypeAnnotation.TargetType.THROWS; import java.util.*; import java.io.*; import java.util.jar.JarEntry; @@ -851,6 +854,7 @@ } } + class AttributeVisitor implements Attribute.Visitor { final ClassFile cf; final ClassReader x; @@ -1088,23 +1092,26 @@ } return null; // already added to parent } + private void parseAnnotation(Annotation anno, Element p) { + Element ea = new Element("Annotation"); + ea.setAttr("name", "" + x.getCpString(anno.type_index)); + for (Annotation.element_value_pair evp : anno.element_value_pairs) { + Element evpe = new Element("Element"); + evpe.setAttr("tag", "" + evp.value.tag); + evpe.setAttr("value", x.getCpString(evp.element_name_index)); + Element child = aev.visit(evp.value, evpe); + if (child != null) { + evpe.add(child); + } + ea.add(evpe); + } + ea.trimToSize(); + p.add(ea); + } private void parseAnnotations(Annotation[] ra, Element p) { - for (Annotation anno : ra) { - Element ea = new Element("Member"); - ea.setAttr("name", "" + x.getCpString(anno.type_index)); - for (Annotation.element_value_pair evp : anno.element_value_pairs) { - Element evpe = new Element("Element"); - evpe.setAttr("tag", "" + evp.value.tag); - evpe.setAttr("value", x.getCpString(evp.element_name_index)); - Element child = aev.visit(evp.value, evpe); - if (child != null) { - evpe.add(child); - } - ea.add(evpe); - } - ea.trimToSize(); - p.add(ea); + for (Annotation anno : ra) { + parseAnnotation(anno, p); } } @@ -1150,6 +1157,145 @@ return null; } + private void parsePosition(Position ap, Element p) { + Element te = new Element(); + switch (ap.type) { + case CLASS_TYPE_PARAMETER: // 0x00 + te.setName("CLASS_TYPE_PARAMETER"); + te.setAttr("idx", "" + ap.parameter_index); + break; + case METHOD_TYPE_PARAMETER: // 0x01 + te.setName("METHOD_TYPE_PARAMETER"); + te.setAttr("idx", "" + ap.parameter_index); + break; + case CLASS_EXTENDS: // 0x10 + te.setName("CLASS_EXTENDS"); + te.setAttr("idx", "" + ap.type_index); + break; + case CLASS_TYPE_PARAMETER_BOUND: // 0x11 + te.setName("CLASS_TYPE_PARAMETER_BOUND"); + te.setAttr("idx1", "" + ap.parameter_index); + te.setAttr("idx2", "" + ap.bound_index); + break; + case METHOD_TYPE_PARAMETER_BOUND: // 0x12 + te.setName("METHOD_TYPE_PARAMETER_BOUND"); + te.setAttr("idx1", "" + ap.parameter_index); + te.setAttr("idx2", "" + ap.bound_index); + break; + case FIELD: // 0x13 + te.setName("FIELD"); + break; + case METHOD_RETURN: // 0x14 + te.setName("METHOD_RETURN"); + break; + case METHOD_RECEIVER: // 0x15 + te.setName("METHOD_RECEIVER"); + break; + case METHOD_FORMAL_PARAMETER: // 0x16 + te.setName("METHOD_FORMAL_PARAMETER"); + te.setAttr("idx", "" + ap.parameter_index); + break; + case THROWS: // 0x17 + te.setName("THROWS"); + te.setAttr("idx", "" + ap.type_index); + break; + case LOCAL_VARIABLE: // 0x40 + te.setName("LOCAL_VARIABLE"); + for (int i = 0; i < ap.lvarIndex.length; i++) { + te.setAttr("lvar_idx_" + i, "" + ap.lvarIndex[i]); + te.setAttr("lvar_len_" + i, "" + ap.lvarLength[i]); + te.setAttr("lvar_off_" + i, "" + ap.lvarOffset[i]); + } + break; + case RESOURCE_VARIABLE: // 0x41 + te.setName("RESOURCE_VARIABLE"); + for (int i = 0; i < ap.lvarIndex.length ; i++) { + te.setAttr("lvar_idx_" + i, "" + ap.lvarIndex[i]); + te.setAttr("lvar_len_" + i, "" + ap.lvarLength[i]); + te.setAttr("lvar_off_" + i, "" + ap.lvarOffset[i]); + } + break; + case EXCEPTION_PARAMETER: // 0x42 + te.setName("EXCEPTION_PARAMETER"); + te.setAttr("idx", "" + ap.exception_index); + break; + case INSTANCEOF: // 0x43 + te.setName("INSTANCE_OF"); + te.setAttr("off", "" + ap.offset); + break; + case NEW: // 0x44 + te.setName("NEW"); + te.setAttr("off", "" + ap.offset); + break; + case CONSTRUCTOR_REFERENCE: // 0x45 + te.setName("CONSTRUCTOR_REFERENCE_RECEIVER"); + te.setAttr("off", "" + ap.offset); + break; + case METHOD_REFERENCE: // 0x46 + te.setName("METHOD_REFERENCE_RECEIVER"); + te.setAttr("off", "" + ap.offset); + break; + case CAST: // 0x47 + te.setName("CAST"); + te.setAttr("off", "" + ap.offset); + te.setAttr("idx", "" + ap.type_index); + break; + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: // 0x48 + te.setName("CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT"); + te.setAttr("off", "" + ap.offset); + te.setAttr("idx", "" + ap.type_index); + break; + case METHOD_INVOCATION_TYPE_ARGUMENT: // 0x49 + te.setName("METHOD_INVOCATION_TYPE_ARGUMENT"); + te.setAttr("off", "" + ap.offset); + te.setAttr("idx", "" + ap.type_index); + break; + case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: // 0x4A + te.setName("CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT"); + te.setAttr("off", "" + ap.offset); + te.setAttr("idx", "" + ap.type_index); + break; + case METHOD_REFERENCE_TYPE_ARGUMENT: // 0x4B + te.setName("METHOD_REFERENCE_TYPE_ARGUMENT"); + te.setAttr("off", "" + ap.offset); + te.setAttr("idx", "" + ap.type_index); + break; + default: + throw new RuntimeException("not implemented"); + } + te.trimToSize(); + p.add(te); + } + private void parseTypeAnnotations(TypeAnnotation pa, Element p) { + Element pta = new Element("RuntimeVisibleTypeAnnotation"); + p.add(pta); + Position pos = pa.position; + parsePosition(pos, pta); + parseAnnotation(pa.annotation, pta); + } + + @Override + public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) { + Element e = new Element(x.getCpString(rvta.attribute_name_index)); + for (TypeAnnotation pa : rvta.annotations) { + parseTypeAnnotations(pa, e); + } + e.sort(); + p.add(e); + return null; + } + + @Override + public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) { + Element e = new Element(x.getCpString(rita.attribute_name_index)); + for (TypeAnnotation pa : rita.annotations) { + parseTypeAnnotations(pa, e); + } + e.sort(); + p.add(e); + return null; + } + @Override public Element visitSignature(Signature_attribute s, Element p) { String aname = x.getCpString(s.attribute_name_index); @@ -1216,21 +1362,6 @@ p.add(e); return null; } - - /* - * TODO - * add these two for now to keep the compiler happy, we will implement - * these along with the JSR-308 changes. - */ - @Override - public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) { - throw new UnsupportedOperationException("Not supported yet."); - } } class StackMapVisitor implements StackMapTable_attribute.stack_map_frame.Visitor { diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/typeannos/Lambda.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/typeannos/Lambda.java Wed May 15 18:26:16 2013 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @Xtest + * @bug 8008077 + * @summary new type annotation location: lambda expressions + * @compile Lambda.java + * @author Werner Dietl + */ + +import java.lang.annotation.*; + +public class Lambda { + + interface LambdaInt { + void generic(S p1, T p2); + } + + static class LambdaImpl implements LambdaInt { + LambdaImpl(S p1, T p2) {} + public void generic(S p1, T p2) {} + } + + LambdaInt getMethodRefTA(LambdaImpl r) { + return r::<@TA Object, @TB Object>generic; + } + + LambdaInt getConstructorRefTA() { + return LambdaImpl::<@TA Object, @TB Object>new; + } + +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TB { } diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/typeannos/Readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/typeannos/Readme.txt Wed May 15 18:26:16 2013 -0700 @@ -0,0 +1,11 @@ +This directory contains tests which exercises all possible TypeAnnotations +structure. These tests are borrowed from +langtools/test/tools.javac/annotations/typeAnnotations. + +The reason it is copied over is that we need to test pack200 and these +annotation may not be present in any of the JDK/JRE jars, yet we need to test +all these cases. + + +Therefore it would be a good practice to sync these tests with the original +if there are any changes. diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/typeannos/TargetTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/typeannos/TargetTypes.java Wed May 15 18:26:16 2013 -0700 @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +import java.util.*; +import java.io.*; + +/* + * @Xtest + * @summary compiler accepts all values + * @author Mahmood Ali + * @author Yuri Gaevsky + * @compile TargetTypes.java + */ + +@Target({TYPE_USE, TYPE_PARAMETER, TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +/** wildcard bound */ +class T0x1C { + void m0x1C(List lst) {} +} + +/** wildcard bound generic/array */ +class T0x1D { + void m0x1D(List> lst) {} +} + +/** typecast */ +class T0x00 { + void m0x00(Long l1) { + Object l2 = (@A Long) l1; + } +} + +/** typecast generic/array */ +class T0x01 { + void m0x01(List list) { + List l = (List<@A T>) list; + } +} + +/** instanceof */ +class T0x02 { + boolean m0x02(String s) { + return (s instanceof @A String); + } +} + +/** object creation (new) */ +class T0x04 { + void m0x04() { + new @A ArrayList(); + } +} + +/** local variable */ +class T0x08 { + void m0x08() { + @A String s = null; + } +} + +/** method parameter generic/array */ +class T0x0D { + void m0x0D(HashMap<@A Object, List<@A List<@A Class>>> s1) {} +} + +/** method receiver */ +class T0x06 { + void m0x06(@A T0x06 this) {} +} + +/** method return type generic/array */ +class T0x0B { + Class<@A Object> m0x0B() { return null; } +} + +/** field generic/array */ +class T0x0F { + HashMap<@A Object, @A Object> c1; +} + +/** method type parameter */ +class T0x20 { + <@A T, @A U> void m0x20() {} +} + +/** class type parameter */ +class T0x22<@A T, @A U> { +} + +/** class type parameter bound */ +class T0x10 { +} + +/** method type parameter bound */ +class T0x12 { + void m0x12() {} +} + +/** class type parameter bound generic/array */ +class T0x11> { +} + + +/** method type parameter bound generic/array */ +class T0x13 { + static > T m0x13() { + return null; + } +} + +/** class extends/implements generic/array */ +class T0x15 extends ArrayList<@A T> { +} + +/** type test (instanceof) generic/array */ +class T0x03 { + void m0x03(T typeObj, Object obj) { + boolean ok = obj instanceof String @A []; + } +} + +/** object creation (new) generic/array */ +class T0x05 { + void m0x05() { + new ArrayList<@A T>(); + } +} + +/** local variable generic/array */ +class T0x09 { + void g() { + List<@A String> l = null; + } + + void a() { + String @A [] as = null; + } +} + +/** type argument in constructor call generic/array */ +class T0x19 { + T0x19() {} + + void g() { + new > T0x19(); + } +} + +/** type argument in method call generic/array */ +class T0x1B { + void m0x1B() { + Collections.emptyList(); + } +} + +/** type argument in constructor call */ +class T0x18 { + T0x18() {} + + void m() { + new <@A Integer> T0x18(); + } +} + +/** type argument in method call */ +class T0x1A { + public static T m() { return null; } + static void m0x1A() { + T0x1A.<@A Integer, @A Short>m(); + } +} + +/** class extends/implements */ +class T0x14 extends @A Object implements @A Serializable, @A Cloneable { +} + +/** exception type in throws */ +class T0x16 { + void m0x16() throws @A Exception {} +} + +/** resource variables **/ +class ResourceVariables { + void m() throws Exception { + try (@A InputStream is = new @A FileInputStream("x")){} + } +} + +/** exception parameters **/ +class ExceptionParameters { + void multipleExceptions() { + try { + new Object(); + } catch (@A Exception e) {} + try { + new Object(); + } catch (@A Exception e) {} + try { + new Object(); + } catch (@A Exception e) {} + } +} diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/typeannos/TestTypeAnnotations.java Wed May 15 18:26:16 2013 -0700 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8001163 + * @summary tests simple TypeAnnotations in classfiles + * @compile -XDignore.symbol.file ../Utils.java + * TestTypeAnnotations.java TargetTypes.java + * TypeUseTarget.java Lambda.java + * @run main TestTypeAnnotations + * @author ksrini + */ +import java.io.File; +import java.io.IOException; + +public class TestTypeAnnotations { + public static void main(String... args) throws IOException { + File testFile = new File("ta.jar"); + Utils.jar("cvf", testFile.getName(), + "-C", Utils.TEST_CLS_DIR.getAbsolutePath(), + "."); + Utils.testWithRepack(testFile, "--unknown-attribute=error"); + } +} diff -r a74a13b9aa93 -r 46864558d068 jdk/test/tools/pack200/typeannos/TypeUseTarget.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/pack200/typeannos/TypeUseTarget.java Wed May 15 18:26:16 2013 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @Xtest + * @bug 6843077 8006775 + * @summary check that type annotations may appear on all type declarations + * @author Mahmood Ali + * @compile TypeUseTarget.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@B +class TypeUseTarget { + @B String @B [] field; + + @B String test(@B TypeUseTarget this, @B String param, @B String @B ... vararg) { + @B Object o = new @B String @B [3]; + TypeUseTarget<@B String> target; + return (@B String) null; + } + + @B String genericMethod(K k) { return null; } + @Decl @B String genericMethod1(K k) { return null; } + @B @Decl String genericMethod2(K k) { return null; } + @Decl @B String genericMethod3(K k) { return null; } + @Decl String genericMethod4(K k) { return null; } + @B @Decl String genericMethod5(K k) { return null; } +} + +@B +interface MyInterface { } + +@B +@interface MyAnnotation { } + +@Target(ElementType.TYPE_USE) +@interface B { } + +@interface Decl { }