aboutsummaryrefslogtreecommitdiffstats
path: root/docs/manual/examples.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/manual/examples.html')
-rw-r--r--docs/manual/examples.html667
1 files changed, 478 insertions, 189 deletions
diff --git a/docs/manual/examples.html b/docs/manual/examples.html
index 3f47fca..804ae17 100644
--- a/docs/manual/examples.html
+++ b/docs/manual/examples.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!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>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -12,76 +23,84 @@
Some typical useful configurations:
<ol>
-<li><a href="#application">A typical application</a>
-<li><a href="#applet">A typical applet</a>
-<li><a href="#midlet">A typical midlet</a>
-<li><a href="#jcapplet">A typical Java Card applet</a>
-<li><a href="#xlet">A typical xlet</a>
-<li><a href="#androidapplication">A typical Android application</a>
-<li><a href="#library">A typical library</a>
-<li><a href="#applications">All possible applications in the input jars</a>
-<li><a href="#applets">All possible applets in the input jars</a>
-<li><a href="#midlets">All possible midlets in the input jars</a>
-<li><a href="#jcapplets">All possible Java Card applets in the input jars</a>
-<li><a href="#xlets">All possible xlets in the input jars</a>
-<li><a href="#androidapplications">All possible Android applications in the input jars</a>
-<li><a href="#servlets">All possible servlets in the input jars</a>
-<li><a href="#native">Processing native methods</a>
-<li><a href="#callback">Processing callback methods</a>
-<li><a href="#enumerations">Processing enumeration classes</a>
-<li><a href="#serializable">Processing serializable classes</a>
-<li><a href="#beans">Processing bean classes</a>
-<li><a href="#annotations">Processing annotations</a>
-<li><a href="#database">Processing database drivers</a>
-<li><a href="#componentui">Processing ComponentUI classes</a>
-<li><a href="#rmi">Processing RMI code</a>
-<li><a href="#resourcefiles">Processing resource files</a>
-<li><a href="#stacktrace">Producing useful obfuscated stack traces</a>
-<li><a href="#repackaging">Obfuscating package names</a>
-<li><a href="#restructuring">Restructuring the output archives</a>
-<li><a href="#filtering">Filtering the input and the output</a>
-<li><a href="#multiple">Processing multiple applications at once</a>
-<li><a href="#incremental">Incremental obfuscation</a>
-<li><a href="#microedition">Preverifying class files for Java Micro Edition</a>
-<li><a href="#upgrade">Upgrading class files to Java 6</a>
-<li><a href="#deadcode">Finding dead code</a>
-<li><a href="#structure">Printing out the internal structure of class files</a>
-<li><a href="#annotated">Using annotations to configure ProGuard</a>
+<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.
-<a name="application">&nbsp;</a>
-<h3>A typical application</h3>
-To shrink, optimize, and obfuscate the ProGuard application itself, one would
-typically create a configuration file <code>proguard.pro</code> and then type:
+<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>
-java -jar proguard.jar @proguard.pro
+bin/proguard @myconfig.pro
</pre>
<p>
-The configuration file would contain the following options:
+The configuration file specifies the input, the output, and the entry points
+of the application:
<pre>
--injars proguard.jar
--outjars proguard_out.jar
+-injars myapplication.jar
+-outjars myapplication_out.jar
-libraryjars &lt;java.home&gt;/lib/rt.jar
--printmapping proguard.map
+-printmapping myapplication.map
--keep public class proguard.ProGuard {
+-keep public class mypackage.MyMain {
public static void main(java.lang.String[]);
}
</pre>
<p>
-Note the use of the <code>&lt;java.home&gt;</code> system property; it is
-replaced automatically.
-<p>
-Also note that all type names are fully specified:
-<code>proguard.ProGuard</code> and <code>java.lang.String[]</code>.
+Note the use of the <code>&lt;java.home&gt;</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
@@ -103,11 +122,10 @@ 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>. For processing 'simple' applications like ProGuard, that is not
-required.
+files</a>.
+
+<h3><a name="applet">A typical applet</a></h3>
-<a name="applet">&nbsp;</a>
-<h3>A typical applet</h3>
These options shrink, optimize, and obfuscate the applet
<code>mypackage.MyApplet</code>:
<pre>
@@ -129,15 +147,15 @@ classes</a>, <a href="#beans">bean classes</a>, <a
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="midlet">&nbsp;</a>
-<h3>A typical midlet</h3>
+<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.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
@@ -172,8 +190,8 @@ methods</a> and <a href="#resourcefiles">resource files</a>.
Note that you will still have to adapt the midlet jar size in the
corresponding jad file; ProGuard doesn't do that for you.
-<a name="jcapplet">&nbsp;</a>
-<h3>A typical Java Card applet</h3>
+<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>
@@ -192,8 +210,8 @@ The configuration is very similar to the configuration for midlets, except that
it now targets the Java Card run-time environment. This environment doesn't
have java.lang.Class, so we're telling ProGuard not to worry about it.
-<a name="xlet">&nbsp;</a>
-<h3>A typical xlet</h3>
+<h3><a name="xlet">A typical xlet</a></h3>
+
These options shrink, optimize, and obfuscate the xlet
<code>mypackage.MyXlet</code>:
<pre>
@@ -212,15 +230,16 @@ These options shrink, optimize, and obfuscate the xlet
The configuration is very similar to the configuration for midlets, except that
it now targets the CDC run-time environment with the Java TV API.
-<a name="androidapplication">&nbsp;</a>
-<h3>A typical Android application</h3>
-These options shrink, optimize, and obfuscate the simple Android application
-based on a single activity <code>mypackage.MyActivity</code>:
+<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 in.jar
--outjars out.jar
--libraryjars /usr/local/java/android-1.5_r1/platforms/android-1.5/android.jar
--overloadaggressively
+-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
@@ -228,27 +247,180 @@ based on a single activity <code>mypackage.MyActivity</code>:
-keep public class mypackage.MyActivity
</pre>
<p>
-The configuration is very similar to the configuration for midlets, except that
-it now targets the Android run-time environment.
+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>, and <a
-href="#resourcefiles">resource files</a>.
+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 Ant and Eclipse build processes of the Android SDK already integrate
+ProGuard by default, with all the proper settings. You only need to enable
+ProGuard (for release builds), 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). 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 &mdash; 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 from scratch: 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 &lt;init&gt;(android.content.Context);
+ public &lt;init&gt;(android.content.Context, android.util.AttributeSet);
+ public &lt;init&gt;(android.content.Context, android.util.AttributeSet, int);
+ public void set*(...);
+}
+
+-keepclasseswithmembers class * {
+ public &lt;init&gt;(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public &lt;init&gt;(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 android.os.Parcelable$Creator CREATOR;
+}
+
+-keepclassmembers class **.R$* {
+ public static &lt;fields&gt;;
+}
+
+-keepclassmembers class * {
+ @android.webkit.JavascriptInterface &lt;methods&gt;;
+}
+</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>
-<a name="library">&nbsp;</a>
-<h3>A typical library</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:
+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 &lt;java.home&gt;/lib/rt.jar
-printmapping out.map
+-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
@@ -273,6 +445,7 @@ serialization code:
-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();
@@ -289,12 +462,12 @@ 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, to implement the <code>.class</code>
-construct. ProGuard will automatically detect them and deal with them, even
-when their names have been obfuscated. However, older versions of ProGuard and
-other obfuscators may rely on the original method names. It may therefore be
-helpful to preserve them, in case these other obfuscators are ever used for
-further obfuscation of the library.
+<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.
@@ -307,6 +480,11 @@ classes otherwise.
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>
@@ -316,8 +494,8 @@ href="#serializable">serializable classes</a>, and <a
href="#annotations">annotations</a>, which are all discussed in their
respective examples.
-<a name="applications">&nbsp;</a>
-<h3>All possible applications in the input jars</h3>
+<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>
@@ -347,8 +525,8 @@ classes</a>, <a href="#beans">bean classes</a>, <a
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="applets">&nbsp;</a>
-<h3>All possible applets in the input jars</h3>
+<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>
@@ -372,15 +550,15 @@ classes</a>, <a href="#beans">bean classes</a>, <a
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="midlets">&nbsp;</a>
-<h3>All possible midlets in the input jars</h3>
+<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.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
@@ -412,8 +590,8 @@ methods</a> and <a href="#resourcefiles">resource files</a>.
Note that you will still have to adapt the midlet jar size in the
corresponding jad file; ProGuard doesn't do that for you.
-<a name="jcapplets">&nbsp;</a>
-<h3>All possible Java Card applets in the input jars</h3>
+<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>
@@ -435,8 +613,8 @@ interface.
The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
out which applets exactly will be preserved.
-<a name="xlets">&nbsp;</a>
-<h3>All possible xlets in the input jars</h3>
+<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>
@@ -458,38 +636,8 @@ We're simply keeping all classes that implement the <code>Xlet</code> interface.
The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
out which xlets exactly will be preserved.
-<a name="androidapplications">&nbsp;</a>
-<h3>All possible Android applications in the input jars</h3>
-These options shrink, optimize, and obfuscate all public activities, services,
-broadcast receivers, and content providers in <code>in.jar</code>:
-<pre>
--injars in.jar
--outjars out.jar
--libraryjars /usr/local/java/android-1.5_r1/platforms/android-1.5/android.jar
--overloadaggressively
--repackageclasses ''
--allowaccessmodification
--optimizations !code/simplification/arithmetic
--printseeds
-
--keep public class * extends android.app.Activity
--keep public class * extends android.app.Service
--keep public class * extends android.content.BroadcastReceiver
--keep public class * extends android.content.ContentProvider
-</pre>
-<p>
-We're keeping all classes that extend the base classes that may be referenced
-by the <code>AndroidManifest.xml</code> file of the application.
-<p>
-The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
-out which implementations 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>, and <a
-href="#resourcefiles">resource files</a>.
+<h3><a name="servlets">All possible servlets in the input jars</a></h3>
-<a name="servlets">&nbsp;</a>
-<h3>All possible servlets in the input jars</h3>
These options shrink, optimize, and obfuscate all public servlets in
<code>in.jar</code>:
<pre>
@@ -521,8 +669,77 @@ classes</a>, <a href="#beans">bean classes</a>, <a
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="native">&nbsp;</a>
-<h3>Processing native methods</h3>
+<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 &lt;java.home&gt;/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
@@ -543,8 +760,8 @@ 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.
-<a name="callback">&nbsp;</a>
-<h3>Processing callback methods</h3>
+<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
@@ -559,8 +776,8 @@ the following option will keep the callback class and method:
<p>
This will preserve the given class and method from being removed or renamed.
-<a name="enumerations">&nbsp;</a>
-<h3>Processing enumeration classes</h3>
+<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
@@ -576,8 +793,8 @@ removed or obfuscated:
}
</pre>
-<a name="serializable">&nbsp;</a>
-<h3>Processing serializable classes</h3>
+<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:
@@ -589,6 +806,7 @@ may require special attention:
<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();
@@ -602,8 +820,7 @@ may require special attention:
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.
- <p>
+ 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
@@ -617,7 +834,7 @@ may require special attention:
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
- static final java.io.ObjectStreamField[] serialPersistentFields;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient &lt;fields&gt;;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
@@ -632,7 +849,7 @@ may require special attention:
The <code>&lt;fields&gt;</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.
+ consistent names.</li>
<li>Occasionally, the serialized data have to remain compatible, but the
classes involved lack <code>serialVersionUID</code> fields. I imagine the
@@ -651,7 +868,7 @@ may require special attention:
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
- static final java.io.ObjectStreamField[] serialPersistentFields;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient &lt;fields&gt;;
!private &lt;fields&gt;;
!private &lt;methods&gt;;
@@ -668,7 +885,7 @@ may require special attention:
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>".
+ keeping all interfaces with "<code>-keep interface *</code>".</li>
</ul>
<p>
@@ -679,8 +896,8 @@ 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.
-<a name="beans">&nbsp;</a>
-<h3>Processing bean classes</h3>
+<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
@@ -696,8 +913,8 @@ names don't change. For instance:
</pre>
<p>
If there are too many elements to list explicitly, wildcards in class names
-and method signatures might be helpful. This example should encompasses all
-possible setters and getters in classes in the package <code>mybeans</code>:
+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*(***);
@@ -715,8 +932,8 @@ 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.
-<a name="annotations">&nbsp;</a>
-<h3>Processing annotations</h3>
+<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,
@@ -744,8 +961,8 @@ has to be preserved as well:
-keepattributes EnclosingMethod
</pre>
-<a name="database">&nbsp;</a>
-<h3>Processing database drivers</h3>
+<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:
@@ -758,8 +975,8 @@ This option also gets rid of the note that ProGuard prints out about
instantiating a driver in your code (without necessarily implementing any
drivers yourself).
-<a name="componentui">&nbsp;</a>
-<h3>Processing ComponentUI classes</h3>
+<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
@@ -773,8 +990,8 @@ point, for instance like this:
<p>
This option also keeps the classes themselves.
-<a name="rmi">&nbsp;</a>
-<h3>Processing RMI code</h3>
+<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:
@@ -798,8 +1015,29 @@ 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.
-<a name="resourcefiles">&nbsp;</a>
-<h3>Processing resource files</h3>
+<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
@@ -818,8 +1056,31 @@ 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.
-<a name="stacktrace">&nbsp;</a>
-<h3>Producing useful obfuscated stack traces</h3>
+<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>
@@ -844,8 +1105,8 @@ 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.
-<a name="repackaging">&nbsp;</a>
-<h3>Obfuscating package names</h3>
+<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>
@@ -951,8 +1212,37 @@ 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.
-<a name="restructuring">&nbsp;</a>
-<h3>Restructuring the output archives</h3>
+<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 &mdash; 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>
@@ -1022,12 +1312,12 @@ 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.
-<a name="filtering">&nbsp;</a>
-<h3>Filtering the input and the output</h3>
+<h3><a name="filtering">Filtering the input and the output</a></h3>
-If you want even greater control, you can add filters to the input and the
-output, filtering out zips, ears, wars, jars, and/or ordinary files. For
-example, if you want to disregard certain files from an input jar:
+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
@@ -1080,10 +1370,10 @@ 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
-the grouping of input and output.
+grouping input and output.
+
+<h3><a name="multiple">Processing multiple applications at once</a></h3>
-<a name="multiple">&nbsp;</a>
-<h3>Processing multiple applications at once</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.
@@ -1100,10 +1390,10 @@ just the input and output options:
</pre>
<p>
After processing, the directory <code>processed_applications</code> will
-contain the processed application jars, with their original names.
+contain processed versions of application jars, with their original names.
+
+<h3><a name="incremental">Incremental obfuscation</a></h3>
-<a name="incremental">&nbsp;</a>
-<h3>Incremental obfuscation</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:
@@ -1149,18 +1439,18 @@ jar as a library jar:
}
</pre>
-<a name="microedition">&nbsp;</a>
-<h3>Preverifying class files for Java Micro Edition</h3>
+<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 compared to the traditional external
+produces slightly more compact results than the traditional external
preverifier.
<pre>
-injars in.jar
-outjars out.jar
--libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
-dontshrink
-dontoptimize
@@ -1175,8 +1465,8 @@ 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.
-<a name="upgrade">&nbsp;</a>
-<h3>Upgrading class files to Java 6</h3>
+<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.
@@ -1198,8 +1488,8 @@ 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.
-<a name="deadcode">&nbsp;</a>
-<h3>Finding dead code</h3>
+<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>
@@ -1232,8 +1522,8 @@ that keeps those fields a priori, in order to avoid having them listed:
}
</pre>
-<a name="structure">&nbsp;</a>
-<h3>Printing out the internal structure of class files</h3>
+<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>
@@ -1250,8 +1540,7 @@ jar:
Note how we don't need to specify the Java run-time jar, because we're not
processing the input jar at all.
-<a name="annotated">&nbsp;</a>
-<h3>Using annotations to configure ProGuard</h3>
+<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
@@ -1291,12 +1580,12 @@ href="#annotations">annotations</a>.
<p>
The directory <code>examples/annotations</code> contains more examples that
illustrate some of the possibilities.
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright &copy; 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright &copy; 2002-2013
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>