## Examples

Some typical useful configurations:

1. A typical application
2. A typical applet
3. A typical midlet
4. A typical Java Card applet
5. A typical xlet
6. A typical Android application
7. A typical library
8. All possible applications in the input jars
9. All possible applets in the input jars
10. All possible midlets in the input jars
11. All possible Java Card applets in the input jars
12. All possible xlets in the input jars
13. All possible Android applications in the input jars
14. All possible servlets in the input jars
15. Processing native methods
16. Processing callback methods
17. Processing enumeration classes
18. Processing serializable classes
19. Processing bean classes
20. Processing annotations
21. Processing database drivers
22. Processing ComponentUI classes
23. Processing RMI code
24. Processing resource files
25. Processing manifest files
26. Producing useful obfuscated stack traces
27. Obfuscating package names
28. Restructuring the output archives
29. Filtering the input and the output
30. Processing multiple applications at once
31. Incremental obfuscation
32. Preverifying class files for Java Micro Edition
33. Upgrading class files to Java 6
34. Finding dead code
35. Printing out the internal structure of class files
36. Using annotations to configure ProGuard

You can find some sample configuration files in the `examples` directory of the ProGuard distribution.

### A typical application

To shrink, optimize, and obfuscate the ProGuard application itself, one would typically create a configuration file `proguard.pro` and then type:

    java -jar proguard.jar @proguard.pro

The configuration file would contain the following options:

    -injars       proguard.jar
    -outjars      proguard_out.jar
    -libraryjars  <java.home>/lib/rt.jar
    -printmapping proguard.map

    -keep public class proguard.ProGuard {
        public static void main(java.lang.String[]);
    }

Note the use of the `<java.home>` system property; it is replaced automatically.

Also note that all type names are fully specified: `proguard.ProGuard` and `java.lang.String[]`.

The access modifiers `public` and `static` are not really required in this case, since we know a priori that the specified class and method have the proper access flags. It just looks more familiar this way.

We're writing out an obfuscation mapping file with `-printmapping`, for de-obfuscating any stack traces later on, or for incremental obfuscation of extensions.

We can further improve the results with a few additional options:

    -optimizationpasses 3
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification

These options are not required; they just shave off some extra bytes from the output jar, by performing up to 3 optimization passes, and by aggressively obfuscating class members and package names.

In general, you might need a few additional options for processing native methods, callback methods, enumerations, serializable classes, bean classes, annotations, and resource files. For processing 'simple' applications like ProGuard, that is not required.

### A typical applet

These options shrink, optimize, and obfuscate the applet `mypackage.MyApplet`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars <java.home>/lib/rt.jar

    -keep public class mypackage.MyApplet

The typical applet methods will be preserved automatically, since `mypackage.MyApplet` is an extension of the `Applet` class in the library `rt.jar`.

If applicable, you should add options for processing native methods, callback methods, enumerations, serializable classes, bean classes, annotations, and resource files.

### A typical midlet

These options shrink, optimize, obfuscate, and preverify the midlet `mypackage.MyMIDlet`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
    -libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification
    -microedition

    -keep public class mypackage.MyMIDlet

Note how we're now targeting the Java Micro Edition run-time environment of `midpapi20.jar` and `cldcapi11.jar`, instead of the Java Standard Edition run-time environment `rt.jar`. You can target other JME environments by picking the appropriate jars.

The typical midlet methods will be preserved automatically, since `mypackage.MyMIDlet` is an extension of the `MIDlet` class in the library `midpapi20.jar`.

The `-microedition` option makes sure the class files are preverified for Java Micro Edition, producing compact `StackMap` attributes. It is no longer necessary to run an external preverifier.

Be careful if you do use the external `preverify` tool on a platform with a case-insensitive filing system, such as Windows. Because this tool unpacks your processed jars, you should then use ProGuard's `-dontusemixedcaseclassnames` option.

If applicable, you should add options for processing native methods and resource files.

Note that you will still have to adapt the midlet jar size in the corresponding jad file; ProGuard doesn't do that for you.

### A typical Java Card applet

These options shrink, optimize, and obfuscate the Java Card applet `mypackage.MyApplet`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/javacard2.2.2/lib/api.jar
    -dontwarn    java.lang.Class
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification

    -keep public class mypackage.MyApplet

