001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.installer;
021:
022: import java.util.ArrayList;
023: import java.util.Enumeration;
024: import java.util.List;
025: import java.util.jar.JarEntry;
026: import java.util.jar.JarFile;
027: import java.io.File;
028: import java.io.IOException;
029: import java.net.URL;
030: import java.net.URLClassLoader;
031: import java.net.MalformedURLException;
032:
033: /**
034: *
035: * This class is used to verify class files in jars after pack/unpack is performed.
036: * All classes are loaded by custom class loader to make sure class files are not corrupted.
037: * Verification is split into 2 separate runs. First run tests IDE jars. Second
038: * run tests Jakarta Tomcat jars.
039: *
040: * @author Marek Slama
041: *
042: */
043:
044: public class VerifyJars {
045:
046: List<File> jarList = new ArrayList<File>();
047:
048: URL[] classPath;
049:
050: private static File inputDir;
051:
052: private static int testType = 0;
053:
054: private static final int TEST_IDE_JARS = 0;
055: private static final int TEST_TOMCAT_JARS = 1;
056:
057: private static int inputDirLength;
058:
059: /** Constants for special test handling. It must be updated according
060: * to cluster and jar names. */
061: private static String JAR_NAME = "ide9/modules/ext/jaxws20/jaxb-xjc.jar";
062: private static String JAR_VERSION = "1.0";
063: private static String TOMCAT_PATH = "enterprise5/jakarta-tomcat";
064:
065: public VerifyJars() {
066: }
067:
068: /**
069: * Input parameters:
070: * 1. Directory to be scanned
071: * 2. Type of test - 0 test IDE jars; 1 test Tomcat jars
072: */
073: public static void main(String[] args) {
074: if (args.length < 2) {
075: System.out
076: .println("Error: 2 input parameters are required.");
077: System.exit(1);
078: }
079:
080: inputDir = new File(args[0]);
081:
082: inputDirLength = inputDir.getAbsolutePath().length();
083:
084: try {
085: testType = Integer.parseInt(args[1]);
086: } catch (NumberFormatException exc) {
087: System.out
088: .println("Error: Cannot parse 2nd input parameter '"
089: + args[1] + "'");
090: }
091:
092: VerifyJars scan = new VerifyJars();
093: scan.scanDir(inputDir);
094: try {
095: scan.getClassPath();
096: } catch (MalformedURLException exc) {
097: exc.printStackTrace();
098: }
099: scan.verifyJars();
100: }
101:
102: private void scanDir(File dir) {
103: File[] arr = dir.listFiles();
104: for (int i = 0; i < arr.length; i++) {
105: if (arr[i].isDirectory()) {
106: scanDir(arr[i]);
107: } else {
108: if (arr[i].getName().endsWith(".jar")) {
109: int pos = arr[i].getAbsolutePath().indexOf(
110: TOMCAT_PATH);
111: if (testType == TEST_IDE_JARS) {
112: //Test IDE jars only, exclude Tomcat jars
113: if (pos == -1) {
114: jarList.add(arr[i]);
115: }
116: } else {
117: //Test Tomcat jars only, exclude IDE jars
118: if (pos != -1) {
119: jarList.add(arr[i]);
120: }
121: }
122: }
123: }
124: }
125: }
126:
127: private void verifyJars() {
128: ClassLoader parent = this .getClass().getClassLoader()
129: .getParent();
130: try {
131: URLClassLoader urlClassLoader = new URLClassLoader(
132: classPath, parent);
133: int tChecked = 0, tPassed = 0, tError = 0;
134: for (int i = 0; i < jarList.size(); i++) {
135: JarFile jarFile = new JarFile(jarList.get(i));
136: String s = jarList.get(i).getAbsolutePath();
137: s = s.substring(inputDirLength + 1, s.length());
138: System.out.println("Verifying: " + s);
139: int iChecked = 0, iPassed = 0, iError = 0;
140: for (Enumeration en = jarFile.entries(); en
141: .hasMoreElements();) {
142: JarEntry je = (JarEntry) en.nextElement();
143: //System.out.println("je.name: " + je.getName());
144: if (je.getName().endsWith(".class")) {
145: String name = je.getName().substring(
146: 0,
147: je.getName().length()
148: - ".class".length());
149: //Hack for unusual jar structure in NB 5.5
150: if (jarList.get(i).getAbsolutePath().endsWith(
151: JAR_NAME)
152: && je.getName().startsWith(JAR_VERSION)) {
153: System.out.println("++");
154: System.out.println("++ Skip entry: "
155: + je.getName());
156: continue;
157: }
158: name = name.replace('/', '.');
159: //System.out.println("Class: " + name);
160: try {
161: iChecked++;
162: tChecked++;
163: Class clazz = Class.forName(name, false,
164: urlClassLoader);
165: iPassed++;
166: tPassed++;
167: } catch (NoClassDefFoundError exc) {
168: iError++;
169: tError++;
170: System.out.println("--");
171: System.out
172: .println("-- NoClassDefFoundError: "
173: + exc.getMessage());
174: } catch (IllegalAccessError exc) {
175: iError++;
176: tError++;
177: System.out.println("--");
178: System.out
179: .println("-- IllegalAccessError: "
180: + exc.getMessage());
181: } catch (IncompatibleClassChangeError exc) {
182: iError++;
183: tError++;
184: System.out.println("--");
185: System.out
186: .println("-- IncompatibleClassChangeError: "
187: + exc.getMessage());
188: } catch (SecurityException exc) {
189: iError++;
190: tError++;
191: System.out.println("--");
192: System.out.println("-- SecurityException: "
193: + exc.getMessage());
194: } catch (ClassFormatError exc) {
195: System.out.println("FATAL ERROR");
196: System.out.println("-- ClassFormatError: "
197: + exc.getMessage());
198: System.exit(2);
199: } catch (ClassNotFoundException exc) {
200: System.out.println("FATAL ERROR");
201: System.out
202: .println("-- ClassNotFoundException: "
203: + exc.getMessage());
204: System.exit(2);
205: }
206: }
207: }
208: System.out.println("Checked:" + iChecked + " Passed:"
209: + iPassed + " Error:" + iError);
210: }
211: System.out.println("Total checked:" + tChecked
212: + " Total passed:" + tPassed + " Total error:"
213: + tError);
214: } catch (IOException exc) {
215: exc.printStackTrace();
216: System.exit(2);
217: }
218: }
219:
220: private void getClassPath() throws MalformedURLException {
221: classPath = new URL[jarList.size()];
222: for (int i = 0; i < jarList.size(); i++) {
223: String s = jarList.get(i).getAbsolutePath();
224: //For Windows replace "\" in path by "/" to get correct URL.
225: if (System.getProperty("os.name").startsWith("Windows")) {
226: s = s.replace('\\', '/');
227: } else {
228: s = s;
229: }
230: //Replace spaces in URL
231: if (System.getProperty("os.name").startsWith("Windows")) {
232: //On Windows path starts with disk like C: so we must add additional slash
233: s = "file:///" + s.replaceAll(" ", "%20");
234: } else {
235: s = "file://" + s.replaceAll(" ", "%20");
236: }
237: classPath[i] = new URL(s);
238: }
239: //Dump class path
240: for (int i = 0; i < classPath.length; i++) {
241: System.out.println("cl[" + i + "]: "
242: + classPath[i].toString());
243: }
244: }
245:
246: }
|