1621 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			1621 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <!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.saikoa.com/dexguard">DexGuard</a> <a class="largebutton" target="_top" href="http://www.saikoa.com/">Saikoa</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.saikoa.com/dexguard">DexGuard</a>
 | |
| <a class="largebutton" target="_top"  href="http://www.saikoa.com/">Saikoa</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 resource injection</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 resource injection</a></h3>
 | |
| 
 | |
| If your application is using JEE-style resource 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="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.
 | |
| <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-2014
 | |
| <a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a> @ <a target="top" href="http://www.saikoa.com/">Saikoa</a>.
 | |
| </address>
 | |
| </body>
 | |
| </html>
 |