?? proguard.java
字號:
/* $Id: ProGuard.java,v 1.84 2004/12/11 16:35:23 eric Exp $ * * ProGuard -- shrinking, optimization, and obfuscation of Java class files. * * Copyright (c) 2002-2004 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package proguard;import proguard.classfile.*;import proguard.classfile.attribute.*;import proguard.classfile.editor.*;import proguard.classfile.instruction.*;import proguard.classfile.util.*;import proguard.classfile.visitor.*;import proguard.io.*;import proguard.obfuscate.*;import proguard.optimize.*;import proguard.optimize.evaluation.*;import proguard.optimize.peephole.*;import proguard.shrink.*;import java.io.*;/** * Tool for shrinking, optimizing, and obfuscating Java class files. * * @author Eric Lafortune */public class ProGuard{ public static final String VERSION = "ProGuard, version 3.2"; private Configuration configuration; private ClassPool programClassPool = new ClassPool(); private ClassPool libraryClassPool = new ClassPool(); /** * Creates a new ProGuard object to process jars as specified by the given * configuration. */ public ProGuard(Configuration configuration) { this.configuration = configuration; } /** * Performs all subsequent ProGuard operations. */ public void execute() throws IOException { System.out.println(VERSION); readInput(); if (configuration.shrink || configuration.optimize || configuration.obfuscate) { initialize(); } if (configuration.printSeeds != null) { printSeeds(); } if (configuration.shrink) { shrink(); } if (configuration.optimize) { optimize(); // Shrink again, if we may. if (configuration.shrink) { configuration.printUsage = null; shrink(); } } if (configuration.obfuscate) { obfuscate(); } if (configuration.shrink || configuration.optimize || configuration.obfuscate) { sortConstantPools(); } if (configuration.programJars.hasOutput()) { writeOutput(); } if (configuration.dump != null) { dump(); } } /** * Reads the input jars (or directories). */ private void readInput() throws IOException { if (configuration.verbose) { System.out.println("Reading jars..."); } // Check if we have at least some program jars. if (configuration.programJars == null) { throw new IOException("The input is empty. You have to specify one or more '-injars' options."); } // Read the input program jars. readInput("Reading program ", configuration.programJars, createDataEntryClassPoolFiller(false)); // Check if we have at least some input class files. if (programClassPool.size() == 0) { throw new IOException("The input doesn't contain any class files. Did you specify the proper '-injars' options?"); } // Read all library jars. if (configuration.libraryJars != null) { readInput("Reading library ", configuration.libraryJars, createDataEntryClassPoolFiller(true)); } // The defaultPackage option implies the allowAccessModification option. if (configuration.defaultPackage != null) { configuration.allowAccessModification = true; } } /** * Creates a DataEntryReader that will decode class files and put them in * the proper class pool. */ private DataEntryReader createDataEntryClassPoolFiller(boolean isLibrary) { // Get the proper class pool. ClassPool classPool = isLibrary ? libraryClassPool : programClassPool; // Prepare a data entry reader to filter all class files, // which are then decoded to class files by a class file reader, // which are then put in the class pool by a class pool filler. return new ClassFileFilter( new ClassFileReader(isLibrary, configuration.skipNonPublicLibraryClasses, configuration.skipNonPublicLibraryClassMembers, new ClassPoolFiller(classPool, configuration.note))); } /** * Reads all input entries from the given class path. */ private void readInput(String messagePrefix, ClassPath classPath, DataEntryReader reader) throws IOException { readInput(messagePrefix, classPath, 0, classPath.size(), reader); } /** * Reads all input entries from the given section of the given class path. */ private void readInput(String messagePrefix, ClassPath classPath, int fromIndex, int toIndex, DataEntryReader reader) throws IOException { for (int index = fromIndex; index < toIndex; index++) { ClassPathEntry entry = classPath.get(index); if (!entry.isOutput()) { readInput(messagePrefix, entry, reader); } } } /** * Reads the given input class path entry. */ private void readInput(String messagePrefix, ClassPathEntry classPathEntry, DataEntryReader dataEntryReader) throws IOException { try { // Create a reader that can unwrap jars, wars, ears, and zips. DataEntryReader reader = DataEntryReaderFactory.createDataEntryReader(messagePrefix, classPathEntry, dataEntryReader); // Create the data entry pump. DirectoryPump directoryPump = new DirectoryPump(new File(classPathEntry.getName())); // Pump the data entries into the reader. directoryPump.pumpDataEntries(reader); } catch (IOException ex) { throw new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")"); } } /** * Initializes the cross-references between all class files. */ private void initialize() throws IOException { // Initialize the class hierarchy for program class files. ClassFileHierarchyInitializer classFileHierarchyInitializer = new ClassFileHierarchyInitializer(programClassPool, libraryClassPool, configuration.warn); programClassPool.classFilesAccept(classFileHierarchyInitializer); // Initialize the rest of the class hierarchy. ClassFileHierarchyInitializer classFileHierarchyInitializer2 = new ClassFileHierarchyInitializer(programClassPool, libraryClassPool, false); libraryClassPool.classFilesAccept(classFileHierarchyInitializer2); // Initialize the other class references. ClassFileReferenceInitializer classFileReferenceInitializer = new ClassFileReferenceInitializer(programClassPool, libraryClassPool, configuration.warn, configuration.note); programClassPool.classFilesAccept(classFileReferenceInitializer); int noteCount = classFileReferenceInitializer.getNoteCount(); if (noteCount > 0) { System.err.println("Note: there were " + noteCount + " class casts of dynamically created class instances."); System.err.println(" You might consider explicitly keeping the mentioned classes and/or"); System.err.println(" their implementations (using '-keep')."); } int hierarchyWarningCount = classFileHierarchyInitializer.getWarningCount(); if (hierarchyWarningCount > 0) { System.err.println("Warning: there were " + hierarchyWarningCount + " unresolved references to superclasses or interfaces."); System.err.println(" You may need to specify additional library jars (using '-libraryjars'),"); System.err.println(" or perhaps the '-dontskipnonpubliclibraryclasses' option."); } int referenceWarningCount = classFileReferenceInitializer.getWarningCount(); if (referenceWarningCount > 0) { System.err.println("Warning: there were " + referenceWarningCount + " unresolved references to program class members."); System.err.println(" Your input class files appear to be inconsistent."); System.err.println(" You may need to recompile them and try again."); } if ((hierarchyWarningCount > 0 ||
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -