File: examples.html

package info (click to toggle)
proguard 3.4-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 4,036 kB
  • ctags: 6,190
  • sloc: java: 33,225; xml: 279; makefile: 17; sh: 2
file content (683 lines) | stat: -rw-r--r-- 25,893 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//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>

<h2>Examples</h2>

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="#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="#servlets">All possible servlets in the input jars</a>
<li><a href="#library">Processing a library</a>
<li><a href="#native">Processing native methods</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="#rmi">Processing RMI code</a>
<li><a href="#stacktrace">Producing useful obfuscated stack traces</a>
<li><a href="#multiple">Processing multiple applications at once</a>
<li><a href="#incremental">Incremental obfuscation</a>
<li><a href="#deadcode">Finding dead code</a>
<li><a href="#structure">Printing out the internal structure of class files</a>
</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:
<pre>
java -jar proguard.jar @proguard.pro
</pre>
<p>

The configuration file would contain the following options:
<pre>
-injars       proguard.jar
-outjars      proguard_out.jar
-libraryjars  &lt;java.home&gt;/lib/rt.jar
-printmapping proguard.map
-overloadaggressively
-defaultpackage ''
-allowaccessmodification

-keep public class proguard.ProGuard {
    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 the type names are fully specified:
<code>proguard.ProGuard</code> and <code>java.lang.String[]</code>.
<p>
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>
We're using the <code>-overloadaggressively</code>,
<code>-defaultpackage</code>, and <code>-allowaccessmodification</code>
options to shave off some extra bytes, but we could leave them out as well.
The <code>-defaultpackage</code> directive moves all classes to the given
package, in this case the root package. Only <code>proguard.ProGuard</code>
keeps its original name.
<p>
We're writing out an obfuscation mapping file with <code>-printmapping</code>,
for de-obfuscating any stack traces later on, or for incremental obfuscation of
extensions.
<p>
In general, you might need a few additional directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>. For processing 'simple' applications like
ProGuard, that is not required.

<a name="applet">&nbsp;</a>
<h3>A typical applet</h3>
These options shrink, optimize, and obfuscate the applet
<code>mypackage.MyApplet</code>:
<pre>
-injars      in.jar
-outjars     out.jar
-libraryjars &lt;java.home&gt;/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 directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>.

<a name="midlet">&nbsp;</a>
<h3>A typical midlet</h3>
These options shrink, optimize, and obfuscate the J2ME 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
-overloadaggressively
-defaultpackage ''
-allowaccessmodification

-keep public class mypackage.MyMIDlet
</pre>
<p>
Note how we're now targeting the J2ME run-time environment of
<code>midpapi20.jar</code> and <code>cldcapi11.jar</code>, instead of the J2SE
run-time environment <code>rt.jar</code>. You can target other J2ME
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>
If applicable, you should add directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>.
<p>
You must preverify your midlets <i>after</i> having processed them, using
J2ME's <code>preverify</code> tool. Because this tool unpacks your processed
jars, you should use ProGuard's <code>-dontusemixedcaseclassnames</code>
option on platforms with case-insensitive filing systems, such as Windows.
<p>
Please note the in-depth article <a
href="http://developers.sun.com/techtopics/mobility/midp/ttips/proguard/">"Obfuscating
MIDlet Suites with ProGuard"</a> at <a
href="http://developers.sun.com/">developers.sun.com</a>.

<a name="applications">&nbsp;</a>
<h3>All possible applications in the input jars</h3>
These options shrink, optimize, and obfuscate all public applications in
<code>in.jar</code>:
<pre>
-injars      in.jar
-outjars     out.jar
-libraryjars &lt;java.home&gt;/lib/rt.jar
-printseeds

-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}
</pre>
<p>
Note the use of <code>-keepclasseswithmembers</code>. We don't want to preserve
all classes, just all classes that have main methods, and those methods.
<p>
The <code>-printseeds</code> 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 directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>.

<a name="applets">&nbsp;</a>
<h3>All possible applets in the input jars</h3>
These options shrink, optimize, and obfuscate all public applets in
<code>in.jar</code>:
<pre>
-injars      in.jar
-outjars     out.jar
-libraryjars &lt;java.home&gt;/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 <code>-printseeds</code> option prints out which applets exactly
will be preserved.
<p>
If applicable, you should add directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>.

<a name="midlets">&nbsp;</a>
<h3>All possible midlets in the input jars</h3>
These options shrink, optimize, and obfuscate all public J2ME 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
-overloadaggressively
-defaultpackage ''
-allowaccessmodification
-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>
And again, the <code>-printseeds</code> option prints out which midlets exactly
will be preserved.
<p>
If applicable, you should add directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>.
<p>
You must preverify your midlets <i>after</i> having processed them, using
J2ME's <code>preverify</code> tool. Because this tool unpacks your processed
jars, you should use ProGuard's <code>-dontusemixedcaseclassnames</code>
option on platforms with case-insensitive filing systems, such as Windows.

<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>
-injars      in.jar
-outjars     out.jar
-libraryjars &lt;java.home&gt;/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>
And again, the <code>-printseeds</code> option prints out which servlets
exactly will be preserved.
<p>
If applicable, you should add directives for processing <a
href="#native">native methods</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, or <a
href="#annotations">annotations</a>.

<a name="library">&nbsp;</a>
<h3>Processing a 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:
<pre>
-injars       in.jar
-outjars      out.jar
-libraryjars  &lt;java.home&gt;/lib/rt.jar
-printmapping out.map

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

-keep public class * {
    public protected *;
}

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

-keepclasseswithmembernames class * {
    native &lt;methods&gt;;
}

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