The configuration is very similar to the configuration for midlets, except that it now targets the Java Card run-time environment. This environment doesn't have java.lang.Class, so we're telling ProGuard not to worry about it.

### A typical xlet

These options shrink, optimize, and obfuscate the xlet `mypackage.MyXlet`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/jtv1.1/javatv.jar
    -libraryjars /usr/local/java/cdc1.1/lib/cdc.jar
    -libraryjars /usr/local/java/cdc1.1/lib/btclasses.zip
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification

    -keep public class mypackage.MyXlet

The configuration is very similar to the configuration for midlets, except that it now targets the CDC run-time environment with the Java TV API.

### A typical Android application

These options shrink, optimize, and obfuscate the simple Android application based on a single activity `mypackage.MyActivity`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/android-1.5_r1/platforms/android-1.5/android.jar
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification
    -optimizations !code/simplification/arithmetic

    -keep public class mypackage.MyActivity

    -keep public class * extends View {
        public <init>(android.content.Context);
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
        public void set*(...);
    }

The configuration is very similar to the configuration for midlets, except that it now targets the Android run-time environment.

The `-optimizations` option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle.

We're also keeping any custom `View` extensions and their typical constructors and setters, since they might be referenced from XML layout files.

If applicable, you should add options for processing native methods, callback methods, annotations, and resource files.

### A typical library

These options shrink, optimize, and obfuscate an entire library, keeping all public and protected classes and class members, native method names, and serialization code:

    -injars       in.jar
    -outjars      out.jar
    -libraryjars  <java.home>/lib/rt.jar
    -printmapping out.map

    -keepparameternames
    -renamesourcefileattribute SourceFile
    -keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                    SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

    -keep public class * {
        public protected *;
    }

    -keepclassmembernames class * {
        java.lang.Class class$(java.lang.String);
        java.lang.Class class$(java.lang.String, boolean);
    }

    -keepclasseswithmembernames class * {
        native <methods>;
    }

    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }

    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }

This configuration should preserve everything we'll ever want to access in the library. Only if there are any other non-public classes or methods that are invoked dynamically, they should be specified using additional `-keep` options.

The `-keepclassmembernames` option for the `class$` methods is not strictly necessary. These methods are inserted by the `javac` compiler and the `jikes` compiler respectively, to implement the `.class` construct. ProGuard will automatically detect them and deal with them, even when their names have been obfuscated. However, older versions of ProGuard and other obfuscators may rely on the original method names. It may therefore be helpful to preserve them, in case these other obfuscators are ever used for further obfuscation of the library.

The "Exceptions" attribute has to be preserved, so the compiler knows which exceptions methods may throw.

The "InnerClasses" attribute (or more precisely, its source name part) has to be preserved too, for any inner classes that can be referenced from outside the library. The `javac` compiler would be unable to find the inner classes otherwise.

The "Signature" attribute is required to be able to access generic types when compiling in JDK 5.0 and higher.

The `-keepparameternames` option keeps the parameter names in the "LocalVariableTable" and "LocalVariableTypeTable" attributes of public library methods. Some IDEs can present these names to the developers who use the library.

Finally, we're keeping the "Deprecated" attribute and the attributes for producing useful stack traces.

We've also added some options for for processing native methods, enumerations, serializable classes, and annotations, which are all discussed in their respective examples.

### All possible applications in the input jars

These options shrink, optimize, and obfuscate all public applications in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars <java.home>/lib/rt.jar
    -printseeds

    -keepclasseswithmembers public class * {
        public static void main(java.lang.String[]);
    }

Note the use of `-keepclasseswithmembers`. We don't want to preserve all classes, just all classes that have main methods, and those methods.

The `-printseeds` option prints out which classes exactly will be preserved, so we know for sure we're getting what we want.

If applicable, you should add options for processing native methods, callback methods, enumerations, serializable classes, bean classes, annotations, and resource files.

### All possible applets in the input jars

These options shrink, optimize, and obfuscate all public applets in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars <java.home>/lib/rt.jar
    -printseeds

    -keep public class * extends java.applet.Applet

We're simply keeping all classes that extend the `Applet` class.

