Usage |
---|
To run ProGuard, just type:
java -jar proguard.jar options ...
|
Or, assuming the ProGuard jar is in your class path:
java proguard.ProGuard options ...
|
Options can also be put in one or more configuration files. Typically, you'll put most options in a configuration file, and just call:
java -jar proguard.jar @myconfig.pro
|
where myconfig.pro
contains the actual options.
You can simply combine command line options and options from configuration files, e.g.:
java -jar proguard.jar @myconfig.pro -printusage -printmapping
|
In a configuration file, a #
sign and all remaining
characters on that line are ignored, allowing you to add comments.
Extra whitespace between words and delimiters is ignored. To specify file names with spaces or special characters, or more exotically, to specify empty class names, words can be quoted with single or double quotes. Note that the quotes may need to be escaped when used on the command line, to avoid gobbling by the shell.
Options can be grouped arbitrarily in arguments on the command line and in lines in configuration files. This means that you can quote any arbitrary section of command line options, to avoid shell expansion of special characters, for instance.
The order of the options is irrelevant. They can be abbreviated to their first unique characters.
Options |
---|
The following table lists all ProGuard options:
@
filename-include
filename'.-include
filename-libraryjars
jarname[:...]-libraryjars
directives. Multiple jars can also be
specified using the path separator (e.g. ':' on Unix, or ';' on Windows
platforms).
Please note that the boot path and class path set for running ProGuard are not considered when looking for library classes. This also means that you explicitly have to specify the run-time jar that your code will use. Although seemingly cumbersome, it allows you to process applications targeted at different run-time environments. For example, you can process J2SE applications as well as J2ME midlets, just by specifying the appropriate run-time jar.
-injars
jarname[:...]-injars
directives. Multiple jars can also be
specified using the path separator (e.g. ':' on Unix, or ';' on Windows
platforms).-outjar
jarname-keep
class_specification-keepclassmembers
class_specificationSerializable
interface.-keepclasseswithmembers
class_specification-keepnames
class_specificationSerializable
interface, so that the
processed code remains compatible with any originally serialized classes.
Classes that aren't used at all can still be removed.-keepclassmembernames
class_specificationclass$
methods when processing a library, so ProGuard can
detect it again when processing an application that uses the processed
library.-keepclasseswithmembernames
class_specification-keepattributes
[attribute_name,...]-keepattributes
directives.
Multiple attributes can also be specified separated by commas. An empty
list or a *
wildcard preserves all attributes. Typical
optional attributes are LineNumberTable
,
LocalVariableTable
, SourceFile
,
Deprecated
, and Synthetic
. The
InnerClasses
attribute name can be specified as well,
referring to the source name part of this attribute. For example, you could
keep the Deprecated
attribute when processing a library. Only applicable when
obfuscating.-renamesourcefileattribute
[string]SourceFile
attributes of the class files. Note that the attribute also has to be
preserved explicitly using the -keepattributes
directive, or
it will be removed anyway. For example, you may want to have your
processed libraries and applications produce useful obfuscated stack traces. Only
applicable when obfuscating.-printseeds
[filename]-keep
commands. The list is printed to the standard
output or to the given file. The list can be useful to verify if the
intended class members are really found, especially if you're using
wildcards. For example, you may want to list all the applications or all the applets that you are keeping.-printusage
[filename]-printmapping
[filename]-verbose
-dump
[filename]-ignorewarnings
-dontwarn
-dontnote
-dontshrink
-keep
commands, and the ones they
depend on, recursively.-dontobfuscate
-keep
commands.
Internal attributes that are useful for debugging, such as source files
names, variable names, and line numbers are removed.-dontusemixedcaseclassnames
-overloadaggressively
Note that the resulting class files fall within the Java bytecode specification (cfr. The Java Virtual Machine Specification, Second Edition, first paragraphs of Section 4.5 and Section 4.6), even though this kind of overloading is not allowed in the Java language (cfr. The Java Language Specification, Second Edition, Section 8.3 and Section 8.4.7). Still, some tools have problems with it. Most notably, Sun's JDK 1.2.2 javac compiler produces an exception when compiling with such a library (cfr. Bug #4216736). You therefore probably shouldn't use this option for processing libraries.
-defaultpackage
[package_name]Note that this kind of repackaging may cause access permissions to become inconsistent, e.g. a class with default access may move to a different package from some other class that is using it. This may seem unusual, but it is formally allowed by Java's binary compatibility specifications (cfr. The Java Language Specification, Second Edition, Section 13.4.6).
Counter-indications: users have reported problems using this option in the circumstances listed below. Some environments don't seem to follow the compatibility specifications and strictly enforce access permissions.
appletviewer
.
When in doubt, just leave the packaging untouched by not using this option.
-dontskipnonpubliclibraryclasses
-keep Options
|
---|
The various -keep
options may seem a bit confusing at first, but
there's actually a pattern behind them. The following table summarizes how they
are related:
Keep | From shrinking & obfuscation | From obfuscation only |
---|---|---|
Classes and class members | -keep |
-keepnames |
Class members only | -keepclassmembers |
-keepclassmembernames |
Classes and class members, if class members present | -keepclasseswithmembers |
-keepclasseswithmembernames |
Each -keep
option is of course followed by a specification of the
classes and class members to which it should be applied.
File Names |
---|
In a ProGuard configuration, file names and jar names can be specified using absolute or relative paths.
The names can contain Java system properties delimited by '<' and '>'. The system properties are automatically replaced by their respective values.
For example, <java.home>/lib/rt.jar
will automatically be
expanded to something like /usr/local/java/jdk/jre/lib/rt.jar
.
Names with special characters like spaces and parentheses should be quoted with single or double quotes. Note that each file name in a list of names has to be quoted individually. Also note that the quotes may need to be escaped when used on the command line, to avoid gobbling by the shell.
For example, on the command line, you could use an option like '-injars
"my program.jar":"/your directory/your program.jar"'
.
Class Specifications |
---|
A class specification is a template of classes and class members (fields and
methods). It is used in the various -keep
options. The
corresponding option is only applied to classes and class members that match
the template.
The template was designed to look very Java-like, with some extensions for wildcards. To get a feel for the syntax, you should probably look at the examples, but this is an attempt at a complete formal definition:
[[!]public|final|abstract ...] ([!]interface)|class classname [extends|implements classname] [{ [[!]public|private|protected|static|volatile|transient ...] <fields> | (fieldtype fieldname); [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> | <init>(argumenttype,...) | classname(argumenttype,...) | (returntype methodname(argumenttype,...)); [[!]public|private|protected|static ... ] *; ... }]
Square brackets "[]" mean that something is optional. Ellipsis dots "..." mean that any number of items may be specified. A vertical bar "|" indicates a choice between alternatives. Non-bold parentheses "()" just group parts of the specification that belong together. The indentation tries to clarify the intended meaning, but white-space is irrelevant in actual configuration files.
class
keyword refers to any interface or class.
The interface
keyword restricts matches to interface
classes. Preceding the interface
keyword by a
!
restricts matches to classes that are not
interfaces.
java.lang.String
. Class names may be specified as regular
expressions containing the following wildcards:
? |
matches any single character, but not the package separator. For example,
"mypackage.Test? " matches "mypackage.Test1 " and
"mypackage.Test2 ", but not
"mypackage.Test12 ". |
* |
matches any string not containing the package separator. For example,
"mypackage.*Test* " matches "mypackage.Test " and
"mypackage.YourTestApplication ", but not
"mypackage.mysubpackage.MyTest ". Or, more generally,
"mypackage.* " matches all classes in
"mypackage ", but not in its subpackages. |
** |
matches any string, possibly containing one or more package separators.
For example, "**.Test "
matches all Test classes in all packages except the root
package. Or, "mypackage.** " matches all classes in
"mypackage " and in its subpackages. |
*
refers to any class, irrespective of its package.
extends
and implements
specifications are typically used to restrict classes with wildcards. They
are currently equivalent, specifying that only classes extending or
implementing the given class qualify. Note that the given class itself is
not included in this set. If required, it should be specified in a
separate option.
<fields>
refers to any field. The wildcard
method name <methods>
refers to any method. The
wildcard class member name *
refers to any field or
method. Note that all of the above wildcards don't have return types. More
general regular expressions are not yet supported.
<init>
wildcard. As in the Java language, the
constructor specification has an argument list, but no return type.
!
specifies that the corresponding access
flag should be unset.
Combining multiple flags is allowed (e.g. public static
). It
means that both access flags have to be set (e.g. public
and static
), except when they are conflicting, in
which case at least one of them has to be set (e.g. at least
public
or protected
).