diff options
Diffstat (limited to 'docs/manual/examples.html')
-rw-r--r-- | docs/manual/examples.html | 1620 |
1 files changed, 0 insertions, 1620 deletions
diff --git a/docs/manual/examples.html b/docs/manual/examples.html deleted file mode 100644 index dec9613..0000000 --- a/docs/manual/examples.html +++ /dev/null @@ -1,1620 +0,0 @@ -<!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> |