Again, the `-printseeds` option prints out which applets exactly will be preserved.

If applicable, you should add options for processing native methods, callback methods, enumerations, serializable classes, bean classes, annotations, and resource files.

### All possible midlets in the input jars

These options shrink, optimize, obfuscate, and preverify all public midlets in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
    -libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification
    -microedition
    -printseeds

    -keep public class * extends javax.microedition.midlet.MIDlet

We're simply keeping all classes that extend the `MIDlet` class.

The `-microedition` option makes sure the class files are preverified for Java Micro Edition, producing compact `StackMap` attributes. It is no longer necessary to run an external preverifier.

Be careful if you do use the external `preverify` tool on a platform with a case-insensitive filing system, such as Windows. Because this tool unpacks your processed jars, you should then use ProGuard's `-dontusemixedcaseclassnames` option.

The `-printseeds` option prints out which midlets exactly will be preserved.

If applicable, you should add options for processing native methods and resource files.

Note that you will still have to adapt the midlet jar size in the corresponding jad file; ProGuard doesn't do that for you.

### All possible Java Card applets in the input jars

These options shrink, optimize, and obfuscate all public Java Card applets in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/javacard2.2.2/lib/api.jar
    -dontwarn    java.lang.Class
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification
    -printseeds

    -keep public class * implements javacard.framework.Applet

We're simply keeping all classes that implement the `Applet` interface.

The `-printseeds` option prints out which applets exactly will be preserved.

### All possible xlets in the input jars

These options shrink, optimize, and obfuscate all public xlets in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/jtv1.1/javatv.jar
    -libraryjars /usr/local/java/cdc1.1/lib/cdc.jar
    -libraryjars /usr/local/java/cdc1.1/lib/btclasses.zip
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification
    -printseeds

    -keep public class * implements javax.tv.xlet.Xlet

We're simply keeping all classes that implement the `Xlet` interface.

The `-printseeds` option prints out which xlets exactly will be preserved.

### All possible Android applications in the input jars

These options shrink, optimize, and obfuscate all public activities, services, broadcast receivers, and content providers in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/android-1.5_r1/platforms/android-1.5/android.jar
    -overloadaggressively
    -repackageclasses ''
    -allowaccessmodification
    -optimizations !code/simplification/arithmetic
    -printseeds

    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.app.Service
    -keep public class * extends android.content.BroadcastReceiver
    -keep public class * extends android.content.ContentProvider

    -keep public class * extends View {
        public <init>(android.content.Context);
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
        public void set*(...);
    }

We're keeping all classes that extend the base classes that may be referenced by the `AndroidManifest.xml` file of the application.

We're also keeping any custom `View` extensions and their typical constructors and setters, since they might be referenced from XML layout files.

The `-printseeds` option prints out which implementations exactly will be preserved.

If applicable, you should add options for processing native methods, callback methods, annotations, and resource files.

### All possible servlets in the input jars

These options shrink, optimize, and obfuscate all public servlets in `in.jar`:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars <java.home>/lib/rt.jar
    -libraryjars /usr/local/java/servlet/servlet.jar
    -printseeds

    -keep public class * implements javax.servlet.Servlet

Keeping all servlets is very similar to keeping all applets. The servlet API is not part of the standard run-time jar, so we're specifying it as a library. Don't forget to use the right path name.

We're then keeping all classes that implement the `Servlet` interface. We're using the `implements` keyword because it looks more familiar in this context, but it is equivalent to `extends`, as far as ProGuard is concerned.

The `-printseeds` option prints out which servlets exactly will be preserved.

If applicable, you should add options for processing native methods, callback methods, enumerations, serializable classes, bean classes, annotations, and resource files.

### Processing native methods

If your application, applet, servlet, library, etc., contains native methods, you'll want to preserve their names and their classes' names, so they can still be linked to the native library. The following additional option will ensure that:

    -keepclasseswithmembernames class * {
        native <methods>;
    }

Note the use of `-keepclasseswithmembernames`. We don't want to preserve all classes or all native methods; we just want to keep the relevant names from being obfuscated.

ProGuard doesn't look at your native code, so it won't automatically preserve the classes or class members that are invoked by the native code. These are entry points, which you'll have to specify explicitly. Callback methods are discussed below as a typical example.

