/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.test.utility.classfile; import java.io.IOException; import java.util.Date; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.eclipse.persistence.tools.workbench.utility.Classpath; import org.eclipse.persistence.tools.workbench.utility.classfile.ClassFile; /** * rip through some JARs, parsing the byte codes of all * the contained .class files, and logging some * performance statistics */ public class ClassFileJarScanner { private String jarFileName; private int totalEntries = 0; private int nonClassFiles = 0; private float matches = 0; private int mismatches = 0; private float elapsedSeconds = 0; public static void main(String[] args) throws IOException { System.out.println("begin..."); System.out.println(); ClassFileJarScanner scanner = new ClassFileJarScanner(toplinkJarFileName()); scanner.scan(); scanner.printSummary(); System.out.println(); scanner = new ClassFileJarScanner(Classpath.rtJarName()); scanner.scan(); scanner.printSummary(); System.out.println(); System.out.println("...end"); } public static String toplinkJarFileName() { return Classpath.javaClasspath().entryForFileNamed("toplink_g.jar").fileName(); } public ClassFileJarScanner(String jarFileName) { super(); this.jarFileName = jarFileName; } public void scan() throws IOException { long startTime = (new Date()).getTime(); this.scanUntimed(); long endTime = (new Date()).getTime(); this.elapsedSeconds = (endTime - startTime) / 1000f; } public void scanUntimed() throws IOException { JarFile jarFile = new JarFile(this.jarFileName); try { this.scanJarFile(jarFile); } finally { jarFile.close(); } } private void scanJarFile(JarFile jarFile) { for (Enumeration entries = jarFile.entries(); entries.hasMoreElements(); ) { this.scanJarEntry(jarFile, (JarEntry) entries.nextElement()); } } private void scanJarEntry(JarFile jarFile, JarEntry jarEntry) { this.totalEntries++; String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".class")) { this.scanStream(jarFile, jarEntry, jarEntryName); } else { this.nonClassFiles++; } } private void scanStream(JarFile jarFile, JarEntry jarEntry, String jarEntryName) { boolean validClassStream = true; ClassFile classFile = null; try { classFile = ClassFile.fromArchiveEntry(jarFile, jarEntry); } catch (IOException ex) { System.out.println("IOException: " + ex); validClassStream = false; } // look for a "synthetic" class... // if (classFile.isSynthetic()) { // System.out.println("\"synthetic\" class: " + classFile.className()); // } if (validClassStream && classFile.className().equals(jarEntryName.substring(0, jarEntryName.length() - 6).replace('/', '.'))) { this.matches++; } else { this.mismatches++; System.out.println("mismatch: " + jarEntryName + " vs. " + classFile.className()); } } public void printSummary() { System.out.println("JAR: " + this.jarFileName); System.out.println("totalEntries: " + this.totalEntries); System.out.println("matches: " + this.matches); System.out.println("mismatches: " + this.mismatches); System.out.println("non-class files: " + this.nonClassFiles); System.out.println("elapsed time: " + this.elapsedSeconds + " seconds"); System.out.println("performance: " + (this.matches/this.elapsedSeconds) + " class files/second"); System.out.println("(approx. 1000/sec?)"); } }