private void assertAttributePresent(ClassFile classFile, String fileName) throws Exception { //We need to count attributes with the same names because there is no appropriate API in the ClassFile. List<SourceFile_attribute> sourceFileAttributes = new ArrayList<>(); for (Attribute a : classFile.attributes.attrs) { if (Attribute.SourceFile.equals(a.getName(classFile.constant_pool))) { sourceFileAttributes.add((SourceFile_attribute) a); } } assertEquals(sourceFileAttributes.size(), 1, "Should be the only SourceFile attribute"); SourceFile_attribute attribute = sourceFileAttributes.get(0); assertEquals(classFile.constant_pool.getUTF8Info(attribute.attribute_name_index).value, Attribute.SourceFile, "Incorrect attribute name"); assertEquals(classFile.constant_pool.getUTF8Info(attribute.sourcefile_index).value, fileName, "Incorrect source file name"); assertEquals(attribute.attribute_length, 2, "Incorrect attribute length"); }
void checkClassFile(final File cfile, String methodToFind) throws Exception { ClassFile classFile = ClassFile.read(cfile); boolean methodFound = false; for (Method method : classFile.methods) { if (method.getName(classFile.constant_pool).equals(methodToFind)) { methodFound = true; Code_attribute code = (Code_attribute) method.attributes.get("Code"); LineNumberTable_attribute lnt = (LineNumberTable_attribute) code.attributes.get("LineNumberTable"); Assert.check(lnt.line_number_table_length == expectedLNT.length, foundLNTLengthDifferentThanExpMsg); int i = 0; for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) { Assert.check(entry.line_number == expectedLNT[i][0] && entry.start_pc == expectedLNT[i][1], "LNT entry at pos " + i + " differ from expected." + "Found " + entry.line_number + ":" + entry.start_pc + ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]); i++; } } } Assert.check(methodFound, seekMethodNotFoundMsg); }
public void testAnnotation(TestResult testResult, ClassFile classFile, Annotation annotation) throws ConstantPoolException { testResult.checkEquals(classFile.constant_pool.getUTF8Value(annotation.type_index), String.format("L%s;", annotationName), "Testing annotation name : " + annotationName); testResult.checkEquals(annotation.num_element_value_pairs, elementValues.size(), "Number of element values"); if (!testResult.checkEquals(annotation.num_element_value_pairs, elementValues.size(), "Number of element value pairs")) { return; } for (int i = 0; i < annotation.num_element_value_pairs; ++i) { Annotation.element_value_pair pair = annotation.element_value_pairs[i]; testResult.checkEquals(classFile.constant_pool.getUTF8Value(pair.element_name_index), elementValues.get(i).elementName, "element_name_index : " + elementValues.get(i).elementName); elementValues.get(i).elementValue.testElementValue(testResult, classFile, pair.value); } }
static void verifyInvokerBytecodeGenerator() throws Exception { int count = 0; int mcount = 0; try (DirectoryStream<Path> ds = newDirectoryStream(new File(".").toPath(), // filter in lambda proxy classes "A$I$$Lambda$?.class")) { for (Path p : ds) { System.out.println(p.toFile()); ClassFile cf = ClassFile.read(p.toFile()); // Check those methods implementing Supplier.get mcount += checkMethod(cf, "get"); count++; } } if (count < 3) { throw new RuntimeException("unexpected number of files, " + "expected atleast 3 files, but got only " + count); } if (mcount < 3) { throw new RuntimeException("unexpected number of methods, " + "expected atleast 3 methods, but got only " + mcount); } }
private void readClass(ClassFile c) throws IOException, ConstantPoolException, InvalidDescriptor { klass = new Element("Class"); cfile.add(klass); String thisk = c.getName(); klass.setAttr("name", thisk); AccessFlags af = new AccessFlags(c.access_flags.flags); klass.setAttr("flags", flagString(af, klass)); if (!"java/lang/Object".equals(thisk)) { klass.setAttr("super", c.getSuperclassName()); } for (int i : c.interfaces) { klass.add(new Element("Interface", "name", getCpString(i))); } readFields(c, klass); readMethods(c, klass); readAttributesFor(c, c.attributes, klass); klass.trimToSize(); }
private void readCP(ClassFile c) throws IOException { cpool = new Element("ConstantPool", c.constant_pool.size()); ConstantPoolVisitor cpv = new ConstantPoolVisitor(cpool, c, c.constant_pool.size()); for (int i = 1 ; i < c.constant_pool.size() ; i++) { try { cpv.visit(c.constant_pool.get(i), i); } catch (InvalidIndex ex) { // can happen periodically when accessing doubles etc. ignore it // ex.printStackTrace(); } } thePool = cpv.getPoolList(); if (verbose) { for (int i = 0; i < thePool.size(); i++) { System.out.println("[" + i + "]: " + thePool.get(i)); } } if (keepCP) { cfile.add(cpool); } }
void checkClassFile(final File cfile, String[] methodsToFind) throws Exception { ClassFile classFile = ClassFile.read(cfile); int numberOfmethodsFound = 0; for (String methodToFind : methodsToFind) { for (Method method : classFile.methods) { if (method.getName(classFile.constant_pool).equals(methodToFind)) { numberOfmethodsFound++; Code_attribute code = (Code_attribute) method.attributes.get("Code"); Assert.check(code.exception_table_length == expectedExceptionTable.length, "The ExceptionTable found has a length different to the expected one"); int i = 0; for (Exception_data entry: code.exception_table) { Assert.check(entry.start_pc == expectedExceptionTable[i][0] && entry.end_pc == expectedExceptionTable[i][1] && entry.handler_pc == expectedExceptionTable[i][2] && entry.catch_type == expectedExceptionTable[i][3], "Exception table entry at pos " + i + " differ from expected."); i++; } } } } Assert.check(numberOfmethodsFound == 2, "Some seek methods were not found"); }
public void run() throws Exception { ClassFile cf = getClassFile("TypeAnnotationPropagationTest$Test.class"); Method f = null; for (Method m : cf.methods) { if (m.getName(cf.constant_pool).contains("f")) { f = m; break; } } int idx = f.attributes.getIndex(cf.constant_pool, Attribute.Code); Code_attribute cattr = (Code_attribute) f.attributes.get(idx); idx = cattr.attributes.getIndex(cf.constant_pool, Attribute.RuntimeVisibleTypeAnnotations); RuntimeVisibleTypeAnnotations_attribute attr = (RuntimeVisibleTypeAnnotations_attribute) cattr.attributes.get(idx); TypeAnnotation anno = attr.annotations[0]; assertEquals(anno.position.lvarOffset, new int[] {3}, "start_pc"); assertEquals(anno.position.lvarLength, new int[] {8}, "length"); assertEquals(anno.position.lvarIndex, new int[] {1}, "index"); }
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) { String aName = e.getKey(); TypeAnnotation.Position expected = e.getValue(); TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); if (actual == null) throw new ComparisionException("Expected annotation not found: " + aName); if (!areEquals(expected, actual.position)) { throw new ComparisionException("Unexpected position for annotation : " + aName + "\n Expected: " + expected.toString() + "\n Found: " + actual.position.toString()); } } return true; }
public static void main(String[] args) throws IOException, ConstantPoolException { Path outdir = Paths.get("."); ToolBox tb = new ToolBox(); final Path moduleInfo = Paths.get("module-info.java"); tb.writeFile(moduleInfo, "module test_module{}"); new JavacTask(tb) .outdir(outdir) .files(moduleInfo) .run(); AccessFlags accessFlags = ClassFile.read(outdir.resolve("module-info.class")) .access_flags; if (!accessFlags.is(AccessFlags.ACC_MODULE)) { throw new RuntimeException("Classfile doesn't have module access flag"); } }
void verifyBytecode() { File compiledTest = new File("Test.class"); try { ClassFile cf = ClassFile.read(compiledTest); BootstrapMethods_attribute bsm_attr = (BootstrapMethods_attribute)cf .getAttribute(Attribute.BootstrapMethods); int length = bsm_attr.bootstrap_method_specifiers.length; if (length != 1) { throw new Error("Bad number of method specifiers " + "in BootstrapMethods attribute: " + length); } } catch (Exception e) { e.printStackTrace(); throw new Error("error reading " + compiledTest +": " + e); } }
void checkClassFile(final File cfile, String methodToFind) throws Exception { ClassFile classFile = ClassFile.read(cfile); boolean methodFound = false; for (Method method : classFile.methods) { if (method.getName(classFile.constant_pool).equals(methodToFind)) { methodFound = true; Code_attribute code = (Code_attribute) method.attributes.get("Code"); LineNumberTable_attribute lnt = (LineNumberTable_attribute) code.attributes.get("LineNumberTable"); Assert.check(lnt.line_number_table_length == expectedLNT.length, "The LineNumberTable found has a length different to the expected one"); int i = 0; for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) { Assert.check(entry.line_number == expectedLNT[i][0] && entry.start_pc == expectedLNT[i][1], "LNT entry at pos " + i + " differ from expected." + "Found " + entry.line_number + ":" + entry.start_pc + ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]); i++; } } } Assert.check(methodFound, "The seek method was not found"); }
@Test public void testSimpleAnnotation(Path base) throws Exception { Path moduleSrc = base.resolve("module-src"); Path m1 = moduleSrc.resolve("m1x"); tb.writeJavaFiles(m1, "@Deprecated module m1x { }"); Path modulePath = base.resolve("module-path"); Files.createDirectories(modulePath); new JavacTask(tb) .options("--module-source-path", moduleSrc.toString()) .outdir(modulePath) .files(findJavaFiles(m1)) .run() .writeAll(); ClassFile cf = ClassFile.read(modulePath.resolve("m1x").resolve("module-info.class")); RuntimeVisibleAnnotations_attribute annotations = (RuntimeVisibleAnnotations_attribute) cf.attributes.map.get(Attribute.RuntimeVisibleAnnotations); if (annotations == null || annotations.annotations.length != 1) { throw new AssertionError("Annotations not correct!"); } }
void checkClassFile(File file) throws IOException, ConstantPoolException, InvalidDescriptor { ClassFile classFile = ClassFile.read(file); ConstantPool constantPool = classFile.constant_pool; //lets get all the methods in the class file. for (Method method : classFile.methods) { for (ElementKey elementKey: aliveRangeMap.keySet()) { String methodDesc = method.getName(constantPool) + method.descriptor.getParameterTypes(constantPool).replace(" ", ""); if (methodDesc.equals(elementKey.elem.toString())) { checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); seenAliveRanges.add(elementKey); } } } }
void checkReferences() throws IOException, ConstantPoolException { File testClasses = new File(System.getProperty("test.classes")); File file = new File(testClasses, CPoolRefClassContainingInlinedCts.class.getName() + ".class"); ClassFile classFile = ClassFile.read(file); int i = 1; CPInfo cpInfo; while (i < classFile.constant_pool.size()) { cpInfo = classFile.constant_pool.get(i); if (cpInfo instanceof CONSTANT_Class_info) { checkClassName(((CONSTANT_Class_info)cpInfo).getName()); } i += cpInfo.size(); } if (numberOfReferencedClassesToBeChecked != 16) { throw new AssertionError("Class reference missing in the constant pool"); } }
void check(String dir, String... fileNames) throws IOException, ConstantPoolException, Descriptor.InvalidDescriptor { for (String fileName : fileNames) { ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); for (Method method : classFileToCheck.methods) { if ((method.access_flags.flags & ACC_STRICT) == 0) { errors.add(String.format(offendingMethodErrorMessage, method.getName(classFileToCheck.constant_pool), classFileToCheck.getName())); } } } }
static void verifyInvokerBytecodeGenerator() throws Exception { int count = 0; int mcount = 0; try (DirectoryStream<Path> ds = newDirectoryStream(new File(".").toPath(), // filter in lambda proxy classes "A$I$$Lambda$*.class")) { for (Path p : ds) { System.out.println(p.toFile()); ClassFile cf = ClassFile.read(p.toFile()); // Check those methods implementing Supplier.get mcount += checkMethod(cf, "get"); count++; } } if (count < 3) { throw new RuntimeException("unexpected number of files, " + "expected atleast 3 files, but got only " + count); } if (mcount < 3) { throw new RuntimeException("unexpected number of methods, " + "expected atleast 3 methods, but got only " + mcount); } }
public Iterable<ClassFile> getClassFiles() throws IOException { return new Iterable<ClassFile>() { public Iterator<ClassFile> iterator() { return new FileIterator(); } }; }
protected ClassFile readClassFile(Path p) throws IOException { InputStream is = null; try { is = Files.newInputStream(p); return ClassFile.read(is); } catch (ConstantPoolException e) { throw new ClassFileError(e); } finally { if (is != null) { is.close(); } } }
public ClassFile next() { if (!hasNext()) { throw new NoSuchElementException(); } try { ClassFile cf = readClassFile(path); count++; return cf; } catch (IOException e) { throw new ClassFileError(e); } }
public static void readClass(byte[] clazz) throws IOException { try (InputStream stream = new ByteArrayInputStream(clazz)) { ClassFile.read(stream); } catch (ConstantPoolException e) { throw new IOException(e); } }
protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException { InputStream is = null; try { is = jarfile.getInputStream(e); return ClassFile.read(is); } catch (ConstantPoolException ex) { throw new ClassFileError(ex); } finally { if (is != null) is.close(); } }
public ConstantPoolVisitor(Element xpool, ClassFile cf, int size) { slist = new ArrayList<>(size); for (int i = 0 ; i < size; i++) { slist.add(null); } this.xpool = xpool; this.cf = cf; this.cfpool = cf.constant_pool; bsmlist = readBSM(); }
String getJavaSuperclassName(ClassFile cf) { try { return getJavaName(cf.getSuperclassName()); } catch (ConstantPoolException e) { return report(e); } }
void checkClassFile(final Path path) throws Exception { ClassFile classFile = ClassFile.read( new BufferedInputStream(Files.newInputStream(path))); for (CPInfo cpInfo : classFile.constant_pool.entries()) { if (cpInfo.getTag() == CONSTANT_Utf8) { CONSTANT_Utf8_info utf8Info = (CONSTANT_Utf8_info)cpInfo; Assert.check(utf8Info.value.length() > 0, "UTF8 with length 0 found at class " + classFile.getName()); } } }
private void testMethods(ClassFile cf) throws ConstantPoolException { for (Method m : cf.methods) { String methodName = cf.constant_pool.getUTF8Value(m.name_index); echo("Testing method : " + methodName); Deprecated_attribute attr = (Deprecated_attribute) m.attributes.get(Attribute.Deprecated); testAttribute(methodName, attr, cf); } }
public String visitString(CONSTANT_String_info info, Void p) { try { ClassFile classFile = classWriter.getClassFile(); int string_index = info.string_index; return stringValue(classFile.constant_pool.getUTF8Info(string_index)); } catch (ConstantPoolException e) { return report(e); } }
@Override public void testElementValue(TestResult testResult, ClassFile classFile, Annotation.element_value element_value) throws ConstantPoolException { testTag(testResult, element_value.tag); Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) element_value; ConstantPool.CONSTANT_Double_info info = (ConstantPool.CONSTANT_Double_info) classFile.constant_pool.get(ev.const_value_index); testResult.checkEquals(info.value, value, "const_value_index"); }
@Override public void testElementValue(TestResult testResult, ClassFile classFile, Annotation.element_value element_value) throws ConstantPoolException { testTag(testResult, element_value.tag); Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) element_value; ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info) classFile.constant_pool.get(ev.const_value_index); testResult.checkEquals(info.value, value, "const_value_index : " + value); }
TestBCI(Class<?> c) throws ConstantPoolException, IOException { Map<String, MethodInfo> methods; String filename = c.getName().replace('.', '/') + ".class"; try (InputStream in = c.getResourceAsStream(filename)) { ClassFile cf = ClassFile.read(in); methods = Arrays.stream(cf.methods) .map(m -> new MethodInfo(cf, m)) .collect(Collectors.toMap(MethodInfo::name, Function.identity())); } this.clazz = c; this.methods = methods; }
@Override public void testElementValue(TestResult testResult, ClassFile classFile, Annotation.element_value element_value) throws ConstantPool.InvalidIndex { testTag(testResult, element_value.tag); Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) element_value; ConstantPool.CONSTANT_Float_info info = (ConstantPool.CONSTANT_Float_info) classFile.constant_pool.get(ev.const_value_index); testResult.checkEquals(info.value, value, "const_value_index"); }
protected void readAttributesFor(ClassFile c, Attributes attrs, Element x) { Element container = new Element(); AttributeVisitor av = new AttributeVisitor(this, c); for (Attribute a : attrs) { av.visit(a, container); } if (!keepOrder) { container.sort(); } x.addAll(container); }
private void check() throws IOException, ConstantPoolException { File file = new File("Test$1.class"); ClassFile classFile = ClassFile.read(file); boolean inheritsFromObject = classFile.getSuperclassName().equals("java/lang/Object"); boolean implementsNoInterface = classFile.interfaces.length == 0; boolean noMethods = classFile.methods.length == 0; if (!(inheritsFromObject && implementsNoInterface && noMethods)) { throw new AssertionError("The inner classes reused as " + "access constructor tag for this code must be empty"); } }
@Override public void testElementValue(TestResult testResult, ClassFile classFile, Annotation.element_value element_value) throws ConstantPoolException { testTag(testResult, element_value.tag); Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) element_value; ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info) classFile.constant_pool.get(ev.const_value_index); testResult.checkEquals(info.value, value ? 1 : 0, "const_value_index : " + value); }
public ClassFile next() { if (!hasNext()) { throw new NoSuchElementException(); } Path path = entries.get(index++); try { return readClassFile(path); } catch (IOException e) { throw new ClassFileError(e); } }
protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException { try (InputStream is = jarfile.getInputStream(e)) { ClassFile cf = ClassFile.read(is); if (jarfile.isMultiRelease()) { VersionHelper.add(jarfile, e, cf); } return cf; } catch (ConstantPoolException ex) { throw new ClassFileError(ex); } }
public ClassFile next() { if (!hasNext()) { throw new NoSuchElementException(); } ClassFile classFile = cf; cf = null; nextEntry = nextEntry(); return classFile; }
private Set<Location> parse(Archive archive, Finder finder, String name) throws IOException { ClassFile cf = archive.reader().getClassFile(name); if (cf == null) { throw new IllegalArgumentException(archive.getName() + " does not contain " + name); } if (cf.access_flags.is(AccessFlags.ACC_MODULE)) return Collections.emptySet(); Set<Location> targets = new HashSet<>(); String cn; try { cn = cf.getName().replace('/', '.'); } catch (ConstantPoolException e) { throw new Dependencies.ClassFileError(e); } if (!finder.accept(archive, cn, cf.access_flags)) return targets; // tests if this class matches the -include if (!filter.matches(cn)) return targets; // skip checking filter.matches for (Dependency d : finder.findDependencies(cf)) { if (filter.accepts(d)) { targets.add(d.getTarget()); archive.addClass(d.getOrigin(), d.getTarget()); } else { // ensure that the parsed class is added the archive archive.addClass(d.getOrigin()); } parsedClasses.putIfAbsent(d.getOrigin(), archive); } return targets; }