### Processing callback methods

If your application, applet, servlet, library, etc., contains callback methods, which are called from external code (native code, scripts,...), you'll want to preserve them, and probably their classes too. They are just entry points to your code, much like, say, the main method of an application. If they aren't preserved by other `-keep` options, something like the following option will keep the callback class and method:

    -keep class mypackage.MyCallbackClass {
        void myCallbackMethod(java.lang.String);
    }

This will preserve the given class and method from being removed or renamed.

### Processing enumeration classes

If your application, applet, servlet, library, etc., contains enumeration classes, you'll have to preserve some special methods. Enumerations were introduced in Java 5. The java compiler translates enumerations into classes with a special structure. Notably, the classes contain implementations of some static methods that the run-time environment accesses by introspection (Isn't that just grand? Introspection is the self-modifying code of a new generation). You have to specify these explicitly, to make sure they aren't removed or obfuscated:

    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }

### Processing serializable classes

More complex applications, applets, servlets, libraries, etc., may contain classes that are serialized. Depending on the way in which they are used, they may require special attention:

- Often, serialization is simply a means of transporting data, without long-term storage. Classes that are shrunk and obfuscated should then continue to function fine with the following additional options:

      -keepclassmembers class * implements java.io.Serializable {
          private static final java.io.ObjectStreamField[] serialPersistentFields;
          private void writeObject(java.io.ObjectOutputStream);
          private void readObject(java.io.ObjectInputStream);
          java.lang.Object writeReplace();
          java.lang.Object readResolve();
      }

  The `-keepclassmembers` option makes sure that any serialization methods are kept. By using this option instead of the basic `-keep` option, we're not forcing preservation of all serializable classes, just preservation of the listed members of classes that are actually used.

- Sometimes, the serialized data are stored, and read back later into newer versions of the serializable classes. One then has to take care the classes remain compatible with their unprocessed versions and with future processed versions. In such cases, the relevant classes will most likely have `serialVersionUID` fields. The following options should then be sufficient to ensure compatibility over time:

      -keepnames class * implements java.io.Serializable

      -keepclassmembers class * implements java.io.Serializable {
          static final long serialVersionUID;
          private static final java.io.ObjectStreamField[] serialPersistentFields;
          !static !transient <fields>;
          private void writeObject(java.io.ObjectOutputStream);
          private void readObject(java.io.ObjectInputStream);
          java.lang.Object writeReplace();
          java.lang.Object readResolve();
      }

  The `serialVersionUID` and `serialPersistentFields` lines makes sure those fields are preserved, if they are present. The `<fields>` line preserves all non-static, non-transient fields, with their original names. The introspection of the serialization process and the de-serialization process will then find consistent names.

- Occasionally, the serialized data have to remain compatible, but the classes involved lack `serialVersionUID` fields. I imagine the original code will then be hard to maintain, since the serial version UID is then computed from a list of features the serializable class. Changing the class ever so slightly may change the computed serial version UID. The list of features is specified in the section on Stream Unique Identifiers of Sun's Java Object Serialization Specification. The following directives should at least partially ensure compatibility with the original classes:

      -keepnames class * implements java.io.Serializable

      -keepclassmembers class * implements java.io.Serializable {
          static final long serialVersionUID;
          private static final java.io.ObjectStreamField[] serialPersistentFields;
          !static !transient <fields>;
          !private <fields>;
          !private <methods>;
          private void writeObject(java.io.ObjectOutputStream);
          private void readObject(java.io.ObjectInputStream);
          java.lang.Object writeReplace();
          java.lang.Object readResolve();
      }

  The new options force preservation of the elements involved in the UID computation. In addition, the user will have to manually specify all interfaces of the serializable classes (using something like "`-keep interface MyInterface`"), since these names are also used when computing the UID. A fast but sub-optimal alternative would be simply keeping all interfaces with "`-keep interface *`".

Note that the above options may preserve more classes and class members than strictly necessary. For instance, a large number of classes may implement the `Serialization` interface, yet only a small number may actually ever be serialized. Knowing your application and tuning the configuration often produces more compact results.

### Processing bean classes

