1021 lines
56 KiB
Markdown
1021 lines
56 KiB
Markdown
This page lists all available options for ProGuard, grouped logically.
|
|
|
|
!!! android R8
|
|
R8, the default Android shrinker, is compatible with ProGuard keep rules.
|
|
|
|
## Input/Output Options {: #iooptions}
|
|
|
|
`@`{: #at} [*filename*](#filename)
|
|
: Short for '[`-include`](#include) [*filename*](#filename)'.
|
|
|
|
`-include`{: #include} [*filename*](#filename)
|
|
: Recursively reads configuration options from the given file *filename*.
|
|
|
|
`-basedirectory`{: #basedirectory} [*directoryname*](#filename)
|
|
: Specifies the base directory for all subsequent relative file names in
|
|
these configuration arguments or this configuration file.
|
|
|
|
`-injars`{: #injars} [*class\_path*](#classpath)
|
|
: Specifies the input jars (or apks, aabs, aars, wars, ears, jmods, zips, or
|
|
directories) of the application to be processed. The class files in these
|
|
jars will be processed and written to the output jars. By default, any
|
|
non-class files will be copied without changes. Please be aware of any
|
|
temporary files (e.g. created by IDEs), especially if you are reading your
|
|
input files straight from directories. The entries in the class path can be
|
|
filtered, as explained in the [filters](#filefilters) section. For better
|
|
readability, class path entries can be specified using multiple `-injars`
|
|
options.
|
|
|
|
`-outjars`{: #outjars} [*class\_path*](#classpath)
|
|
: Specifies the names of the output jars (or apks, aabs, aars, wars, ears,
|
|
jmods, zips, or directories). The processed input of the preceding
|
|
[`-injars`](usage.md#injars) options will be written to the named jars. This
|
|
allows you to collect the contents of groups of input jars into
|
|
corresponding groups of output jars. In addition, the output entries can be
|
|
filtered, as explained in the [filters](#filefilters) section. Each
|
|
processed class file or resource file is then written to the first output
|
|
entry with a matching filter, within the group of output jars. You must
|
|
avoid letting the output files overwrite any input files. For better
|
|
readability, class path entries can be specified using multiple
|
|
[`-outjars`](usage.md#outjars) options. Without any
|
|
[`-outjars`](usage.md#outjars) options, no jars will be written.
|
|
|
|
`-libraryjars`{: #libraryjars} [*class\_path*](#classpath)
|
|
: Specifies the library jars (or apks, aabs, aars, wars, ears, jmods, zips,
|
|
directories) of the application to be processed. The files in these jars
|
|
will not be included in the output jars. The specified library jars should
|
|
at least contain the class files that are *extended* by application class
|
|
files. Library class files that are only *called* needn't be present,
|
|
although their presence can improve the results of the optimization step.
|
|
The entries in the class path can be filtered, as explained in the
|
|
[filters](#filefilters) section. For better readability, class path entries
|
|
can be specified using multiple `-libraryjars` options. Please note that the
|
|
boot path and the class path set for running ProGuard are not considered
|
|
when looking for library classes. This means that you explicitly have to
|
|
specify the run-time jar that your code will use. Although this may seem
|
|
cumbersome, it allows you to process applications targeted at different
|
|
run-time environments. For example, you can process [J2SE
|
|
applications](examples.md#application) as well as [JME
|
|
midlets](examples.md#midlet), just by specifying the appropriate
|
|
run-time jar.
|
|
|
|
`-skipnonpubliclibraryclasses`{: #skipnonpubliclibraryclasses}
|
|
: Specifies to skip non-public classes while reading library jars, to speed
|
|
up processing and reduce memory usage of ProGuard. By default, ProGuard
|
|
reads non-public and public library classes alike. However, non-public
|
|
classes are often not relevant, if they don't affect the actual program code
|
|
in the input jars. Ignoring them then speeds up ProGuard, without affecting
|
|
the output. Unfortunately, some libraries, including recent JSE run-time
|
|
libraries, contain non-public library classes that are extended by public
|
|
library classes. You then can't use this option. ProGuard will print out
|
|
warnings if it can't find classes due to this option being set.
|
|
|
|
`-dontskipnonpubliclibraryclasses`{: #dontskipnonpubliclibraryclasses}
|
|
: Specifies not to ignore non-public library classes. As of version 4.5,
|
|
this is the default setting.
|
|
|
|
`-dontskipnonpubliclibraryclassmembers`{: #dontskipnonpubliclibraryclassmembers}
|
|
: Specifies not to ignore package visible library class members (fields and
|
|
methods). By default, ProGuard skips these class members while parsing
|
|
library classes, as program classes will generally not refer to them.
|
|
Sometimes however, program classes reside in the same packages as library
|
|
classes, and they do refer to their package visible class members. In those
|
|
cases, it can be useful to actually read the class members, in order to make
|
|
sure the processed code remains consistent.
|
|
|
|
`-keepdirectories`{: #keepdirectories} \[*[directory\_filter](#filefilters)*\]
|
|
: Specifies the directories to be kept in the output jars (or apks, aabs,
|
|
aars, wars, ears, jmods, zips, or directories). By default, directory
|
|
entries are removed. This reduces the jar size, but it may break your
|
|
program if the code tries to find them with constructs like
|
|
"`com.example.MyClass.class.getResource("")`". You'll then want to keep the
|
|
directory corresponding to the package, "`-keepdirectories com.example`". If
|
|
the option is specified without a filter, all directories are kept. With a
|
|
filter, only matching directories are kept. For instance, "`-keepdirectories
|
|
mydirectory`" matches the specified directory, "`-keepdirectories
|
|
mydirectory/*`" matches its immediate subdirectories, and "`-keepdirectories
|
|
mydirectory/**`" matches all of its subdirectories.
|
|
|
|
`-target`{: #target} *version*
|
|
: **Deprecated: this option is only applicable for Java class file versions <= 11.**
|
|
Specifies the version number to be set in the processed class files. The
|
|
version number can be one of `1.0`,..., `1.9`, or the more recent short
|
|
numbers `5`,..., `12`. By default, the version numbers of the class files
|
|
are left unchanged. For example, you may want to [upgrade class files to
|
|
Java 6](examples.md#upgrade). ProGuard changes their version numbers and
|
|
preverifies them. You can also downgrade class files to older versions than
|
|
Java 8. ProGuard changes their version numbers and backports Java 8
|
|
constructs. ProGuard generally doesn't backport changes in the Java runtime,
|
|
except for the Java 8 stream API and the Java 8 date API, if you add the
|
|
backported libraries `net.sourceforge.streamsupport` and `org.threeten` as
|
|
input, respectively.
|
|
|
|
`-forceprocessing`{: #forceprocessing}
|
|
: Specifies to process the input, even if the output seems up to date. The
|
|
up-to-dateness test is based on a comparison of the date stamps of the
|
|
specified input, output, and configuration files or directories.
|
|
|
|
## Keep Options {: #keepoptions}
|
|
|
|
!!! tip "ProGuard Playground"
|
|
The [**ProGuard Playground**](https://playground.proguard.com) is a useful tool to help you further tweak the keep rules.
|
|
|
|
<iframe frameborder="0" width="100%" height="200px" style="border-radius: 0.25rem; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);" src="https://playground.proguard.com/p/FT5qr8?embed"></iframe>
|
|
|
|
|
|
`-keep`{: #keep} \[[,*modifier*](#keepoptionmodifiers),...\] [*class\_specification*](#classspecification)
|
|
: Specifies classes and class members (fields and methods) to be preserved
|
|
as entry points to your code. For example, in order to [keep an
|
|
application](examples.md#application), you can specify the main class along
|
|
with its main method. In order to [process a library](examples.md#library),
|
|
you should specify all publicly accessible elements.
|
|
|
|
`-keepclassmembers`{: #keepclassmembers} \[[,*modifier*](#keepoptionmodifiers),...\] [*class\_specification*](#classspecification)
|
|
: Specifies class members to be preserved, if their classes are preserved as
|
|
well. For example, you may want to [keep all serialization fields and
|
|
methods](examples.md#serializable) of classes that implement the
|
|
`Serializable` interface.
|
|
|
|
`-keepclasseswithmembers`{: #keepclasseswithmembers} \[[,*modifier*](#keepoptionmodifiers),...\] [*class\_specification*](#classspecification)
|
|
: Specifies classes and class members to be preserved, on the condition that
|
|
all of the specified class members are present. For example, you may want to
|
|
[keep all applications](examples.md#applications) that have a main method,
|
|
without having to list them explicitly.
|
|
|
|
`-keepnames`{: #keepnames} [*class\_specification*](#classspecification)
|
|
: Short for [`-keep`](#keep),[`allowshrinking`](#allowshrinking)
|
|
[*class\_specification*](#classspecification) Specifies classes and class
|
|
members whose names are to be preserved, if they aren't removed in the
|
|
shrinking phase. For example, you may want to [keep all class
|
|
names](examples.md#serializable) of classes that implement the
|
|
`Serializable` interface, so that the processed code remains compatible with
|
|
any originally serialized classes. Classes that aren't used at all can still
|
|
be removed. Only applicable when obfuscating.
|
|
|
|
`-keepclassmembernames`{: #keepclassmembernames} [*class\_specification*](#classspecification)
|
|
: Short for
|
|
[`-keepclassmembers`](#keepclassmembers),[`allowshrinking`](#allowshrinking)
|
|
[*class\_specification*](#classspecification) Specifies class members whose
|
|
names are to be preserved, if they aren't removed in the shrinking phase.
|
|
For example, you may want to preserve the name of the synthetic `class$`
|
|
methods when [processing a library](examples.md#library) compiled by JDK 1.2
|
|
or older, so obfuscators can detect it again when processing an application
|
|
that uses the processed library (although ProGuard itself doesn't need
|
|
this). Only applicable when obfuscating.
|
|
|
|
`-keepclasseswithmembernames`{: #keepclasseswithmembernames} [*class\_specification*](#classspecification)
|
|
: Short for
|
|
[`-keepclasseswithmembers`](#keepclasseswithmembers),[`allowshrinking`](#allowshrinking)
|
|
[*class\_specification*](#classspecification) Specifies classes and class
|
|
members whose names are to be preserved, on the condition that all of the
|
|
specified class members are present after the shrinking phase. For example,
|
|
you may want to [keep all native method names](examples.md#native) and the
|
|
names of their classes, so that the processed code can still link with the
|
|
native library code. Native methods that aren't used at all can still be
|
|
removed. If a class file is used, but none of its native methods are, its
|
|
name will still be obfuscated. Only applicable when obfuscating.
|
|
|
|
`-if`{: #if} [*class\_specification*](#classspecification)
|
|
: Specifies classes and class members that must be `present` to activate the
|
|
subsequent keep option ([`-keep`](usage.md#keep),
|
|
[`-keepclassmembers`](usage.md#keepclassmembers),...). The condition and
|
|
the subsequent keep option can share wildcards and references to wildcards.
|
|
For example, you can keep classes on the condition that classes with related
|
|
names exist in your project, with frameworks like
|
|
[Dagger](examples.md#dagger) and [Butterknife](examples.md#butterknife).
|
|
|
|
`-printseeds`{: #printseeds} \[[*filename*](#filename)\]
|
|
: Specifies to exhaustively list classes and class members matched by the
|
|
various `-keep` options. 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](examples.md#applications) or all
|
|
the [applets](examples.md#applets) that you are keeping.
|
|
|
|
## Shrinking Options {: #shrinkingoptions}
|
|
|
|
`-dontshrink`{: #dontshrink}
|
|
: Specifies not to shrink the input. By default, ProGuard shrinks the code: it
|
|
removes all unused classes and class members. It only keeps the ones listed
|
|
by the various [`-keep`](usage.md#keep) options, and the ones on which they
|
|
depend, directly or indirectly. It also applies a shrinking step after each
|
|
optimization step, since some optimizations may open up the possibility to
|
|
remove more classes and class members.
|
|
|
|
`-printusage`{: #printusage} \[[*filename*](#filename)\]
|
|
: Specifies to list dead code of the input class files. The list is printed
|
|
to the standard output or to the given file. For example, you can [list the
|
|
unused code of an application](examples.md#deadcode). Only applicable when
|
|
shrinking.
|
|
|
|
`-whyareyoukeeping`{: #whyareyoukeeping} [*class\_specification*](#classspecification)
|
|
: Specifies to print details on why the given classes and class members are
|
|
being kept in the shrinking step. This can be useful if you are wondering
|
|
why some given element is present in the output. In general, there can be
|
|
many different reasons. This option prints the shortest chain of methods to
|
|
a specified seed or entry point, for each specified class and class member.
|
|
*In the current implementation, the shortest chain that is printed out may
|
|
sometimes contain circular deductions -- these do not reflect the actual
|
|
shrinking process.* If the [`-verbose`](#verbose) option if specified, the
|
|
traces include full field and method signatures. Only applicable when
|
|
shrinking.
|
|
|
|
## Optimization Options {: #optimizationoptions}
|
|
|
|
`-dontoptimize`{: #dontoptimize}
|
|
: Specifies not to optimize the input class files. By default, ProGuard
|
|
optimizes all code. It inlines and merges classes and class members, and
|
|
it optimizes all methods at a bytecode level.
|
|
|
|
`-optimizations`{: #optimizations} [*optimization\_filter*](optimizations.md)
|
|
: Specifies the optimizations to be enabled and disabled, at a more
|
|
fine-grained level. Only applicable when optimizing. *This is an expert
|
|
option.*
|
|
|
|
`-optimizationpasses`{: #optimizationpasses} *n*
|
|
: Specifies the number of optimization passes to be performed. By default, a
|
|
single pass is performed. Multiple passes may result in further
|
|
improvements. If no improvements are found after an optimization pass, the
|
|
optimization is ended. Only applicable when optimizing.
|
|
|
|
`-assumenosideeffects`{: #assumenosideeffects} [*class\_specification*](#classspecification)
|
|
: Specifies methods that don't have any side effects, other than possibly
|
|
returning a value. For example, the method `System.currentTimeMillis()`
|
|
returns a value, but it doesn't have any side effects. In the optimization
|
|
step, ProGuard can then remove calls to such methods, if it can determine
|
|
that the return values aren't used. ProGuard will analyze your program code
|
|
to find such methods automatically. It will not analyze library code, for
|
|
which this option can therefore be useful. For example, you could specify
|
|
the method `System.currentTimeMillis()`, so that any idle calls to it will
|
|
be removed. With some care, you can also use the option to [remove logging
|
|
code](examples.md#logging). Note that ProGuard applies the option to the
|
|
entire hierarchy of the specified methods. Only applicable when optimizing.
|
|
In general, making assumptions can be dangerous; you can easily break the
|
|
processed code. *Only use this option if you know what you're doing!*
|
|
|
|
`-assumenoexternalsideeffects`{: #assumenoexternalsideeffects} [*class\_specification*](#classspecification)
|
|
: Specifies methods that don't have any side effects, except possibly on the
|
|
instances on which they are called. This statement is weaker than
|
|
[`-assumenosideeffects`](#assumenosideeffects), because it allows side
|
|
effects on the parameters or the heap. For example, the
|
|
`StringBuffer#append` methods have side effects, but no external side
|
|
effects. This is useful when [removing logging code](examples.md#logging),
|
|
to also remove any related string concatenation code. Only applicable when
|
|
optimizing. Making assumptions can be dangerous; you can easily break the
|
|
processed code. *Only use this option if you know what you're doing!*
|
|
|
|
`-assumenoescapingparameters`{: #assumenoescapingparameters} [*class\_specification*](#classspecification)
|
|
: Specifies methods that don't let their reference parameters escape to the
|
|
heap. Such methods can use, modify, or return the parameters, but not store
|
|
them in any fields, either directly or indirectly. For example, the method
|
|
`System.arrayCopy` does not let its reference parameters escape, but method
|
|
`System.setSecurityManager` does. Only applicable when optimizing. Making
|
|
assumptions can be dangerous; you can easily break the processed code. *Only
|
|
use this option if you know what you're doing!*
|
|
|
|
`-assumenoexternalreturnvalues`{: #assumenoexternalreturnvalues} [*class\_specification*](#classspecification)
|
|
: Specifies methods that don't return reference values that were already on
|
|
the heap when they are called. For example, the `ProcessBuilder#start`
|
|
returns a `Process` reference value, but it is a new instance that wasn't on
|
|
the heap yet. Only applicable when optimizing. Making assumptions can be
|
|
dangerous; you can easily break the processed code. *Only use this option if
|
|
you know what you're doing!*
|
|
|
|
`-assumevalues`{: #assumevalues} [*class\_specification*](#classspecification)
|
|
: Specifies fixed values or ranges of values for primitive fields and
|
|
methods. Making assumptions can be dangerous; you can easily break the
|
|
processed code. *Only use this option if you know what you're doing!*
|
|
|
|
`-allowaccessmodification`{: #allowaccessmodification}
|
|
: Specifies that the access modifiers of classes and class members may be
|
|
broadened during processing. This can improve the results of the
|
|
optimization step. For instance, when inlining a public getter, it may be
|
|
necessary to make the accessed field public too. Although Java's binary
|
|
compatibility specifications formally do not require this (cfr. [The Java
|
|
Language Specification, Third
|
|
Edition](http://docs.oracle.com/javase/specs/jls/se12/html/index.html),
|
|
[Section
|
|
13.4.6](http://docs.oracle.com/javase/specs/jls/se12/html/jls-13.html#jls-13.4.6)),
|
|
some virtual machines would have problems with the processed code otherwise.
|
|
Only applicable when optimizing (and when obfuscating with the
|
|
[`-repackageclasses`](#repackageclasses) option). *Counter-indication:* you
|
|
probably shouldn't use this option when processing code that is to be used
|
|
as a library, since classes and class members that weren't designed to be
|
|
public in the API may become public.
|
|
|
|
`-mergeinterfacesaggressively`{: #mergeinterfacesaggressively}
|
|
: Specifies that interfaces may be merged, even if their implementing
|
|
classes don't implement all interface methods. This can reduce the size of
|
|
the output by reducing the total number of classes. Note that Java's binary
|
|
compatibility specifications allow such constructs (cfr. [The Java Language
|
|
Specification, Third
|
|
Edition](http://docs.oracle.com/javase/specs/jls/se12/html/index.html),
|
|
[Section
|
|
13.5.3](http://docs.oracle.com/javase/specs/jls/se12/html/jls-13.html#jls-13.5.3)),
|
|
even if they are not allowed in the Java language (cfr. [The Java Language
|
|
Specification, Third
|
|
Edition](http://docs.oracle.com/javase/specs/jls/se12/html/index.html),
|
|
[Section
|
|
8.1.4](http://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.1.4)).
|
|
Only applicable when optimizing.
|
|
|
|
*Counter-indication:* setting this option can reduce the performance
|
|
of the processed code on some JVMs, since advanced just-in-time
|
|
compilation tends to favor more interfaces with fewer
|
|
implementing classes. Worse, some JVMs may not be able to handle the
|
|
resulting code. Notably:
|
|
|
|
- Sun's JRE 1.3 may throw an `InternalError` when encountering
|
|
more than 256 *Miranda* methods (interface methods
|
|
without implementations) in a class.
|
|
|
|
`-optimizeaggressively`{: #optimizeaggressively}
|
|
: Enables more aggressive assumptions during optimization. This might lead to
|
|
improved performance and/or reduced code size, but might result in different behavior in rare cases.
|
|
For example, reading from an array might cause an
|
|
`ArrayIndexOutOfBoundsException` to be thrown. Strictly speaking, this means
|
|
that such an instruction can have a side effect. If this instruction is removed
|
|
during optimization, the code will thus behave differently under specific
|
|
circumstances. By default, such instructions are always preserved. Setting this
|
|
option will lead to these instructions being candidates for removal during
|
|
optimization. Additionally, class merging is only enabled when this option is set.
|
|
|
|
## Obfuscation Options {: #obfuscationoptions}
|
|
|
|
`-dontobfuscate`{: #dontobfuscate}
|
|
: Specifies not to obfuscate the input class files. By default, ProGuard
|
|
obfuscates the code: it assigns new short random names to classes and
|
|
class members. It removes internal attributes that are only useful for
|
|
debugging, such as source files names, variable names, and line numbers.
|
|
|
|
`-printmapping`{: #printmapping} \[[*filename*](#filename)\]
|
|
: Specifies to print the mapping from old names to new names for classes and
|
|
class members that have been renamed. The mapping is printed to the standard
|
|
output or to the given file. For example, it is required for subsequent
|
|
[incremental obfuscation](examples.md#incremental), or if you ever want to
|
|
make sense again of [obfuscated stack traces](examples.md#stacktrace). Only
|
|
applicable when obfuscating.
|
|
|
|
`-applymapping`{: #applymapping} [*filename*](#filename)
|
|
: Specifies to reuse the given name mapping that was printed out in a
|
|
previous obfuscation run of ProGuard. Classes and class members that are
|
|
listed in the mapping file receive the names specified along with them.
|
|
Classes and class members that are not mentioned receive new names. The
|
|
mapping may refer to input classes as well as library classes. This option
|
|
can be useful for [incremental obfuscation](examples.md#incremental), i.e.
|
|
processing add-ons or small patches to an existing piece of code. If the
|
|
structure of the code changes fundamentally, ProGuard may print out warnings
|
|
that applying a mapping is causing conflicts. You may be able to reduce this
|
|
risk by specifying the option
|
|
[`-useuniqueclassmembernames`](#useuniqueclassmembernames) in both
|
|
obfuscation runs. Only a single mapping file is allowed. Only applicable
|
|
when obfuscating.
|
|
|
|
`-obfuscationdictionary`{: #obfuscationdictionary} [*filename*](#filename)
|
|
: Specifies a text file from which all valid words are used as obfuscated
|
|
field and method names. By default, short names like 'a', 'b', etc. are used
|
|
as obfuscated names. With an obfuscation dictionary, you can specify a list
|
|
of reserved key words, or identifiers with foreign characters, for instance.
|
|
White space, punctuation characters, duplicate words, and comments after a
|
|
`#` sign are ignored. Note that an obfuscation dictionary hardly improves
|
|
the obfuscation. Decent compilers can automatically replace them, and the
|
|
effect can fairly simply be undone by obfuscating again with simpler names.
|
|
The most useful application is specifying strings that are typically already
|
|
present in class files (such as 'Code'), thus reducing the class file sizes
|
|
just a little bit more. Only applicable when obfuscating.
|
|
|
|
`-classobfuscationdictionary`{: #classobfuscationdictionary} [*filename*](#filename)
|
|
: Specifies a text file from which all valid words are used as obfuscated
|
|
class names. The obfuscation dictionary is similar to the one of the option
|
|
[`-obfuscationdictionary`](#obfuscationdictionary). Only applicable when
|
|
obfuscating.
|
|
|
|
`-packageobfuscationdictionary`{: #packageobfuscationdictionary} [*filename*](#filename)
|
|
: Specifies a text file from which all valid words are used as obfuscated
|
|
package names. The obfuscation dictionary is similar to the one of the
|
|
option [`-obfuscationdictionary`](#obfuscationdictionary). Only applicable
|
|
when obfuscating.
|
|
|
|
`-overloadaggressively`{: #overloadaggressively}
|
|
: Specifies to apply aggressive overloading while obfuscating. Multiple
|
|
fields and methods can then get the same names, as long as their arguments
|
|
and return types are different, as required by Java bytecode (not just their
|
|
arguments, as required by the Java language). This option can make the
|
|
processed code even smaller (and less comprehensible). Only applicable when
|
|
obfuscating.
|
|
|
|
*Counter-indication:* the resulting class files fall within the Java
|
|
bytecode specification (cfr. [The Java Virtual Machine
|
|
Specification](http://docs.oracle.com/javase/specs/jvms/se12/html/index.html),
|
|
first paragraphs of [Section
|
|
4.5](http://docs.oracle.com/javase/specs/jvms/se12/html/jvms-4.html#jvms-4.5)
|
|
and [Section
|
|
4.6](http://docs.oracle.com/javase/specs/jvms/se12/html/jvms-4.html#jvms-4.6)),
|
|
even though this kind of overloading is not allowed in the Java language
|
|
(cfr. [The Java Language Specification, Third
|
|
Edition](http://docs.oracle.com/javase/specs/jls/se12/html/index.html),
|
|
[Section
|
|
8.3](http://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.3)
|
|
and [Section
|
|
8.4.5](http://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.4.5)).
|
|
Still, some tools have problems with it. Notably:
|
|
|
|
- Sun's JDK 1.2.2 `javac` compiler produces an exception when
|
|
compiling with such a library (cfr. [Bug
|
|
\#4216736](http://bugs.sun.com/view_bug.do?bug_id=4216736)). You
|
|
probably shouldn't use this option for processing libraries.
|
|
- Sun's JRE 1.4 and later fail to serialize objects with
|
|
overloaded primitive fields.
|
|
- Sun's JRE 1.5 `pack200` tool reportedly has problems with
|
|
overloaded class members.
|
|
- The class `java.lang.reflect.Proxy` can't handle
|
|
overloaded methods.
|
|
- Google's Dalvik VM can't handle overloaded static fields.
|
|
|
|
`-useuniqueclassmembernames`{: #useuniqueclassmembernames}
|
|
: Specifies to assign the same obfuscated names to class members that have
|
|
the same names, and different obfuscated names to class members that have
|
|
different names (for each given class member signature). Without the option,
|
|
more class members can be mapped to the same short names like 'a', 'b', etc.
|
|
The option therefore increases the size of the resulting code slightly, but
|
|
it ensures that the saved obfuscation name mapping can always be respected
|
|
in subsequent incremental obfuscation steps.
|
|
|
|
For instance, consider two distinct interfaces containing methods with the
|
|
same name and signature. Without this option, these methods may get
|
|
different obfuscated names in a first obfuscation step. If a patch is then
|
|
added containing a class that implements both interfaces, ProGuard will
|
|
have to enforce the same method name for both methods in an incremental
|
|
obfuscation step. The original obfuscated code is changed, in order to
|
|
keep the resulting code consistent. With this option *in the initial
|
|
obfuscation step*, such renaming will never be necessary.
|
|
|
|
This option is only applicable when obfuscating. In fact, if you are
|
|
planning on performing incremental obfuscation, you probably want to avoid
|
|
shrinking and optimization altogether, since these steps could remove or
|
|
modify parts of your code that are essential for later additions.
|
|
|
|
`-dontusemixedcaseclassnames`{: #dontusemixedcaseclassnames}
|
|
: Specifies not to generate mixed-case class names while obfuscating. By
|
|
default, obfuscated class names can contain a mix of upper-case characters
|
|
and lower-case characters. This creates perfectly acceptable and usable
|
|
jars. Only if a jar is unpacked on a platform with a case-insensitive filing
|
|
system (say, Windows), the unpacking tool may let similarly named class
|
|
files overwrite each other. Code that self-destructs when it's unpacked!
|
|
Developers who really want to unpack their jars on Windows can use this
|
|
option to switch off this behavior. Obfuscated jars will become slightly
|
|
larger as a result. Only applicable when obfuscating.
|
|
|
|
`-keeppackagenames`{: #keeppackagenames} \[*[package\_filter](#filters)*\]
|
|
: Specifies not to obfuscate the given package names. The optional filter is
|
|
a comma-separated list of package names. Package names can contain **?**,
|
|
**\***, and **\*\*** wildcards, and they can be preceded by the **!**
|
|
negator. Only applicable when obfuscating.
|
|
|
|
`-flattenpackagehierarchy`{: #flattenpackagehierarchy} \[*package\_name*\]
|
|
: Specifies to repackage all packages that are renamed, by moving them into
|
|
the single given parent package. Without argument or with an empty string
|
|
(''), the packages are moved into the root package. This option is one
|
|
example of further [obfuscating package names](examples.md#repackaging). It
|
|
can make the processed code smaller and less comprehensible. Only applicable
|
|
when obfuscating.
|
|
|
|
`-repackageclasses`{: #repackageclasses} \[*package\_name*\]
|
|
: Specifies to repackage all class files that are renamed, by moving them
|
|
into the single given package. Without argument or with an empty string
|
|
(''), the package is removed completely. This option overrides the
|
|
[`-flattenpackagehierarchy`](#flattenpackagehierarchy) option. It is another
|
|
example of further [obfuscating package names](examples.md#repackaging).
|
|
It can make the processed code even smaller and less comprehensible. Its
|
|
deprecated name is `-defaultpackage`. Only applicable when obfuscating.
|
|
|
|
*Counter-indication:* classes that look for resource files in their
|
|
package directories will no longer work properly if they are moved
|
|
elsewhere. When in doubt, just leave the packaging untouched by not using
|
|
this option.
|
|
|
|
`-keepattributes`{: #keepattributes} \[*[attribute\_filter](attributes.md)*\]
|
|
: Specifies any optional attributes to be preserved. The attributes can be
|
|
specified with one or more [`-keepattributes`](usage.md#keepattributes)
|
|
directives. The optional filter is a comma-separated list of [attribute
|
|
names](attributes.md) that Java virtual machines and ProGuard support.
|
|
Attribute names can contain **?**, **\***, and **\*\*** wildcards, and they
|
|
can be preceded by the **!** negator. For example, you should at least keep
|
|
the `Exceptions`, `InnerClasses`, and `Signature` attributes when
|
|
[processing a library](examples.md#library). You should also keep the
|
|
`SourceFile` and `LineNumberTable` attributes for [producing useful
|
|
obfuscated stack traces](examples.md#stacktrace). Finally, you may want to
|
|
[keep annotations](examples.md#annotations) if your code depends on them.
|
|
Only applicable when obfuscating.
|
|
|
|
`-keepparameternames`{: #keepparameternames}
|
|
: Specifies to keep the parameter names and types of methods that are kept.
|
|
This option actually keeps trimmed versions of the debugging attributes
|
|
`LocalVariableTable` and `LocalVariableTypeTable`. It can be useful when
|
|
[processing a library](examples.md#library). Some IDEs can use the
|
|
information to assist developers who use the library, for example with tool
|
|
tips or autocompletion. Only applicable when obfuscating.
|
|
|
|
When processing Kotlin metadata the Kotlin function, constructor and property setter
|
|
parameter names are also kept.
|
|
|
|
`-renamesourcefileattribute`{: #renamesourcefileattribute} \[*string*\]
|
|
: Specifies a constant string to be put in the `SourceFile` attributes (and
|
|
`SourceDir` attributes) of the class files. Note that the attribute has to
|
|
be present to start with, so it also has to be preserved explicitly using
|
|
the [`-keepattributes`](usage.md#keepattributes) directive. For example, you
|
|
may want to have your processed libraries and applications produce [useful
|
|
obfuscated stack traces](examples.md#stacktrace). Only applicable when
|
|
obfuscating.
|
|
|
|
`-keepkotlinmetadata`{: #keepkotlinmetadata} {: .deprecated}
|
|
: ** Deprecated: use `-keep class kotlin.Metadata` instead. **
|
|
Specifies to process `kotlin.Metadata` annotations if present.
|
|
Currently only shrinking and obfuscation of its content is supported.
|
|
Classes containing such annotations should be excuded from optimization
|
|
if this option is enabled.
|
|
|
|
`-adaptclassstrings`{: #adaptclassstrings} \[*[class\_filter](#filters)*\]
|
|
: Specifies that string constants that correspond to class names should be
|
|
obfuscated as well. Without a filter, all string constants that correspond
|
|
to class names are adapted. With a filter, only string constants in classes
|
|
that match the filter are adapted. For example, if your code contains a
|
|
large number of hard-coded strings that refer to classes, and you prefer not
|
|
to keep their names, you may want to use this option. Primarily applicable
|
|
when obfuscating, although corresponding classes are automatically kept in
|
|
the shrinking step too.
|
|
|
|
`-adaptresourcefilenames`{: #adaptresourcefilenames} \[*[file\_filter](#filefilters)*\]
|
|
: Specifies the resource files to be renamed, based on the obfuscated names
|
|
of the corresponding class files (if any). Without a filter, all resource
|
|
files that correspond to class files are renamed. With a filter, only
|
|
matching files are renamed. For example, see [processing resource
|
|
files](examples.md#resourcefiles). Only applicable when obfuscating.
|
|
|
|
`-adaptresourcefilecontents`{: #adaptresourcefilecontents} \[*[file\_filter](#filefilters)*\]
|
|
: Specifies the resource files and native libraries whose contents are to be
|
|
updated. Any class names mentioned in the resource files are renamed, based
|
|
on the obfuscated names of the corresponding classes (if any). Any function
|
|
names in the native libraries are renamed, based on the obfuscated names of
|
|
the corresponding native methods (if any). Without a filter, the contents of
|
|
all resource files updated. With a filter, only matching files are updated.
|
|
The resource files are parsed and written using UTF-8 encoding. For an
|
|
example, see [processing resource files](examples.md#resourcefiles). Only
|
|
applicable when obfuscating. *Caveat:* You probably only want to apply this
|
|
option to text files and native libraries, since parsing and adapting
|
|
general binary files as text files can cause unexpected problems. Therefore,
|
|
make sure that you specify a sufficiently narrow filter.
|
|
|
|
## Preverification Options {: #preverificationoptions}
|
|
|
|
`-dontpreverify`{: #dontpreverify}
|
|
: Specifies not to preverify the processed class files. By default, class
|
|
files are preverified if they are targeted at Java Micro Edition or at Java
|
|
6 or higher. For Java Micro Edition, preverification is required, so you
|
|
will need to run an external preverifier on the processed code if you
|
|
specify this option. For Java 6, preverification is optional, but as of Java
|
|
7, it is required.
|
|
|
|
`-microedition`{: #microedition}
|
|
: Specifies that the processed class files are targeted at Java Micro
|
|
Edition. The preverifier will then add the appropriate StackMap attributes,
|
|
which are different from the default StackMapTable attributes for Java
|
|
Standard Edition. For example, you will need this option if you are
|
|
[processing midlets](examples.md#midlets).
|
|
|
|
`-android`{: #android}
|
|
: Specifies that the processed class files are targeted at the Android
|
|
platform. ProGuard then makes sure some features are compatible with
|
|
Android.
|
|
|
|
## General Options {: #generaloptions}
|
|
|
|
`-verbose`{: #verbose}
|
|
: Specifies to write out some more information during processing. If the
|
|
program terminates with an exception, this option will print out the entire
|
|
stack trace, instead of just the exception message.
|
|
|
|
`-dontnote`{: #dontnote} \[*[class\_filter](#filters)*\]
|
|
: Specifies not to print notes about potential mistakes or omissions in the
|
|
configuration, such as typos in class names or missing options that might be
|
|
useful. The optional filter is a regular expression; ProGuard doesn't print
|
|
notes about classes with matching names.
|
|
|
|
`-dontwarn`{: #dontwarn} \[*[class\_filter](#filters)*\]
|
|
: Specifies not to warn about unresolved references and other important
|
|
problems at all. The optional filter is a regular expression; ProGuard
|
|
doesn't print warnings about classes with matching names. Ignoring warnings
|
|
can be dangerous. For instance, if the unresolved classes or class members
|
|
are indeed required for processing, the processed code will not function
|
|
properly. *Only use this option if you know what you're doing!*
|
|
|
|
`-ignorewarnings`{: #ignorewarnings}
|
|
: Specifies to print any warnings about unresolved references and other
|
|
important problems, but to continue processing in any case. Ignoring
|
|
warnings can be dangerous. For instance, if the unresolved classes or class
|
|
members are indeed required for processing, the processed code will not
|
|
function properly. *Only use this option if you know what you're doing!*
|
|
|
|
`-printconfiguration`{: #printconfiguration} \[[*filename*](#filename)\]
|
|
: Specifies to write out the entire configuration that has been parsed, with
|
|
included files and replaced variables. The structure is printed to the
|
|
standard output or to the given file. This can sometimes be useful to
|
|
debug configurations, or to convert XML configurations into a more
|
|
readable format.
|
|
|
|
`-dump`{: #dump} \[[*filename*](#filename)\]
|
|
: Specifies to write out the internal structure of the class files, after
|
|
any processing. The structure is printed to the standard output or to the
|
|
given file. For example, you may want to [write out the contents of a given
|
|
jar file](examples.md#structure), without processing it at all.
|
|
|
|
`-addconfigurationdebugging`{: #addconfigurationdebugging}
|
|
: Specifies to instrument the processed code with debugging statements that
|
|
print out suggestions for missing ProGuard configuration. This can be very
|
|
useful to get practical hints _at run-time_, if your processed code crashes
|
|
because it still lacks some configuration for reflection. For example, the
|
|
code may be [serializing classes with the GSON library](examples.md#gson)
|
|
and you may need some configuration for it. You can generally just
|
|
copy/paste the suggestions from the console into your configuration file.
|
|
*Counter-indication:* do not use this option in release versions, as it adds
|
|
obfuscation information to the processed code.
|
|
|
|
## Class Paths {: #classpath}
|
|
|
|
ProGuard accepts a generalization of class paths to specify input files
|
|
and output files. A class path consists of entries, separated by the
|
|
traditional path separator (e.g. '**:**' on Unix, or '**;**' on Windows
|
|
platforms). The order of the entries determines their priorities, in
|
|
case of duplicates.
|
|
|
|
Each input entry can be:
|
|
|
|
- A class file or resource file,
|
|
- An apk file, containing any of the above,
|
|
- A jar file, containing any of the above,
|
|
- An aar file, containing any of the above,
|
|
- A war file, containing any of the above,
|
|
- An ear file, containing any of the above,
|
|
- A jmod file, containing any of the above,
|
|
- A zip file, containing any of the above,
|
|
- A directory (structure), containing any of the above.
|
|
|
|
The paths of directly specified class files and resource files is
|
|
ignored, so class files should generally be part of a jar file, an aar
|
|
file, a war file, an ear file, a zip file, or a directory. In addition,
|
|
the paths of class files should not have any additional directory
|
|
prefixes inside the archives or directories.
|
|
|
|
Each output entry can be:
|
|
|
|
- An apk file, in which all class files and resource files will
|
|
be collected.
|
|
- A jar file, in which any and all of the above will be collected,
|
|
- An aar file, in which any and all of the above will be collected,
|
|
- A war file, in which any and all of the above will be collected,
|
|
- An ear file, in which any and all of the above will be collected,
|
|
- A jmod file, in which any and all of the above will be collected,
|
|
- A zip file, in which any and all of the above will be collected,
|
|
- A directory, in which any and all of the above will be collected.
|
|
|
|
When writing output entries, ProGuard generally packages the results
|
|
in a sensible way, reconstructing the input entries as much as required.
|
|
Writing everything to an output directory is the most straightforward
|
|
option: the output directory will contain a complete reconstruction of
|
|
the input entries. The packaging can be almost arbitrarily complex
|
|
though: you could process an entire application, packaged in a zip file
|
|
along with its documentation, writing it out as a zip file again. The
|
|
Examples section shows a few ways to [restructure output
|
|
archives](examples.md#restructuring).
|
|
|
|
Files and directories can be specified as discussed in the section on
|
|
[file names](#filename) below.
|
|
|
|
In addition, ProGuard provides the possibility to filter the class path
|
|
entries and their contents, based on their full relative file names.
|
|
Each class path entry can be followed by up to 8 types of [file
|
|
filters](#filefilters) between parentheses, separated by semi-colons:
|
|
|
|
- A filter for all jmod names that are encountered,
|
|
- A filter for all aar names that are encountered,
|
|
- A filter for all apk names that are encountered,
|
|
- A filter for all zip names that are encountered,
|
|
- A filter for all ear names that are encountered,
|
|
- A filter for all war names that are encountered,
|
|
- A filter for all jar names that are encountered,
|
|
- A filter for all class file names and resource file names that
|
|
are encountered.
|
|
|
|
If fewer than 8 filters are specified, they are assumed to be the latter
|
|
filters. Any empty filters are ignored. More formally, a filtered class
|
|
path entry looks like this:
|
|
|
|
classpathentry([[[[[[[jmodfilter;]aarfilter;]apkfilter;]zipfilter;]earfilter;]warfilter;]jarfilter;]filefilter)
|
|
|
|
Square brackets "\[\]" mean that their contents are optional.
|
|
|
|
For example, "`rt.jar(java/**.class,javax/**.class)`" matches all class
|
|
files in the `java` and `javax` directories inside the `rt` jar.
|
|
|
|
For example, "`input.jar(!**.gif,images/**)`" matches all files in the
|
|
`images` directory inside the `input` jar, except gif files.
|
|
|
|
The different filters are applied to all corresponding file types,
|
|
irrespective of their nesting levels in the input; they are orthogonal.
|
|
|
|
For example, "`input.war(lib/**.jar,support/**.jar;**.class,**.gif)`"
|
|
only considers jar files in the `lib` and `support` directories in the
|
|
`input` war, not any other jar files. It then matches all class files
|
|
and gif files that are encountered.
|
|
|
|
The filters allow for an almost infinite number of packaging and
|
|
repackaging possibilities. The Examples section provides a few more
|
|
examples for [filtering input and output](examples.md#filtering).
|
|
|
|
## File Names {: #filename}
|
|
|
|
ProGuard accepts absolute paths and relative paths for the various file
|
|
names and directory names. A relative path is interpreted as follows:
|
|
|
|
- relative to the base directory, if set, or otherwise
|
|
- relative to the configuration file in which it is specified, if any,
|
|
or otherwise
|
|
- relative to the working directory.
|
|
|
|
The names can contain Java system properties (or Ant properties, when
|
|
using Ant), delimited by angular brackets, '**<**' and '**>**'.
|
|
The properties are automatically replaced by their corresponding values.
|
|
|
|
For example, `<java.home>/lib/rt.jar` is automatically expanded to
|
|
something like `/usr/local/java/jdk/jre/lib/rt.jar`. Similarly,
|
|
`<user.home>` is expanded to the user's home directory, and `<user.dir>`
|
|
is expanded to the current working directory.
|
|
|
|
Names with special characters like spaces and parentheses must be quoted
|
|
with single or double quotes. Each file name in a list of names has to
|
|
be quoted individually. Note that the quotes themselves may need to be
|
|
escaped when used on the command line, to avoid them being gobbled by
|
|
the shell.
|
|
|
|
For example, on the command line, you could use an option like
|
|
`'-injars "my program.jar":"/your directory/your program.jar"'`.
|
|
|
|
## File Filters {: #filefilters}
|
|
|
|
Like general [filters](#filters), a file filter is a comma-separated
|
|
list of file names that can contain wildcards. Only files with matching
|
|
file names are read (in the case of input jars), or written (in the case
|
|
of output jars). The following wildcards are supported:
|
|
|
|
| Wildcard | Meaning
|
|
|------|-----------------------------------------------------------------------------------------
|
|
| `?` | matches any single character in a file name.
|
|
| `*` | matches any part of a filename not containing the directory separator.
|
|
| `**` | matches any part of a filename, possibly containing any number of directory separators.
|
|
|
|
For example, "`java/**.class,javax/**.class`" matches all class files in
|
|
the `java` and `javax`.
|
|
|
|
Furthermore, a file name can be preceded by an exclamation mark '**!**'
|
|
to *exclude* the file name from further attempts to match with
|
|
*subsequent* file names.
|
|
|
|
For example, "`!**.gif,images/**`" matches all files in the `images`
|
|
directory, except gif files.
|
|
|
|
The Examples section provides a few more examples for [filtering input
|
|
and output](examples.md#filtering).
|
|
|
|
## Filters {: #filters}
|
|
|
|
ProGuard offers options with filters for many different aspects of the
|
|
configuration: names of files, directories, classes, packages,
|
|
attributes, optimizations, etc.
|
|
|
|
A filter is a list of comma-separated names that can contain wildcards.
|
|
Only names that match an item on the list pass the filter. The supported
|
|
wildcards depend on the type of names for which the filter is being
|
|
used, but the following wildcards are typical:
|
|
|
|
| Wildcard | Meaning
|
|
|------|-----------------------------------------------------------------------------------------------------------
|
|
| `?` | matches any single character in a name.
|
|
| `*` | matches any part of a name not containing the package separator or directory separator.
|
|
| `**` | matches any part of a name, possibly containing any number of package separators or directory separators.
|
|
|
|
For example, "`foo,*bar`" matches the name `foo` and all names ending
|
|
with `bar`.
|
|
|
|
Furthermore, a name can be preceded by a negating exclamation mark
|
|
'**!**' to *exclude* the name from further attempts to match with
|
|
*subsequent* names. So, if a name matches an item in the filter, it is
|
|
accepted or rejected right away, depending on whether the item has a
|
|
negator. If the name doesn't match the item, it is tested against the
|
|
next item, and so on. It if doesn't match any items, it is accepted or
|
|
rejected, depending on the whether the last item has a negator or not.
|
|
|
|
For example, "`!foobar,*bar`" matches all names ending with `bar`,
|
|
except `foobar`.
|
|
|
|
## Overview of `Keep` Options {: #keepoverview}
|
|
|
|
The various [`-keep`](usage.md#keep) options for shrinking and obfuscation 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 being removed or renamed | From being renamed
|
|
|-----------------------------------------------------|------------------------------------------------------|--------------------------------------------------------------
|
|
| Classes and class members | [`-keep`](#keep) | [`-keepnames`](#keepnames)
|
|
| Class members only | [`-keepclassmembers`](#keepclassmembers) | [`-keepclassmembernames`](#keepclassmembernames)
|
|
| Classes and class members, if class members present | [`-keepclasseswithmembers`](#keepclasseswithmembers) | [`-keepclasseswithmembernames`](#keepclasseswithmembernames)
|
|
|
|
Each of these [`-keep`](usage.md#keep) options is of course followed by a
|
|
[specification](#classspecification) of the classes and class members
|
|
(fields and methods) to which it should be applied.
|
|
|
|
If you're not sure which option you need, you should probably simply use
|
|
`-keep`. It will make sure the specified classes and class members are
|
|
not removed in the shrinking step, and not renamed in the obfuscation
|
|
step.
|
|
|
|
!!! warning ""
|
|
- If you specify a class, without class members, ProGuard only
|
|
preserves the class and its parameterless constructor as
|
|
entry points. It may still remove, optimize, or obfuscate its other
|
|
class members.
|
|
- If you specify a method, ProGuard only preserves the method as an
|
|
entry point. Its code may still be optimized and adapted.
|
|
|
|
## Keep Option Modifiers {: #keepoptionmodifiers}
|
|
|
|
`includedescriptorclasses`
|
|
: Specifies that any classes in the type descriptors of the methods and
|
|
fields that the [-keep](#keep) option keeps should be kept as well. This is
|
|
typically useful when [keeping native method names](examples.md#native), to
|
|
make sure that the parameter types of native methods aren't renamed either.
|
|
Their signatures then remain completely unchanged and compatible with the
|
|
native libraries.
|
|
|
|
`includecode`
|
|
: Specifies that code attributes of the methods that the [-keep](#keep)
|
|
option keeps should be kept as well, i.e. may not be optimized or obfuscated.
|
|
This is typically useful for already optimized or obfuscated classes,
|
|
to make sure that their code is not modified during optimization.
|
|
|
|
`allowshrinking`
|
|
: Specifies that the entry points specified in the [-keep](#keep) option may
|
|
be shrunk, even if they have to be preserved otherwise. That is, the entry
|
|
points may be removed in the shrinking step, but if they are necessary after
|
|
all, they may not be optimized or obfuscated.
|
|
|
|
`allowoptimization`
|
|
: Specifies that the entry points specified in the [-keep](#keep) option may
|
|
be optimized, even if they have to be preserved otherwise. That is, the
|
|
entry points may be altered in the optimization step, but they may not be
|
|
removed or obfuscated. This modifier is only useful for achieving unusual
|
|
requirements.
|
|
|
|
`allowobfuscation`
|
|
: Specifies that the entry points specified in the [-keep](#keep) option may
|
|
be obfuscated, even if they have to be preserved otherwise. That is, the
|
|
entry points may be renamed in the obfuscation step, but they may not be
|
|
removed or optimized. This modifier is only useful for achieving unusual
|
|
requirements.
|
|
|
|
## Class Specifications {: #classspecification}
|
|
|
|
A class specification is a template of classes and class members (fields
|
|
and methods). It is used in the various [`-keep`](usage.md#keep) options and in the
|
|
`-assumenosideeffects` option. 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](examples.md), but this is an attempt at a complete
|
|
formal definition:
|
|
|
|
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
|
|
[extends|implements [@annotationtype] classname]
|
|
[{
|
|
[@annotationtype]
|
|
[[!]public|private|protected|static|volatile|transient ...]
|
|
<fields> | (fieldtype fieldname [= values]);
|
|
|
|
[@annotationtype]
|
|
[[!]public|private|protected|static|synchronized|native|abstract|strictfp ...]
|
|
<methods> | <init>(argumenttype,...) | classname(argumenttype,...) | (returntype methodname(argumenttype,...) [return values]);
|
|
}]
|
|
|
|
Square brackets "\[\]" mean that their contents are optional. Ellipsis
|
|
dots "..." mean that any number of the preceding items may be specified.
|
|
A vertical bar "|" delimits two 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.
|
|
|
|
- The `class` keyword refers to any interface or class. The
|
|
`interface` keyword restricts matches to interface classes. The
|
|
`enum` keyword restricts matches to enumeration classes. Preceding
|
|
the `interface` or `enum` keywords by a `!` restricts matches to
|
|
classes that are not interfaces or enumerations, respectively.
|
|
|
|
- Every *classname* must be fully qualified, e.g. `java.lang.String`.
|
|
Inner classes are separated by a dollar sign "`$`", e.g.
|
|
`java.lang.Thread$State`. Class names may be specified as regular
|
|
expressions containing the following wildcards:
|
|
|
|
| Wildcard | Meaning
|
|
|-------|-----------
|
|
| `?` | matches any single character in a class name, but not the package separator. For example, "`com.example.Test?`" matches "`com.example.Test1`" and "`com.example.Test2`", but not "`com.example.Test12`".
|
|
| `*` | matches any part of a class name not containing the package separator. For example, "`com.example.*Test*`" matches "`com.example.Test`" and "`com.example.YourTestApplication`", but not "`com.example.mysubpackage.MyTest`". Or, more generally, "`com.example.*`" matches all classes in "`com.example`", but not in its subpackages.
|
|
| `**` | matches any part of a class name, possibly containing any number of package separators. For example, "`**.Test`" matches all `Test` classes in all packages except the root package. Or, "`com.example.**`" matches all classes in "`com.example`" and in its subpackages.
|
|
| `<n>` | matches the _n_'th matched wildcard in the same option. For example, "`com.example.*Foo<1>`" matches "`com.example.BarFooBar`".
|
|
|
|
For additional flexibility, class names can actually be
|
|
comma-separated lists of class names, with optional `!` negators,
|
|
just like file name filters. This notation doesn't look very
|
|
Java-like, so it should be used with moderation.
|
|
For convenience and for backward compatibility, the class name `*`
|
|
refers to any class, irrespective of its package, when used on its own (e.g. `-keep class *`).
|
|
|
|
- The `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 (directly or indirectly) qualify. The given class itself is not
|
|
included in this set. If required, it should be specified in a separate
|
|
option.
|
|
|
|
- The `@` specifications can be used to restrict classes and class
|
|
members to the ones that are annotated with the specified
|
|
annotation types. An *annotationtype* is specified just like a
|
|
*classname*.
|
|
|
|
- Fields and methods are specified much like in Java, except that
|
|
method argument lists don't contain argument names (just like in
|
|
other tools like `javadoc` and `javap`). The specifications can also
|
|
contain the following catch-all wildcards:
|
|
|
|
| Wildcard | Meaning
|
|
|-------------|------------------------------
|
|
| `<init>` | matches any constructor.
|
|
| `<fields>` | matches any field.
|
|
| `<methods>` | matches any method.
|
|
| `*` | matches any field or method.
|
|
|
|
Note that the above wildcards don't have return types. Only the
|
|
`<init>` wildcard has an argument list.
|
|
|
|
Fields and methods may also be specified using regular expressions.
|
|
Names can contain the following wildcards:
|
|
|
|
| Wildcard | Meaning
|
|
|-------|-----------------------------------------------------------------
|
|
| `?` | matches any single character in a method name.
|
|
| `*` | matches any part of a method name.
|
|
| `<n>` | matches the _n_'th matched wildcard in the same option.
|
|
|
|
Types in descriptors can contain the following wildcards:
|
|
|
|
| Wildcard | Meaning
|
|
|-------|-----------------------------------------------------------------------------------------
|
|
| `%` | matches any primitive type ("`boolean`", "`int`", etc) or "`void`" type.
|
|
| `?` | matches any single character in a class name.
|
|
| `*` | matches any part of a class name not containing the package separator.
|
|
| `**` | matches any part of a class name, possibly containing any number of package separators.
|
|
| `***` | matches any type (primitive or non-primitive, array or non-array).
|
|
| `...` | matches any number of arguments of any type.
|
|
| `<n>` | matches the _n_'th matched wildcard in the same option.
|
|
|
|
Note that the `?`, `*`, and `**` wildcards will never match
|
|
primitive types. Furthermore, only the `***` wildcards will match
|
|
array types of any dimension. For example, "`** get*()`" matches
|
|
"`java.lang.Object getObject()`", but not "`float getFloat()`",
|
|
nor "`java.lang.Object[] getObjects()`".
|
|
|
|
- Constructors can also be specified using their short class names
|
|
(without package) or using their full class names. As in the Java
|
|
language, the constructor specification has an argument list, but no
|
|
return type.
|
|
|
|
- The class access modifiers and class member access modifiers are
|
|
typically used to restrict wildcarded classes and class members.
|
|
They specify that the corresponding access flags have to be set for
|
|
the member to match. A preceding `!` 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`).
|
|
|
|
ProGuard supports the additional modifiers `synthetic`, `bridge`,
|
|
and `varargs`, which may be set by compilers.
|
|
|
|
- With the option [`-assumevalues`](#assumevalues), fields and methods
|
|
with primitive return types can have *values* or *ranges of values*.
|
|
The assignment keyword is `=` or `return`, interchangeably. For
|
|
example, "`boolean flag = true;`" or "`int method() return 5;`".
|
|
Ranges of values are separated by `..`, for example,
|
|
"`int f = 100..200;`". A range includes its begin value and
|
|
end value.
|