ProGuard can also be used to list unused fields and methods in an application, and to print out the internal structure of class files.
Input jars | ||||
Shrunk code | ||||
- shrink → | - obfuscate → | Output jars | ||
Resource jars | ----------------- (unchanged) -----------------→ | |||
Library jars | ----------------- (unchanged) -----------------→ | Library jars |
ProGuard typically reads the input jars (or directories), shrinks their class files, obfuscates the shrunk class files, and writes them to one or more output jars (or directories). In order to determine which code has to be preserved, which code can be discarded, and which code can be obfuscated, you have to specify one or more seed classes or methods. These seeds are typically main classes, applets, midlets,... In the shrinking phase, ProGuard recursively determines which classes and class members are used, and discards the rest. In the obfuscation phase, all classes and class members get new names, except for the seeds, so they can still be called by their original names.
You can optionally specify resource jars (or directories). ProGuard copies all non-class resource files from these jars to the output jars. Their names and contents remain unchanged. If no resource jars are specified, the input jars are used as resource jars.
ProGuard requires the library jars (or directories) of the input jars to be specified, or at least the library jars containing classes that are extended by input classes. The library jars themselves always remain unchanged.
ProGuard automatically handles Class.forName("SomeClass")
and
SomeClass.class
constructs. The referenced classes are preserved
in the shrinking phase, and the string arguments are properly replaced in the
obfuscation phase. With variable string arguments, it's generally not possible
to determine their possible values (they might be read from a configuration
file, for instance). However, ProGuard will note constructs like
"(SomeClass)Class.forName(variable).newInstance()
". These might
be an indication that the class or interface SomeClass
and/or its
implementations may need to be preserved. The user can adapt his configuration
accordingly.