If your application, applet, servlet, library, etc., makes extensive use of introspection on bean classes to find bean editor classes, or getter and setter methods, then configuration may become painful. There's not much else you can do than making sure the bean class names, or the getter and setter names don't change. For instance:

    -keep public class mypackage.MyBean {
        public void setMyProperty(int);
        public int getMyProperty();
    }

    -keep public class mypackage.MyBeanEditor

If there are too many elements to list explicitly, wildcards in class names and method signatures might be helpful. This example should encompasses all possible setters and getters in classes in the package `mybeans`:

    -keep class mybeans.** {
        void set*(***);
        void set*(int, ***);

        boolean is*();
        boolean is*(int);

        *** get*();
        *** get*(int);
    }

The '`***`' wildcard matches any type (primitive or non-primitive, array or non-array). The methods with the '`int`' arguments matches properties that are lists.

### Processing annotations

If your application, applet, servlet, library, etc., uses annotations, you may want to preserve them in the processed output. Annotations are represented by attributes that have no direct effect on the execution of the code. However, their values can be retrieved through introspection, allowing developers to adapt the execution behavior accordingly. By default, ProGuard treats annotation attributes as optional, and removes them in the obfuscation step. If they are required, you'll have to specify this explicitly:

    -keepattributes *Annotation*

For brevity, we're specifying a wildcarded attribute name, which will match `RuntimeVisibleAnnotations`, `RuntimeInvisibleAnnotations`, `RuntimeVisibleParameterAnnotations`, `RuntimeInvisibleParameterAnnotations`, and `AnnotationDefault`. Depending on the purpose of the processed code, you could refine this selection, for instance not keeping the run-time invisible annotations (which are only used at compile-time).

Some code may make further use of introspection to figure out the enclosing methods of anonymous inner classes. In that case, the corresponding attribute has to be preserved as well:

    -keepattributes EnclosingMethod

### Processing database drivers

Database drivers are implementations of the `Driver` interface. Since they are often created dynamically, you may want to preserve any implementations that you are processing as entry points:

    -keep class * implements java.sql.Driver

This option also gets rid of the note that ProGuard prints out about `(java.sql.Driver)Class.forName` constructs, if you are instantiating a driver in your code (without necessarily implementing any drivers yourself).

### Processing ComponentUI classes

Swing UI look and feels are implemented as extensions of the `ComponentUI` class. For some reason, these have to contain a static method `createUI`, which the Swing API invokes using introspection. You should therefore always preserve the method as an entry point, for instance like this:

    -keep class * extends javax.swing.plaf.ComponentUI {
        public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
    }

This option also keeps the classes themselves.

### Processing RMI code

Reportedly, the easiest way to handle RMI code is to process the code with ProGuard first and then invoke the `rmic` tool. If that is not possible, you may want to try something like this:

    -keepattributes Exceptions

    -keep interface * extends java.rmi.Remote {
        <methods>;
    }

    -keep class * implements java.rmi.Remote {
        <init>(java.rmi.activation.ActivationID, java.rmi.MarshalledObject);
    }

The first `-keep` option keeps all your Remote interfaces and their methods. The second one keeps all the implementations, along with their particular RMI constructors, if any.

The `Exceptions` attribute has to be kept too, because the RMI handling code performs introspection to check whether the method signatures are compatible.

### Processing resource files

If your application, applet, servlet, library, etc., contains resource files, it may be necessary to adapt their names and/or their contents when the application is obfuscated. The following two options can achieve this automatically:

    -adaptresourcefilenames    **.properties,**.gif,**.jpg
    -adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF

The -adaptresourcefilenames option in this case renames properties files and image files in the processed output, based on the obfuscated names of their corresponding class files (if any). The -adaptresourcefilecontents option looks for class names in properties files and in the manifest file, and replaces these names by the obfuscated names (if any). You'll probably want to adapt the filters to suit your application.

### Processing manifest files

As illustrated in the previous section, manifest files can be treated like ordinary resource files. ProGuard can adapt obfuscated class names in the files, but it won't make any other changes. If you want anything else, you should apply an external tool. For instance, if a manifest file contains signing information, you should sign the jar again after it has been processed.

If you're merging several input jars into a single output jar, you'll have to pick one, typically by specifying filters:

    -injars  in1.jar
    -injars  in2.jar(!META-INF/MANIFEST.MF)
    -injars  in3.jar(!META-INF/MANIFEST.MF)
    -outjars out.jar

