protected void addPathFile(final File pathComponent) throws IOException { if (!this.pathComponents.contains(pathComponent)) { this.pathComponents.addElement(pathComponent); } if (pathComponent.isDirectory()) { return; } final String absPathPlusTimeAndLength = pathComponent.getAbsolutePath() + pathComponent.lastModified() + "-" + pathComponent.length(); String classpath = AntClassLoader.pathMap.get(absPathPlusTimeAndLength); if (classpath == null) { JarFile jarFile = null; try { jarFile = new JarFile(pathComponent); final Manifest manifest = jarFile.getManifest(); if (manifest == null) { return; } classpath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); } finally { if (jarFile != null) { jarFile.close(); } } if (classpath == null) { classpath = ""; } AntClassLoader.pathMap.put(absPathPlusTimeAndLength, classpath); } if (!"".equals(classpath)) { final URL baseURL = AntClassLoader.FILE_UTILS.getFileURL(pathComponent); final StringTokenizer st = new StringTokenizer(classpath); while (st.hasMoreTokens()) { final String classpathElement = st.nextToken(); final URL libraryURL = new URL(baseURL, classpathElement); if (!libraryURL.getProtocol().equals("file")) { this.log( "Skipping jar library " + classpathElement + " since only relative URLs are supported by this" + " loader", 3); } else { final String decodedPath = Locator.decodeUri(libraryURL.getFile()); final File libraryFile = new File(decodedPath); if (!libraryFile.exists() || this.isInPath(libraryFile)) { continue; } this.addPathFile(libraryFile); } } } }
/** Generates the transitive closure of the Class-Path attribute for the specified jar file. */ List<String> getJarPath(String jar) throws IOException { List<String> files = new ArrayList<String>(); files.add(jar); jarPaths.add(jar); // take out the current path String path = jar.substring(0, Math.max(0, jar.lastIndexOf('/') + 1)); // class path attribute will give us jar file name with // '/' as separators, so we need to change them to the // appropriate one before we open the jar file. JarFile rf = new JarFile(jar.replace('/', File.separatorChar)); if (rf != null) { Manifest man = rf.getManifest(); if (man != null) { Attributes attr = man.getMainAttributes(); if (attr != null) { String value = attr.getValue(Attributes.Name.CLASS_PATH); if (value != null) { StringTokenizer st = new StringTokenizer(value); while (st.hasMoreTokens()) { String ajar = st.nextToken(); if (!ajar.endsWith("/")) { // it is a jar file ajar = path.concat(ajar); /* check on cyclic dependency */ if (!jarPaths.contains(ajar)) { files.addAll(getJarPath(ajar)); } } } } } } } rf.close(); return files; }
public static void main(String[] args) throws IOException { List /*<String>*/ classes = new ArrayList(); String origJavaHome = System.getProperty("java.home"); String javaHome = origJavaHome.toLowerCase(); if (javaHome.endsWith("jre")) { origJavaHome = origJavaHome.substring(0, origJavaHome.length() - 4); javaHome = javaHome.substring(0, javaHome.length() - 4); } for (int i = 0; i < args.length; i++) { try { File file = new File(args[i]); BufferedReader reader = new BufferedReader(new FileReader(file)); String line = null; while ((line = reader.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line, "[ \t\n\r\f"); if (tok.hasMoreTokens()) { String t = tok.nextToken(); // Understand only "Loading" from -XX:+TraceClassLoadingPreorder. // This ignores old "Loaded" from -verbose:class to force correct // classlist generation on Mustang. if (t.equals("Loading")) { t = tok.nextToken(); t = t.replace('.', '/'); // Check to make sure it came from the boot class path if (tok.hasMoreTokens()) { String tmp = tok.nextToken(); if (tmp.equals("from")) { if (tok.hasMoreTokens()) { tmp = tok.nextToken().toLowerCase(); // System.err.println("Loaded " + t + " from " + tmp); if (tmp.startsWith(javaHome)) { // OK, remember this class for later classes.add(t); } } } } } } } } catch (IOException e) { System.err.println("Error reading file " + args[i]); throw (e); } } Set /*<String>*/ seenClasses = new HashSet(); for (Iterator iter = classes.iterator(); iter.hasNext(); ) { String str = (String) iter.next(); if (seenClasses.add(str)) { System.out.println(str); } } // Try to complete certain packages // Note: not using this new code yet; need to consider whether the // footprint increase is worth any startup gains // Note also that the packages considered below for completion are // (obviously) platform-specific // JarFile rtJar = new JarFile(origJavaHome + File.separator + // "jre" + File.separator + // "lib" + File.separator + // "rt.jar"); // completePackage(seenClasses, rtJar, "java/awt"); // completePackage(seenClasses, rtJar, "sun/awt"); // completePackage(seenClasses, rtJar, "sun/awt/X11"); // completePackage(seenClasses, rtJar, "java/awt/im/spi"); // completePackage(seenClasses, rtJar, "java/lang"); }