001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.drlvm.tests.regression.h3225;
019:
020: import java.io.File;
021: import java.io.IOException;
022:
023: import java.util.Enumeration;
024: import java.util.Iterator;
025: import java.util.Set;
026: import java.util.StringTokenizer;
027: import java.util.TreeSet;
028:
029: import java.util.jar.JarEntry;
030: import java.util.jar.JarFile;
031: import junit.framework.TestCase;
032:
033: /**
034: * Loads classes from the list and measures load time.
035: *
036: * @see http://issues.apache.org/jira/browse/HARMONY-2615
037: */
038: public class PerfTest extends TestCase {
039: public static void main(String args[]) {
040: (new PerfTest()).test();
041: }
042:
043: public void test() {
044: try {
045: PerfTest test = new PerfTest();
046: test.readProperty(BOOT_CLASS_PATH_PROPERTY);
047: // test.readProperty(CLASS_PATH_PROPERTY);
048: test.load();
049: System.out.println("SUCCESS");
050: } catch (Throwable e) {
051: System.out.println("Unexpected " + e);
052: e.printStackTrace(System.out);
053: }
054: }
055:
056: private static final String JAR_SUFFIX = ".jar";
057:
058: private static final String CLASS_SUFFIX = ".class";
059:
060: private static final int CLASS_SUFFIX_LENGTH = CLASS_SUFFIX
061: .length();
062:
063: private static final String BOOT_CLASS_PATH_PROPERTY = "sun.boot.class.path";
064:
065: private static final String CLASS_PATH_PROPERTY = "java.class.path";
066:
067: private static final boolean LOG_CLASSES = true;
068:
069: /**
070: * Class name storage.
071: */
072: private Set<String> classNames = new TreeSet<String>();
073:
074: /**
075: * Reads all class names from the specified Jar.
076: */
077: private int readJar(String fileName) throws IOException {
078: JarFile jarFile = new JarFile(fileName);
079: int num = 0;
080:
081: System.out.print("Reading " + fileName + ": ");
082: for (Enumeration e = jarFile.entries(); e.hasMoreElements();) {
083: JarEntry jarEntry = (JarEntry) e.nextElement();
084:
085: if (jarEntry.isDirectory()) {
086: continue;
087: }
088: String entryName = jarEntry.getName();
089:
090: if (!entryName.endsWith(CLASS_SUFFIX)) {
091: continue;
092: }
093: String className = entryName.substring(0,
094: entryName.length() - CLASS_SUFFIX_LENGTH).replace(
095: '/', '.');
096:
097: Loader loader = new Loader();
098: Throwable result = loader.verifyClass(className);
099: if (null == result) {
100: if (LOG_CLASSES) {
101: System.out.println("Added " + className);
102: }
103: classNames.add(className);
104: num++;
105: } else {
106: if (LOG_CLASSES) {
107: System.out.println("Skipped " + className
108: + " due to " + result);
109: }
110: }
111: }
112: System.out.println(num + " class files");
113: return num;
114: }
115:
116: /**
117: * Reads all class names from all jars listed in the specified property.
118: */
119: private void readProperty(String propertyName) throws IOException {
120: System.out.println("Reading from property: " + propertyName);
121:
122: String propertyValue = System.getProperty(propertyName);
123:
124: if (propertyValue == null) {
125: throw new IOException("Property not found: " + propertyName);
126: }
127:
128: StringTokenizer tokenizer = new StringTokenizer(propertyValue,
129: File.pathSeparator);
130:
131: int num = 0;
132: while (tokenizer.hasMoreTokens()) {
133: String token = tokenizer.nextToken();
134:
135: if (!token.endsWith(JAR_SUFFIX)) {
136: System.out.println("Ignoring " + token);
137: continue;
138: }
139: File file = new File(token);
140:
141: if (!file.isFile()) {
142: System.out.println("Missing " + token);
143: continue;
144: }
145: num += readJar(token);
146: }
147: System.out.println("Got " + num + " classes from "
148: + propertyName);
149: }
150:
151: /**
152: * Tries to load all known classes.
153: */
154: private void load() throws IOException {
155:
156: System.out.println("Loading classes");
157: long total = System.currentTimeMillis();
158:
159: for (Iterator<String> i = classNames.iterator(); i.hasNext();) {
160: String className = i.next();
161: Loader loader = new Loader();
162: assertNull("Failed to verify " + className, loader
163: .verifyClass(className));
164: }
165: System.out.println("Total time: "
166: + (System.currentTimeMillis() - total));
167: }
168:
169: final static int LENGTH = 1024;
170: /**
171: * Use a static buffer for speed.
172: */
173: static byte[] buffer = new byte[LENGTH];
174:
175: /**
176: * Tries to load a class.
177: */
178: class Loader extends ClassLoader {
179:
180: public Throwable verifyClass(String name) {
181: try {
182: final String path = name.replace('.', '/') + ".class";
183: java.io.InputStream is = ClassLoader
184: .getSystemResourceAsStream(path);
185: if (is == null) {
186: return new IOException("Cannot find " + path);
187: }
188: int offset = 0, bytes_read = 0;
189: while ((bytes_read = is.read(buffer, offset, LENGTH
190: - offset)) > 0) {
191: offset += bytes_read;
192: }
193: if (bytes_read != -1) {
194: return new IOException("Class " + name
195: + " is too big, please increase LENGTH = "
196: + LENGTH);
197: }
198:
199: defineClass(name, buffer, 0, offset).getConstructors();
200: return null;
201: } catch (Throwable e) {
202: return e;
203: }
204: }
205: }
206: }
|