The filters will let ProGuard copy the manifest file from the first jar and ignore any manifest files in the second and third input jars. Note that ProGuard will leave the order of the files in the jars unchanged; manifest files are not necessarily put first.

### Producing useful obfuscated stack traces

These options let obfuscated applications or libraries produce stack traces that can still be deciphered later on:

    -printmapping out.map

    -renamesourcefileattribute SourceFile
    -keepattributes SourceFile,LineNumberTable

We're keeping all source file attributes, but we're replacing their values by the string "SourceFile". We could use any string. This string is already present in all class files, so it doesn't take up any extra space. If you're working with J++, you'll want to keep the "SourceDir" attribute as well.

We're also keeping the line number tables of all methods.

Whenever both of these attributes are present, the Java run-time environment will include line number information when printing out exception stack traces.

The information will only be useful if we can map the obfuscated names back to their original names, so we're saving the mapping to a file `out.map`. The information can then be used by the ReTrace tool to restore the original stack trace.

### Obfuscating package names

Package names can be obfuscated in various ways, with increasing levels of obfuscation and compactness. For example, consider the following classes:

    mycompany.myapplication.MyMain
    mycompany.myapplication.Foo
    mycompany.myapplication.Bar
    mycompany.myapplication.extra.FirstExtra
    mycompany.myapplication.extra.SecondExtra
    mycompany.util.FirstUtil
    mycompany.util.SecondUtil

Let's assume the class name `mycompany.myapplication.MyMain` is the main application class that is kept by the configuration. All other class names can be obfuscated.

By default, packages that contain classes that can't be renamed aren't renamed either, and the package hierarchy is preserved. This results in obfuscated class names like these:

    mycompany.myapplication.MyMain
    mycompany.myapplication.a
    mycompany.myapplication.b
    mycompany.myapplication.a.a
    mycompany.myapplication.a.b
    mycompany.a.a
    mycompany.a.b

The `-flattenpackagehierarchy` option obfuscates the package names further, by flattening the package hierarchy of obfuscated packages:

    -flattenpackagehierarchy 'myobfuscated'

The obfuscated class names then look as follows:

    mycompany.myapplication.MyMain
    mycompany.myapplication.a
    mycompany.myapplication.b
    myobfuscated.a.a
    myobfuscated.a.b
    myobfuscated.b.a
    myobfuscated.b.b

Alternatively, the `-repackageclasses` option obfuscates the entire packaging, by combining obfuscated classes into a single package:

    -repackageclasses 'myobfuscated'

The obfuscated class names then look as follows:

    mycompany.myapplication.MyMain
    mycompany.myapplication.a
    mycompany.myapplication.b
    myobfuscated.a
    myobfuscated.b
    myobfuscated.c
    myobfuscated.d

Additionally specifying the `-allowaccessmodification` option allows access permissions of classes and class members to be broadened, opening up the opportunity to repackage all obfuscated classes:

    -repackageclasses 'myobfuscated'
    -allowaccessmodification

The obfuscated class names then look as follows:

    mycompany.myapplication.MyMain
    myobfuscated.a
    myobfuscated.b
    myobfuscated.c
    myobfuscated.d
    myobfuscated.e
    myobfuscated.f

The specified target package can always be the root package. For instance:

    -repackageclasses ''
    -allowaccessmodification

The obfuscated class names are then the shortest possible names:

    mycompany.myapplication.MyMain
    a
    b
    c
    d
    e
    f

Note that not all levels of obfuscation of package names may be acceptable for all code. Notably, you may have to take into account that your application may contain resource files that have to be adapted.

### Restructuring the output archives

In simple applications, all output classes and resources files are merged into a single jar. For example:

    -injars  classes
    -injars  in1.jar
    -injars  in2.jar
    -injars  in3.jar
    -outjars out.jar

This configuration merges the processed versions of the files in the `classes` directory and the three jars into a single output jar `out.jar`.

If you want to preserve the structure of your input jars (and/or wars, ears, zips, or directories), you can specify an output directory (or a war, an ear, or a zip). For example:

    -injars  in1.jar
    -injars  in2.jar
    -injars  in3.jar
    -outjars out