-keepclassmembers class * extends java.lang.Enum {
    public **[] values();
}
</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
<code>-keep</code> directives.
<p>
The <code>-keepclassmembernames</code> directive 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.
<p>
We've added some directives for keeping the "Deprecated" attribute, for <a
href="#stacktrace">useful stack traces</a>, for <a href="#native">native
methods</a>, <a href="#serializable">serializable classes</a>, and for <a
href="#annotations">annotations</a> (possibly with enumerations), which are
all discussed in their respective examples.
<p>
The "InnerClasses" attribute (or more precisely, its source name part) has to
be preserved as well, 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.

<a name="native">&nbsp;</a>
<h3>Processing native methods</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 class * {
    native &lt;methods&gt;;
}
</pre>
<p>
Note the use of <code>-keepclasseswithmembernames</code>. We don't want to
preserve all classes or all native methods; we just want to keep the relevant
names from being obfuscated.
<p>
ProGuard doesn't have your native code, so it can'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 name="serializable">&nbsp;</a>
<h3>Processing serializable classes</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 directives:

<pre>
-keepclassmembers class * implements java.io.Serializable {
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
</pre>
<p>

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

<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 directives 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;
    !static !transient &lt;fields&gt;;
    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> line makes sure that field is preserved.
    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.

<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 chapter on <a
    href="http://java.sun.com/j2se/1.4/docs/guide/serialization/spec/class.html#wp4100">Stream
    Unique Identifiers</a> of Sun's <a
    href="http://java.sun.com/j2se/1.4/docs/guide/serialization/">Object
    Serialization Guide</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;
    !static !transient &lt;fields&gt;;
    !private &lt;fields&gt;;
    !private &lt;methods&gt;;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
</pre>
<p>

    The new directives 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>".

</ul>
<p>

Note that the above directives 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 will
often produce more compact results.

<a name="beans">&nbsp;</a>
<h3>Processing bean classes</h3>
If your application, applet, servlet, library, etc., uses extensive
introspection on bean classes to find bean editor classes, or getter and
setter methods, then configuration may become laborious. 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 encompasses a wide range
of setters and getters:
<pre>
-keep class mybeans.** {
    void set*(%);
    void set*(**);
    void set*(%[]);
    void set*(**[]);
    void set*(int, %);
    void set*(int, **);

    %    get*();
    **   get*();
    %[]  get*();
    **[] get*();
    %    get*(int);
    **   get*(int);
}
</pre>
<p>
The '<code>%</code>' wildcard matches any primitive type, while the
'<code>**</code>' wildcard matches any class name. Array types  have to be
specified explicitly. This results in a short list of alternative method
signatures.

<a name="annotations">&nbsp;</a>
<h3>Processing annotations</h3>
As of JDK 5.0, class files can contain annotations. 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*

-keepclassmembers class * extends java.lang.Enum {
    public static **[] values();
}
</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>
If your annotations contain enumeration classes, you'll have to preserve the
<code>values()</code> method in these classes. The run-time environment
accesses this method by introspection (Isn't that just grand? Introspection is
the self-modifying code of a new generation).
<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
will have to be preserved as well:
<pre>
-keepattributes EnclosingMethod
</pre>

<a name="rmi">&nbsp;</a>
<h3>Processing RMI code</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>
-keep interface * extends java.rmi.Remote {
    &lt;methods&gt;;
}

-keep class * implements java.rmi.Remote {
    &lt;init&gt;(java.rmi.activation.ActivationID, java.rmi.MarshalledObject);
}
</pre>
<p>
The first directive keeps all your Remote interfaces and their methods. The
second one keeps all the implementations, along with their particular RMI
constructors, if any.

<a name="stacktrace">&nbsp;</a>
<h3>Producing useful obfuscated stack traces</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.

<a name="multiple">&nbsp;</a>
<h3>Processing multiple applications at once</h3>
You can process several 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
-injars  application.war
-outjars processed_applications
</pre>
<p>
After processing, the directory <code>processed_applications</code> will
contain the processed application jars and war, with their original names.
<p>
If you want explicit control over the output names, or 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 <code>-injars</code> and
<code>-outjars</code> options. For example:
<pre>
-injars  application1.jar
-injars  application2.jar
-injars  application3.jar
-outjars application_out1.war

-injars  application.war
-outjars application_out2.war
</pre>
<p>
This configuration creates two wars: one containing all processed application
jars, and one containing the processed contents of the input war.
<p>
Note that ProGuard will try to package output archives in a sensible way,
reconstructing the input entries as much as required. 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.

<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:
<pre>
-injars       proguardgui.jar
-outjars      proguardgui_out.jar
-libraryjars  &lt;java.home&gt;/lib/rt.jar
-libraryjars  proguard.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: the new one as the input jar, and the old
one as a library jar. The <code>-applymapping</code> 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.

<a name="deadcode">&nbsp;</a>
<h3>Finding dead code</h3>
These options list unused fields and methods in the application
<code>mypackage.MyApplication</code>:
<pre>
-injars      in.jar
-libraryjars &lt;java.home&gt;/lib/rt.jar
-dontoptimize
-dontobfuscate
-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.
<p>
We're saving a little bit of time by skipping the optimization and obfuscation
steps.

<a name="structure">&nbsp;</a>
<h3>Printing out the internal structure of class files</h3>
These options print out the internal structure of all class files in the input
jar:
<pre>
-injars in.jar
-dontshrink
-dontoptimize
-dontobfuscate
-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.
<p>

<hr>
<address>
Copyright &copy; 2002-2005
<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
</address>
</body>
</html>