diff options
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/docs/manual/examples.html')
-rw-r--r-- | third_party/java/proguard/proguard5.3.3/docs/manual/examples.html | 1693 |
1 files changed, 1693 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/docs/manual/examples.html b/third_party/java/proguard/proguard5.3.3/docs/manual/examples.html new file mode 100644 index 0000000000..bb0b11a559 --- /dev/null +++ b/third_party/java/proguard/proguard5.3.3/docs/manual/examples.html @@ -0,0 +1,1693 @@ +<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> +<meta http-equiv="content-style-type" content="text/css"> +<link rel="stylesheet" type="text/css" href="style.css"> +<title>ProGuard Examples</title> +</head> +<body> + +<script type="text/javascript" language="JavaScript"> +<!-- +if (window.self==window.top) + document.write('<a class="largebutton" target="_top" href="../index.html#manual/examples.html">ProGuard index</a> <a class="largebutton" target="_top" href="http://www.guardsquare.com/dexguard">DexGuard</a> <a class="largebutton" target="_top" href="http://www.guardsquare.com/">GuardSquare</a> <a class="largebutton" target="other" href="http://sourceforge.net/projects/proguard/">Sourceforge</a>') +//--> +</script> +<noscript> +<a class="largebutton" target="_top" href="../index.html#manual/examples.html">ProGuard index</a> +<a class="largebutton" target="_top" href="http://www.guardsquare.com/dexguard">DexGuard</a> +<a class="largebutton" target="_top" href="http://www.guardsquare.com/">GuardSquare</a> +<a class="largebutton" target="other" href="http://sourceforge.net/projects/proguard/">Sourceforge</a> +</noscript> + +<h2>Examples</h2> + +Some typical useful configurations: +<ol> +<li><a href="#application">A typical application</a></li> +<li><a href="#applet">A typical applet</a></li> +<li><a href="#midlet">A typical midlet</a></li> +<li><a href="#jcapplet">A typical Java Card applet</a></li> +<li><a href="#xlet">A typical xlet</a></li> +<li><a href="#androidactivity">A simple Android activity</a></li> +<li><a href="#androidapplication">A complete Android application</a></li> +<li><a href="#library">A typical library</a></li> +<li><a href="#applications">All possible applications in the input jars</a></li> +<li><a href="#applets">All possible applets in the input jars</a></li> +<li><a href="#midlets">All possible midlets in the input jars</a></li> +<li><a href="#jcapplets">All possible Java Card applets in the input jars</a></li> +<li><a href="#xlets">All possible xlets in the input jars</a></li> +<li><a href="#servlets">All possible servlets in the input jars</a></li> +<li><a href="#scala">Scala applications with the Scala runtime</a></li> +<li><a href="#native">Processing native methods</a></li> +<li><a href="#callback">Processing callback methods</a></li> +<li><a href="#enumerations">Processing enumeration classes</a></li> +<li><a href="#serializable">Processing serializable classes</a></li> +<li><a href="#beans">Processing bean classes</a></li> +<li><a href="#annotations">Processing annotations</a></li> +<li><a href="#database">Processing database drivers</a></li> +<li><a href="#componentui">Processing ComponentUI classes</a></li> +<li><a href="#rmi">Processing RMI code</a></li> +<li><a href="#injection">Processing dependency injection</a></li> +<li><a href="#dagger">Processing Dagger code</a></li> +<li><a href="#butterknife">Processing Butterknife code</a></li> +<li><a href="#resourcefiles">Processing resource files</a></li> +<li><a href="#manifestfiles">Processing manifest files</a></li> +<li><a href="#stacktrace">Producing useful obfuscated stack traces</a></li> +<li><a href="#repackaging">Obfuscating package names</a></li> +<li><a href="#logging">Removing logging code</a></li> +<li><a href="#restructuring">Restructuring the output archives</a></li> +<li><a href="#filtering">Filtering the input and the output</a></li> +<li><a href="#multiple">Processing multiple applications at once</a></li> +<li><a href="#incremental">Incremental obfuscation</a></li> +<li><a href="#microedition">Preverifying class files for Java Micro Edition</a></li> +<li><a href="#upgrade">Upgrading class files to Java 6</a></li> +<li><a href="#deadcode">Finding dead code</a></li> +<li><a href="#structure">Printing out the internal structure of class files</a></li> +<li><a href="#annotated">Using annotations to configure ProGuard</a></li> +</ol> + +You can find some sample configuration files in the <code>examples</code> +directory of the ProGuard distribution. + +<h3><a name="application">A typical application</a></h3> + +To shrink, optimize, and obfuscate a simple Java application, you typically +create a configuration file like <code>myconfig.pro</code>, which can be used +with +<pre> +bin/proguard @myconfig.pro +</pre> +<p> +The configuration file specifies the input, the output, and the entry points +of the application: +<pre> +-injars myapplication.jar +-outjars myapplication_out.jar +-libraryjars <java.home>/lib/rt.jar +-printmapping myapplication.map + +-keep public class mypackage.MyMain { + public static void main(java.lang.String[]); +} +</pre> +<p> +Note the use of the <code><java.home></code> system property. ProGuard +automatically replaces it when parsing the file. +<p> +The <a href="usage.html#keep"><code>-keep</code></a> option specifies the +entry point of the application that has to be preserved. +The access modifiers <code>public</code> and <code>static</code> 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. +<p> +Note that all type names are fully specified: +<code>mypackage.MyMain</code> and <code>java.lang.String[]</code>. +<p> +We're writing out an obfuscation mapping file with <a +href="usage.html#printmapping"><code>-printmapping</code></a>, for +de-obfuscating any stack traces later on, or for incremental obfuscation of +extensions. +<p> +We can further improve the results with a few additional options: +<pre> +-optimizationpasses 3 +-overloadaggressively +-repackageclasses '' +-allowaccessmodification +</pre> +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 <a href="#repackaging">package names</a>. +<p> +In general, you might need a few additional options for processing <a +href="#native">native methods</a>, <a href="#callback">callback methods</a>, +<a href="#enumerations">enumerations</a>, <a href="#serializable">serializable +classes</a>, <a href="#beans">bean classes</a>, <a +href="#annotations">annotations</a>, and <a href="#resourcefiles">resource +files</a>. + +<h3><a name="applet">A typical applet</a></h3> + +These options shrink, optimize, and obfuscate the applet +<code>mypackage.MyApplet</code>: +<pre> +-injars in.jar +-outjars out.jar +-libraryjars <java.home>/lib/rt.jar + +-keep public class mypackage.MyApplet +</pre> +<p> +The typical applet methods will be preserved automatically, since +<code>mypackage.MyApplet</code> is an extension of the <code>Applet</code> +class in the library <code>rt.jar</code>. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, <a +href="#enumerations">enumerations</a>, <a href="#serializable">serializable +classes</a>, <a href="#beans">bean classes</a>, <a +href="#annotations">annotations</a>, and <a href="#resourcefiles">resource +files</a>. + +<h3><a name="midlet">A typical midlet</a></h3> + +These options shrink, optimize, obfuscate, and preverify the midlet +<code>mypackage.MyMIDlet</code>: +<pre> +-injars in.jar +-outjars out.jar +-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar +-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar +-overloadaggressively +-repackageclasses '' +-allowaccessmodification +-microedition + +-keep public class mypackage.MyMIDlet +</pre> +<p> +Note how we're now targeting the Java Micro Edition run-time environment of +<code>midpapi20.jar</code> and <code>cldcapi11.jar</code>, instead of the Java +Standard Edition run-time environment <code>rt.jar</code>. You can target +other JME environments by picking the appropriate jars. +<p> +The typical midlet methods will be preserved automatically, since +<code>mypackage.MyMIDlet</code> is an extension of the <code>MIDlet</code> +class in the library <code>midpapi20.jar</code>. +<p> +The <a href="usage.html#microedition"><code>-microedition</code></a> option +makes sure the class files are preverified for Java Micro Edition, producing +compact <code>StackMap</code> attributes. It is no longer necessary to run an +external preverifier. +<p> +Be careful if you do use the external <code>preverify</code> 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 <a +href="usage.html#dontusemixedcaseclassnames"><code>-dontusemixedcaseclassnames</code></a> +option. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a> and <a href="#resourcefiles">resource files</a>. +<p> +Note that you will still have to adapt the midlet jar size in the +corresponding jad file; ProGuard doesn't do that for you. + +<h3><a name="jcapplet">A typical Java Card applet</a></h3> + +These options shrink, optimize, and obfuscate the Java Card applet +<code>mypackage.MyApplet</code>: +<pre> +-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 +</pre> +<p> +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. + +<h3><a name="xlet">A typical xlet</a></h3> + +These options shrink, optimize, and obfuscate the xlet +<code>mypackage.MyXlet</code>: +<pre> +-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 +</pre> +<p> +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. + +<h3><a name="androidactivity">A simple Android activity</a></h3> + +These options shrink, optimize, and obfuscate the single Android +activity <code>mypackage.MyActivity</code>: +<pre> +-injars bin/classes +-outjars bin/classes-processed.jar +-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar + +-dontpreverify +-repackageclasses '' +-allowaccessmodification +-optimizations !code/simplification/arithmetic + +-keep public class mypackage.MyActivity +</pre> +<p> +We're targeting the Android run-time and keeping the activity as an entry +point. +<p> +Preverification is irrelevant for the dex compiler and the Dalvik VM, so we +can switch it off with the +<a href="usage.html#dontpreverify"><code>-dontpreverify</code></a> option. +<p> +The <a href="usage.html#optimizations"><code>-optimizations</code></a> option +disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle. +Note that the Dalvik VM also can't +handle <a href="usage.html#overloadaggressively">aggressive overloading</a> +(of static fields). +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, +<a href="#enumerations">enumerations</a>, +<a href="#annotations">annotations</a>, and +<a href="#resourcefiles">resource files</a>. + +<h3><a name="androidapplication">A complete Android application</a></h3> + +<img class="float" src="attention.gif" width="64" height="64" alt="attention" +/> The standard build processes of the Android SDK (with Ant, Gradle, Android +Studio, and Eclipse) already integrate ProGuard with all the proper settings. +You only need to enable ProGuard by uncommenting the line +"<code>proguard.config=.....</code>" in the +file <code>project.properties</code> (created or updated by Android SDK +revision 17 or higher) or by adapting your <code>build.gradle</code> file. You +then <em>don't</em> need any of the configuration below. +<p> +Notes: +<ul> +<li>In case of problems, you may want to check if the configuration files that + are listed on this line (<code>proguard-project.txt</code>,...) contain + the necessary settings for your application.</li> +<li>Android SDK revision 20 and higher have a different configuration file for + enabling optimization: + <code>${sdk.dir}/tools/proguard/proguard-android-optimize.txt</code> + instead of the default + <code>${sdk.dir}/tools/proguard/proguard-android.txt</code>.</li> +<li>The build processes are already setting the necessary program jars, + library jars, and output jars for you — don't specify them again.</li> +<li>If you get warnings about missing referenced classes: it's all too common + that libraries refer to missing classes. + See <a href="troubleshooting.html#unresolvedclass">"Warning: can't find + referenced class"</a> in the Troubleshooting section.</li> +</ul> +<p> +For more information, you can consult the official <a target="other" +href="http://developer.android.com/guide/developing/tools/proguard.html">Developer +Guide</a> in the Android SDK. +<p> +If you're constructing a build process <em>from scratch</em>: these options +shrink, optimize, and obfuscate all public activities, services, broadcast +receivers, and content providers from the compiled classes and external +libraries: +<pre> +-injars bin/classes +-injars libs +-outjars bin/classes-processed.jar +-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar + +-dontpreverify +-repackageclasses '' +-allowaccessmodification +-optimizations !code/simplification/arithmetic +-keepattributes *Annotation* + +-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 android.view.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*(...); +} + +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers class * extends android.content.Context { + public void *(android.view.View); + public void *(android.view.MenuItem); +} + +-keepclassmembers class * implements android.os.Parcelable { + static ** CREATOR; +} + +-keepclassmembers class **.R$* { + public static <fields>; +} + +-keepclassmembers class * { + @android.webkit.JavascriptInterface <methods>; +} +</pre> +<p> +Most importantly, we're keeping all fundamental classes that may be referenced +by the <code>AndroidManifest.xml</code> file of the application. If your +manifest file contains other classes and methods, you may have to specify +those as well. +<p> +We're keeping annotations, since they might be used by custom +<code>RemoteViews</code>. +<p> +We're keeping any custom <code>View</code> extensions and other classes with +typical constructors, since they might be referenced from XML layout files. +<p> +We're also keeping possible <code>onClick</code> handlers in +custom <code>Context</code> extensions, since they might be referenced from +XML layout files. +<p> +We're also keeping the required static fields in <code>Parcelable</code> +implementations, since they are accessed by introspection. +<p> +We're keeping the static fields of referenced inner classes of auto-generated + <code>R</code> classes, just in case your code is accessing those fields by +introspection. Note that the compiler already inlines primitive fields, so +ProGuard can generally remove all these classes entirely anyway (because the +classes are not referenced and therefore not required). +<p> +Finally, we're keeping annotated Javascript interface methods, so they can be +exported and accessed by their original names. Javascript interface methods +that are not annotated (in code targeted at Android versions older than 4.2) +still need to be preserved manually. +<p> +If you're using additional Google APIs, you'll have to specify +those as well, for instance: +<pre> +-libraryjars /usr/local/android-sdk/add-ons/google_apis-7_r01/libs/maps.jar +</pre> +<p> +If you're using Google's optional License Verification Library, you can +obfuscate its code along with your own code. You do have to preserve +its <code>ILicensingService</code> interface for the library to work: +<pre> +-keep public interface com.android.vending.licensing.ILicensingService +</pre> +<p> +If you're using the Android Compatibility library, you should add the +following line, to let ProGuard know it's ok that the library references some +classes that are not available in all versions of the API: +<pre> +-dontwarn android.support.** +</pre> +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, +<a href="#enumerations">enumerations</a>, +and <a href="#resourcefiles">resource files</a>. You may also want to add +options for producing <a href="#stacktrace">useful stack traces</a> and +to <a href="#logging">remove logging</a>. You can find a complete sample +configuration in <code>examples/android.pro</code> in the ProGuard +distribution. + +<h3><a name="library">A typical library</a></h3> + +These options shrink, optimize, and obfuscate an entire library, keeping all +public and protected classes and class members, native method names, and +serialization code. The processed version of the library can then still be +used as such, for developing code based on its public API. +<pre> +-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,includedescriptorclasses class * { + native <methods>; +} + +-keepclassmembers,allowoptimization 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(); +} +</pre> +<p> +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 <a +href="usage.html#keep"><code>-keep</code></a> options. +<p> +The <a +href="usage.html#keepclassmembernames"><code>-keepclassmembernames</code></a> +option for the <code>class$</code> methods is not strictly necessary. These +methods are inserted by the <code>javac</code> compiler and the +<code>jikes</code> compiler respectively, in JDK 1.2 and older, to implement +the <code>.class</code> construct. ProGuard will automatically detect them and +deal with them, even when their names have been obfuscated. However, 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. +<p> +The "Exceptions" attribute has to be preserved, so the compiler knows which +exceptions methods may throw. +<p> +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 <code>javac</code> compiler would be unable to find the inner +classes otherwise. +<p> +The "Signature" attribute is required to be able to access generic types when +compiling in JDK 5.0 and higher. +<p> +The <a href="usage.html#keepparameternames"><code>-keepparameternames</code></a> +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. +<p> +Finally, we're keeping the "Deprecated" attribute and the attributes for +producing <a href="#stacktrace">useful stack traces</a>. +<p> +We've also added some options for for processing <a href="#native">native +methods</a>, <a href="#enumerations">enumerations</a>, <a +href="#serializable">serializable classes</a>, and <a +href="#annotations">annotations</a>, which are all discussed in their +respective examples. + +<h3><a name="applications">All possible applications in the input jars</a></h3> + +These options shrink, optimize, and obfuscate all public applications in +<code>in.jar</code>: +<pre> +-injars in.jar +-outjars out.jar +-libraryjars <java.home>/lib/rt.jar +-printseeds + +-keepclasseswithmembers public class * { + public static void main(java.lang.String[]); +} +</pre> +<p> +Note the use of <a +href="usage.html#keepclasseswithmembers"><code>-keepclasseswithmembers</code></a>. +We don't want to preserve all classes, just all classes that have main +methods, and those methods. +<p> +The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints +out which classes exactly will be preserved, so we know for sure we're getting +what we want. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, <a +href="#enumerations">enumerations</a>, <a href="#serializable">serializable +classes</a>, <a href="#beans">bean classes</a>, <a +href="#annotations">annotations</a>, and <a href="#resourcefiles">resource +files</a>. + +<h3><a name="applets">All possible applets in the input jars</a></h3> + +These options shrink, optimize, and obfuscate all public applets in +<code>in.jar</code>: +<pre> +-injars in.jar +-outjars out.jar +-libraryjars <java.home>/lib/rt.jar +-printseeds + +-keep public class * extends java.applet.Applet +</pre> +<p> +We're simply keeping all classes that extend the <code>Applet</code> class. +<p> +Again, the <a href="usage.html#printseeds"><code>-printseeds</code></a> option +prints out which applets exactly will be preserved. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, <a +href="#enumerations">enumerations</a>, <a href="#serializable">serializable +classes</a>, <a href="#beans">bean classes</a>, <a +href="#annotations">annotations</a>, and <a href="#resourcefiles">resource +files</a>. + +<h3><a name="midlets">All possible midlets in the input jars</a></h3> + +These options shrink, optimize, obfuscate, and preverify all public midlets in +<code>in.jar</code>: +<pre> +-injars in.jar +-outjars out.jar +-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar +-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar +-overloadaggressively +-repackageclasses '' +-allowaccessmodification +-microedition +-printseeds + +-keep public class * extends javax.microedition.midlet.MIDlet +</pre> +<p> +We're simply keeping all classes that extend the <code>MIDlet</code> class. +<p> +The <a href="usage.html#microedition"><code>-microedition</code></a> option +makes sure the class files are preverified for Java Micro Edition, producing +compact <code>StackMap</code> attributes. It is no longer necessary to run an +external preverifier. +<p> +Be careful if you do use the external <code>preverify</code> 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 <a +href="usage.html#dontusemixedcaseclassnames"><code>-dontusemixedcaseclassnames</code></a> +option. +<p> +The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints +out which midlets exactly will be preserved. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a> and <a href="#resourcefiles">resource files</a>. +<p> +Note that you will still have to adapt the midlet jar size in the +corresponding jad file; ProGuard doesn't do that for you. + +<h3><a name="jcapplets">All possible Java Card applets in the input jars</a></h3> + +These options shrink, optimize, and obfuscate all public Java Card applets in +<code>in.jar</code>: +<pre> +-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 +</pre> +<p> +We're simply keeping all classes that implement the <code>Applet</code> +interface. +<p> +The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints +out which applets exactly will be preserved. + +<h3><a name="xlets">All possible xlets in the input jars</a></h3> + +These options shrink, optimize, and obfuscate all public xlets in +<code>in.jar</code>: +<pre> +-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 +</pre> +<p> +We're simply keeping all classes that implement the <code>Xlet</code> interface. +<p> +The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints +out which xlets exactly will be preserved. + +<h3><a name="servlets">All possible servlets in the input jars</a></h3> + +These options shrink, optimize, and obfuscate all public servlets in +<code>in.jar</code>: +<pre> +-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 +</pre> +<p> +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. +<p> +We're then keeping all classes that implement the <code>Servlet</code> +interface. We're using the <code>implements</code> keyword because it looks +more familiar in this context, but it is equivalent to <code>extends</code>, +as far as ProGuard is concerned. +<p> +The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints +out which servlets exactly will be preserved. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, <a +href="#enumerations">enumerations</a>, <a href="#serializable">serializable +classes</a>, <a href="#beans">bean classes</a>, <a +href="#annotations">annotations</a>, and <a href="#resourcefiles">resource +files</a>. + +<h3><a name="scala">Scala applications with the Scala runtime</a></h3> + +These options shrink, optimize, and obfuscate all public Scala applications in +<code>in.jar</code>: +<pre> +-injars in.jar +-injars /usr/local/java/scala-2.9.1/lib/scala-library.jar +-outjars out.jar +-libraryjars <java.home>/lib/rt.jar + +-dontwarn scala.** + +-keepclasseswithmembers public class * { + public static void main(java.lang.String[]); +} + +-keep class * implements org.xml.sax.EntityResolver + +-keepclassmembers class * { + ** MODULE$; +} + +-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool { + long eventCount; + int workerCounts; + int runControl; + scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack; + scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack; +} + +-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread { + int base; + int sp; + int runState; +} + +-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask { + int status; +} + +-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue { + scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head; + scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail; + scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe; +} +</pre> +<p> +The configuration is essentially the same as +for <a href="#applications">processing applications</a>, because Scala is +compiled to ordinary Java bytecode. However, the example processes the Scala +runtime library as well. The processed jar can be an order of magnitude +smaller and a few times faster than the original code (for the Scala code +examples, for instance). +<p> +The <a href="usage.html#dontwarn"><code>-dontwarn</code></a> option tells +ProGuard not to complain about some artefacts in the Scala runtime, the way it +is compiled by the <code>scalac</code> compiler (at least in Scala 2.9.1 and +older). Note that this option should always be used with care. +<p> +The additional <a href="usage.html#keepoverview"><code>-keep</code></a> +options make sure that some classes and some fields that are accessed by means +of introspection are not removed or renamed. +<p> +If applicable, you should add options for processing <a href="#native">native +methods</a>, <a href="#callback">callback methods</a>, <a +href="#enumerations">enumerations</a>, <a href="#serializable">serializable +classes</a>, <a href="#beans">bean classes</a>, <a +href="#annotations">annotations</a>, and <a href="#resourcefiles">resource +files</a>. +<h3><a name="native">Processing native methods</a></h3> + +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: +<pre> +-keepclasseswithmembernames,includedescriptorclasses class * { + native <methods>; +} +</pre> +<p> +Note the use of +<a href="usage.html#keepclasseswithmembernames"><code>-keepclasseswithmembernames</code></a>. +We don't want to preserve all classes or all native methods; we just want to +keep the relevant names from being obfuscated. The modifier +<a href="usage.html#includedescriptorclasses">includedescriptorclasses</a> +additionally makes sure that the return types and parameter types aren't +renamed either, so the entire signatures remain compatible with the native +libraries. +<p> +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. <a +href="callback">Callback methods</a> are discussed below as a typical example. + +<h3><a name="callback">Processing callback methods</a></h3> + +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 <code>-keep</code> options, something like +the following option will keep the callback class and method: +<pre> +-keep class mypackage.MyCallbackClass { + void myCallbackMethod(java.lang.String); +} +</pre> +<p> +This will preserve the given class and method from being removed or renamed. + +<h3><a name="enumerations">Processing enumeration classes</a></h3> + +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: +<pre> +-keepclassmembers,allowoptimization enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +</pre> + +<h3><a name="serializable">Processing serializable classes</a></h3> + +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: +<ul> + +<li>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: + +<pre> +-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(); +} +</pre> +<p> + + The <a + href="usage.html#keepclassmembers"><code>-keepclassmembers</code></a> + option makes sure that any serialization methods are kept. By using this + option instead of the basic <code>-keep</code> option, we're not + forcing preservation of <i>all</i> serializable classes, just preservation + of the listed members of classes that are actually used.</li> + +<li>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 <code>serialVersionUID</code> fields. The following options should + then be sufficient to ensure compatibility over time: + +<pre> +-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(); +} +</pre> +<p> + + The <code>serialVersionUID</code> and <code>serialPersistentFields</code> + lines makes sure those fields are preserved, if they are present. + The <code><fields></code> 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.</li> + +<li>Occasionally, the serialized data have to remain compatible, but the + classes involved lack <code>serialVersionUID</code> 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 <a + href="http://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100">Stream + Unique Identifiers</a> of Sun's <a + href="http://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html">Java + Object Serialization Specification</a>. The following directives should at + least partially ensure compatibility with the original classes: + +<pre> +-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(); +} +</pre> +<p> + + 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 "<code>-keep + interface MyInterface</code>"), since these names are also used when + computing the UID. A fast but sub-optimal alternative would be simply + keeping all interfaces with "<code>-keep interface *</code>".</li> + +<li>In the rare event that you are serializing lambda expressions in Java 8 or + higher, you need to preserve some methods and adapt the hard-coded names + of the classes in which they occur: + +<pre> +-keepclassmembers class * { + private static synthetic java.lang.Object $deserializeLambda$(java.lang.invoke.SerializedLambda); +} + +-keepclassmembernames class * { + private static synthetic *** lambda$*(...); +} + +-adaptclassstrings com.example.Test +</pre> +<p> + + This should satisfy the reflection in the deserialization code of the + Java run-time. + +</ul> +<p> + +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 <code>Serialization</code> interface, yet only a small number may actually +ever be serialized. Knowing your application and tuning the configuration +often produces more compact results. + +<h3><a name="beans">Processing bean classes</a></h3> + +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: +<pre> +-keep public class mypackage.MyBean { + public void setMyProperty(int); + public int getMyProperty(); +} + +-keep public class mypackage.MyBeanEditor +</pre> +<p> +If there are too many elements to list explicitly, wildcards in class names +and method signatures might be helpful. This example preserves all possible +setters and getters in classes in the package <code>mybeans</code>: +<pre> +-keep class mybeans.** { + void set*(***); + void set*(int, ***); + + boolean is*(); + boolean is*(int); + + *** get*(); + *** get*(int); +} +</pre> +<p> +The '<code>***</code>' wildcard matches any type (primitive or non-primitive, +array or non-array). The methods with the '<code>int</code>' arguments matches +properties that are lists. + +<h3><a name="annotations">Processing annotations</a></h3> + +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: +<pre> +-keepattributes *Annotation* +</pre> +<p> +For brevity, we're specifying a wildcarded attribute name, which will match +<code>RuntimeVisibleAnnotations</code>, +<code>RuntimeInvisibleAnnotations</code>, +<code>RuntimeVisibleParameterAnnotations</code>, +<code>RuntimeInvisibleParameterAnnotations</code>, and +<code>AnnotationDefault</code>. 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). +<p> +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: +<pre> +-keepattributes EnclosingMethod +</pre> + +<h3><a name="database">Processing database drivers</a></h3> + +Database drivers are implementations of the <code>Driver</code> interface. +Since they are often created dynamically, you may want to preserve any +implementations that you are processing as entry points: +<pre> +-keep class * implements java.sql.Driver +</pre> +<p> +This option also gets rid of the note that ProGuard prints out about +<code>(java.sql.Driver)Class.forName</code> constructs, if you are +instantiating a driver in your code (without necessarily implementing any +drivers yourself). + +<h3><a name="componentui">Processing ComponentUI classes</a></h3> + +Swing UI look and feels are implemented as extensions of the +<code>ComponentUI</code> class. For some reason, these have to contain a +static method <code>createUI</code>, which the Swing API invokes using +introspection. You should therefore always preserve the method as an entry +point, for instance like this: +<pre> +-keep class * extends javax.swing.plaf.ComponentUI { + public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent); +} +</pre> +<p> +This option also keeps the classes themselves. + +<h3><a name="rmi">Processing RMI code</a></h3> + +Reportedly, the easiest way to handle RMI code is to process the code with +ProGuard first and then invoke the <code>rmic</code> tool. If that is not +possible, you may want to try something like this: +<pre> +-keepattributes Exceptions + +-keep interface * extends java.rmi.Remote { + <methods>; +} + +-keep class * implements java.rmi.Remote { + <init>(java.rmi.activation.ActivationID, java.rmi.MarshalledObject); +} +</pre> +<p> +The first <code>-keep</code> option keeps all your Remote interfaces and their +methods. The second one keeps all the implementations, along with their +particular RMI constructors, if any. +<p> +The <code>Exceptions</code> attribute has to be kept too, because the RMI +handling code performs introspection to check whether the method signatures +are compatible. + +<h3><a name="injection">Processing dependency injection</a></h3> + +If your application is using JEE-style dependency injection, the application +container will automatically assign instances of resource classes to fields and +methods that are annotated with <code>@Resource</code>. The container applies +introspection, even accessing private class members directly. It typically +constructs a resource name based on the type name and the class member name. +We then have to avoid that such class members are removed or renamed: +<pre> +-keepclassmembers class * { + @javax.annotation.Resource *; +} +</pre> +<p> +The Spring framework has another similar annotation <code>@Autowired</code>: +<pre> +-keepclassmembers class * { + @org.springframework.beans.factory.annotation.Autowired *; +} +</pre> + +<h3><a name="dagger">Processing Dagger code</a></h3> + +If your Android application includes Dagger for dependency injection, you need +a few lines of configuration, since Dagger heavily relies on reflection to tie +together the code at runtime. You need to preserve the annotated class +members, the generated classes, and a utility class: +<pre> +-keepclassmembers,allowobfuscation class * { + @dagger.** *; +} + +-keep class **$$ModuleAdapter +-keep class **$$InjectAdapter +-keep class **$$StaticInjection + +-keepnames class dagger.Lazy +</pre> +<p> +Unfortunately, you still need to explicitly preserve the corresponding base +classes from your project. For example, for a generated class like +<code>com.example.SomeClass$$ModuleAdapter</code>, you still need to specify: +<pre> +-keep class com.example.SomeClass +</pre> +<p> +Dagger can then still combine the corresponding pairs of classes, based on +their names. You can figure out the base classes by listing the generated +classes in the <code>gen</code> directory of your project (e.g. +<code>com/examples/SomeClass$$ModuleAdapter.class</code>). +<p> +Dagger 2 no longer relies on reflection with these naming conventions, which +makes life a lot easier. + +<h3><a name="butterknife">Processing Butterknife code</a></h3> + +If your Android application includes Butterknife to inject views, you also +need a few lines of configuration, since Butterknife relies on reflection to +tie together the code at runtime: +<pre> +-keep @interface butterknife.* + +-keepclasseswithmembers class * { + @butterknife.* <fields>; +} + +-keepclasseswithmembers class * { + @butterknife.* <methods>; +} + +-keepclasseswithmembers class * { + @butterknife.On* <methods>; +} + +-keep class **$$ViewInjector { + public static void inject(...); + public static void reset(...); +} + +-keep class **$$ViewBinder { + public static void bind(...); + public static void unbind(...); +} +</pre> +<p> +These settings preserve the Butterknife annotations, the annotated fields and +methods, and the generated classes and methods that Butterknife accesses by +reflection. + +<h3><a name="resourcefiles">Processing resource files</a></h3> + +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: +<pre> +-adaptresourcefilenames **.properties,**.gif,**.jpg +-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF +</pre> +<p> +The <a href="usage.html#adaptresourcefilenames">-adaptresourcefilenames</a> +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 <a +href="usage.html#adaptresourcefilecontents">-adaptresourcefilecontents</a> +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. + +<h3><a name="manifestfiles">Processing manifest files</a></h3> + +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. +<p> +If you're merging several input jars into a single output jar, you'll have to +pick one, typically by specifying <a href="usage.html#filters">filters</a>: +<pre> +-injars in1.jar +-injars in2.jar(!META-INF/MANIFEST.MF) +-injars in3.jar(!META-INF/MANIFEST.MF) +-outjars out.jar +</pre> +<p> +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. + +<h3><a name="stacktrace">Producing useful obfuscated stack traces</a></h3> + +These options let obfuscated applications or libraries produce stack traces +that can still be deciphered later on: +<pre> +-printmapping out.map + +-renamesourcefileattribute SourceFile +-keepattributes SourceFile,LineNumberTable +</pre> +<p> +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. +<p> +We're also keeping the line number tables of all methods. +<p> +Whenever both of these attributes are present, the Java run-time environment +will include line number information when printing out exception stack traces. +<p> +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 +<code>out.map</code>. The information can then be used by the <a +href="retrace/index.html">ReTrace</a> tool to restore the original stack trace. + +<h3><a name="repackaging">Obfuscating package names</a></h3> + +Package names can be obfuscated in various ways, with increasing levels of +obfuscation and compactness. For example, consider the following classes: +<pre> +mycompany.myapplication.MyMain +mycompany.myapplication.Foo +mycompany.myapplication.Bar +mycompany.myapplication.extra.FirstExtra +mycompany.myapplication.extra.SecondExtra +mycompany.util.FirstUtil +mycompany.util.SecondUtil +</pre> +<p> +Let's assume the class name <code>mycompany.myapplication.MyMain</code> is the +main application class that is kept by the configuration. All other class names +can be obfuscated. +<p> +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: +<pre> +mycompany.myapplication.MyMain +mycompany.myapplication.a +mycompany.myapplication.b +mycompany.myapplication.a.a +mycompany.myapplication.a.b +mycompany.a.a +mycompany.a.b +</pre> +<p> +The <a +href="usage.html#flattenpackagehierarchy"><code>-flattenpackagehierarchy</code></a> +option obfuscates the package names further, by flattening the package +hierarchy of obfuscated packages: +<pre> +-flattenpackagehierarchy 'myobfuscated' +</pre> +<p> +The obfuscated class names then look as follows: +<pre> +mycompany.myapplication.MyMain +mycompany.myapplication.a +mycompany.myapplication.b +myobfuscated.a.a +myobfuscated.a.b +myobfuscated.b.a +myobfuscated.b.b +</pre> +<p> +Alternatively, the <a +href="usage.html#repackageclasses"><code>-repackageclasses</code></a> option +obfuscates the entire packaging, by combining obfuscated classes into a single +package: +<pre> +-repackageclasses 'myobfuscated' +</pre> +The obfuscated class names then look as follows: +<pre> +mycompany.myapplication.MyMain +mycompany.myapplication.a +mycompany.myapplication.b +myobfuscated.a +myobfuscated.b +myobfuscated.c +myobfuscated.d +</pre> +<p> +Additionally specifying the <a +href="usage.html#allowaccessmodification"><code>-allowaccessmodification</code></a> +option allows access permissions of classes and class members to +be broadened, opening up the opportunity to repackage all obfuscated classes: +<pre> +-repackageclasses 'myobfuscated' +-allowaccessmodification +</pre> +The obfuscated class names then look as follows: +<pre> +mycompany.myapplication.MyMain +myobfuscated.a +myobfuscated.b +myobfuscated.c +myobfuscated.d +myobfuscated.e +myobfuscated.f +</pre> +<p> +The specified target package can always be the root package. For instance: +<pre> +-repackageclasses '' +-allowaccessmodification +</pre> +The obfuscated class names are then the shortest possible names: +<pre> +mycompany.myapplication.MyMain +a +b +c +d +e +f +</pre> +<p> +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 <a href="#resourcefiles">resource files</a> that have to be adapted. + +<h3><a name="logging">Removing logging code</a></h3> + +You can let ProGuard remove logging code. The trick is to specify that the +logging methods don't have side-effects — even though they actually do, +since they write to the console or to a log file. ProGuard will take your word +for it and remove the invocations (in the optimization step) and if possible +the logging classes and methods themselves (in the shrinking step). +<p> +For example, this configuration removes invocations of the Android logging +methods: +<pre> +-assumenosideeffects class android.util.Log { + public static boolean isLoggable(java.lang.String, int); + public static int v(...); + public static int i(...); + public static int w(...); + public static int d(...); + public static int e(...); +} +</pre> +<p> +The wildcards are a shortcut to match all versions of the methods. Be careful +not to use a <code>*</code> wildcard to match all methods, because it would +also match methods like <code>wait()</code>, higher up the hierarchy. Removing +those invocations will generally break your code. +<p> +Note that you generally can't remove logging code that uses +<code>System.out.println</code>, since you would be removing all invocations +of <code>java.io.PrintStream#println</code>, which could break your +application. You can work around it by creating your own logging methods and +let ProGuard remove those. + +<h3><a name="restructuring">Restructuring the output archives</a></h3> + +In simple applications, all output classes and resources files are merged into +a single jar. For example: +<pre> +-injars classes +-injars in1.jar +-injars in2.jar +-injars in3.jar +-outjars out.jar +</pre> +<p> +This configuration merges the processed versions of the files in the +<code>classes</code> directory and the three jars into a single output jar +<code>out.jar</code>. +<p> +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: +<pre> +-injars in1.jar +-injars in2.jar +-injars in3.jar +-outjars out +</pre> +<p> +The input jars will then be reconstructed in the directory <code>out</code>, +with their original names. +<p> +You can also combine archives into higher level archives. For example: +<pre> +-injars in1.jar +-injars in2.jar +-injars in3.jar +-outjars out.war +</pre> +<p> +The other way around, you can flatten the archives inside higher level +archives into simple archives: +<pre> +-injars in.war +-outjars out.jar +</pre> +<p> +This configuration puts the processed contents of all jars inside +<code>in.war</code> (plus any other contents of <code>in.war</code>) into +<code>out.jar</code>. +<p> +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 +<a href="usage.html#injars"><code>-injars</code></a> and <a +href="usage.html#outjars"><code>-outjars</code></a> options. For example: +<pre> +-injars base_in1.jar +-injars base_in2.jar +-injars base_in3.jar +-outjars base_out.jar + +-injars extra_in.jar +-outjars extra_out.jar +</pre> +<p> +This configuration puts the processed results of all <code>base_in*.jar</code> +jars into <code>base_out.jar</code>, and the processed results of the +<code>extra_in.jar</code> into <code>extra_out.jar</code>. Note that only the +order of the options matters; the additional whitespace is just for clarity. +<p> +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. + +<h3><a name="filtering">Filtering the input and the output</a></h3> + +If you want even greater control, you can add +<a href="usage.html#filters">filters</a> 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: +<pre> +-injars in.jar(!images/**) +-outjars out.jar +</pre> +<p> +This configuration removes any files in the <code>images</code> directory and +its subdirectories. +<p> +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: +<pre> +-injars in1.jar +-injars in2.jar(!META-INF/MANIFEST.MF) +-injars in3.jar(!META-INF/MANIFEST.MF) +-outjars out.jar +</pre> +<p> +Another useful application is speeding up the processing by ProGuard, by +disregarding a large number of irrelevant classes in the runtime library jar: +<pre> +-libraryjars <java.home>/lib/rt.jar(java/**,javax/**) +</pre> +<p> +The filter makes ProGuard disregard <code>com.sun.**</code> classes, for +instance , which don't affect the processing of ordinary applications. +<p> +It is also possible to filter the jars (and/or wars, ears, zips) themselves, +based on their names. For example: +<pre> +-injars in(**/acme_*.jar;) +-outjars out.jar +</pre> +<p> +Note the semi-colon in the filter; the filter in front of it applies to jar +names. In this case, only <code>acme_*.jar</code> jars are read from the +directory <code>in</code> 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. +<p> +On the other hand, you can also filter the output, in order to control what +content goes where. For example: +<pre> +-injars in.jar +-outjars code_out.jar(**.class) +-outjars resources_out.jar +</pre> +<p> +This configuration splits the processed output, sending <code>**.class</code> +files to <code>code_out.jar</code>, and all remaining files to +<code>resources_out.jar</code>. +<p> +Again, the filtering can be arbitrarily complex, especially when combined with +grouping input and output. + +<h3><a name="multiple">Processing multiple applications at once</a></h3> + +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. +<p> +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: +<pre> +-injars application1.jar +-injars application2.jar +-injars application3.jar +-outjars processed_applications +</pre> +<p> +After processing, the directory <code>processed_applications</code> will +contain processed versions of application jars, with their original names. + +<h3><a name="incremental">Incremental obfuscation</a></h3> + +After having <a href="#application">processed an application</a>, e.g. +ProGuard itself, you can still incrementally add other pieces of code that +depend on it, e.g. the ProGuard GUI: +<pre> +-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[]); +} +</pre> +<p> +We're reading both unprocessed jars as input. Their processed contents will go +to the respective output jars. The <a +href="usage.html#applymapping"><code>-applymapping</code></a> 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. +<p> +The added code in this example is straightforward; it doesn't affect the +original code. The <code>proguard_out.jar</code> 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 <a +href="usage.html#useuniqueclassmembernames"><code>-useuniqueclassmembernames</code></a>, +<a href="usage.html#dontshrink"><code>-dontshrink</code></a>, and <a +href="usage.html#dontoptimize"><code>-dontoptimize</code></a> <i>in the +original processing step</i>. 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: +<pre> +-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[]); +} +</pre> + +<h3><a name="microedition">Preverifying class files for Java Micro Edition</a></h3> + +Even if you're not interested in shrinking, optimizing, and obfuscating your +midlets, as shown in the <a href="#midlets">midlets example</a>, 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. +<pre> +-injars in.jar +-outjars out.jar +-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar +-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar + +-dontshrink +-dontoptimize +-dontobfuscate + +-microedition +</pre> +<p> +We're not processing the input, just making sure the class files are +preverified by targeting them at Java Micro Edition with the <a +href="usage.html#microedition"><code>-microedition</code></a> option. Note +that we don't need any <code>-keep</code> options to specify entry points; all +class files are simply preverified. + +<h3><a name="upgrade">Upgrading class files to Java 6</a></h3> + +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. +<pre> +-injars in.jar +-outjars out.jar +-libraryjars <java.home>/lib/rt.jar + +-dontshrink +-dontoptimize +-dontobfuscate + +-target 1.6 +</pre> +<p> +We're not processing the input, just retargeting the class files with the <a +href="usage.html#target"><code>-target</code></a> option. They will +automatically be preverified for Java 6 as a result. Note that we don't need +any <code>-keep</code> options to specify entry points; all class files are +simply updated and preverified. + +<h3><a name="deadcode">Finding dead code</a></h3> + +These options list unused classes, fields, and methods in the application +<code>mypackage.MyApplication</code>: +<pre> +-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[]); +} +</pre> +<p> +We're not specifying an output jar, just printing out some results. We're +saving some processing time by skipping the other processing steps. +<p> +The java compiler inlines primitive constants and String constants +(<code>static final</code> fields). ProGuard would therefore list such fields +as not being used in the class files that it analyzes, even if they <i>are</i> +used in the source files. We can add a <a +href="usage.html#keepclassmembers"><code>-keepclassmembers</code></a> option +that keeps those fields a priori, in order to avoid having them listed: +<pre> +-keepclassmembers class * { + static final % *; + static final java.lang.String *; +} +</pre> + +<h3><a name="structure">Printing out the internal structure of class files</a></h3> + +These options print out the internal structure of all class files in the input +jar: +<pre> +-injars in.jar + +-dontshrink +-dontoptimize +-dontobfuscate +-dontpreverify + +-dump +</pre> +<p> +Note how we don't need to specify the Java run-time jar, because we're not +processing the input jar at all. + +<h3><a name="annotated">Using annotations to configure ProGuard</a></h3> + +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. +<p> +You can find a set of such predefined annotations in the directory +<code>examples/annotations/lib</code> in the ProGuard distribution. +The annotation classes are defined in <code>annotations.jar</code>. The +corresponding ProGuard configuration (or meta-configuration, if you prefer) +is specified in <code>annotations.pro</code>. With these files, you can start +annotating your code. For instance, a java source file +<code>Application.java</code> can be annotated as follows: +<pre> +@KeepApplication +public class Application { + .... +} +</pre> +<p> +The ProGuard configuration file for the application can then be simplified by +leveraging off these annotations: +<pre> +-injars in.jar +-outjars out.jar +-libraryjars <java.home>/lib/rt.jar + +-include lib/annotations.pro +</pre> +<p> +The annotations are effectively replacing the application-dependent +<code>-keep</code> options. You may still wish to add traditional +<code>-keep</code> options for processing <a href="#native">native +methods</a>, <a href="#enumerations">enumerations</a>, <a +href="#serializable">serializable classes</a>, and <a +href="#annotations">annotations</a>. +<p> +The directory <code>examples/annotations</code> contains more examples that +illustrate some of the possibilities. + +<hr /> +<address> +Copyright © 2002-2017 +<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a> @ <a target="top" href="http://www.guardsquare.com/">GuardSquare</a>. +</address> +</body> +</html> |