The input jars will then be reconstructed in the directory `out`, with their original names.

You can also combine archives into higher level archives. For example:

    -injars  in1.jar
    -injars  in2.jar
    -injars  in3.jar
    -outjars out.war

The other way around, you can flatten the archives inside higher level archives into simple archives:

    -injars  in.war
    -outjars out.jar

This configuration puts the processed contents of all jars inside `in.war` (plus any other contents of `in.war`) into `out.jar`.

If you want to combine input jars (and/or wars, ears, zips, or directories) into output jars (and/or wars, ears, zips, or directories), you can group the `-injars` and `-outjars` options. For example:

    -injars base_in1.jar
    -injars base_in2.jar
    -injars base_in3.jar
    -outjars base_out.jar

    -injars  extra_in.jar
    -outjars extra_out.jar

This configuration puts the processed results of all `base_in*.jar` jars into `base_out.jar`, and the processed results of the `extra_in.jar` into `extra_out.jar`. Note that only the order of the options matters; the additional whitespace is just for clarity.

This grouping, archiving, and flattening can be arbitrarily complex. ProGuard always tries to package output archives in a sensible way, reconstructing the input entries as much as required.

### Filtering the input and the output

If you want even greater control, you can add filters to the input and the output, filtering out zips, ears, wars, jars, and/or ordinary files. For example, if you want to disregard certain files from an input jar:

    -injars  in.jar(!images/**)
    -outjars out.jar

This configuration removes any files in the `images` directory and its subdirectories.

Such filters can be convenient for avoiding warnings about duplicate files in the output. For example, only keeping the manifest file from a first input jar:

    -injars  in1.jar
    -injars  in2.jar(!META-INF/MANIFEST.MF)
    -injars  in3.jar(!META-INF/MANIFEST.MF)
    -outjars out.jar

Another useful application is speeding up the processing by ProGuard, by disregarding a large number of irrelevant classes in the runtime library jar:

    -libraryjars <java.home>/lib/rt.jar(java/**,javax/**)

The filter makes ProGuard disregard `com.sun.**` classes, for instance , which don't affect the processing of ordinary applications.

It is also possible to filter the jars (and/or wars, ears, zips) themselves, based on their names. For example:

    -injars  in(**/acme_*.jar;)
    -outjars out.jar

Note the semi-colon in the filter; the filter in front of it applies to jar names. In this case, only `acme_*.jar` jars are read from the directory `in` and its subdirectories. Filters for war names, ear names, and zip names can be prefixed with additional semi-colons. All types of filters can be combined. They are orthogonal.

On the other hand, you can also filter the output, in order to control what content goes where. For example:

    -injars  in.jar
    -outjars code_out.jar(**.class)
    -outjars resources_out.jar

This configuration splits the processed output, sending `**.class` files to `code_out.jar`, and all remaining files to `resources_out.jar`.

Again, the filtering can be arbitrarily complex, especially when combined with grouping input and output.

### Processing multiple applications at once

You can process several dependent or independent applications (or applets, midlets,...) in one go, in order to save time and effort. ProGuard's input and output handling offers various ways to keep the output nicely structured.

The easiest way is to specify your input jars (and/or wars, ears, zips, and directories) and a single output directory. ProGuard will then reconstruct the input in this directory, using the original jar names. For example, showing just the input and output options:

    -injars  application1.jar
    -injars  application2.jar
    -injars  application3.jar
    -outjars processed_applications

After processing, the directory `processed_applications` will contain processed versions of application jars, with their original names.

### Incremental obfuscation

After having processed an application, e.g. ProGuard itself, you can still incrementally add other pieces of code that depend on it, e.g. the ProGuard GUI:

    -injars       proguardgui.jar
    -outjars      proguardgui_out.jar
    -injars       proguard.jar
    -outjars      proguard_out.jar
    -libraryjars  <java.home>/lib/rt.jar
    -applymapping proguard.map

    -keep public class proguard.gui.ProGuardGUI {
        public static void main(java.lang.String[]);
    }

We're reading both unprocessed jars as input. Their processed contents will go to the respective output jars. The `-applymapping` option then makes sure the ProGuard part of the code gets the previously produced obfuscation mapping. The final application will consist of the obfuscated ProGuard jar and the additional obfuscated GUI jar.

The added code in this example is straightforward; it doesn't affect the original code. The `proguard_out.jar` will be identical to the one produced in the initial processing step. If you foresee adding more complex extensions to your code, you should specify the options `-useuniqueclassmembernames`, `-dontshrink`, and `-dontoptimize` in the original processing step. These options ensure that the obfuscated base jar will always remain usable without changes. You can then specify the base jar as a library jar:

    -injars       proguardgui.jar
    -outjars      proguardgui_out.jar
    -libraryjars  proguard.jar
    -libraryjars  <java.home>/lib/rt.jar
    -applymapping proguard.map

    -keep public class proguard.gui.ProGuardGUI {
        public static void main(java.lang.String[]);
    }

### Preverifying class files for Java Micro Edition

Even if you're not interested in shrinking, optimizing, and obfuscating your midlets, as shown in the midlets example, you can still use ProGuard to preverify the class files for Java Micro Edition. ProGuard produces slightly more compact results than the traditional external preverifier.

    -injars      in.jar
    -outjars     out.jar
    -libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
    -libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar

    -dontshrink
    -dontoptimize
    -dontobfuscate

    -microedition

We're not processing the input, just making sure the class files are preverified by targeting them at Java Micro Edition with the `-microedition` option. Note that we don't need any `-keep` options to specify entry points; all class files are simply preverified.

### Upgrading class files to Java 6

The following options upgrade class files to Java 6, by updating their internal version numbers and preverifying them. The class files can then be loaded more efficiently by the Java 6 Virtual Machine.

    -injars      in.jar
    -outjars     out.jar
    -libraryjars <java.home>/lib/rt.jar

    -dontshrink
    -dontoptimize
    -dontobfuscate

    -target 1.6

We're not processing the input, just retargeting the class files with the `-target` option. They will automatically be preverified for Java 6 as a result. Note that we don't need any `-keep` options to specify entry points; all class files are simply updated and preverified.

### Finding dead code

These options list unused classes, fields, and methods in the application `mypackage.MyApplication`:

    -injars      in.jar
    -libraryjars <java.home>/lib/rt.jar

    -dontoptimize
    -dontobfuscate
    -dontpreverify
    -printusage

    -keep public class mypackage.MyApplication {
        public static void main(java.lang.String[]);
    }

We're not specifying an output jar, just printing out some results. We're saving some processing time by skipping the other processing steps.

The java compiler inlines primitive constants and String constants (`static final` fields). ProGuard would therefore list such fields as not being used in the class files that it analyzes, even if they are used in the source files. We can add a `-keepclassmembers` option that keeps those fields a priori, in order to avoid having them listed:

    -keepclassmembers class * {
        static final %                *;
        static final java.lang.String *;
    }

### Printing out the internal structure of class files

These options print out the internal structure of all class files in the input jar:

    -injars in.jar

    -dontshrink
    -dontoptimize
    -dontobfuscate
    -dontpreverify

    -dump

Note how we don't need to specify the Java run-time jar, because we're not processing the input jar at all.

### Using annotations to configure ProGuard

The traditional ProGuard configuration allows to keep a clean separation between the code and the configuration for shrinking, optimization, and obfuscation. However, it is also possible to define specific annotations, and then annotate the code to configure the processing.

You can find a set of such predefined annotations in the directory `examples/annotations/lib` in the ProGuard distribution. The annotation classes are defined in `annotations.jar`. The corresponding ProGuard configuration (or meta-configuration, if you prefer) is specified in `annotations.pro`. With these files, you can start annotating your code. For instance, a java source file `Application.java` can be annotated as follows:

    @KeepApplication
    public class Application {
      ....
    }

The ProGuard configuration file for the application can then be simplified by leveraging off these annotations:

    -injars      in.jar
    -outjars     out.jar
    -libraryjars <java.home>/lib/rt.jar

    -include lib/annotations.pro

The annotations are effectively replacing the application-dependent `-keep` options. You may still wish to add traditional `-keep` options for processing native methods, enumerations, serializable classes, and annotations.

The directory `examples/annotations` contains more examples that illustrate some of the possibilities.