add export to c# button
This commit is contained in:
parent
a1a397d06d
commit
1a20bea369
1
.idea/encodings.xml
generated
1
.idea/encodings.xml
generated
@ -2,5 +2,6 @@
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/data/colors.txt" charset="windows-1252" />
|
||||
<file url="file://$PROJECT_DIR$/data/places.txt" charset="windows-1252" />
|
||||
</component>
|
||||
</project>
|
@ -80,6 +80,7 @@ public class B3
|
||||
public final RadioButton msSqlStyle;
|
||||
public final CheckBox generateRelationalModelCB;
|
||||
public final Button saveSQLScriptBTN;
|
||||
public final Button saveCSScriptBTN;
|
||||
public final CheckBox generateInsertsCB;
|
||||
public final CheckBox singleInsertStatementCB;
|
||||
public final CheckBox addCurrentDateToDatabaseNameCB;
|
||||
@ -743,6 +744,22 @@ public class B3
|
||||
}
|
||||
});
|
||||
|
||||
this.saveCSScriptBTN = new Button("Generate/Save C# script");
|
||||
this.saveCSScriptBTN.setTooltip(new Tooltip("The ddl-script will be generated and saved into a file"));
|
||||
this.saveCSScriptBTN.setMaxWidth(Double.MAX_VALUE);
|
||||
setMouseHandler(this.saveCSScriptBTN);
|
||||
GridPane.setFillWidth(this.saveCSScriptBTN, Boolean.TRUE);
|
||||
this.saveCSScriptBTN.setBackground(new Background(new BackgroundFill(C2.ButtonBackgroundColor, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
|
||||
this.saveCSScriptBTN.setOnAction(arg0 -> {
|
||||
if (B3.this.generateRelationalModelCB.isSelected()) {
|
||||
try {
|
||||
B3.this.saveSQLScript();
|
||||
} catch (ZZ20 ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.generateInsertsCB = new CheckBox("Generate insert statement");
|
||||
this.generateInsertsCB.setTooltip(new Tooltip("If selected, insert statements are generated in the ddl-script"));
|
||||
@ -878,7 +895,14 @@ public class B3
|
||||
box.getChildren().addAll(this.addCurrentDateToDatabaseNameCB, this.generateInsertsCB, this.singleInsertStatementCB, this.saveSQLScriptBTN);
|
||||
TitledPane createddl = new TitledPane("Create DDL", box);
|
||||
createddl.setExpanded(false);
|
||||
this.buttonPane.add(createddl, 0, ri, 2, 1);
|
||||
this.buttonPane.add(createddl, 0, ri++, 2, 1);
|
||||
|
||||
VBox csbox = new VBox(10.0D);
|
||||
csbox.getChildren().addAll(saveCSScriptBTN);
|
||||
|
||||
TitledPane createcsharp = new TitledPane("Create C# Code", csbox);
|
||||
createcsharp.setExpanded(false);
|
||||
this.buttonPane.add(createcsharp, 0, ri, 2, 1);
|
||||
|
||||
this.statusInformation = new TextField("Creation Mode: entity-set -> press left mouse button on working area -> enter name of entity-set -> press enter key");
|
||||
this.statusInformation.setEditable(false);
|
||||
|
@ -7,6 +7,10 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/lib" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.idea" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/data" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/proguard" />
|
||||
<excludePattern pattern=".gitignore" />
|
||||
<excludePattern pattern="*.bat" />
|
||||
<excludePattern pattern="*.iml" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
BIN
noEasyDB_optimized.jar
Normal file
BIN
noEasyDB_optimized.jar
Normal file
Binary file not shown.
BIN
noEasyDB_optimized_old.jar
Normal file
BIN
noEasyDB_optimized_old.jar
Normal file
Binary file not shown.
1
optimize.bat
Normal file
1
optimize.bat
Normal file
@ -0,0 +1 @@
|
||||
proguard\bin\proguard.bat -verbose -injar out/artifacts/noEasyDB/noEasyDB.jar -outjars noEasyDB_optimized.jar -keep class at.fos.ermodel.gui.A1 { *; } -libraryjars "<java.home>/jmods/java.desktop.jmod;<java.home>/jmods/java.base.jmod;<java.home>/jmods/javafx.base.jmod;<java.home>/jmods/javafx.graphics.jmod;<java.home>/jmods/javafx.controls.jmod;<java.home>/jmods/javafx.swing.jmod"
|
339
proguard/LICENSE
Normal file
339
proguard/LICENSE
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
14
proguard/bin/proguard.bat
Normal file
14
proguard/bin/proguard.bat
Normal file
@ -0,0 +1,14 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Start-up script for ProGuard -- free class file shrinker, optimizer,
|
||||
REM obfuscator, and preverifier for Java bytecode.
|
||||
REM
|
||||
REM Note: when passing file names containing spaces to this script,
|
||||
REM you'll have to add escaped quotes around them, e.g.
|
||||
REM "\"C:/My Directory/My File.txt\""
|
||||
|
||||
IF EXIST "%PROGUARD_HOME%" GOTO home
|
||||
SET PROGUARD_HOME=%~dp0\..
|
||||
:home
|
||||
|
||||
java -jar "%PROGUARD_HOME%\lib\proguard.jar" %*
|
24
proguard/bin/proguard.sh
Normal file
24
proguard/bin/proguard.sh
Normal file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Start-up script for ProGuard -- free class file shrinker, optimizer,
|
||||
# obfuscator, and preverifier for Java bytecode.
|
||||
#
|
||||
# Note: when passing file names containing spaces to this script,
|
||||
# you'll have to add escaped quotes around them, e.g.
|
||||
# "\"/My Directory/My File.txt\""
|
||||
|
||||
# Account for possibly missing/basic readlink.
|
||||
# POSIX conformant (dash/ksh/zsh/bash).
|
||||
PROGUARD=`readlink -f "$0" 2>/dev/null`
|
||||
if test "$PROGUARD" = ''
|
||||
then
|
||||
PROGUARD=`readlink "$0" 2>/dev/null`
|
||||
if test "$PROGUARD" = ''
|
||||
then
|
||||
PROGUARD="$0"
|
||||
fi
|
||||
fi
|
||||
|
||||
PROGUARD_HOME=`dirname "$PROGUARD"`/..
|
||||
|
||||
java -jar "$PROGUARD_HOME/lib/proguard.jar" "$@"
|
14
proguard/bin/proguardgui.bat
Normal file
14
proguard/bin/proguardgui.bat
Normal file
@ -0,0 +1,14 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Start-up script for the GUI of ProGuard -- free class file shrinker,
|
||||
REM optimizer, obfuscator, and preverifier for Java bytecode.
|
||||
REM
|
||||
REM Note: when passing file names containing spaces to this script,
|
||||
REM you'll have to add escaped quotes around them, e.g.
|
||||
REM "\"C:/My Directory/My File.txt\""
|
||||
|
||||
IF EXIST "%PROGUARD_HOME%" GOTO home
|
||||
SET PROGUARD_HOME=%~dp0\..
|
||||
:home
|
||||
|
||||
java -jar "%PROGUARD_HOME%\lib\proguardgui.jar" %*
|
27
proguard/bin/proguardgui.sh
Normal file
27
proguard/bin/proguardgui.sh
Normal file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Start-up script for the GUI of ProGuard -- free class file shrinker,
|
||||
# optimizer, obfuscator, and preverifier for Java bytecode.
|
||||
#
|
||||
# Note: when passing file names containing spaces to this script,
|
||||
# you'll have to add escaped quotes around them, e.g.
|
||||
# "\"/My Directory/My File.txt\""
|
||||
|
||||
# Account for possibly missing/basic readlink.
|
||||
# POSIX conformant (dash/ksh/zsh/bash).
|
||||
PROGUARD=`readlink -f "$0" 2>/dev/null`
|
||||
if test "$PROGUARD" = ''
|
||||
then
|
||||
PROGUARD=`readlink "$0" 2>/dev/null`
|
||||
if test "$PROGUARD" = ''
|
||||
then
|
||||
PROGUARD="$0"
|
||||
fi
|
||||
fi
|
||||
|
||||
PROGUARD_HOME=`dirname "$PROGUARD"`/..
|
||||
|
||||
# On Linux, Java 1.6.0_24 and higher hang when starting the GUI:
|
||||
# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7027598
|
||||
# We're using the -D option as a workaround.
|
||||
java -DsuppressSwingDropSupport=true -jar "$PROGUARD_HOME/lib/proguardgui.jar" "$@"
|
14
proguard/bin/retrace.bat
Normal file
14
proguard/bin/retrace.bat
Normal file
@ -0,0 +1,14 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Start-up script for Retrace -- companion tool for ProGuard, free class file
|
||||
REM shrinker, optimizer, obfuscator, and preverifier for Java bytecode.
|
||||
REM
|
||||
REM Note: when passing file names containing spaces to this script,
|
||||
REM you'll have to add escaped quotes around them, e.g.
|
||||
REM "\"C:/My Directory/My File.txt\""
|
||||
|
||||
IF EXIST "%PROGUARD_HOME%" GOTO home
|
||||
SET PROGUARD_HOME=%~dp0\..
|
||||
:home
|
||||
|
||||
java -jar "%PROGUARD_HOME%\lib\retrace.jar" %*
|
24
proguard/bin/retrace.sh
Normal file
24
proguard/bin/retrace.sh
Normal file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Start-up script for Retrace -- companion tool for ProGuard, free class file
|
||||
# shrinker, optimizer, obfuscator, and preverifier for Java bytecode.
|
||||
#
|
||||
# Note: when passing file names containing spaces to this script,
|
||||
# you'll have to add escaped quotes around them, e.g.
|
||||
# "\"/My Directory/My File.txt\""
|
||||
|
||||
# Account for possibly missing/basic readlink.
|
||||
# POSIX conformant (dash/ksh/zsh/bash).
|
||||
PROGUARD=`readlink -f "$0" 2>/dev/null`
|
||||
if test "$PROGUARD" = ''
|
||||
then
|
||||
PROGUARD=`readlink "$0" 2>/dev/null`
|
||||
if test "$PROGUARD" = ''
|
||||
then
|
||||
PROGUARD="$0"
|
||||
fi
|
||||
fi
|
||||
|
||||
PROGUARD_HOME=`dirname "$PROGUARD"`/..
|
||||
|
||||
java -jar "$PROGUARD_HOME/lib/retrace.jar" "$@"
|
19
proguard/docs/downloads.md
Normal file
19
proguard/docs/downloads.md
Normal file
@ -0,0 +1,19 @@
|
||||
**ProGuard** is distributed under the terms of the GNU General Public License.
|
||||
Please consult the [license page](license.md) for more details.
|
||||
|
||||
ProGuard is written in Java, so it requires a Java Runtime Environment
|
||||
(JRE 1.8 or higher).
|
||||
|
||||
You can download ProGuard in various forms:
|
||||
|
||||
- [Pre-built artifacts](https://search.maven.org/search?q=g:com.guardsquare) at Maven Central
|
||||
- A [Git repository of the source code](https://github.com/Guardsquare/proguard) at Github
|
||||
- The [complete ProGuard manual](https://www.guardsquare.com/proguard) at Guardsquare
|
||||
|
||||
You can find major releases, minor releases with important bug fixes, and
|
||||
beta releases with the latest new features and any less urgent bug fixes.
|
||||
|
||||
If you're still working with an older version of ProGuard, check out the
|
||||
[release notes](releasenotes.md), to see if you're missing something essential.
|
||||
Unless noted otherwise, ProGuard remains compatible across versions, so
|
||||
don't be afraid to update.
|
36
proguard/docs/index.md
Normal file
36
proguard/docs/index.md
Normal file
@ -0,0 +1,36 @@
|
||||
**ProGuard** is a free Java class file shrinker, optimizer, obfuscator, and
|
||||
preverifier. It detects and removes unused classes, fields, methods, and
|
||||
attributes. It optimizes bytecode and removes unused instructions. It renames
|
||||
the remaining classes, fields, and methods using short meaningless names. The
|
||||
resulting applications and libraries are smaller, faster, and a bit better
|
||||
hardened against reverse engineering.
|
||||
|
||||
Typical applications:
|
||||
|
||||
- Reducing the size of apps for faster downloads, shorter startup
|
||||
times, and smaller memory footprints.
|
||||
- Optimizing code for better performance on mobile devices.
|
||||
|
||||
**ProGuard**'s main advantage compared to other Java obfuscators is probably
|
||||
its compact template-based configuration. A few intuitive command line options
|
||||
or a simple configuration file are usually sufficient. The user manual
|
||||
explains all available options and shows examples of this powerful
|
||||
configuration style.
|
||||
|
||||
**ProGuard** is fast. It only takes seconds to process programs and libraries
|
||||
of several megabytes. The results section presents actual figures for a number
|
||||
of applications.
|
||||
|
||||
**ProGuard** is a command-line tool with an optional graphical user interface.
|
||||
It also comes with plugins for Ant, for Gradle, and for the JME Wireless
|
||||
Toolkit. It is already part of Google's Android SDK, where it can be enabled
|
||||
with a simple flag.
|
||||
|
||||
**ProGuard** provides basic protection against reverse engineering and
|
||||
tampering, with basic name obfuscation.
|
||||
[**DexGuard**](http://www.guardsquare.com/dexguard), its specialized
|
||||
commercial extension for Android, focuses further on the protection of apps,
|
||||
additionally optimizing, obfuscating and encrypting strings, classes,
|
||||
resources, resource files, asset files, and native libraries. Professional
|
||||
developers should definitely consider it for security-sensitive apps.
|
||||
|
212
proguard/docs/manual/FAQ.md
Normal file
212
proguard/docs/manual/FAQ.md
Normal file
@ -0,0 +1,212 @@
|
||||
## What is shrinking? {: #shrinking}
|
||||
|
||||
Java source code (.java files) is typically compiled to bytecode (.class
|
||||
files). Bytecode is more compact than Java source code, but it may still
|
||||
contain a lot of unused code, especially if it includes program libraries.
|
||||
Shrinking programs such as **ProGuard** can analyze bytecode and remove unused
|
||||
classes, fields, and methods. The program remains functionally equivalent,
|
||||
including the information given in exception stack traces.
|
||||
|
||||
## What is name obfuscation? {: #obfuscation}
|
||||
|
||||
By default, compiled bytecode still contains a lot of debugging information:
|
||||
source file names, line numbers, field names, method names, argument names,
|
||||
variable names, etc. This information makes it straightforward to decompile
|
||||
the bytecode and reverse-engineer entire programs. Sometimes, this is not
|
||||
desirable. Shrinkers such as **ProGuard** can remove the debugging
|
||||
information and replace all names by meaningless character sequences, making
|
||||
apps smaller. The program remains functionally equivalent, except for the class
|
||||
names, method names, and line numbers given in exception stack traces.
|
||||
|
||||
## What is preverification? {: #preverification}
|
||||
|
||||
When loading class files, the class loader performs some sophisticated
|
||||
verification of the byte code. This analysis makes sure the code can't
|
||||
accidentally or intentionally break out of the sandbox of the virtual machine.
|
||||
Java Micro Edition and Java 6 introduced split verification. This means that
|
||||
the JME preverifier and the Java 6 compiler add preverification information to
|
||||
the class files (StackMap and StackMapTable attributes, respectively), in
|
||||
order to simplify the actual verification step for the class loader. Class
|
||||
files can then be loaded faster and in a more memory-efficient way.
|
||||
**ProGuard** automatically preverifies the code that it processes.
|
||||
|
||||
## What kind of optimizations does ProGuard support? {: #optimization}
|
||||
|
||||
Apart from removing unused classes, fields, and methods in the shrinking step,
|
||||
**ProGuard** can also perform optimizations at the bytecode level, inside and
|
||||
across methods. Thanks to techniques like control flow analysis, data flow
|
||||
analysis, partial evaluation, static single assignment, global value
|
||||
numbering, and liveness analysis, **ProGuard** can:
|
||||
|
||||
- Evaluate constant expressions.
|
||||
- Remove unnecessary field accesses and method calls.
|
||||
- Remove unnecessary branches.
|
||||
- Remove unnecessary comparisons and instanceof tests.
|
||||
- Remove unused code blocks.
|
||||
- Merge identical code blocks.
|
||||
- Reduce variable allocation.
|
||||
- Remove write-only fields and unused method parameters.
|
||||
- Inline constant fields, method parameters, and return values.
|
||||
- Inline methods that are short or only called once.
|
||||
- Simplify tail recursion calls.
|
||||
- Merge classes and interfaces.
|
||||
- Make methods private, static, and final when possible.
|
||||
- Make classes static and final when possible.
|
||||
- Replace interfaces that have single implementations.
|
||||
- Perform over 200 peephole optimizations, like replacing `"The answer is
|
||||
"+42` by `"The answer is 42"`.
|
||||
- Optionally remove logging code.
|
||||
|
||||
The positive effects of these optimizations will depend on your code and on
|
||||
the virtual machine on which the code is executed. Simple virtual machines may
|
||||
benefit more than advanced virtual machines with sophisticated JIT compilers.
|
||||
At the very least, your bytecode may become a bit smaller.
|
||||
|
||||
## Can I use ProGuard to process my commercial application? {: #commercial}
|
||||
|
||||
Yes, you can. **ProGuard** itself is distributed under the GPL, but this
|
||||
doesn't affect the programs that you process. Your code remains yours, and its
|
||||
license can remain the same.
|
||||
|
||||
## Does ProGuard work with Java 2, 5,..., 19? {: #jdk1.4}
|
||||
|
||||
Yes, **ProGuard** supports all JDKs from 1.1 up to and including 19. Java 2
|
||||
introduced some small differences in the class file format. Java 5 added
|
||||
attributes for generics and for annotations. Java 6 introduced optional
|
||||
preverification attributes. Java 7 made preverification obligatory and
|
||||
introduced support for dynamic languages. Java 8 added more attributes and
|
||||
default methods. Java 9 added support for modules. Java 11 added dynamic
|
||||
constants and nest-based access control. Java 14 added records. Java 15
|
||||
added sealed classes.
|
||||
**ProGuard** handles all versions correctly.
|
||||
|
||||
## Does ProGuard work with Java Micro Edition? {: #jme}
|
||||
|
||||
Yes. **ProGuard** itself runs in Java Standard Edition, but you can freely
|
||||
specify the run-time environment at which your programs are targeted,
|
||||
including Java Micro Edition. **ProGuard** then also performs the required
|
||||
preverification, producing more compact results than the traditional external
|
||||
preverifier.
|
||||
|
||||
## Does ProGuard Support Android Apps?
|
||||
|
||||
The **ProGuard Gradle Plugin** is compatible with Android Gradle Plugin (AGP) versions 4.x - 7.x.
|
||||
|
||||
The **ProGuard** [keep rules configuration format](configuration/usage.md) is also supported by R8 (the default Android shrinker),
|
||||
so you can use your R8, ProGuard and DexGuard keep rules interchangeably.
|
||||
|
||||
See [Gradle Plugin setup](setup/gradleplugin.md) page for more information.
|
||||
|
||||
## Does ProGuard have support for Ant? {: #ant}
|
||||
|
||||
Yes. **ProGuard** provides an Ant task, so that it integrates seamlessly into
|
||||
your Ant build process. You can still use configurations in **ProGuard**'s own
|
||||
readable format. Alternatively, if you prefer XML, you can specify the
|
||||
equivalent XML configuration.
|
||||
|
||||
See [Ant setup](setup/ant.md) page for more information.
|
||||
|
||||
## Does ProGuard have support for Java/Kotlin Gradle projects? {: #gradle}
|
||||
|
||||
Yes. **ProGuard** also provides a Gradle task, so that it integrates into your
|
||||
Gradle build process. You can specify configurations in **ProGuard**'s own
|
||||
format or embedded in the Groovy configuration.
|
||||
|
||||
See [Gradle setup](setup/gradle.md) page for more information.
|
||||
|
||||
## Does ProGuard have support for Maven? {: #maven}
|
||||
|
||||
While we don't officially provide a Maven integration and
|
||||
we cannot provide support there are solutions available,
|
||||
their offered functionality is not guaranteed by Guardsquare.
|
||||
|
||||
Some open-source implementations:
|
||||
|
||||
- [https://github.com/wvengen/proguard-maven-plugin](https://github.com/wvengen/proguard-maven-plugin)
|
||||
- [https://github.com/dingxin/proguard-maven-plugin](https://github.com/dingxin/proguard-maven-plugin)
|
||||
|
||||
## Does ProGuard come with a GUI? {: #gui}
|
||||
|
||||
Yes. First of all, **ProGuard** is perfectly usable as a command-line tool
|
||||
that can easily be integrated into any automatic build process. For casual
|
||||
users, there's also a graphical user interface that simplifies creating,
|
||||
loading, editing, executing, and saving ProGuard configurations.
|
||||
|
||||
## Does ProGuard handle `Class.forName` calls? {: #forname}
|
||||
|
||||
Yes. **ProGuard** automatically handles constructs like
|
||||
`Class.forName("SomeClass")` and `SomeClass.class`. The referenced classes are
|
||||
preserved in the shrinking phase, and the string arguments are properly
|
||||
replaced in the obfuscation phase.
|
||||
|
||||
With variable string arguments, it's generally not possible to determine their
|
||||
possible values. They might be read from a configuration file, for instance.
|
||||
However, **ProGuard** will note a number of constructs like
|
||||
"`(SomeClass)Class.forName(variable).newInstance()`". These might be an
|
||||
indication that the class or interface `SomeClass` and/or its implementations
|
||||
may need to be preserved. The developer can adapt his configuration
|
||||
accordingly.
|
||||
|
||||
## Does ProGuard handle resource files? {: #resource}
|
||||
|
||||
Yes. **ProGuard** copies all non-class resource files, optionally adapting
|
||||
their names and their contents to the obfuscation that has been applied.
|
||||
|
||||
## Does ProGuard encrypt string constants? {: #encrypt}
|
||||
|
||||
No. String encryption in program code has to be perfectly reversible by
|
||||
definition, so it only improves the obfuscation level. It increases the
|
||||
footprint of the code. However, by popular demand, **ProGuard**'s
|
||||
closed-source sibling for Android,
|
||||
[**DexGuard**](http://www.guardsquare.com/dexguard), does provide string
|
||||
encryption, along with more protection techniques against static and dynamic
|
||||
analysis.
|
||||
|
||||
## Does ProGuard perform control flow obfuscation?
|
||||
|
||||
No. Control flow obfuscation injects additional branches into the bytecode, in
|
||||
an attempt to fool decompilers. **ProGuard** does not do this, except to some
|
||||
extent in its optimization techniques. **ProGuard**'s closed-source sibling
|
||||
for Android, [**DexGuard**](http://www.guardsquare.com/dexguard), does offer
|
||||
control flow obfuscation, as one of the many additional techniques to harden
|
||||
Android apps.
|
||||
|
||||
## Does ProGuard support incremental obfuscation? {: #incremental}
|
||||
|
||||
Yes. This feature allows you to specify a previous obfuscation mapping file in
|
||||
a new obfuscation step, in order to produce add-ons or patches for obfuscated
|
||||
code.
|
||||
|
||||
## Can ProGuard obfuscate using reserved keywords? {: #keywords}
|
||||
|
||||
Yes. You can specify your own obfuscation dictionary, such as a list of
|
||||
reserved key words, identifiers with foreign characters, random source files,
|
||||
or a text by Shakespeare. Note that this hardly improves the obfuscation.
|
||||
Decent decompilers can automatically replace reserved keywords, and the effect
|
||||
can be undone fairly easily, by obfuscating again with simpler names.
|
||||
|
||||
## Can ProGuard reconstruct obfuscated stack traces? {: #stacktrace}
|
||||
|
||||
Yes. **ProGuard** comes with a companion tool, **ReTrace**, that can
|
||||
'de-obfuscate' stack traces produced by obfuscated applications. The
|
||||
reconstruction is based on the mapping file that **ProGuard** can write out.
|
||||
If line numbers have been obfuscated away, a list of alternative method names
|
||||
is presented for each obfuscated method name that has an ambiguous reverse
|
||||
mapping. Please refer to the [ProGuard User Manual](manual/index.md) for more
|
||||
details.
|
||||
|
||||
## How is DexGuard different from ProGuard?
|
||||
|
||||
[**DexGuard**](http://www.guardsquare.com/dexguard) is a commercial extension
|
||||
of **ProGuard**:
|
||||
|
||||
- **DexGuard** is specialized for Android applications and libraries: it
|
||||
optimizes and obfuscates not just the bytecode, but also the manifest file,
|
||||
resources, resource files, asset files, and native libraries.
|
||||
- **DexGuard** focuses on making apps self-defending against reverse
|
||||
engineering and tampering. **DexGuard**'s techniques for obfuscation,
|
||||
encryption, and detection are a lot stronger than **ProGuard**'s basic name
|
||||
obfuscation.
|
||||
- **DexGuard** is backward compatible with **ProGuard**: it reads the same
|
||||
configuration. It already comes with tuned configuration for the Android
|
||||
runtime and for common Android libraries.
|
71
proguard/docs/manual/building.md
Normal file
71
proguard/docs/manual/building.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Building ProGuard
|
||||
|
||||
!!! info
|
||||
|
||||
**ProGuard** is distributed under the terms of the GNU General Public License. Please consult the [license page](license/license.md) for more details.
|
||||
|
||||
Building ProGuard is easy - you'll need:
|
||||
|
||||
* a Java 8 JDK installed
|
||||
* a clone of the [ProGuard](https://github.com/Guardsquare/proguard.git) repository
|
||||
|
||||
You can then execute a composite build with the following Gradle command:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```bash
|
||||
./gradlew assemble
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
```bash
|
||||
gradlew assemble
|
||||
```
|
||||
|
||||
|
||||
The artifacts will be generated in the `lib` directory. You can then execute ProGuard using the
|
||||
scripts in `bin`, for example:
|
||||
|
||||
=== "Linux/macOS"
|
||||
|
||||
```bash
|
||||
bin/proguard.sh
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
|
||||
```bash
|
||||
bin\proguard.bat
|
||||
```
|
||||
|
||||
## Publish to Maven local
|
||||
|
||||
|
||||
You can publish the artifacts to your local Maven cache (something like `~/.m2/`):
|
||||
|
||||
=== "Linux/macOS"
|
||||
```bash
|
||||
./gradlew publishToMavenLocal
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
```bash
|
||||
gradlew publishToMavenLocal
|
||||
```
|
||||
|
||||
## Building a release distribution
|
||||
|
||||
You can build tar and zip archives with the binaries and documentation:
|
||||
|
||||
|
||||
=== "Linux/macOS"
|
||||
|
||||
```bash
|
||||
./gradlew distTar distZip
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
|
||||
```bash
|
||||
gradlew distTar distZip
|
||||
```
|
||||
|
176
proguard/docs/manual/configuration/attributes.md
Normal file
176
proguard/docs/manual/configuration/attributes.md
Normal file
@ -0,0 +1,176 @@
|
||||
Class files essentially define classes, their fields, and their methods. A lot
|
||||
of essential and non-essential data are attached to these classes, fields, and
|
||||
methods as *attributes*. For instance, attributes can contain bytecode, source
|
||||
file names, line number tables, etc.
|
||||
|
||||
ProGuard's obfuscation step removes attributes that are generally not
|
||||
necessary for executing the code. With the
|
||||
[`-keepattributes`](usage.md#keepattributes) option, you can specify a filter
|
||||
for attributes that you do want to keep, for instance if your code accesses
|
||||
them through reflection, or if you want to preserve some compilation or
|
||||
debugging information. The filter works like any [filter](usage.md#filters) in
|
||||
ProGuard.
|
||||
|
||||
The following wildcards are supported:
|
||||
|
||||
| Wildcard | Meaning
|
||||
|-----|----------------------------------------------------
|
||||
| `?` | matches any single character in an attribute name.
|
||||
| `*` | matches any part of an attribute name.
|
||||
|
||||
An attribute name that is preceded by an exclamation mark '**!**' is
|
||||
*excluded* from further attempts to match with *subsequent* attribute names in
|
||||
the filter. Make sure to specify filters correctly, since they are not checked
|
||||
for potential typos.
|
||||
|
||||
For example, the following setting preserves the optional attributes that are
|
||||
typically necessary when processing code that is intended to be used as a
|
||||
library:
|
||||
```proguard
|
||||
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
|
||||
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
|
||||
```
|
||||
|
||||
The Java bytecode specifications currently specify the following list of
|
||||
attributes.
|
||||
|
||||
## Optional attributes
|
||||
|
||||
ProGuard's obfuscation step by default discards the following optional
|
||||
attributes. You can keep them with the
|
||||
[`-keepattributes`](usage.md#keepattributes) option.
|
||||
|
||||
`SourceFile`
|
||||
: Specifies the name of the source file from which the class file was
|
||||
compiled. If present, this name is reported in stack traces.
|
||||
|
||||
`SourceDir`<div>(J++ extension)</div>
|
||||
: Specifies the name of the source directory from which the class file was
|
||||
compiled.
|
||||
|
||||
`Record` <div>(Java 14 or higher)</div>
|
||||
: Specifies the components of a record class. Code may access this information
|
||||
by reflection.
|
||||
|
||||
`InnerClasses`
|
||||
: Specifies the relationship between a class and its inner classes and outer
|
||||
classes. Other than this and the naming convention with a '\$' separator
|
||||
between the names of inner classes and outer classes, inner classes are just
|
||||
like ordinary classes. Compilers may need this information to find classes
|
||||
referenced in a compiled library. Code may access this information by
|
||||
reflection, for instance to derive the simple name of the class.
|
||||
|
||||
`PermittedSubclasses` <div>(Java 15 or higher)</div>
|
||||
: Specifies the allowed extensions or implementations of sealed classes or
|
||||
interfaces.
|
||||
|
||||
`EnclosingMethod`<div>(Java 5 or higher)</div>
|
||||
: Specifies the method in which the class was defined. Compilers may need this
|
||||
information to find classes referenced in a compiled library. Code may
|
||||
access this information by reflection, for instance to derive the simple
|
||||
name of the class.
|
||||
|
||||
`Deprecated`
|
||||
: Indicates that the class, field, or method is deprecated.
|
||||
|
||||
`Synthetic`
|
||||
: Indicates that the class, field, or method was generated by the compiler.
|
||||
|
||||
`Signature`<div>(Java 5 or higher)</div>
|
||||
: Specifies the generic signature of the class, field, or method. Compilers
|
||||
may need this information to properly compile classes that use generic types
|
||||
from compiled libraries. Code may access this signature by reflection.
|
||||
|
||||
`MethodParameters`<div>(Java 8 or higher)</div>
|
||||
: Specifies the names and access flags of the parameters of the method. Code
|
||||
may access this information by reflection.
|
||||
|
||||
`Exceptions`
|
||||
: Specifies the exceptions that a method may throw. Compilers may use this
|
||||
information to enforce catching them.
|
||||
|
||||
`LineNumberTable`
|
||||
: Specifies the line numbers of the method. If present, these line numbers are
|
||||
reported in stack traces.
|
||||
|
||||
`LocalVariableTable`
|
||||
: Specifies the names and types of local variables of the method. If present,
|
||||
some IDEs may use this information for helping with auto-completion.
|
||||
|
||||
`LocalVariableTypeTable`<div>(Java 5 or higher)</div>
|
||||
: Specifies the names and generic types of local variables of the method. If
|
||||
present, some IDEs may use this information for helping with
|
||||
auto-completion.
|
||||
|
||||
`RuntimeVisibleAnnotations`<div>(Java 5 or higher)</div>
|
||||
: Specifies the annotations that are visible at run-time, for classes, fields,
|
||||
and methods. Compilers and annotation processors may use these annotations.
|
||||
Code may access them by reflection.
|
||||
|
||||
`RuntimeInvisibleAnnotations`<div>(Java 5 or higher)</div>
|
||||
|
||||
: Specifies the annotations that are visible at compile-time, for classes,
|
||||
fields, and methods. Compilers and annotation processors may use these
|
||||
annotations.
|
||||
|
||||
`RuntimeVisibleParameterAnnotations`<div>(Java 5 or higher)</div>
|
||||
|
||||
: Specifies the annotations that are visible at run-time, for method
|
||||
parameters. Compilers and annotation processors may use these annotations.
|
||||
Code may access them by reflection.
|
||||
|
||||
`RuntimeInvisibleParameterAnnotations`<div>(Java 5 or higher)</div>
|
||||
|
||||
: Specifies the annotations that are visible at compile-time, for method
|
||||
parameters. Compilers and annotation processors may use these annotations.
|
||||
|
||||
`RuntimeVisibleTypeAnnotations`<div>(Java 8 or higher)</div>
|
||||
: Specifies the annotations that are visible at run-time, for generic types,
|
||||
instructions, etc. Compilers and annotation processors may use these
|
||||
annotations. Code may access them by reflection.
|
||||
|
||||
`RuntimeInvisibleTypeAnnotations`<div>(Java 8 or higher)</div>
|
||||
|
||||
: Specifies the annotations that are visible at compile-time, for generic
|
||||
types, instructions, etc. Compilers and annotation processors may use these
|
||||
annotations.
|
||||
|
||||
`AnnotationDefault`<div>(Java 5 or higher)</div>
|
||||
: Specifies a default value for an annotation.
|
||||
|
||||
## Essential attributes
|
||||
|
||||
ProGuard automatically keeps the following essential attributes, processing
|
||||
them as necessary. We're listing them for the sake of completeness:
|
||||
|
||||
`ConstantValue`
|
||||
: Specifies a constant integer, float, class, string, etc.
|
||||
|
||||
`Code`
|
||||
: Specifies the actual bytecode of a method.
|
||||
|
||||
`StackMap`<div>(Java Micro Edition)</div>
|
||||
: Provides preverification information. The Java Virtual Machine can use this
|
||||
information to speed up the verification step when loading a class.
|
||||
|
||||
`StackMapTable`<div>(Java 6 or higher)</div>
|
||||
: Provides preverification information. The Java Virtual Machine can use this
|
||||
information to speed up the verification step when loading a class.
|
||||
|
||||
`BootstrapMethods`<div>(Java 7 or higher)</div>
|
||||
: Specifies the methods to bootstrap dynamic method invocations.
|
||||
|
||||
`Module`<div>(Java 9 or higher)</div>
|
||||
: Specifies the dependencies of a _module_.
|
||||
|
||||
`ModuleMainClass`<div>(Java 9 or higher)</div>
|
||||
: Specifies the main class of a _module_.
|
||||
|
||||
`ModulePackages`<div>(Java 9 or higher)</div>
|
||||
: Specifies the packages of a _module_.
|
||||
|
||||
`NestHost`<div>(Java 11 or higher)</div>
|
||||
: Specifies the host class of a _nest_, for example an outer class.
|
||||
|
||||
`NestMembers`<div>(Java 11 or higher)</div>
|
||||
: Specifies the members of a _nest_, for example the inner classes.
|
1409
proguard/docs/manual/configuration/examples.md
Normal file
1409
proguard/docs/manual/configuration/examples.md
Normal file
File diff suppressed because it is too large
Load Diff
221
proguard/docs/manual/configuration/optimizations.md
Normal file
221
proguard/docs/manual/configuration/optimizations.md
Normal file
@ -0,0 +1,221 @@
|
||||
The optimization step of ProGuard can be switched off with the
|
||||
[`-dontoptimize`](usage.md#dontoptimize) option. For more fine-grained
|
||||
control over individual optimizations, experts can use the
|
||||
[`-optimizations`](usage.md#optimizations) option, with a filter based
|
||||
on the optimization names listed below. The filter works like any
|
||||
[filter](usage.md#filters) in ProGuard.
|
||||
|
||||
The following wildcards are supported:
|
||||
|
||||
| Wildcard | Meaning
|
||||
|-----|-------------------------------------------------------
|
||||
| `?` | matches any single character in an optimization name.
|
||||
| `*` | matches any part of an optimization name.
|
||||
|
||||
An optimization that is preceded by an exclamation mark '**!**' is
|
||||
*excluded* from further attempts to match with *subsequent* optimization
|
||||
names in the filter. Make sure to specify filters correctly, since they
|
||||
are not checked for potential typos.
|
||||
|
||||
For example,
|
||||
"**`code/simplification/variable,code/simplification/arithmetic`**" only
|
||||
performs the two specified peephole optimizations.
|
||||
|
||||
For example, "`!method/propagation/*`" performs all optimizations,
|
||||
except the ones that propagate values between methods.
|
||||
|
||||
For example, "`!code/simplification/advanced,code/simplification/*`"
|
||||
only performs all peephole optimizations.
|
||||
|
||||
Some optimizations necessarily imply other optimizations. These are then
|
||||
indicated. Note that the list is likely to change for newer versions, as
|
||||
optimizations are added and reorganized.
|
||||
|
||||
`library/gson`
|
||||
: Optimizes usages of the Gson library, whenever possible. See [Gson
|
||||
optimization](optimizations.md#gson) for more details.
|
||||
|
||||
`class/marking/final`
|
||||
: Marks classes as final, whenever possible.
|
||||
|
||||
`class/unboxing/enum`
|
||||
: Simplifies enum types to integer constants, whenever possible.
|
||||
|
||||
`class/merging/vertical`
|
||||
: Merges classes vertically in the class hierarchy, whenever possible.
|
||||
|
||||
`class/merging/horizontal`
|
||||
: Merges classes horizontally in the class hierarchy, whenever possible.
|
||||
|
||||
`class/merging/wrapper`
|
||||
: Merges wrapper classes with their wrapped classes, whenever possible.
|
||||
|
||||
`field/removal/writeonly`<div>(⇒ `code/removal/advanced`)</div>
|
||||
: Removes write-only fields.
|
||||
|
||||
`field/marking/private`
|
||||
: Marks fields as private, whenever possible.
|
||||
|
||||
`field/generalization/class`
|
||||
: Generalizes the classes of field accesses, whenever possible.
|
||||
|
||||
`field/specialization/type`
|
||||
: Specializes the types of fields, whenever possible
|
||||
|
||||
`field/propagation/value`<div>(⇒ `code/simplification/advanced`)</div>
|
||||
: Propagates the values of fields across methods.
|
||||
|
||||
`method/marking/private`
|
||||
: Marks methods as private, whenever possible (*devirtualization*).
|
||||
|
||||
`method/marking/static`<div>(⇒ `code/removal/advanced`)</div>
|
||||
: Marks methods as static, whenever possible (*devirtualization*).
|
||||
|
||||
`method/marking/final`
|
||||
: Marks methods as final, whenever possible.
|
||||
|
||||
`method/marking/synchronized`
|
||||
: Unmarks methods as synchronized, whenever possible.
|
||||
|
||||
`method/removal/parameter`<div>(⇒ `code/removal/advanced`)</div>
|
||||
: Removes unused method parameters.
|
||||
|
||||
`method/generalization/class`
|
||||
: Generalizes the classes of method invocations, whenever possible.
|
||||
|
||||
`method/specialization/parametertype`
|
||||
: Specializes the types of method parameters, whenever possible.
|
||||
|
||||
`method/specialization/returntype`
|
||||
: Specializes the types of method return values, whenever possible.
|
||||
|
||||
`method/propagation/parameter`<div>(⇒ `code/simplification/advanced`)</div>
|
||||
: Propagates the values of method parameters from method invocations to the
|
||||
invoked methods.
|
||||
|
||||
`method/propagation/returnvalue`<div>(⇒ `code/simplification/advanced`)</div>
|
||||
: Propagates the values of method return values from methods to their
|
||||
invocations.
|
||||
|
||||
`method/inlining/short`
|
||||
: Inlines short methods.
|
||||
|
||||
`method/inlining/unique`
|
||||
: Inlines methods that are only called once.
|
||||
|
||||
`method/inlining/tailrecursion`
|
||||
: Simplifies tail recursion calls, whenever possible.
|
||||
|
||||
`code/merging`
|
||||
: Merges identical blocks of code by modifying branch targets.
|
||||
|
||||
`code/simplification/variable`
|
||||
: Performs peephole optimizations for variable loading and storing.
|
||||
|
||||
`code/simplification/arithmetic`
|
||||
: Performs peephole optimizations for arithmetic instructions.
|
||||
|
||||
`code/simplification/cast`
|
||||
: Performs peephole optimizations for casting operations.
|
||||
|
||||
`code/simplification/field`
|
||||
: Performs peephole optimizations for field loading and storing.
|
||||
|
||||
`code/simplification/branch`<div>(⇒ `code/removal/simple`)</div>
|
||||
: Performs peephole optimizations for branch instructions.
|
||||
|
||||
`code/simplification/object`
|
||||
: Performs peephole optimizations for object instantiation.
|
||||
|
||||
`code/simplification/string`
|
||||
: Performs peephole optimizations for constant strings.
|
||||
|
||||
`code/simplification/math`
|
||||
: Performs peephole optimizations for Math method calls.
|
||||
|
||||
`code/simplification/advanced`<div>(*best used with* `code/removal/advanced`)</div>
|
||||
: Simplifies code based on control flow analysis and data flow analysis.
|
||||
|
||||
`code/removal/advanced`<div>(⇒ `code/removal/exception`)</div>
|
||||
: Removes dead code based on control flow analysis and data flow analysis.
|
||||
|
||||
`code/removal/simple`<div>(⇒ `code/removal/exception`)</div>
|
||||
: Removes dead code based on a simple control flow analysis.
|
||||
|
||||
`code/removal/variable`
|
||||
: Removes unused variables from the local variable frame.
|
||||
|
||||
`code/removal/exception`
|
||||
: Removes exceptions with empty try blocks.
|
||||
|
||||
`code/allocation/variable`
|
||||
: Optimizes variable allocation on the local variable frame.
|
||||
|
||||
ProGuard also provides some unofficial settings to control
|
||||
optimizations, that may disappear in future versions. These are Java
|
||||
system properties, which can be set as JVM arguments (with `-D...`):
|
||||
|
||||
`maximum.inlined.code.length` (default = 8 bytes)
|
||||
: Specifies the maximum code length (expressed in bytes) of short methods
|
||||
that are eligible to be inlined. Inlining methods that are too long may
|
||||
unnecessarily inflate the code size.
|
||||
|
||||
`maximum.resulting.code.length` (default = 8000 bytes for JSE, 2000 bytes for JME)
|
||||
: Specifies the maximum resulting code length (expressed in bytes) allowed
|
||||
when inlining methods. Many Java virtual machines do not apply just-in-time
|
||||
compilation to methods that are too long, so it's important not to let them
|
||||
grow too large.
|
||||
|
||||
## Aggressive optimization
|
||||
|
||||
ProGuard provides the `-optimizeaggressively` option. If set, this enables more
|
||||
aggressive assumptions during optimization. This might lead to
|
||||
improved performance and/or reduced code size, but might result in different behavior in rare cases.
|
||||
For example, reading from an array might cause an
|
||||
`ArrayIndexOutOfBoundsException` to be thrown. Strictly speaking, this means
|
||||
that such an instruction can have a side effect. If this instruction is removed
|
||||
during optimization, the code will thus behave differently under specific
|
||||
circumstances. By default, such instructions are always preserved. Setting this
|
||||
option will lead to these instructions being candidates for removal during
|
||||
optimization. Additionally, class merging is only enabled when this option is set.
|
||||
|
||||
## Gson optimization {: #gson}
|
||||
|
||||
ProGuard optimizes Gson code by detecting which domain classes are serialized
|
||||
using the Gson library. It replaces the reflection-based implementation of
|
||||
GSON for reading and writing fields with injected and optimized code that
|
||||
accesses the fields of the domain classes directly when reading and writing
|
||||
JSON. The benefits of this optimization are the following:
|
||||
|
||||
- Domain classes used in conjunction with GSON can be freely obfuscated.
|
||||
- The injected serialization code gives better performance compared to the
|
||||
GSON implementation, which relies on reflection.
|
||||
- Less configuration is needed as the optimization automatically keeps classes
|
||||
and fields that are required for serialization.
|
||||
|
||||
### Configuration
|
||||
|
||||
The Gson optimization is enabled by default and doesn't require any additional
|
||||
configuration, as long as the application code doesn't use unsupported Gson
|
||||
features(see [Known limitations](optimizations.md#gsonlimitations)).
|
||||
|
||||
### Known limitations {: #gsonlimitations}
|
||||
|
||||
ProGuard can not optimize the following use cases of Gson:
|
||||
|
||||
- Serializing classes containing one of the following Gson annotations:
|
||||
- `@JsonAdapter`
|
||||
- `@Since`
|
||||
- `@Until`
|
||||
- Serializing classes that have generic type variables in their signature.
|
||||
- Serializing classes using a Gson instance that was built with one of the
|
||||
following settings on the GsonBuilder:
|
||||
- `excludeFieldsWithModifier`
|
||||
- `setFieldNamingPolicy`
|
||||
|
||||
When one of the above Gson features is used, ProGuard automatically preserves
|
||||
the original Gson implementation for all affected domain classes.
|
||||
|
||||
This means that the serialized fields of these domain classes need to be
|
||||
explicitly kept again in the ProGuard configuration so that they can be
|
||||
safely accessed through reflection.
|
1020
proguard/docs/manual/configuration/usage.md
Normal file
1020
proguard/docs/manual/configuration/usage.md
Normal file
File diff suppressed because it is too large
Load Diff
40
proguard/docs/manual/feedback.md
Normal file
40
proguard/docs/manual/feedback.md
Normal file
@ -0,0 +1,40 @@
|
||||
By now, we've invested an enormous amount of time in **ProGuard**. You can
|
||||
help by providing feedback! If you have problems, bugs, bug fixes, ideas,
|
||||
encouragements, etc., please let us know.
|
||||
|
||||
At [Guardsquare](http://www.guardsquare.com/), we develop ProGuard and its
|
||||
professional siblings DexGuard (for Android) and iXGuard (for iOS). If you
|
||||
find ProGuard useful and you are interested in more features or professional
|
||||
support, this is the place to go.
|
||||
|
||||
ProGuard is currently hosted on GitHub:
|
||||
|
||||
- You can report issues on our
|
||||
[issue tracker](https://github.com/Guardsquare/proguard/issues).
|
||||
|
||||
- You can clone the
|
||||
[source code](https://github.com/Guardsquare/proguard) yourself and create
|
||||
[pull requests](https://github.com/Guardsquare/proguard/pulls).
|
||||
|
||||
!!! tip
|
||||
The [***Guardsquare Community***](https://community.guardsquare.com/) is the place to be for all your ProGuard-related questions and feedback.
|
||||
|
||||
You may also find answers on
|
||||
[Stack Overflow](http://stackoverflow.com/questions/tagged/proguard).
|
||||
|
||||
ProGuard used to be hosted on Sourceforge:
|
||||
|
||||
- You can still read answers in the [help
|
||||
forum](https://sourceforge.net/projects/proguard/forums/forum/182456).
|
||||
|
||||
- You can still find discussions in the [open discussion
|
||||
forum](https://sourceforge.net/projects/proguard/forums/forum/182455).
|
||||
|
||||
- We still have reports on the
|
||||
[bug tracking page](http://sourceforge.net/p/proguard/bugs/).
|
||||
|
||||
- We still have new ideas on the the
|
||||
[feature request page](http://sourceforge.net/p/proguard/feature-requests/).
|
||||
|
||||
- You can still find all earlier versions in the
|
||||
[download section](https://sourceforge.net/projects/proguard/files/).
|
126
proguard/docs/manual/home.md
Normal file
126
proguard/docs/manual/home.md
Normal file
@ -0,0 +1,126 @@
|
||||
Welcome to the manual for **ProGuard** version 7.3 ([what's new?](releasenotes.md)).
|
||||
|
||||
ProGuard is an open-sourced Java class file shrinker, optimizer, obfuscator, and
|
||||
preverifier. As a result, ProGuard processed applications and libraries are smaller and faster.
|
||||
|
||||
- The ***shrinking step*** detects and removes unused classes, fields, methods, and
|
||||
attributes.
|
||||
- The ***optimizer step*** optimizes bytecode and removes unused instructions.
|
||||
- The ***name obfuscation step*** renames the remaining classes, fields, and methods using short meaningless names.
|
||||
- The final ***preverification step*** adds preverification information to the classes, which is required for Java Micro Edition and for Java 6 and higher.
|
||||
|
||||
The default Android shrinker, R8, is compatible with ProGuard [configuration](configuration/usage.md).
|
||||
|
||||
If you are getting started with ProGuard, please follow the [Quick Start](building.md) guide in order to arrive at a basic setup for your application or library as quickly as possible.
|
||||
|
||||
Experienced users can directly consult the [Configuration section](configuration/usage.md) where all features are described.
|
||||
|
||||
If during the process you run into any issues, please make sure to check the [Troubleshooting section](troubleshooting/troubleshooting.md).
|
||||
|
||||
## How it works
|
||||
|
||||
<div class="center">
|
||||
<div class="diagram">
|
||||
<div class="row">
|
||||
<div class="green box">Input jars</div>
|
||||
<div class="right arrow">shrink</div>
|
||||
<div class="right arrow">optimize</div>
|
||||
<div class="right arrow">obfuscate</div>
|
||||
<div class="right arrow">preverify</div>
|
||||
<div class="green box">Output jars</div>
|
||||
</div>
|
||||
<div class="distributed">
|
||||
<div class="green box">Library jars</div>
|
||||
<div class="right arrow">(unchanged)</div>
|
||||
<div class="green box">Library jars</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
ProGuard first reads the **input jars** (or aars, wars, ears, zips, apks, or
|
||||
directories). It then subsequently shrinks, optimizes, obfuscates, and
|
||||
preverifies them. You can optionally let ProGuard perform multiple
|
||||
optimization passes. ProGuard writes the processed results to one or more
|
||||
**output jars** (or aars, wars, ears, zips, apks, or directories). The input
|
||||
may contain resource files, whose names and contents can optionally be updated
|
||||
to reflect the obfuscated class names.
|
||||
|
||||
ProGuard requires the **library jars** (or aars, wars, ears, zips, apks, or
|
||||
directories) of the input jars to be specified. These are essentially the
|
||||
libraries that you would need for compiling the code. ProGuard uses them to
|
||||
reconstruct the class dependencies that are necessary for proper processing.
|
||||
The library jars themselves always remain unchanged. You should still put them
|
||||
in the class path of your final application.
|
||||
|
||||
## Entry points
|
||||
|
||||
In order to determine which code has to be preserved and which code can be
|
||||
discarded or obfuscated, you have to specify one or more *entry points* to
|
||||
your code. These entry points are typically classes with main methods,
|
||||
applets, midlets, activities, etc.
|
||||
|
||||
- In the **shrinking step**, ProGuard starts from these seeds and recursively
|
||||
determines which classes and class members are used. All other classes and
|
||||
class members are discarded.
|
||||
- In the **optimization step**, ProGuard further optimizes the code. Among
|
||||
other optimizations, classes and methods that are not entry points can be
|
||||
made private, static, or final, unused parameters can be removed, and some
|
||||
methods may be inlined.
|
||||
- In the **name obfuscation step**, ProGuard renames classes and class members that
|
||||
are not entry points. In this entire process, keeping the entry points
|
||||
ensures that they can still be accessed by their original names.
|
||||
- The **preverification step** is the only step that doesn't have to know the
|
||||
entry points.
|
||||
|
||||
The [Usage section](configuration/usage.md) of this manual describes the necessary [`-keep`
|
||||
options](configuration/usage.md#keepoptions) and the [Examples section](configuration/examples.md)
|
||||
provides plenty of examples.
|
||||
|
||||
## Reflection
|
||||
|
||||
Reflection and introspection present particular problems for any automatic
|
||||
processing of code. In ProGuard, classes or class members in your code that
|
||||
are created or invoked dynamically (that is, by name) have to be specified as
|
||||
entry points too. For example, `Class.forName()` constructs may refer to any
|
||||
class at run-time. It is generally impossible to compute which classes have to
|
||||
be preserved (with their original names), since the class names might be read
|
||||
from a configuration file, for instance. You therefore have to specify them in
|
||||
your ProGuard configuration, with the same simple [`-keep`](configuration/usage.md#keep)
|
||||
options.
|
||||
|
||||
However, ProGuard already detects and handles the following cases for you:
|
||||
|
||||
- `Class.forName("SomeClass")`
|
||||
- `SomeClass.class`
|
||||
- `SomeClass.class.getField("someField")`
|
||||
- `SomeClass.class.getDeclaredField("someField")`
|
||||
- `SomeClass.class.getMethod("someMethod", null)`
|
||||
- `SomeClass.class.getMethod("someMethod", new Class[] { A.class,... })`
|
||||
- `SomeClass.class.getDeclaredMethod("someMethod", null)`
|
||||
- `SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class,... })`
|
||||
- `AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")`
|
||||
- `AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")`
|
||||
- `AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")`
|
||||
|
||||
The names of the classes and class members may of course be different,
|
||||
but the constructs should be literally the same for ProGuard to
|
||||
recognize them. The referenced classes and class members are preserved
|
||||
in the shrinking phase, and the string arguments are properly updated in
|
||||
the obfuscation phase.
|
||||
|
||||
Furthermore, ProGuard will offer some suggestions if keeping some
|
||||
classes or class members appears necessary. For example, ProGuard will
|
||||
note constructs like
|
||||
"`(SomeClass)Class.forName(variable).newInstance()`". These might be an
|
||||
indication that the class or interface `SomeClass` and/or its
|
||||
implementations may need to be preserved. You can then adapt your
|
||||
configuration accordingly.
|
||||
|
||||
!!! tip
|
||||
Generate an instrumented build to allow ProGuard finding cases of reflection at *run-time*. The tailored configuration advice for your application will be outputted to the console, and can be copy/pasted to your configuration. To do so, just enable the option [`-addconfigurationdebugging`](configuration/usage.md#addconfigurationdebugging)
|
||||
|
||||
|
||||
For proper results, you should at least be somewhat familiar with the
|
||||
code that you are processing. Obfuscating code that performs a lot of
|
||||
reflection may require trial and error, especially without the necessary
|
||||
information about the internals of the code.
|
6
proguard/docs/manual/languages/java.md
Normal file
6
proguard/docs/manual/languages/java.md
Normal file
@ -0,0 +1,6 @@
|
||||
## Java language support
|
||||
|
||||
!!! Warning
|
||||
ProGuard no longer supports backporting, and cannot backport class files compiled with Java >11.
|
||||
|
||||
Provide supports Java versions up to and including 19.
|
83
proguard/docs/manual/languages/kotlin.md
Normal file
83
proguard/docs/manual/languages/kotlin.md
Normal file
@ -0,0 +1,83 @@
|
||||
The Kotlin compiler injects code and metadata into the classes that it generates to support features not natively supported by the Java and Android environments. The metadata injected by the Kotlin compiler takes the shape of an annotation added to classes which leaks semantic information that can aid attackers.
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
In most cases, you do not need to keep Kotlin metadata for app projects - therefore, no configuration changes are necessary and the Kotlin metadata can be safely removed.
|
||||
However, there are two common reasons to explicitly keep the metadata, [reflection](#reflection) and [libraries](#library-projects).
|
||||
|
||||
ProGuard will only keep the Kotlin metadata of a class if you explicitly keep that class or one of its members, and you add the `-keep class kotlin.Metadata` option to your configuration.
|
||||
Note that this option may also be required by an SDK of your project, and indirectly added as a consumer rule.
|
||||
|
||||
For example, if you have the following keep rule for a Kotlin class named `com.example.KotlinExample`, by default the class will be kept but its metadata will not:
|
||||
|
||||
```
|
||||
# Keep the class com.example.KotlinExample
|
||||
-keep class com.example.KotlinExample
|
||||
```
|
||||
|
||||
You can add `-keep class kotlin.Metadata` to your configuration to instruct ProGuard to keep and adapt Kotlin metadata:
|
||||
|
||||
```
|
||||
# Add this option to tell ProGuard to keep and adapt Kotlin metadata
|
||||
-keep class kotlin.Metadata
|
||||
```
|
||||
|
||||
|
||||
### App Projects
|
||||
|
||||
|
||||
The most common case to keep Kotlin metadata would be if you use the [kotlin-reflect](https://kotlinlang.org/docs/reference/reflection.html) library. Just like when using Java reflection, you will need `-keep` rules in your configuration to keep the specific classes and members accessed through reflection.
|
||||
|
||||
In this case, to instruct ProGuard to keep and adapt the corresponding Kotlin metadata, add the following to your configuration:
|
||||
|
||||
```
|
||||
-keep class kotlin.Metadata
|
||||
```
|
||||
|
||||
A popular framework that relies on reflection is [Jackson](https://github.com/FasterXML/jackson-module-kotlin).
|
||||
|
||||
### Library Projects
|
||||
|
||||
When developing an SDK that exposes Kotlin-specific features to its users, you need to preserve the metadata of the public API.
|
||||
These include features such as named parameters, suspend functions, top-level functions and type aliases.
|
||||
|
||||
In the case of a library, you would already be keeping the public API, so you can simply add the following
|
||||
to your configuration:
|
||||
|
||||
```
|
||||
-keep class kotlin.Metadata
|
||||
```
|
||||
|
||||
## Protection
|
||||
|
||||
### Obfuscation
|
||||
|
||||
ProGuard will apply the same obfuscations to Kotlin identifiers in metadata, such as class or member names, to match those in the Java class files.
|
||||
This ensures that, even where the Kotlin metadata is required, no sensitive names remain in the metadata.
|
||||
|
||||
### Shrinking
|
||||
|
||||
ProGuard will remove all unused Kotlin metadata components such as unused functions and properties.
|
||||
This ensures that, even where the Kotlin metadata is required, only the used components are kept.
|
||||
|
||||
|
||||
|
||||
### Data Classes
|
||||
|
||||
Data classes in Kotlin have an auto-generated `toString` method that lists all properties
|
||||
of the class and their value. ProGuard automatically detects these classes and adapts
|
||||
the names of properties to their obfuscated counterpart.
|
||||
|
||||
### Intrinsics Null Checks
|
||||
|
||||
To better support java interoperability, Kotlin injects numerous method calls to e.g.
|
||||
check that a parameter is not null when it wasn't marked as `Nullable`. In pure Kotlin
|
||||
codebases, these injected method calls are unnecessary and instead leak information
|
||||
via their parameters (e.g. names of checked parameters).
|
||||
|
||||
ProGuard automatically detects calls to these methods and removes the Strings to
|
||||
ensure that the resulting code contains no references to original parameter names, member names etc.
|
||||
|
||||
|
259
proguard/docs/manual/license/gpl.md
Normal file
259
proguard/docs/manual/license/gpl.md
Normal file
@ -0,0 +1,259 @@
|
||||
# GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place -
|
||||
Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
## Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public License is intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users. This General Public License applies to
|
||||
most of the Free Software Foundation's software and to any other program whose
|
||||
authors commit to using it. (Some other Free Software Foundation software is
|
||||
covered by the GNU Library General Public License instead.) You can apply it
|
||||
to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom to
|
||||
distribute copies of free software (and charge for this service if you wish),
|
||||
that you receive source code or can get it if you want it, that you can change
|
||||
the software or use pieces of it in new free programs; and that you know you
|
||||
can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to
|
||||
deny you these rights or to ask you to surrender the rights. These
|
||||
restrictions translate to certain responsibilities for you if you distribute
|
||||
copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that you have. You must
|
||||
make sure that they, too, receive or can get the source code. And you must
|
||||
show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If the
|
||||
software is modified by someone else and passed on, we want its recipients to
|
||||
know that what they have is not the original, so that any problems introduced
|
||||
by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents.
|
||||
We wish to avoid the danger that redistributors of a free program will
|
||||
individually obtain patent licenses, in effect making the program
|
||||
proprietary. To prevent this, we have made it clear that any patent must
|
||||
be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
**0.** This License applies to any program or other work which contains a
|
||||
notice placed by the copyright holder saying it may be distributed under the
|
||||
terms of this General Public License. The "Program", below, refers to any such
|
||||
program or work, and a "work based on the Program" means either the Program or
|
||||
any derivative work under copyright law: that is to say, a work containing the
|
||||
Program or a portion of it, either verbatim or with modifications and/or
|
||||
translated into another language. (Hereinafter, translation is included
|
||||
without limitation in the term "modification".) Each licensee is addressed as
|
||||
"you".
|
||||
|
||||
Activities other than copying, distribution and modification are not covered
|
||||
by this License; they are outside its scope. The act of running the Program is
|
||||
not restricted, and the output from the Program is covered only if its
|
||||
contents constitute a work based on the Program (independent of having been
|
||||
made by running the Program). Whether that is true depends on what the Program
|
||||
does.
|
||||
|
||||
**1.** You may copy and distribute verbatim copies of the Program's source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||
and to the absence of any warranty; and give any other recipients of the
|
||||
Program a copy of this License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you may
|
||||
at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
**2.** You may modify your copy or copies of the Program or any portion of it,
|
||||
thus forming a work based on the Program, and copy and distribute such
|
||||
modifications or work under the terms of Section 1 above, provided that you
|
||||
also meet all of these conditions:
|
||||
|
||||
- **a)** You must cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change.
|
||||
- **b)** You must cause any work that you distribute or publish, that in whole
|
||||
or in part contains or is derived from the Program or any part thereof, to
|
||||
be licensed as a whole at no charge to all third parties under the terms of
|
||||
this License.
|
||||
- **c)** If the modified program normally reads commands interactively when
|
||||
run, you must cause it, when started running for such interactive use in the
|
||||
most ordinary way, to print or display an announcement including an
|
||||
appropriate copyright notice and a notice that there is no warranty (or
|
||||
else, saying that you provide a warranty) and that users may redistribute
|
||||
the program under these conditions, and telling the user how to view a copy
|
||||
of this License. (Exception: if the Program itself is interactive but does
|
||||
not normally print such an announcement, your work based on the Program is
|
||||
not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License,
|
||||
and its terms, do not apply to those sections when you distribute them as
|
||||
separate works. But when you distribute the same sections as part of a whole
|
||||
which is a work based on the Program, the distribution of the whole must be on
|
||||
the terms of this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise the
|
||||
right to control the distribution of derivative or collective works based on
|
||||
the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program with
|
||||
the Program (or with a work based on the Program) on a volume of a storage or
|
||||
distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
**3.** You may copy and distribute the Program (or a work based on it, under
|
||||
Section 2) in object code or executable form under the terms of Sections 1 and
|
||||
2 above provided that you also do one of the following:
|
||||
|
||||
- **a)** Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2 above on
|
||||
a medium customarily used for software interchange; or,
|
||||
- **b)** Accompany it with a written offer, valid for at least three years, to
|
||||
give any third party, for a charge no more than your cost of physically
|
||||
performing source distribution, a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of Sections 1
|
||||
and 2 above on a medium customarily used for software interchange; or,
|
||||
- **c)** Accompany it with the information you received as to the offer to
|
||||
distribute corresponding source code. (This alternative is allowed only for
|
||||
noncommercial distribution and only if you received the program in object
|
||||
code or executable form with such an offer, in accord with Subsection b
|
||||
above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable work, complete source code means all
|
||||
the source code for all modules it contains, plus any associated interface
|
||||
definition files, plus the scripts used to control compilation and
|
||||
installation of the executable. However, as a special exception, the source
|
||||
code distributed need not include anything that is normally distributed (in
|
||||
either source or binary form) with the major components (compiler, kernel, and
|
||||
so on) of the operating system on which the executable runs, unless that
|
||||
component itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access to
|
||||
copy from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place counts as distribution of the source code,
|
||||
even though third parties are not compelled to copy the source along with the
|
||||
object code.
|
||||
|
||||
**4.** You may not copy, modify, sublicense, or distribute the Program except
|
||||
as expressly provided under this License. Any attempt otherwise to copy,
|
||||
modify, sublicense or distribute the Program is void, and will automatically
|
||||
terminate your rights under this License. However, parties who have received
|
||||
copies, or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
**5.** You are not required to accept this License, since you have not signed
|
||||
it. However, nothing else grants you permission to modify or distribute the
|
||||
Program or its derivative works. These actions are prohibited by law if you do
|
||||
not accept this License. Therefore, by modifying or distributing the Program
|
||||
(or any work based on the Program), you indicate your acceptance of this
|
||||
License to do so, and all its terms and conditions for copying, distributing
|
||||
or modifying the Program or works based on it.
|
||||
|
||||
**6.** Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the original
|
||||
licensor to copy, distribute or modify the Program subject to these terms and
|
||||
conditions. You may not impose any further restrictions on the recipients'
|
||||
exercise of the rights granted herein. You are not responsible for enforcing
|
||||
compliance by third parties to this License.
|
||||
|
||||
**7.** If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or otherwise)
|
||||
that contradict the conditions of this License, they do not excuse you from
|
||||
the conditions of this License. If you cannot distribute so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not distribute the Program at all.
|
||||
For example, if a patent license would not permit royalty-free redistribution
|
||||
of the Program by all those who receive copies directly or indirectly through
|
||||
you, then the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system, which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose that
|
||||
choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
**8.** If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original
|
||||
copyright holder who places the Program under this License may add an explicit
|
||||
geographical distribution limitation excluding those countries, so that
|
||||
distribution is permitted only in or among countries not thus excluded. In
|
||||
such case, this License incorporates the limitation as if written in the body
|
||||
of this License.
|
||||
|
||||
**9.** The Free Software Foundation may publish revised and/or new versions of
|
||||
the General Public License from time to time. Such new versions will be
|
||||
similar in spirit to the present version, but may differ in detail to address
|
||||
new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any later
|
||||
version", you have the option of following the terms and conditions either of
|
||||
that version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of this License,
|
||||
you may choose any version ever published by the Free Software Foundation.
|
||||
|
||||
**10.** If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author to
|
||||
ask for permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make
|
||||
exceptions for this. Our decision will be guided by the two goals of
|
||||
preserving the free status of all derivatives of our free software and of
|
||||
promoting the sharing and reuse of software generally.
|
||||
|
||||
**NO WARRANTY**
|
||||
|
||||
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE
|
||||
THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
|
||||
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
|
||||
LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
|
||||
THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
36
proguard/docs/manual/license/gplexception.md
Normal file
36
proguard/docs/manual/license/gplexception.md
Normal file
@ -0,0 +1,36 @@
|
||||
# Special Exception to the GNU General Public License
|
||||
|
||||
Copyright © 2002-2020 Guardsquare NV
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
In addition, as a special exception, Guardsquare NV gives permission to link
|
||||
the code of this program with the following stand-alone applications:
|
||||
|
||||
- Gradle,
|
||||
- Apache Ant,
|
||||
- Apache Maven,
|
||||
- the Google Android SDK,
|
||||
- the Intel TXE/DAL SDK,
|
||||
- the Eclipse ProGuardDT GUI,
|
||||
- the EclipseME JME IDE,
|
||||
- the Oracle NetBeans Java IDE,
|
||||
- the Oracle JME Wireless Toolkit, and
|
||||
- the Simple Build Tool for Scala (and its scripts).
|
||||
|
||||
and distribute linked combinations including the two. You must obey the GNU
|
||||
General Public License in all respects for all of the code used other than
|
||||
these programs. If you modify this file, you may extend this exception to your
|
||||
version of the file, but you are not obligated to do so. If you do not wish to
|
||||
do so, delete this exception statement from your version.
|
26
proguard/docs/manual/license/license.md
Normal file
26
proguard/docs/manual/license/license.md
Normal file
@ -0,0 +1,26 @@
|
||||
**ProGuard** is free. You can use it freely for processing your applications,
|
||||
commercial or not. Your code obviously remains yours after having been
|
||||
processed, and its license can remain unchanged.
|
||||
|
||||
The **ProGuard code** itself is copyrighted, but its distribution license
|
||||
provides you with some rights for modifying and redistributing its code and
|
||||
its documentation. More specifically, ProGuard is distributed under the terms
|
||||
of the [GNU General Public License](gpl.md) (GPL), version 2, as published by
|
||||
the [Free Software Foundation](http://www.fsf.org/) (FSF).
|
||||
|
||||
In short, this means that you may freely redistribute the program, modified or
|
||||
as is, on the condition that you make the complete source code available as
|
||||
well. If you develop a program that is linked with ProGuard, the program as a
|
||||
whole has to be distributed at no charge under the GPL.
|
||||
|
||||
We are granting a [special exception](gplexception.md) to the latter clause
|
||||
(in wording suggested by the
|
||||
[FSF](http://www.gnu.org/copyleft/gpl-faq.html#GPLIncompatibleLibs)), for
|
||||
combinations with the following stand-alone applications: Gradle, Apache Ant,
|
||||
Apache Maven, the Google Android SDK, the Intel TXE/DAL SDK, the Eclipse
|
||||
ProGuardDT GUI, the EclipseME JME IDE, the Oracle NetBeans Java IDE, the
|
||||
Oracle JME Wireless Toolkit, and the Simple Build Tool for Scala.
|
||||
|
||||
The **ProGuard user documentation** is copyrighted as well. It may only
|
||||
be redistributed without changes, along with the unmodified version of
|
||||
the code.
|
78
proguard/docs/manual/quickstart.md
Normal file
78
proguard/docs/manual/quickstart.md
Normal file
@ -0,0 +1,78 @@
|
||||
# Quick Start
|
||||
|
||||
This page will guide you through the basic steps of processing your application or library with ProGuard.
|
||||
For details on advanced settings or more background information please refer to the relevant parts of the manual.
|
||||
|
||||
|
||||
There are two ways to execute ProGuard:
|
||||
|
||||
1. Standalone
|
||||
2. Integrated mode in your Gradle, Ant or Maven project.
|
||||
|
||||
You can also build ProGuard from [source](https://github.com/Guardsquare/proguard) by following the [build instructions](building.md).
|
||||
|
||||
## Standalone
|
||||
|
||||
Firstly, download a [ProGuard release](https://github.com/Guardsquare/proguard/releases) or [build ProGuard](building.md) from source.
|
||||
ProGuard can then be executed directly from the command line by calling a script found in the `bin` directory:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```bash
|
||||
bin/proguard.sh -injars path/to/my-application.jar \
|
||||
-outjars path/to/obfuscated-application.jar \
|
||||
-libraryjars path/to/java/home/lib/rt.jar
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
```bat
|
||||
bin\proguard.bat -injars path/to/my-application.jar ^
|
||||
-outjars path/to/obfuscated-application.jar ^
|
||||
-libraryjars path/to/java/home/lib/rt.jar
|
||||
```
|
||||
|
||||
For more detailed information see [standalone mode](setup/standalone.md).
|
||||
|
||||
## Integrated
|
||||
|
||||
The ProGuard artifacts are hosted at [Maven Central](https://search.maven.org/search?q=g:com.guardsquare).
|
||||
|
||||
### Android Gradle project
|
||||
|
||||
When working on your Android application (apk, aab) or library (aar), you can include ProGuard in your Gradle build by:
|
||||
|
||||
- Using ProGuard's Gradle plugin, which you can apply in your `build.gradle` file (AGP 4.x - 7.x).
|
||||
- Using the integrated ProGuard by disabling R8 in your `gradle.properties` (only applicable for AGP < 7).
|
||||
|
||||
For more detailed information see [Android Gradle](setup/gradleplugin.md).
|
||||
|
||||
### Java or Kotlin Gradle project
|
||||
|
||||
Your non-mobile Java or Kotlin applications can execute ProGuard's Gradle task:
|
||||
```proguard
|
||||
task myProguardTask(type: proguard.gradle.ProGuardTask) {
|
||||
.....
|
||||
}
|
||||
```
|
||||
|
||||
For more detailed information see [Java/Kotlin Gradle](setup/gradle.md).
|
||||
|
||||
### Ant project
|
||||
|
||||
You can also include ProGuard in your Ant build, all you have to do is to include the related task into your `build.xml` file:
|
||||
```xml
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="/usr/local/java/proguard/lib/proguard.jar" />
|
||||
```
|
||||
|
||||
For more detailed information see [Ant](setup/ant.md).
|
||||
|
||||
|
||||
### Maven project
|
||||
|
||||
!!! warning
|
||||
While we don't officially provide a maven integration and we cannot provide support there are solutions available, their offered functionality is not guaranteed by Guardsquare.
|
||||
|
||||
Some open-source implementations:
|
||||
|
||||
- [https://github.com/wvengen/proguard-maven-plugin](https://github.com/wvengen/proguard-maven-plugin)
|
||||
- [https://github.com/dingxin/proguard-maven-plugin](https://github.com/dingxin/proguard-maven-plugin)
|
141
proguard/docs/manual/refcard.md
Normal file
141
proguard/docs/manual/refcard.md
Normal file
@ -0,0 +1,141 @@
|
||||
## Usage
|
||||
|
||||
| OS | Command
|
||||
|------------|-----------------------------
|
||||
| Windows: | `proguard` *options* ...
|
||||
| Linux/Mac: | `proguard.sh` *options* ...
|
||||
|
||||
Typically:
|
||||
|
||||
| OS | Command
|
||||
|------------|-----------------------------
|
||||
| Windows: | `proguard @myconfig.pro`
|
||||
| Linux/Mac: | `proguard.sh @myconfig.pro`
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Meaning
|
||||
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------
|
||||
| [`@`](configuration/usage.md#at)[*filename*](configuration/usage.md#filename) | Short for '`-include` *filename*'.
|
||||
| [`-include`](configuration/usage.md#include) [*filename*](configuration/usage.md#filename) | Read configuration options from the given file.
|
||||
| [`-basedirectory`](configuration/usage.md#basedirectory) [*directoryname*](configuration/usage.md#filename) | Specifies the base directory for subsequent relative file names.
|
||||
| [`-injars`](configuration/usage.md#injars) [*class\_path*](configuration/usage.md#classpath) | Specifies the program jars (or apks, aabs, aars, wars, ears, jmods, zips, or directories).
|
||||
| [`-outjars`](configuration/usage.md#outjars) [*class\_path*](configuration/usage.md#classpath) | Specifies the names of the output jars (or apks, aabs, aars, wars, ears, jmods, zips, or directories).
|
||||
| [`-libraryjars`](configuration/usage.md#libraryjars) [*class\_path*](configuration/usage.md#classpath) | Specifies the library jars (or apks, aabs, aars, wars, ears, jmods, zips, or directories).
|
||||
| [`-skipnonpubliclibraryclasses`](configuration/usage.md#skipnonpubliclibraryclasses) | Ignore non-public library classes.
|
||||
| [`-dontskipnonpubliclibraryclasses`](configuration/usage.md#dontskipnonpubliclibraryclasses) | Don't ignore non-public library classes (the default).
|
||||
| [`-dontskipnonpubliclibraryclassmembers`](configuration/usage.md#dontskipnonpubliclibraryclassmembers) | Don't ignore package visible library class members.
|
||||
| [`-keepdirectories`](configuration/usage.md#keepdirectories) \[[*directory\_filter*](configuration/usage.md#filters)\] | Keep the specified directories in the output jars (or wars, ears, zips, or directories).
|
||||
| [`-target`](configuration/usage.md#target) *version* | **deprecated** Set the given version number in the processed classes.
|
||||
| [`-forceprocessing`](configuration/usage.md#forceprocessing) | Process the input, even if the output seems up to date.
|
||||
| [`-keep`](configuration/usage.md#keep) \[[,*modifier*](configuration/usage.md#keepoptionmodifiers),...\] [*class\_specification*](configuration/usage.md#classspecification) | Preserve the specified classes *and* class members.
|
||||
| [`-keepclassmembers`](configuration/usage.md#keepclassmembers) \[[,*modifier*](configuration/usage.md#keepoptionmodifiers),...\] [*class\_specification*](configuration/usage.md#classspecification) | Preserve the specified class members, if their classes are preserved as well.
|
||||
| [`-keepclasseswithmembers`](configuration/usage.md#keepclasseswithmembers) \[[,*modifier*](configuration/usage.md#keepoptionmodifiers),...\] [*class\_specification*](configuration/usage.md#classspecification) | Preserve the specified classes *and* class members, if all of the specified class members are present.
|
||||
| [`-keepnames`](configuration/usage.md#keepnames) [*class\_specification*](configuration/usage.md#classspecification) | Preserve the names of the specified classes *and* class members (if they aren't removed in the shrinking step).
|
||||
| [`-keepclassmembernames`](configuration/usage.md#keepclassmembernames) [*class\_specification*](configuration/usage.md#classspecification) | Preserve the names of the specified class members (if they aren't removed in the shrinking step).
|
||||
| [`-keepclasseswithmembernames`](configuration/usage.md#keepclasseswithmembernames) [*class\_specification*](configuration/usage.md#classspecification) | Preserve the names of the specified classes *and* class members, if all of the specified class members are present (after the shrinking step).
|
||||
| [`-if`](configuration/usage.md#if) [*class\_specification*](configuration/usage.md#classspecification) | Specify classes and class members that must be present to activate the subsequent `keep` option.
|
||||
| [`-printseeds`](configuration/usage.md#printseeds) \[[*filename*](configuration/usage.md#filename)\] | List classes and class members matched by the various [`-keep`](configuration/usage.md#keep) options, to the standard output or to the given file.
|
||||
| [`-dontshrink`](configuration/usage.md#dontshrink) | Don't shrink the input class files.
|
||||
| [`-printusage`](configuration/usage.md#printusage) \[[*filename*](configuration/usage.md#filename)\] | List dead code of the input class files, to the standard output or to the given file.
|
||||
| [`-whyareyoukeeping`](configuration/usage.md#whyareyoukeeping) [*class\_specification*](configuration/usage.md#classspecification) | Print details on why the given classes and class members are being kept in the shrinking step.
|
||||
| [`-dontoptimize`](configuration/usage.md#dontoptimize) | Don't optimize the input class files.
|
||||
| [`-optimizations`](configuration/usage.md#optimizations) [*optimization\_filter*](configuration/optimizations.md) | The optimizations to be enabled and disabled.
|
||||
| [`-optimizationpasses`](configuration/usage.md#optimizationpasses) *n* | The number of optimization passes to be performed.
|
||||
| [`-assumenosideeffects`](configuration/usage.md#assumenosideeffects) [*class\_specification*](configuration/usage.md#classspecification) | Assume that the specified methods don't have any side effects, while optimizing.
|
||||
| [`-assumenoexternalsideeffects`](configuration/usage.md#assumenoexternalsideeffects) [*class\_specification*](configuration/usage.md#classspecification) | Assume that the specified methods don't have any external side effects, while optimizing.
|
||||
| [`-assumenoescapingparameters`](configuration/usage.md#assumenoescapingparameters) [*class\_specification*](configuration/usage.md#classspecification) | Assume that the specified methods don't let any reference parameters escape to the heap, while optimizing.
|
||||
| [`-assumenoexternalreturnvalues`](configuration/usage.md#assumenoexternalreturnvalues) [*class\_specification*](configuration/usage.md#classspecification) | Assume that the specified methods don't return any external reference values, while optimizing.
|
||||
| [`-assumevalues`](configuration/usage.md#assumevalues) [*class\_specification*](configuration/usage.md#classspecification) | Assume fixed values or ranges of values for primitive fields and methods, while optimizing.
|
||||
| [`-allowaccessmodification`](configuration/usage.md#allowaccessmodification) | Allow the access modifiers of classes and class members to be modified, while optimizing.
|
||||
| [`-mergeinterfacesaggressively`](configuration/usage.md#mergeinterfacesaggressively) | Allow any interfaces to be merged, while optimizing.
|
||||
| [`-dontobfuscate`](configuration/usage.md#dontobfuscate) | Don't obfuscate the input class files.
|
||||
| [`-printmapping`](configuration/usage.md#printmapping) \[[*filename*](configuration/usage.md#filename)\] | Print the mapping from old names to new names for classes and class members that have been renamed, to the standard output or to the given file.
|
||||
| [`-applymapping`](configuration/usage.md#applymapping) [*filename*](configuration/usage.md#filename) | Reuse the given mapping, for incremental obfuscation.
|
||||
| [`-obfuscationdictionary`](configuration/usage.md#obfuscationdictionary) [*filename*](configuration/usage.md#filename) | Use the words in the given text file as obfuscated field names and method names.
|
||||
| [`-classobfuscationdictionary`](configuration/usage.md#classobfuscationdictionary) [*filename*](configuration/usage.md#filename) | Use the words in the given text file as obfuscated class names.
|
||||
| [`-packageobfuscationdictionary`](configuration/usage.md#packageobfuscationdictionary) [*filename*](configuration/usage.md#filename) | Use the words in the given text file as obfuscated package names.
|
||||
| [`-overloadaggressively`](configuration/usage.md#overloadaggressively) | Apply aggressive overloading while obfuscating.
|
||||
| [`-useuniqueclassmembernames`](configuration/usage.md#useuniqueclassmembernames) | Ensure uniform obfuscated class member names for subsequent incremental obfuscation.
|
||||
| [`-dontusemixedcaseclassnames`](configuration/usage.md#dontusemixedcaseclassnames) | Don't generate mixed-case class names while obfuscating.
|
||||
| [`-keeppackagenames`](configuration/usage.md#keeppackagenames) \[*[package\_filter](configuration/usage.md#filters)*\] | Keep the specified package names from being obfuscated.
|
||||
| [`-flattenpackagehierarchy`](configuration/usage.md#flattenpackagehierarchy) \[*package\_name*\] | Repackage all packages that are renamed into the single given parent package.
|
||||
| [`-repackageclasses`](configuration/usage.md#repackageclasses) \[*package\_name*\] | Repackage all class files that are renamed into the single given package.
|
||||
| [`-keepattributes`](configuration/usage.md#keepattributes) \[*[attribute\_filter](configuration/usage.md#filters)*\] | Preserve the given optional attributes; typically `Exceptions`, `InnerClasses`, `Signature`, `Deprecated`, `SourceFile`, `SourceDir`, `LineNumberTable`, `LocalVariableTable`, `LocalVariableTypeTable`, `Synthetic`, `EnclosingMethod`, and `*Annotation*`.
|
||||
| [`-keepparameternames`](configuration/usage.md#keepparameternames) | Keep the parameter names and types of methods that are kept.
|
||||
| [`-renamesourcefileattribute`](configuration/usage.md#renamesourcefileattribute) \[*string*\] | Put the given constant string in the `SourceFile` attributes.
|
||||
| [`-adaptclassstrings`](configuration/usage.md#adaptclassstrings) \[[*class\_filter*](configuration/usage.md#filters)\] | Adapt string constants in the specified classes, based on the obfuscated names of any corresponding classes.
|
||||
| [`-keepkotlinmetadata`](configuration/usage.md#keepkotlinmetadata) ** deprecated ** | Keep and adapt Kotlin metadata.
|
||||
| [`-adaptresourcefilecontents`](configuration/usage.md#adaptresourcefilecontents) \[[*file\_filter*](configuration/usage.md#filefilters)\] | Update the contents of the specified resource files, based on the obfuscated names of the processed classes.
|
||||
| [`-dontpreverify`](configuration/usage.md#dontpreverify) | Don't preverify the processed class files.
|
||||
| [`-microedition`](configuration/usage.md#microedition) | Target the processed class files at Java Micro Edition.
|
||||
| [`-android`](configuration/usage.md#android) | Target the processed class files at Android.
|
||||
| [`-verbose`](configuration/usage.md#verbose) | Write out some more information during processing.
|
||||
| [`-dontnote`](configuration/usage.md#dontnote) \[[*class\_filter*](configuration/usage.md#filters)\] | Don't print notes about potential mistakes or omissions in the configuration.
|
||||
| [`-dontwarn`](configuration/usage.md#dontwarn) \[[*class\_filter*](configuration/usage.md#filters)\] | Don't warn about unresolved references at all.
|
||||
| [`-ignorewarnings`](configuration/usage.md#ignorewarnings) | Print warnings about unresolved references, but continue processing anyhow.
|
||||
| [`-printconfiguration`](configuration/usage.md#printconfiguration) \[[*filename*](configuration/usage.md#filename)\] | Write out the entire configuration, in traditional ProGuard style, to the standard output or to the given file.
|
||||
| [`-dump`](configuration/usage.md#dump) \[[*filename*](configuration/usage.md#filename)\] | Write out the internal structure of the processed class files, to the standard output or to the given file.
|
||||
| [`-addconfigurationdebugging`](configuration/usage.md#addconfigurationdebugging) | Instrument the processed code with debugging statements that print out suggestions for missing ProGuard configuration.
|
||||
| [`-optimizeaggressively`](configuration/usage.md#optimizeaggressively) | Enables more aggressive assumptions during optimization
|
||||
|
||||
Notes:
|
||||
|
||||
- *class\_path* is a list of jars, apks, aabs, aars, wars, ears, jmods, zips,
|
||||
and directories, with optional filters, separated by path separators.
|
||||
- *filename* can contain Java system properties delimited by
|
||||
'**<**' and '**>**'.
|
||||
- If *filename* contains special characters, the entire name should be
|
||||
quoted with single or double quotes.
|
||||
|
||||
## Overview of `Keep` Options {: #keepoverview}
|
||||
|
||||
| Keep | From being removed or renamed | From being renamed
|
||||
|-----------------------------------------------------|--------------------------------------------------------------|------------------------------------------------------------------------
|
||||
| Classes and class members | [`-keep`](configuration/usage.md#keep) | [`-keepnames`](configuration/usage.md#keepnames)
|
||||
| Class members only | [`-keepclassmembers`](configuration/usage.md#keepclassmembers) | [`-keepclassmembernames`](configuration/usage.md#keepclassmembernames)
|
||||
| Classes and class members, if class members present | [`-keepclasseswithmembers`](configuration/usage.md#keepclasseswithmembers) | [`-keepclasseswithmembernames`](configuration/usage.md#keepclasseswithmembernames)
|
||||
|
||||
The [**ProGuard Playground**](https://playground.proguard.com) is a useful tool to help you further tweak the keep rules.
|
||||
|
||||
<iframe frameborder="0" width="100%" height="200px" style="border-radius: 0.25rem; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);" src="https://playground.proguard.com/p/FT5qr8?embed"></iframe>
|
||||
|
||||
## Keep Option Modifiers {: #keepoptionmodifiers}
|
||||
|
||||
| Modifier | Meaning
|
||||
|-----------------------------------------------------------------|---------------------------------------------------------------------------
|
||||
| [`includedescriptorclasses`](configuration/usage.md#includedescriptorclasses) | Also keep any classes in the descriptors of specified fields and methods.
|
||||
| [`includecode`](configuration/usage.md#includecode) | Also keep the code of the specified methods unchanged.
|
||||
| [`allowshrinking`](configuration/usage.md#allowshrinking) | Allow the specified entry points to be removed in the shrinking step.
|
||||
| [`allowoptimization`](configuration/usage.md#allowoptimization) | Allow the specified entry points to be modified in the optimization step.
|
||||
| [`allowobfuscation`](configuration/usage.md#allowobfuscation) | Allow the specified entry points to be renamed in the obfuscation step.
|
||||
|
||||
## Class Specifications {: #classspecification}
|
||||
|
||||
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
|
||||
[extends|implements [@annotationtype] classname]
|
||||
[{
|
||||
[@annotationtype]
|
||||
[[!]public|private|protected|static|volatile|transient ...]
|
||||
<fields> | (fieldtype fieldname [= values]);
|
||||
|
||||
[@annotationtype]
|
||||
[[!]public|private|protected|static|synchronized|native|abstract|strictfp ...]
|
||||
<methods> | <init>(argumenttype,...) | classname(argumenttype,...) | (returntype methodname(argumenttype,...));
|
||||
|
||||
[@annotationtype] [[!]public|private|protected|static ... ] *;
|
||||
...
|
||||
}]
|
||||
|
||||
Notes:
|
||||
|
||||
- Class names must always be fully qualified, i.e. including their
|
||||
package names.
|
||||
- Types in *classname*, *annotationtype*, *returntype*, and
|
||||
*argumenttype* can contain wildcards: '`?`' for a single character,
|
||||
'`*`' for any number of characters (but not the package separator),
|
||||
'`**`' for any number of (any) characters, '`%`' for any primitive
|
||||
type, '`***`' for any type, '`...`' for any number of arguments, and
|
||||
'`<n>`' for the *n*'th matched wildcard in the same option.
|
||||
- *fieldname* and *methodname* can contain wildcards as well: '`?`'
|
||||
for a single character and '`*`' for any number of characters.
|
1101
proguard/docs/manual/releasenotes.md
Normal file
1101
proguard/docs/manual/releasenotes.md
Normal file
File diff suppressed because it is too large
Load Diff
454
proguard/docs/manual/setup/ant.md
Normal file
454
proguard/docs/manual/setup/ant.md
Normal file
@ -0,0 +1,454 @@
|
||||
**ProGuard** can be run as a task in the Java-based build tool Ant
|
||||
(version 1.8 or higher).
|
||||
|
||||
Before you can use the **`proguard`** task, you have to tell Ant about this
|
||||
new task. The easiest way is to add the following line to your
|
||||
`build.xml` file:
|
||||
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="/usr/local/java/proguard/lib/proguard-ant.jar" />
|
||||
|
||||
Please make sure the class path is set correctly for your system.
|
||||
|
||||
There are three ways to configure the ProGuard task:
|
||||
|
||||
1. using an external configuration file,
|
||||
2. using embedded ProGuard configuration options, or
|
||||
3. using the equivalent XML configuration tags.
|
||||
|
||||
These three ways can be combined, depending on practical circumstances
|
||||
and personal preference.
|
||||
|
||||
## 1. An external ProGuard configuration file
|
||||
|
||||
The simplest way to use the ProGuard task in an Ant build file is to
|
||||
keep your ProGuard configuration file, and include it from Ant. You can
|
||||
include your ProGuard configuration file by setting the
|
||||
[**`configuration`**](#configuration_attribute) attribute of your `proguard`
|
||||
task. Your ant build file will then look like this:
|
||||
```xml
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="/usr/local/java/proguard/lib/proguard-ant.jar" />
|
||||
<proguard configuration="myconfigfile.pro"/>
|
||||
```
|
||||
|
||||
This is a convenient option if you prefer ProGuard's configuration style
|
||||
over XML, if you want to keep your build file small, or if you have to
|
||||
share your configuration with developers who don't use Ant.
|
||||
|
||||
## 2. Embedded ProGuard configuration options
|
||||
|
||||
Instead of keeping an external ProGuard configuration file, you can also
|
||||
copy the contents of the file into the nested text of the **`proguard`**
|
||||
task (the PCDATA area). Your Ant build file will then look like this:
|
||||
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="/usr/local/java/proguard/lib/proguard-ant.jar" />
|
||||
<proguard>
|
||||
-injars in.jar
|
||||
-outjars out.jar
|
||||
-libraryjars ${java.home}/lib/rt.jar
|
||||
|
||||
-keepclasseswithmembers public class * {
|
||||
public static void main(java.lang.String[]);
|
||||
}
|
||||
</proguard>
|
||||
|
||||
Some minor syntactical changes are required in order to conform with the
|
||||
XML standard.
|
||||
|
||||
Firstly, the **`#`** character cannot be used for comments in an XML file.
|
||||
Comments must be enclosed by an opening **`<!--`** and a closing `-->`. All
|
||||
occurrences of the **`#`** character can be removed.
|
||||
|
||||
Secondly, the use of **`<`** and `>` characters would upset the structure of
|
||||
the XML build file. Environment variables can be specified with the
|
||||
usual Ant style **`${...}`**, instead of the ProGuard style `<...>`. Other
|
||||
occurrences of **`<`** and `>` have to be encoded as `<` and `>`
|
||||
respectively.
|
||||
|
||||
## 3. XML configuration tags
|
||||
|
||||
If you really prefer a full-blown XML configuration, you can replace the
|
||||
ProGuard configuration options by XML configuration tags. The resulting
|
||||
configuration will be equivalent, but much more verbose and difficult to
|
||||
read, as XML goes. The remainder of this page presents the supported
|
||||
tags. For a more extensive discussion of their meaning, please consult
|
||||
the traditional [Usage](../configuration/usage.md) section. You can find some sample
|
||||
configuration files in the **`examples/ant`** directory of the ProGuard
|
||||
distribution.
|
||||
|
||||
### Task Attributes and Nested Elements {: #attributes}
|
||||
|
||||
The **`<proguard>`** task and the `<proguardconfiguration>` task can have
|
||||
the following attributes (only for **`<proguard>`**) and nested elements:
|
||||
|
||||
`configuration`{: #configuration} = "*filename*"
|
||||
: Read and merge options from the given ProGuard-style configuration file.
|
||||
Note: for reading multiple configuration files or XML-style configurations,
|
||||
use the [**`configuration`**](#configuration_element) *element*.
|
||||
|
||||
[**`skipnonpubliclibraryclasses`**](../configuration/usage.md#skipnonpubliclibraryclasses) = "*boolean*" (default = false)
|
||||
: Ignore non-public library classes.
|
||||
|
||||
[**`skipnonpubliclibraryclassmembers`**](../configuration/usage.md#dontskipnonpubliclibraryclassmembers) = "*boolean*" (default = true)
|
||||
: Ignore package visible library class members.
|
||||
|
||||
[**`target`**](../configuration/usage.md#target) = "*version*" (default = none)
|
||||
: Set the given version number in the processed classes.
|
||||
|
||||
[**`forceprocessing`**](../configuration/usage.md#forceprocessing) = "*boolean*" (default = false)
|
||||
: Process the input, even if the output seems up to date.
|
||||
|
||||
[**`printseeds`**](../configuration/usage.md#printseeds) = "*boolean or filename*" (default = false)
|
||||
: List classes and class members matched by the various **`keep`** commands,
|
||||
to the standard output or to the given file.
|
||||
|
||||
[**`shrink`**](../configuration/usage.md#dontshrink) = "*boolean*" (default = true)
|
||||
: Shrink the input class files.
|
||||
|
||||
[**`printusage`**](../configuration/usage.md#printusage) = "*boolean or filename*" (default = false)
|
||||
: List dead code of the input class files, to the standard output or to the
|
||||
given file.
|
||||
|
||||
[**`optimize`**](../configuration/usage.md#dontoptimize) = "*boolean*" (default = true)
|
||||
: Optimize the input class files.
|
||||
|
||||
[**`optimizationpasses`**](../configuration/usage.md#optimizationpasses) = "*n*" (default = 1)
|
||||
: The number of optimization passes to be performed.
|
||||
|
||||
[**`allowaccessmodification`**](../configuration/usage.md#allowaccessmodification) = "*boolean*" (default = false)
|
||||
: Allow the access modifiers of classes and class members to be modified,
|
||||
while optimizing.
|
||||
|
||||
[**`mergeinterfacesaggressively`**](../configuration/usage.md#mergeinterfacesaggressively) = "*boolean*" (default = false)
|
||||
: Allow any interfaces to be merged, while optimizing.
|
||||
|
||||
[**`obfuscate`**](../configuration/usage.md#dontobfuscate) = "*boolean*" (default = true)
|
||||
: Obfuscate the input class files.
|
||||
|
||||
[**`printmapping`**](../configuration/usage.md#printmapping) = "*boolean or filename*" (default = false)
|
||||
: Print the mapping from old names to new names for classes and class
|
||||
members that have been renamed, to the standard output or to the given file.
|
||||
|
||||
[**`applymapping`**](../configuration/usage.md#applymapping) = "*filename*" (default = none)
|
||||
: Reuse the given mapping, for incremental obfuscation.
|
||||
|
||||
[**`obfuscationdictionary`**](../configuration/usage.md#obfuscationdictionary) = "*filename*" (default = none)
|
||||
: Use the words in the given text file as obfuscated field names and method
|
||||
names.
|
||||
|
||||
[**`classobfuscationdictionary`**](../configuration/usage.md#classobfuscationdictionary) = "*filename*" (default = none)
|
||||
: Use the words in the given text file as obfuscated class names.
|
||||
|
||||
[**`packageobfuscationdictionary`**](../configuration/usage.md#packageobfuscationdictionary) = "*filename*" (default = none)
|
||||
: Use the words in the given text file as obfuscated package names.
|
||||
|
||||
[**`overloadaggressively`**](../configuration/usage.md#overloadaggressively) = "*boolean*" (default = false)
|
||||
: Apply aggressive overloading while obfuscating.
|
||||
|
||||
[**`useuniqueclassmembernames`**](../configuration/usage.md#useuniqueclassmembernames) = "*boolean*" (default = false)
|
||||
: Ensure uniform obfuscated class member names for subsequent incremental
|
||||
obfuscation.
|
||||
|
||||
[**`usemixedcaseclassnames`**](../configuration/usage.md#dontusemixedcaseclassnames) = "*boolean*" (default = true)
|
||||
: Generate mixed-case class names while obfuscating.
|
||||
|
||||
[**`flattenpackagehierarchy`**](../configuration/usage.md#flattenpackagehierarchy) = "*package\_name*" (default = none)
|
||||
: Repackage all packages that are renamed into the single given parent
|
||||
package.
|
||||
|
||||
[**`repackageclasses`**](../configuration/usage.md#repackageclasses) = "*package\_name*" (default = none)
|
||||
: Repackage all class files that are renamed into the single given package.
|
||||
|
||||
[**`keepparameternames`**](../configuration/usage.md#keepparameternames) = "*boolean*" (default = false)
|
||||
: Keep the parameter names and types of methods that are kept.
|
||||
|
||||
[**`renamesourcefileattribute`**](../configuration/usage.md#renamesourcefileattribute) = "*string*" (default = none)
|
||||
: Put the given constant string in the **`SourceFile`** attributes.
|
||||
|
||||
[**`preverify`**](../configuration/usage.md#dontpreverify) = "*boolean*" (default = true)
|
||||
: Preverify the processed class files if they are targeted at Java Micro
|
||||
Edition or at Java 6 or higher.
|
||||
|
||||
[**`microedition`**](../configuration/usage.md#microedition) = "*boolean*" (default = false)
|
||||
: Target the processed class files at Java Micro Edition.
|
||||
|
||||
[**`android`**](../configuration/usage.md#android) = "*boolean*" (default = false)
|
||||
: Target the processed class files at Android.
|
||||
|
||||
[**`verbose`**](../configuration/usage.md#verbose) = "*boolean*" (default = false)
|
||||
: Write out some more information during processing.
|
||||
|
||||
[**`note`**](../configuration/usage.md#dontnote) = "*boolean*" (default = true)
|
||||
: Print notes about potential mistakes or omissions in the configuration.
|
||||
Use the nested element [dontnote](#dontnote) for more fine-grained control.
|
||||
|
||||
[**`warn`**](../configuration/usage.md#dontwarn) = "*boolean*" (default = true)
|
||||
: Print warnings about unresolved references. Use the nested element
|
||||
[dontwarn](#dontwarn) for more fine-grained control. *Only use this option
|
||||
if you know what you're doing!*
|
||||
|
||||
[**`ignorewarnings`**](../configuration/usage.md#ignorewarnings) = "*boolean*" (default = false)
|
||||
: Print warnings about unresolved references, but continue processing
|
||||
anyhow. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`printconfiguration`**](../configuration/usage.md#printconfiguration) = "*boolean or filename*" (default = false)
|
||||
: Write out the entire configuration in traditional ProGuard style, to the
|
||||
standard output or to the given file. Useful to replace unreadable XML
|
||||
configurations.
|
||||
|
||||
[**`dump`**](../configuration/usage.md#dump) = "*boolean or filename*" (default = false)
|
||||
: Write out the internal structure of the processed class files, to the
|
||||
standard output or to the given file.
|
||||
|
||||
[**`addconfigurationdebugging`**](../configuration/usage.md#addconfigurationdebugging) = "*boolean*" (default = false)
|
||||
: Adds debugging information to the code, to print out ProGuard
|
||||
configuration suggestions at runtime. *Do not use this option in release
|
||||
versions.*
|
||||
|
||||
[**`<injar`**](../configuration/usage.md#injars) [*class\_path*](#classpath) `/>`
|
||||
: Specifies the program jars (or apks, aabs, aars, wars, ears, jmods, zips, or
|
||||
directories).
|
||||
|
||||
[**`<outjar`**](../configuration/usage.md#outjars) [*class\_path*](#classpath) `/>`
|
||||
: Specifies the names of the output jars (or apks, aabs, aars, wars, ears,
|
||||
jmods, zips, or directories).
|
||||
|
||||
[**`<libraryjar`**](../configuration/usage.md#libraryjars) [*class\_path*](#classpath) `/>`
|
||||
: Specifies the library jars (or apks, aabs, aars, wars, ears, jmods, zips, or
|
||||
directories).
|
||||
|
||||
[**`<keepdirectory name = `**](../configuration/usage.md#keepdirectories)"*directory\_name*" `/>`<br/>[`<keepdirectories filter = `](../configuration/usage.md#keepdirectories)"[*directory\_filter*](../configuration/usage.md#filefilters)" `/>`
|
||||
: Keep the specified directories in the output jars (or apks, aabs, aars, wars,
|
||||
ears, jmods, zips, or directories).
|
||||
|
||||
[**`<keep`**](../configuration/usage.md#keep) [*modifiers*](#keepmodifier) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</keep>`
|
||||
: Preserve the specified classes *and* class members.
|
||||
|
||||
[**`<keepclassmembers`**](../configuration/usage.md#keepclassmembers) [*modifiers*](#keepmodifier) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</keepclassmembers>`
|
||||
: Preserve the specified class members, if their classes are preserved as
|
||||
well.
|
||||
|
||||
[**`<keepclasseswithmembers`**](../configuration/usage.md#keepclasseswithmembers) [*modifiers*](#keepmodifier) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</keepclasseswithmembers>`
|
||||
: Preserve the specified classes *and* class members, if all of the
|
||||
specified class members are present.
|
||||
|
||||
[**`<keepnames`**](../configuration/usage.md#keepnames) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</keepnames>`
|
||||
: Preserve the names of the specified classes *and* class members (if they
|
||||
aren't removed in the shrinking step).
|
||||
|
||||
[**`<keepclassmembernames`**](../configuration/usage.md#keepclassmembernames) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</keepclassmembernames>`
|
||||
: Preserve the names of the specified class members (if they aren't removed
|
||||
in the shrinking step).
|
||||
|
||||
[**`<keepclasseswithmembernames`**](../configuration/usage.md#keepclasseswithmembernames) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</keepclasseswithmembernames>`
|
||||
: Preserve the names of the specified classes *and* class members, if all of
|
||||
the specified class members are present (after the shrinking step).
|
||||
|
||||
[**`<whyareyoukeeping`**](../configuration/usage.md#whyareyoukeeping) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</whyareyoukeeping>`
|
||||
: Print details on why the given classes and class members are being kept in
|
||||
the shrinking step.
|
||||
|
||||
[**`<assumenosideeffects`**](../configuration/usage.md#assumenosideeffects) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</assumenosideeffects>`
|
||||
: Assume that the specified methods don't have any side effects, while
|
||||
optimizing. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`<assumenoexternalsideeffects`**](../configuration/usage.md#assumenoexternalsideeffects) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</assumenoexternalsideeffects>`
|
||||
: Assume that the specified methods don't have any external side effects,
|
||||
while optimizing. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`<assumenoescapingparameters`**](../configuration/usage.md#assumenoescapingparameters) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</assumenoescapingparameters>`
|
||||
: Assume that the specified methods don't let any reference parameters
|
||||
escape to the heap, while optimizing. *Only use this option if you know what
|
||||
you're doing!*
|
||||
|
||||
[**`<assumenoexternalreturnvalues`**](../configuration/usage.md#assumenoexternalreturnvalues) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</assumenoexternalreturnvalues>`
|
||||
: Assume that the specified methods don't return any external reference
|
||||
values, while optimizing. *Only use this option if you know what you're
|
||||
doing!*
|
||||
|
||||
[**`<assumevalues`**](../configuration/usage.md#assumevalues) [*class\_specification*](#classspecification) `>` [*class\_member\_specifications*](#classmemberspecification) `</assumevalues>`
|
||||
: Assume fixed values or ranges of values for primitive fields and methods,
|
||||
while optimizing. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`<optimization name = `**](../configuration/usage.md#optimizations)"[*optimization\_name*](../configuration/optimizations.md)" `/>`<br/>[`<optimizations filter = `](../configuration/usage.md#optimizations)""[*optimization\_filter*](../configuration/optimizations.md)" `/>`
|
||||
: Perform only the specified optimizations.
|
||||
|
||||
[**`<keeppackagename name = `**](../configuration/usage.md#keeppackagenames)"*package\_name*" `/>`<br/>[`<keeppackagenames filter = `](../configuration/usage.md#keeppackagenames)"[*package\_filter*](../configuration/usage.md#filters)" `/>`
|
||||
: Keep the specified package names from being obfuscated. If no name is
|
||||
given, all package names are preserved.
|
||||
|
||||
[**`<keepattribute name = `**](../configuration/usage.md#keepattributes)"*attribute\_name*" `/>`<br/>[`<keepattributes filter = `](../configuration/usage.md#keepattributes)"[*attribute\_filter*](../configuration/usage.md#filters)" `/>`
|
||||
: Preserve the specified optional Java bytecode attributes, with optional
|
||||
wildcards. If no name is given, all attributes are preserved.
|
||||
|
||||
[**`<adaptclassstrings filter = `**](../configuration/usage.md#adaptclassstrings)"[*class\_filter*](../configuration/usage.md#filters)" `/>`
|
||||
: Adapt string constants in the specified classes, based on the obfuscated
|
||||
names of any corresponding classes.
|
||||
|
||||
[**`<adaptresourcefilenames filter = `**](../configuration/usage.md#adaptresourcefilenames)"[*file\_filter*](../configuration/usage.md#filefilters)" `/>`
|
||||
: Rename the specified resource files, based on the obfuscated names of the
|
||||
corresponding class files.
|
||||
|
||||
[**`<adaptresourcefilecontents filter = `**](../configuration/usage.md#adaptresourcefilecontents)"[*file\_filter*](../configuration/usage.md#filefilters)" `/>`
|
||||
: Update the contents of the specified resource files, based on the
|
||||
obfuscated names of the processed classes.
|
||||
|
||||
[**`<dontnote filter = `**](../configuration/usage.md#dontnote)"[*class\_filter*](../configuration/usage.md#filters)" `/>`
|
||||
: Don't print notes about classes matching the specified class name filter.
|
||||
|
||||
[**`<dontwarn filter = `**](../configuration/usage.md#dontwarn)"[*class\_filter*](../configuration/usage.md#filters)" `/>`
|
||||
: Don't print warnings about classes matching the specified class name
|
||||
filter. *Only use this option if you know what you're doing!*
|
||||
|
||||
`<configuration refid = `{: #configuration_element } "*ref\_id*" `/>`<br/>`<configuration file = `"*name*" `/>`
|
||||
: The first form includes the XML-style configuration specified in a
|
||||
**`<proguardconfiguration>`** task (or `<proguard>` task) with attribute
|
||||
**`id`** = "*ref\_id*". Only the nested elements of this configuration are
|
||||
considered, not the attributes. The second form includes the ProGuard-style
|
||||
configuration from the specified file. The element is actually a
|
||||
**`fileset`** element and supports all of its attributes and nested
|
||||
elements, including multiple files.
|
||||
|
||||
## Class Path Attributes and Nested Elements {: #classpath}
|
||||
|
||||
The jar elements are **`path`** elements, so they can have any of the
|
||||
standard **`path`** attributes and nested elements. The most common
|
||||
attributes are:
|
||||
|
||||
`path` = "*path*"
|
||||
: The names of the jars (or apks, aabs, aars, wars, ears, jmods, zips, or
|
||||
directories), separated by the path separator.
|
||||
|
||||
`location` = "*name*" (or `file` = "*name*", or `dir` = "*name*", or `name` = "*name*")
|
||||
: Alternatively, the name of a single jar (or apk, aab, aar, war, ear, jmod,
|
||||
zip, or directory).
|
||||
|
||||
`refid` = "*ref\_id*"
|
||||
: Alternatively, a reference to the path or file set with the attribute
|
||||
**`id`** = "*ref\_id*".
|
||||
|
||||
In addition, the jar elements can have ProGuard-style filter attributes:
|
||||
|
||||
`filter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all class file names and resource file names that
|
||||
are encountered.
|
||||
|
||||
`apkfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all apk names that are encountered.
|
||||
|
||||
`aabfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all aab names that are encountered.
|
||||
|
||||
`jarfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all jar names that are encountered.
|
||||
|
||||
`aarfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all aar names that are encountered.
|
||||
|
||||
`warfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all war names that are encountered.
|
||||
|
||||
`earfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all ear names that are encountered.
|
||||
|
||||
`jmodfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all jmod names that are encountered.
|
||||
|
||||
`zipfilter` = "[*file\_filter*](../configuration/usage.md#filefilters)"
|
||||
: An optional filter for all zip names that are encountered.
|
||||
|
||||
## Keep Modifier Attributes {: #keepmodifier}
|
||||
|
||||
The keep tags can have the following *modifier* attributes:
|
||||
|
||||
[**`includedescriptorclasses`**](../configuration/usage.md#includedescriptorclasses) = "*boolean*" (default = false)
|
||||
: Specifies whether the classes of the fields and methods specified in the
|
||||
keep tag must be kept as well.
|
||||
|
||||
[**`allowshrinking`**](../configuration/usage.md#allowshrinking) = "*boolean*" (default = false)
|
||||
: Specifies whether the entry points specified in the keep tag may be
|
||||
shrunk.
|
||||
|
||||
[**`allowoptimization`**](../configuration/usage.md#allowoptimization) = "*boolean*" (default = false)
|
||||
: Specifies whether the entry points specified in the keep tag may be
|
||||
optimized.
|
||||
|
||||
[**`allowobfuscation`**](../configuration/usage.md#allowobfuscation) = "*boolean*" (default = false)
|
||||
: Specifies whether the entry points specified in the keep tag may be
|
||||
obfuscated.
|
||||
|
||||
## Class Specification Attributes and Nested Elements {: #classspecification}
|
||||
|
||||
The keep tags can have the following *class\_specification* attributes
|
||||
and *class\_member\_specifications* nested elements:
|
||||
|
||||
`access` = "*access\_modifiers*"
|
||||
: The optional access modifiers of the class. Any space-separated list of
|
||||
"public", "final", and "abstract", with optional negators "!".
|
||||
|
||||
`annotation` = "*annotation\_name*"
|
||||
: The optional fully qualified name of an annotation of the class, with
|
||||
optional wildcards.
|
||||
|
||||
`type` = "*type*"
|
||||
: The optional type of the class: one of "class", "interface", or
|
||||
"!interface".
|
||||
|
||||
`name` = "*class\_name*"
|
||||
: The optional fully qualified name of the class, with optional wildcards.
|
||||
|
||||
`extendsannotation` = "*annotation\_name*"
|
||||
: The optional fully qualified name of an annotation of the the class that
|
||||
the specified classes must extend, with optional wildcards.
|
||||
|
||||
`extends` = "*class\_name*"
|
||||
: The optional fully qualified name of the class the specified classes must
|
||||
extend, with optional wildcards.
|
||||
|
||||
`implements` = "*class\_name*"
|
||||
: The optional fully qualified name of the class the specified classes must
|
||||
implement, with optional wildcards.
|
||||
|
||||
`<field` [*class\_member\_specification*](#classmemberspecification) `/>`
|
||||
: Specifies a field.
|
||||
|
||||
`<method` [*class\_member\_specification*](#classmemberspecification) `/>`
|
||||
: Specifies a method.
|
||||
|
||||
`<constructor` [*class\_member\_specification*](#classmemberspecification) `/>`
|
||||
: Specifies a constructor.
|
||||
|
||||
## Class Member Specification Attributes {: #classmemberspecification}
|
||||
|
||||
The class member tags can have the following
|
||||
*class\_member\_specification* attributes:
|
||||
|
||||
`access` = "*access\_modifiers*"
|
||||
: The optional access modifiers of the class. Any space-separated list of
|
||||
"public", "protected", "private", "static", etc., with optional negators
|
||||
"!".
|
||||
|
||||
`annotation` = "*annotation\_name*"
|
||||
: The optional fully qualified name of an annotation of the class member,
|
||||
with optional wildcards.
|
||||
|
||||
`type` = "*type*"
|
||||
: The optional fully qualified type of the class member, with optional
|
||||
wildcards. Not applicable for constructors, but required for methods for
|
||||
which the **`parameters`** attribute is specified.
|
||||
|
||||
`name` = "*name*"
|
||||
: The optional name of the class member, with optional wildcards. Not
|
||||
applicable for constructors.
|
||||
|
||||
`parameters` = "*parameters*"
|
||||
: The optional comma-separated list of fully qualified method parameters,
|
||||
with optional wildcards. Not applicable for fields, but required for
|
||||
constructors, and for methods for which the **`type`** attribute is
|
||||
specified.
|
||||
|
||||
`values` = "*values*"
|
||||
: The optional fixed value or range of values for a primitive field
|
||||
or method.
|
470
proguard/docs/manual/setup/gradle.md
Normal file
470
proguard/docs/manual/setup/gradle.md
Normal file
@ -0,0 +1,470 @@
|
||||
**ProGuard** can be run as a task in the Java-based build tool Gradle
|
||||
(version 2.1 or higher).
|
||||
|
||||
!!! android "Android projects"
|
||||
If you have an Android project, you can find instructions [here](gradleplugin.md).
|
||||
|
||||
|
||||
Before you can use the **`proguard`** task, you have to make sure Gradle can
|
||||
find it in its class path at build time. One way is to add the following
|
||||
line to your **`build.gradle`** file:
|
||||
```Groovy
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.guardsquare:proguard-gradle:7.1.0'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please make sure the class path is set correctly for your system.
|
||||
|
||||
You can then define a task:
|
||||
```Groovy
|
||||
task myProguardTask(type: proguard.gradle.ProGuardTask) {
|
||||
.....
|
||||
}
|
||||
```
|
||||
|
||||
The embedded configuration is much like a standard ProGuard
|
||||
configuration. Notable similarities and differences:
|
||||
|
||||
- Like in ProGuard configurations, we're using all lower-case
|
||||
names for the settings.
|
||||
- The options don't have a dash as prefix.
|
||||
- Arguments typically have quotes.
|
||||
- Some settings are specified as named arguments.
|
||||
|
||||
You can find some sample build files in the **`examples/gradle`** directory
|
||||
of the ProGuard distribution.
|
||||
|
||||
If you prefer a more verbose configuration derived from the Ant task,
|
||||
you can import the Ant task as a [Gradle task](#anttask).
|
||||
|
||||
## Settings {: #proguard}
|
||||
|
||||
The ProGuard task supports the following settings in its closure:
|
||||
|
||||
`configuration` [*files*](#file)
|
||||
: Read and merge options from the given ProGuard configuration files.
|
||||
The files are resolved and parsed lazily, during the execution phase.
|
||||
|
||||
[**`injars`**](../configuration/usage.md#injars) [*class\_path*](#classpath)
|
||||
: Specifies the program jars (or apks, aabs, aars, wars, ears, jmods, zips, or
|
||||
directories). The files are resolved and read lazily, during the execution
|
||||
phase.
|
||||
|
||||
[**`outjars`**](../configuration/usage.md#outjars) [*class\_path*](#classpath)
|
||||
: Specifies the names of the output jars (or apks, aabs, aars, wars, ears,
|
||||
jmods, zips, or directories). The files are resolved and written lazily,
|
||||
during the execution phase.
|
||||
|
||||
[**`libraryjars`**](../configuration/usage.md#libraryjars) [*class\_path*](#classpath)
|
||||
: Specifies the names of the output jars (or apks, aabs, aars, wars, ears,
|
||||
jmods, zips, or directories). The files are resolved and written lazily,
|
||||
during the execution phase.
|
||||
|
||||
[**`skipnonpubliclibraryclasses`**](../configuration/usage.md#skipnonpubliclibraryclasses)
|
||||
: Ignore non-public library classes.
|
||||
|
||||
[**`dontskipnonpubliclibraryclassmembers`**](../configuration/usage.md#dontskipnonpubliclibraryclassmembers)
|
||||
: Don't ignore package visible library class members.
|
||||
|
||||
[**`keepdirectories`**](../configuration/usage.md#keepdirectories) \['[*directory\_filter*](../configuration/usage.md#filefilters)'\]
|
||||
: Keep the specified directories in the output jars (or apks, aabs, aars, wars,
|
||||
ears, jmods, zips, or directories).
|
||||
|
||||
[**`target`**](../configuration/usage.md#target) '*version*'
|
||||
: Set the given version number in the processed classes.
|
||||
|
||||
[**`forceprocessing`**](../configuration/usage.md#forceprocessing)
|
||||
: Process the input, even if the output seems up to date.
|
||||
|
||||
[**`keep`**](../configuration/usage.md#keep) \[[*modifier*,...](#keepmodifier)\] [*class\_specification*](#classspecification)
|
||||
: Preserve the specified classes *and* class members.
|
||||
|
||||
[**`keepclassmembers`**](../configuration/usage.md#keepclassmembers) \[[*modifier*,...](#keepmodifier)\] [*class\_specification*](#classspecification)
|
||||
: Preserve the specified class members, if their classes are preserved as
|
||||
well.
|
||||
|
||||
[**`keepclasseswithmembers`**](../configuration/usage.md#keepclasseswithmembers) \[[*modifier*,...](#keepmodifier)\] [*class\_specification*](#classspecification)
|
||||
: Preserve the specified classes *and* class members, if all of the
|
||||
specified class members are present.
|
||||
|
||||
[**`keepnames`**](../configuration/usage.md#keepnames) [*class\_specification*](#classspecification)
|
||||
: Preserve the names of the specified classes *and* class members (if they
|
||||
aren't removed in the shrinking step).
|
||||
|
||||
[**`keepclassmembernames`**](../configuration/usage.md#keepclassmembernames) [*class\_specification*](#classspecification)
|
||||
: Preserve the names of the specified class members (if they aren't removed
|
||||
in the shrinking step).
|
||||
|
||||
[**`keepclasseswithmembernames`**](../configuration/usage.md#keepclasseswithmembernames) [*class\_specification*](#classspecification)
|
||||
: Preserve the names of the specified classes *and* class members, if all of
|
||||
the specified class members are present (after the shrinking step).
|
||||
|
||||
[**`printseeds`**](../configuration/usage.md#printseeds) \[[*file*](#file)\]
|
||||
: List classes and class members matched by the various **`keep`** commands,
|
||||
to the standard output or to the given file.
|
||||
|
||||
[**`dontshrink`**](../configuration/usage.md#dontshrink)
|
||||
: Don't shrink the input class files.
|
||||
|
||||
[**`printusage`**](../configuration/usage.md#printusage) \[[*file*](#file)\]
|
||||
: List dead code of the input class files, to the standard output or to the
|
||||
given file.
|
||||
|
||||
[**`whyareyoukeeping`**](../configuration/usage.md#whyareyoukeeping) [*class\_specification*](#classspecification)
|
||||
: Print details on why the given classes and class members are being kept in
|
||||
the shrinking step.
|
||||
|
||||
[**`dontoptimize`**](../configuration/usage.md#dontoptimize)
|
||||
: Don't optimize the input class files.
|
||||
|
||||
[**`optimizations`**](../configuration/usage.md#optimizations) '[*optimization\_filter*](../configuration/optimizations.md)'
|
||||
: Perform only the specified optimizations.
|
||||
|
||||
[**`optimizationpasses`**](../configuration/usage.md#optimizationpasses) *n*
|
||||
: The number of optimization passes to be performed.
|
||||
|
||||
[**`assumenosideeffects`**](../configuration/usage.md#assumenosideeffects) [*class\_specification*](#classspecification)
|
||||
: Assume that the specified methods don't have any side effects, while
|
||||
optimizing. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`assumenoexternalsideeffects`**](../configuration/usage.md#assumenoexternalsideeffects) [*class\_specification*](#classspecification)
|
||||
: Assume that the specified methods don't have any external side effects,
|
||||
while optimizing. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`assumenoescapingparameters`**](../configuration/usage.md#assumenoescapingparameters) [*class\_specification*](#classspecification)
|
||||
: Assume that the specified methods don't let any reference parameters
|
||||
escape to the heap, while optimizing. *Only use this option if you know what
|
||||
you're doing!*
|
||||
|
||||
[**`assumenoexternalreturnvalues`**](../configuration/usage.md#assumenoexternalreturnvalues) [*class\_specification*](#classspecification)
|
||||
: Assume that the specified methods don't return any external reference
|
||||
values, while optimizing. *Only use this option if you know what you're
|
||||
doing!*
|
||||
|
||||
[**`assumevalues`**](../configuration/usage.md#assumevalues) [*class\_specification*](#classspecification)
|
||||
: Assume fixed values or ranges of values for primitive fields and methods,
|
||||
while optimizing. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`allowaccessmodification`**](../configuration/usage.md#allowaccessmodification)
|
||||
: Allow the access modifiers of classes and class members to be modified,
|
||||
while optimizing.
|
||||
|
||||
[**`mergeinterfacesaggressively`**](../configuration/usage.md#mergeinterfacesaggressively)
|
||||
: Allow any interfaces to be merged, while optimizing.
|
||||
|
||||
[**`dontobfuscate`**](../configuration/usage.md#dontobfuscate)
|
||||
: Don't obfuscate the input class files.
|
||||
|
||||
[**`printmapping`**](../configuration/usage.md#printmapping) \[[*file*](#file)\]
|
||||
: Print the mapping from old names to new names for classes and class
|
||||
members that have been renamed, to the standard output or to the given file.
|
||||
|
||||
[**`applymapping`**](../configuration/usage.md#applymapping) [*file*](#file)
|
||||
: Reuse the given mapping, for incremental obfuscation.
|
||||
|
||||
[**`obfuscationdictionary`**](../configuration/usage.md#obfuscationdictionary) [*file*](#file)
|
||||
: Use the words in the given text file as obfuscated field names and method
|
||||
names.
|
||||
|
||||
[**`classobfuscationdictionary`**](../configuration/usage.md#classobfuscationdictionary) [*file*](#file)
|
||||
: Use the words in the given text file as obfuscated class names.
|
||||
|
||||
[**`packageobfuscationdictionary`**](../configuration/usage.md#packageobfuscationdictionary) [*file*](#file)
|
||||
: Use the words in the given text file as obfuscated package names.
|
||||
|
||||
[**`overloadaggressively`**](../configuration/usage.md#overloadaggressively)
|
||||
: Apply aggressive overloading while obfuscating.
|
||||
|
||||
[**`useuniqueclassmembernames`**](../configuration/usage.md#useuniqueclassmembernames)
|
||||
: Ensure uniform obfuscated class member names for subsequent incremental
|
||||
obfuscation.
|
||||
|
||||
[**`dontusemixedcaseclassnames`**](../configuration/usage.md#dontusemixedcaseclassnames)
|
||||
: Don't generate mixed-case class names while obfuscating.
|
||||
|
||||
[**`keeppackagenames`**](../configuration/usage.md#keeppackagenames) \['[*package\_filter*](../configuration/usage.md#filters)'\]
|
||||
: Keep the specified package names from being obfuscated. If no name is
|
||||
given, all package names are preserved.
|
||||
|
||||
[**`flattenpackagehierarchy`**](../configuration/usage.md#flattenpackagehierarchy) '*package\_name*'
|
||||
: Repackage all packages that are renamed into the single given parent
|
||||
package.
|
||||
|
||||
[**`repackageclasses`**](../configuration/usage.md#repackageclasses) \['*package\_name*'\]
|
||||
: Repackage all class files that are renamed into the single given package.
|
||||
|
||||
[**`keepattributes`**](../configuration/usage.md#keepattributes) \['[*attribute\_filter*](../configuration/usage.md#filters)'\]
|
||||
: Preserve the specified optional Java bytecode attributes, with optional
|
||||
wildcards. If no name is given, all attributes are preserved.
|
||||
|
||||
[**`keepparameternames`**](../configuration/usage.md#keepparameternames)
|
||||
: Keep the parameter names and types of methods that are kept.
|
||||
|
||||
[**`renamesourcefileattribute`**](../configuration/usage.md#renamesourcefileattribute) \['*string*'\]
|
||||
: Put the given constant string in the **`SourceFile`** attributes.
|
||||
|
||||
[**`adaptclassstrings`**](../configuration/usage.md#adaptclassstrings) \['[*class\_filter*](../configuration/usage.md#filters)'\]
|
||||
: Adapt string constants in the specified classes, based on the obfuscated
|
||||
names of any corresponding classes.
|
||||
|
||||
[**`adaptresourcefilenames`**](../configuration/usage.md#adaptresourcefilenames) \['[*file\_filter*](../configuration/usage.md#filefilters)'\]
|
||||
: Rename the specified resource files, based on the obfuscated names of the
|
||||
corresponding class files.
|
||||
|
||||
[**`adaptresourcefilecontents`**](../configuration/usage.md#adaptresourcefilecontents) \['[*file\_filter*](../configuration/usage.md#filefilters)'\]
|
||||
: Update the contents of the specified resource files, based on the
|
||||
obfuscated names of the processed classes.
|
||||
|
||||
[**`dontpreverify`**](../configuration/usage.md#dontpreverify)
|
||||
: Don't preverify the processed class files if they are targeted at Java
|
||||
Micro Edition or at Java 6 or higher.
|
||||
|
||||
[**`microedition`**](../configuration/usage.md#microedition)
|
||||
: Target the processed class files at Java Micro Edition.
|
||||
|
||||
[**`android`**](../configuration/usage.md#android)
|
||||
: Target the processed class files at Android.
|
||||
|
||||
[**`verbose`**](../configuration/usage.md#verbose)
|
||||
: Write out some more information during processing.
|
||||
|
||||
[**`dontnote`**](../configuration/usage.md#dontnote) '[*class\_filter*](../configuration/usage.md#filters)'
|
||||
: Don't print notes about classes matching the specified class name filter.
|
||||
|
||||
[**`dontwarn`**](../configuration/usage.md#dontwarn) '[*class\_filter*](../configuration/usage.md#filters)'
|
||||
: Don't print warnings about classes matching the specified class name
|
||||
filter. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`ignorewarnings`**](../configuration/usage.md#ignorewarnings)
|
||||
: Print warnings about unresolved references, but continue processing
|
||||
anyhow. *Only use this option if you know what you're doing!*
|
||||
|
||||
[**`printconfiguration`**](../configuration/usage.md#printconfiguration) \[[*file*](#file)\]
|
||||
: Write out the entire configuration in traditional ProGuard style, to the
|
||||
standard output or to the given file. Useful to replace unreadable XML
|
||||
configurations.
|
||||
|
||||
[**`dump`**](../configuration/usage.md#dump) \[[*file*](#file)\]
|
||||
: Write out the internal structure of the processed class files, to the
|
||||
standard output or to the given file.
|
||||
|
||||
[**`addconfigurationdebugging`**](../configuration/usage.md#addconfigurationdebugging)
|
||||
: Adds debugging information to the code, to print out ProGuard
|
||||
configuration suggestions at runtime. *Do not use this option in release
|
||||
versions.*
|
||||
|
||||
## Class Paths {: #classpath}
|
||||
|
||||
Class paths are specified as Gradle file collections, which means they
|
||||
can be specified as simple strings, with **`files(Object)`**, etc.
|
||||
|
||||
In addition, they can have ProGuard filters, specified as
|
||||
comma-separated named arguments after the file:
|
||||
|
||||
`filter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all class file names and resource file names that
|
||||
are encountered.
|
||||
|
||||
`apkfilter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all apk names that are encountered.
|
||||
|
||||
`jarfilter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all jar names that are encountered.
|
||||
|
||||
`aarfilter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all aar names that are encountered.
|
||||
|
||||
`warfilter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all war names that are encountered.
|
||||
|
||||
`earfilter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all ear names that are encountered.
|
||||
|
||||
`zipfilter:` '[*file\_filter*](../configuration/usage.md#filefilters)'
|
||||
: An optional filter for all zip names that are encountered.
|
||||
|
||||
## Files {: #file}
|
||||
|
||||
Files are specified as Gradle files, which means they can be specified
|
||||
as simple strings, as File instances, with `file(Object)`, etc.
|
||||
|
||||
In Gradle, file names (any strings really) in double quotes can contain
|
||||
properties or code inside `${...}`. These are automatically expanded.
|
||||
|
||||
For example, `"${System.getProperty('java.home')}/lib/rt.jar"` is
|
||||
expanded to something like `'/usr/local/java/jdk/jre/lib/rt.jar'`.
|
||||
Similarly, `System.getProperty('user.home')` is expanded to the user's
|
||||
home directory, and `System.getProperty('user.dir')` is expanded to the
|
||||
current working directory.
|
||||
|
||||
## Keep Modifiers {: #keepmodifier}
|
||||
|
||||
The keep settings can have the following named arguments that modify
|
||||
their behaviors:
|
||||
|
||||
[**`if:`**](../configuration/usage.md#if) [*class\_specification*](#classspecification)
|
||||
: Specifies classes and class members that must be present to activate the
|
||||
keep option.
|
||||
|
||||
[**`includedescriptorclasses:`**](../configuration/usage.md#includedescriptorclasses) *boolean* (default = false)
|
||||
: Specifies whether the classes of the fields and methods specified in the
|
||||
keep tag must be kept as well.
|
||||
|
||||
[**`allowshrinking:`**](../configuration/usage.md#allowshrinking) *boolean* (default = false)
|
||||
: Specifies whether the entry points specified in the keep tag may be
|
||||
shrunk.
|
||||
|
||||
[**`allowoptimization:`**](../configuration/usage.md#allowoptimization) *boolean* (default = false)
|
||||
: Specifies whether the entry points specified in the keep tag may be
|
||||
optimized.
|
||||
|
||||
[**`allowobfuscation:`**](../configuration/usage.md#allowobfuscation) *boolean* (default = false)
|
||||
: Specifies whether the entry points specified in the keep tag may be
|
||||
obfuscated.
|
||||
|
||||
Names arguments are comma-separated, as usual.
|
||||
|
||||
## Class Specifications {: #classspecification}
|
||||
|
||||
A class specification is a template of classes and class members (fields
|
||||
and methods). There are two alternative ways to specify such a template:
|
||||
|
||||
1. As a string containing a ProGuard class specification. This is
|
||||
the most compact and most readable way. The specification looks like
|
||||
a Java declaration of a class with fields and methods. For example:
|
||||
```Groovy
|
||||
keep 'public class com.example.MyMainClass { \
|
||||
public static void main(java.lang.String[]); \
|
||||
}'
|
||||
```
|
||||
|
||||
2. As a Gradle-style setting: a method call with named arguments and
|
||||
a closure. This is more verbose, but it might be useful for
|
||||
programmatic specifications. For example:
|
||||
```Groovy
|
||||
keep access: 'public',
|
||||
name: 'com.example.MyMainClass', {
|
||||
method access: 'public static',
|
||||
type: 'void',
|
||||
name: 'main',
|
||||
parameters: 'java.lang.String[]'
|
||||
}
|
||||
```
|
||||
|
||||
The [ProGuard class specification](../configuration/usage.md#classspecification)
|
||||
is described on the traditional Usage page.
|
||||
|
||||
A Gradle-style class specification can have the following named
|
||||
arguments:
|
||||
|
||||
`access:` '*access\_modifiers*'
|
||||
: The optional access modifiers of the class. Any space-separated list of
|
||||
"public", "final", and "abstract", with optional negators "!".
|
||||
|
||||
`annotation:` '*annotation\_name*'
|
||||
: The optional fully qualified name of an annotation of the class, with
|
||||
optional wildcards.
|
||||
|
||||
`type:` '*type*'
|
||||
: The optional type of the class: one of "class", "interface", or
|
||||
"!interface".
|
||||
|
||||
`name:` '*class\_name*'
|
||||
: The optional fully qualified name of the class, with optional wildcards.
|
||||
|
||||
`extendsannotation:` '*annotation\_name*'
|
||||
: The optional fully qualified name of an annotation of the the class that
|
||||
the specified classes must extend, with optional wildcards.
|
||||
|
||||
`'extends':` '*class\_name*'
|
||||
: The optional fully qualified name of the class the specified classes must
|
||||
extend, with optional wildcards.
|
||||
|
||||
`'implements':` '*class\_name*'
|
||||
: The optional fully qualified name of the class the specified classes must
|
||||
implement, with optional wildcards.
|
||||
|
||||
The named arguments are optional. Without any arguments, there are no
|
||||
constraints, so the settings match all classes.
|
||||
|
||||
## Gradle-style Class Member Specifications {: #classmemberspecification}
|
||||
|
||||
The closure of a Gradle-style class specification can specify class
|
||||
members with these settings:
|
||||
|
||||
`field` *field\_constraints*
|
||||
: Specifies a field.
|
||||
|
||||
`method` *method\_constraints*
|
||||
: Specifies a method.
|
||||
|
||||
`constructor` *constructor\_constraints*
|
||||
: Specifies a constructor.
|
||||
|
||||
A class member setting can have the following named arguments to express
|
||||
constraints:
|
||||
|
||||
`access:` '*access\_modifiers*'
|
||||
: The optional access modifiers of the class. Any space-separated list of
|
||||
"public", "protected", "private", "static", etc., with optional negators
|
||||
"!".
|
||||
|
||||
`'annotation':` '*annotation\_name*'
|
||||
: The optional fully qualified name of an annotation of the class member,
|
||||
with optional wildcards.
|
||||
|
||||
`type:` '*type*'
|
||||
: The optional fully qualified type of the class member, with optional
|
||||
wildcards. Not applicable for constructors, but required for methods for
|
||||
which the **`parameters`** argument is specified.
|
||||
|
||||
`name:` '*name*'
|
||||
: The optional name of the class member, with optional wildcards. Not
|
||||
applicable for constructors.
|
||||
|
||||
`parameters:` '*parameters*'
|
||||
: The optional comma-separated list of fully qualified method parameters,
|
||||
with optional wildcards. Not applicable for fields, but required for
|
||||
constructors, and for methods for which the **`type`** argument is
|
||||
specified.
|
||||
|
||||
The named arguments are optional. Without any arguments, there are no
|
||||
constraints, so the settings match all constructors, fields, or methods.
|
||||
|
||||
A class member setting doesn't have a closure.
|
||||
|
||||
## Alternative: imported Ant task {: #anttask}
|
||||
|
||||
Instead of using the Gradle task, you could also integrate the Ant task
|
||||
in your Gradle build file:
|
||||
```proguard
|
||||
ant.project.basedir = '../..'
|
||||
|
||||
ant.taskdef(resource: 'proguard/ant/task.properties',
|
||||
classpath: '/usr/local/java/proguard/lib/proguard.jar')
|
||||
```
|
||||
|
||||
Gradle automatically converts the elements and attributes to Groovy
|
||||
methods, so converting the configuration is essentially mechanical. The
|
||||
one-on-one mapping can be useful, but the resulting configuration is
|
||||
more verbose. For instance:
|
||||
```proguard
|
||||
task proguard << {
|
||||
ant.proguard(printmapping: 'proguard.map',
|
||||
overloadaggressively: 'on',
|
||||
repackageclasses: '',
|
||||
renamesourcefileattribute: 'SourceFile') {
|
||||
|
||||
injar(file: 'application.jar')
|
||||
injar(file: 'gui.jar', filter: '!META-INF/**')
|
||||
|
||||
.....
|
||||
}
|
||||
}
|
||||
```
|
250
proguard/docs/manual/setup/gradleplugin.md
Normal file
250
proguard/docs/manual/setup/gradleplugin.md
Normal file
@ -0,0 +1,250 @@
|
||||
|
||||
This page will guide you through to the basic steps of processing your Android application or library with ProGuard.
|
||||
|
||||
!!! tip "Java / Kotlin desktop or server projects"
|
||||
If you have a Java / Kotlin desktop or server project, you can find instructions [here](gradle.md).
|
||||
|
||||
## ProGuard Gradle Plugin (AGP version 4.x - AGP 7.x)
|
||||
|
||||
You can add the ProGuard plugin to your project by
|
||||
including the following in your root level `build.gradle(.kts)` file:
|
||||
|
||||
=== "Groovy"
|
||||
```Groovy
|
||||
buildscript {
|
||||
repositories {
|
||||
google() // For the Android Gradle plugin.
|
||||
mavenCentral() // For the ProGuard Gradle Plugin and anything else.
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:x.y.z' // The Android Gradle plugin.
|
||||
classpath 'com.guardsquare:proguard-gradle:7.1.0' // The ProGuard Gradle plugin.
|
||||
}
|
||||
}
|
||||
```
|
||||
=== "Kotlin"
|
||||
```kotlin
|
||||
buildscript {
|
||||
repositories {
|
||||
google() // For the Android Gradle plugin.
|
||||
mavenCentral() // For the ProGuard Gradle Plugin and anything else.
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:x.y.z") // The Android Gradle plugin.
|
||||
classpath("com.guardsquare:proguard-gradle:7.1.0") // The ProGuard Gradle plugin.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To actually apply the plugin to your project,
|
||||
just add the line to your module level `build.gradle(.kts)` file after applying the Android Gradle plugin as shown below.
|
||||
|
||||
=== "Groovy"
|
||||
```Groovy
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.guardsquare.proguard'
|
||||
```
|
||||
=== "Kotlin"
|
||||
```kotlin
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("proguard")
|
||||
}
|
||||
```
|
||||
|
||||
ProGuard expects unobfuscated class files as input. Therefore, other obfuscators such as R8 have to be disabled.
|
||||
|
||||
=== "Groovy"
|
||||
```Groovy
|
||||
android {
|
||||
...
|
||||
buildTypes {
|
||||
release {
|
||||
// Deactivate R8.
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
=== "Kotlin"
|
||||
```kotlin
|
||||
android {
|
||||
...
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
// Deactivate R8.
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
ProGuard can be executed automatically whenever you build any of the configured variants.
|
||||
You can configure a variant using the `proguard` block in your module level `build.gradle(.kts)` files.
|
||||
This is a top-level block and should be placed outside the `android` block.
|
||||
|
||||
For example, in the snippet below, ProGuard is configured to only process the release variant of the application,
|
||||
using a configuration provided by the user (`proguard-project.txt`) and a [default configuration](#default-configurations) (`proguard-android-optimize.txt`).
|
||||
|
||||
=== "Groovy"
|
||||
```Groovy
|
||||
android {
|
||||
...
|
||||
}
|
||||
|
||||
proguard {
|
||||
configurations {
|
||||
release {
|
||||
defaultConfiguration 'proguard-android-optimize.txt'
|
||||
configuration 'proguard-project.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
=== "Kotlin"
|
||||
```kotlin
|
||||
android {
|
||||
...
|
||||
}
|
||||
|
||||
proguard {
|
||||
configurations {
|
||||
register("release") {
|
||||
defaultConfiguration("proguard-android-optimize.txt")
|
||||
configuration("proguard-project.txt")
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can then build your application as usual:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```sh
|
||||
./gradlew assembleRelease
|
||||
```
|
||||
=== "Windows"
|
||||
```
|
||||
gradlew assembleRelease
|
||||
```
|
||||
|
||||
### Default configurations
|
||||
|
||||
There are three default configurations available:
|
||||
|
||||
| Default configuration | Description |
|
||||
|-----------------------|-------------|
|
||||
| `proguard-android.txt` | ProGuard will obfuscate and shrink your application |
|
||||
| `proguard-android-optimize.txt` | ProGuard will obfuscate, shrink and optimize your application |
|
||||
| `proguard-android-debug.txt` | ProGuard will process the application without any obfuscation,<br>optimization or shrinking |
|
||||
|
||||
### Consumer rules
|
||||
|
||||
ProGuard will apply the consumer rules provided by library dependencies. If you need to exclude these rules,
|
||||
you can use the `consumerRuleFilter`.
|
||||
|
||||
#### consumerRuleFilter
|
||||
|
||||
The `consumerRuleFilter` option allows you to specify a list of maven group and
|
||||
module name pairs to filter out the ProGuard consumer rules of the dependencies
|
||||
that match the specified group and module pairs.
|
||||
|
||||
A group and module name pair is very similar to the maven coordinates you write
|
||||
when specifying the dependencies in the `dependencies` block, but without the
|
||||
version part.
|
||||
|
||||
=== "Groovy"
|
||||
```Groovy
|
||||
proguard {
|
||||
configurations {
|
||||
release {
|
||||
consumerRuleFilter 'groupName:moduleName', 'anotherGroupName:anotherModuleName'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
=== "Kotlin"
|
||||
```Kotlin
|
||||
proguard {
|
||||
configurations {
|
||||
register("release") {
|
||||
consumerRuleFilter("groupName:moduleName", "anotherGroupName:anotherModuleName")
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
The example [`android-plugin`](https://github.com/Guardsquare/proguard/tree/master/examples/android-plugin)
|
||||
has a small working Android project using the ProGuard Gradle Plugin.
|
||||
|
||||
## AGP Integrated ProGuard (AGP version <7)
|
||||
|
||||
ProGuard is integrated with older versions of the Android Gradle plugin.
|
||||
If you have an Android Gradle project that uses such an AGP version,
|
||||
you can enable ProGuard instead of the default `R8` obfuscator as follows:
|
||||
|
||||
1. Disable R8 in your `gradle.properties`:
|
||||
```ini
|
||||
android.enableR8=false
|
||||
android.enableR8.libraries=false
|
||||
```
|
||||
|
||||
2. Override the default version of ProGuard with the most recent one in your
|
||||
main `build.gradle`:
|
||||
```Groovy
|
||||
buildscript {
|
||||
...
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
dependencySubstitution {
|
||||
substitute module('net.sf.proguard:proguard-gradle') with module('com.guardsquare:proguard-gradle:7.1.0')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Enable minification as usual in your `build.gradle`:
|
||||
```Groovy
|
||||
android {
|
||||
...
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
|
||||
proguardFile 'proguard-project.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are two default configurations available when using the integrated ProGuard:
|
||||
|
||||
| Default configuration | Description |
|
||||
|-----------------------|-------------|
|
||||
| `proguard-android.txt` | ProGuard will obfuscate and shrink your application |
|
||||
| `proguard-android-optimize.txt` | ProGuard will obfuscate, shrink and optimize your application |
|
||||
|
||||
4. Add any necessary configuration to your `proguard-project.txt`.
|
||||
|
||||
You can then build your application as usual:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```sh
|
||||
./gradlew assembleRelease
|
||||
```
|
||||
=== "Windows"
|
||||
```
|
||||
gradlew assembleRelease
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
The example [`android-agp3-agp4`](https://github.com/Guardsquare/proguard/tree/master/examples/android-agp3-agp4)
|
||||
has a small working Android project for AGP < 7.
|
||||
|
||||
|
||||
|
54
proguard/docs/manual/setup/standalone.md
Normal file
54
proguard/docs/manual/setup/standalone.md
Normal file
@ -0,0 +1,54 @@
|
||||
To run ProGuard, just type:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```bash
|
||||
bin/proguard.sh <options...>
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
```
|
||||
bin\proguard <options...>
|
||||
```
|
||||
|
||||
Typically, you'll put most options in a configuration file (say,
|
||||
`myconfig.pro`), and just call:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```bash
|
||||
bin/proguard.sh @myconfig.pro
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
```bash
|
||||
bin\proguard @myconfig.pro
|
||||
```
|
||||
|
||||
You can combine command line options and options from configuration
|
||||
files. For instance:
|
||||
|
||||
=== "Linux/macOS"
|
||||
```bash
|
||||
bin/proguard.sh @myconfig.pro -verbose
|
||||
```
|
||||
|
||||
=== "Windows"
|
||||
```
|
||||
bin\proguard @myconfig.pro -verbose
|
||||
```
|
||||
|
||||
You can add comments in a configuration file, starting with a `#`
|
||||
character and continuing until the end of the line.
|
||||
|
||||
Extra whitespace between words and delimiters is ignored. File names
|
||||
with spaces or special characters should be quoted with single or double
|
||||
quotes.
|
||||
|
||||
Options can be grouped arbitrarily in arguments on the command line and
|
||||
in lines in configuration files. This means that you can quote arbitrary
|
||||
sections of command line options, to avoid shell expansion of special
|
||||
characters, for instance.
|
||||
|
||||
The order of the options is generally irrelevant. For quick experiments,
|
||||
you can abbreviate them to their first unique characters.
|
||||
|
||||
All available options are described in the [Configuration section](../configuration/usage.md).
|
8
proguard/docs/manual/tools/appsweep.md
Normal file
8
proguard/docs/manual/tools/appsweep.md
Normal file
@ -0,0 +1,8 @@
|
||||
# AppSweep
|
||||
|
||||
[AppSweep](https://appsweep.guardsquare.com/) is a free online app security testing tool that allows you to find and fix security
|
||||
issues in your Android app's code and dependencies.
|
||||
|
||||
<center>
|
||||

|
||||
</center>
|
7
proguard/docs/manual/tools/playground.md
Normal file
7
proguard/docs/manual/tools/playground.md
Normal file
@ -0,0 +1,7 @@
|
||||
# ProGuard Playground
|
||||
|
||||
[ProGuard Playground](https://playground.proguard.com/) is an online rule visualizer tool compatible with ProGuard, R8 and DexGuard
|
||||
keep rules. It allows you to write keep rules and in real-time see which entities in your app
|
||||
will be matched by those rules.
|
||||
|
||||
<iframe frameborder="0" width="100%" height="400px" style="border-radius: 0.25rem; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);" src="https://playground.proguard.com/p/FT5qr8?embed"></iframe>
|
382
proguard/docs/manual/tools/retrace.md
Normal file
382
proguard/docs/manual/tools/retrace.md
Normal file
@ -0,0 +1,382 @@
|
||||
# ReTrace
|
||||
|
||||
**ReTrace** is a companion tool for ProGuard and DexGuard that
|
||||
'de-obfuscates' stack traces.
|
||||
|
||||
When an obfuscated program throws an exception, the resulting stack
|
||||
trace typically isn't very informative. Class names and method names
|
||||
have been replaced by short meaningless strings. Source file names and
|
||||
line numbers are missing altogether. While this may be intentional, it
|
||||
can also be inconvenient when debugging problems.
|
||||
|
||||
<img src="PG_ReTrace.png" alt="ReTrace deobfuscation workflow" style="display: block; margin-left: auto; margin-right: auto;" />
|
||||
|
||||
ReTrace can read an obfuscated stack trace and restore it to what it
|
||||
would look like without obfuscation. The restoration is based on the
|
||||
mapping file that an obfuscator (like ProGuard, DexGuard or R8) can write out while obfuscating. The mapping
|
||||
file links the original class names and class member names to their
|
||||
obfuscated names.
|
||||
|
||||
## Usage {: #usage }
|
||||
|
||||
You can find the ReTrace jar in the `lib` directory of the ProGuard
|
||||
distribution. To run ReTrace, just type:
|
||||
|
||||
`java -jar retrace.jar `\[*options...*\] *mapping\_file*
|
||||
\[*stacktrace\_file*\]
|
||||
|
||||
Alternatively, the `bin` directory contains some short Linux and Windows
|
||||
scripts containing this command. These are the arguments:
|
||||
|
||||
*mapping\_file*
|
||||
: Specifies the name of the mapping file.
|
||||
|
||||
*stacktrace\_file*
|
||||
: Optionally specifies the name of the file containing the stack trace. If
|
||||
no file is specified, a stack trace is read from the standard input. The
|
||||
stack trace must be encoded with UTF-8 encoding. Blank lines and
|
||||
unrecognized lines are ignored.
|
||||
|
||||
The following options are supported:
|
||||
|
||||
`-verbose`
|
||||
: Specifies to print out more informative stack traces that include not only
|
||||
method names, but also method return types and arguments.
|
||||
|
||||
`-regex` *regular\_expression*
|
||||
|
||||
: Specifies the regular expression that is used to parse the lines in the
|
||||
stack trace. Specifying a different regular expression allows to
|
||||
de-obfuscate more general types of input than just stack traces. A relatively
|
||||
simple expression like this works for basic stack trace formats:
|
||||
|
||||
(?:.*? at %c\.%m\(%s(?::%l)?\))|(?:(?:.*?[:"] +)?%c(?::.*)?)
|
||||
|
||||
It for instance matches the following lines:
|
||||
|
||||
Exception in thread "main" myapplication.MyException: Some message
|
||||
at com.example.MyClass.myMethod(MyClass.java:123)
|
||||
|
||||
The regular expression is a Java regular expression (cfr. the
|
||||
documentation of `java.util.regex.Pattern`), with a few additional
|
||||
wildcards:
|
||||
|
||||
| Wildcard | Description | Example
|
||||
|----------|--------------------------------------------|-------------------------------------------
|
||||
| `%c` | matches a class name | `com.example.MyClass`
|
||||
| `%C` | matches a class name with slashes | `com/example/MyClass`
|
||||
| `%t` | matches a field type or method return type | `com.example.MyClass[]`
|
||||
| `%f` | matches a field name | `myField`
|
||||
| `%m` | matches a method name | `myMethod`
|
||||
| `%a` | matches a list of method arguments | `boolean,int`
|
||||
| `%s` | matches a source file name | `MyClass.java`
|
||||
| `%l` | matches a line number inside a method | `123`
|
||||
|
||||
Elements that match these wildcards are de-obfuscated,
|
||||
when possible. Note that regular expressions must not contain any
|
||||
capturing groups. Use non-capturing groups instead: `(?:`...`)`
|
||||
|
||||
You can print out the default regular expression by running ReTrace without
|
||||
arguments. It also matches more complex stack traces.
|
||||
|
||||
The restored stack trace is printed to the standard output. The
|
||||
completeness of the restored stack trace depends on the presence of line
|
||||
number tables in the obfuscated class files:
|
||||
|
||||
- If all line numbers have been preserved while obfuscating the
|
||||
application, ReTrace will be able to restore the stack
|
||||
trace completely.
|
||||
- If the line numbers have been removed, mapping obfuscated method
|
||||
names back to their original names has become ambiguous. Retrace
|
||||
will list all possible original method names for each line in the
|
||||
stack trace. The user can then try to deduce the actual stack trace
|
||||
manually, based on the logic of the program.
|
||||
|
||||
Source file names are currently restored based on the names of the
|
||||
outer-most classes. If you prefer to keep the obfuscated name, you can
|
||||
replace `%s` in the default regular expression by `.*`
|
||||
|
||||
Unobfuscated elements and obfuscated elements for which no mapping is
|
||||
available will be left unchanged.
|
||||
|
||||
|
||||
## Examples {: #examples }
|
||||
|
||||
### Restoring a stack trace with line numbers {: #with}
|
||||
|
||||
Assume for instance an application has been obfuscated using the
|
||||
following extra options:
|
||||
|
||||
-printmapping mapping.txt
|
||||
|
||||
-renamesourcefileattribute MyApplication
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
Now assume the processed application throws an exception:
|
||||
|
||||
java.io.IOException: Can't read [dummy.jar] (No such file or directory)
|
||||
at proguard.y.a(MyApplication:188)
|
||||
at proguard.y.a(MyApplication:158)
|
||||
at proguard.y.a(MyApplication:136)
|
||||
at proguard.y.a(MyApplication:66)
|
||||
at proguard.ProGuard.c(MyApplication:218)
|
||||
at proguard.ProGuard.a(MyApplication:82)
|
||||
at proguard.ProGuard.main(MyApplication:538)
|
||||
Caused by: java.io.IOException: No such file or directory
|
||||
at proguard.d.q.a(MyApplication:50)
|
||||
at proguard.y.a(MyApplication:184)
|
||||
... 6 more
|
||||
|
||||
If we have saved the stack trace in a file `stacktrace.txt`, we can use
|
||||
the following command to recover the stack trace:
|
||||
|
||||
retrace mapping.txt stacktrace.txt
|
||||
|
||||
The output will correspond to the original stack trace:
|
||||
|
||||
java.io.IOException: Can't read [dummy.jar] (No such file or directory)
|
||||
at proguard.InputReader.readInput(InputReader.java:188)
|
||||
at proguard.InputReader.readInput(InputReader.java:158)
|
||||
at proguard.InputReader.readInput(InputReader.java:136)
|
||||
at proguard.InputReader.execute(InputReader.java:66)
|
||||
at proguard.ProGuard.readInput(ProGuard.java:218)
|
||||
at proguard.ProGuard.execute(ProGuard.java:82)
|
||||
at proguard.ProGuard.main(ProGuard.java:538)
|
||||
Caused by: java.io.IOException: No such file or directory
|
||||
at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:50)
|
||||
at proguard.InputReader.readInput(InputReader.java:184)
|
||||
... 6 more
|
||||
|
||||
### Restoring a stack trace with line numbers (verbose) {: #withverbose}
|
||||
|
||||
In the previous example, we could also use the verbose flag:
|
||||
|
||||
java -jar retrace.jar -verbose mapping.txt stacktrace.txt
|
||||
|
||||
The output will then look as follows:
|
||||
|
||||
java.io.IOException: Can't read [dummy.jar] (No such file or directory)
|
||||
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPathEntry,proguard.io.DataEntryReader)(InputReader.java:188)
|
||||
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPath,int,int,proguard.io.DataEntryReader)(InputReader.java:158)
|
||||
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPath,proguard.io.DataEntryReader)(InputReader.java:136)
|
||||
at proguard.InputReader.void execute(proguard.classfile.ClassPool,proguard.classfile.ClassPool)(InputReader.java:66)
|
||||
at proguard.ProGuard.void readInput()(ProGuard.java:218)
|
||||
at proguard.ProGuard.void execute()(ProGuard.java:82)
|
||||
at proguard.ProGuard.void main(java.lang.String[])(ProGuard.java:538)
|
||||
Caused by: java.io.IOException: No such file or directory
|
||||
at proguard.io.DirectoryPump.void pumpDataEntries(proguard.io.DataEntryReader)(DirectoryPump.java:50)
|
||||
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPathEntry,proguard.io.DataEntryReader)(InputReader.java:184)
|
||||
... 6 more
|
||||
|
||||
### Restoring a stack trace without line numbers {: #without}
|
||||
|
||||
Assume for instance the application has been obfuscated using
|
||||
the following extra options, this time without preserving the line
|
||||
number tables:
|
||||
|
||||
-printmapping mapping.txt
|
||||
|
||||
A stack trace `stacktrace.txt` will then lack line number information,
|
||||
showing "Unknown source" instead:
|
||||
|
||||
java.io.IOException: Can't read [dummy.jar] (No such file or directory)
|
||||
at proguard.y.a(Unknown Source)
|
||||
at proguard.y.a(Unknown Source)
|
||||
at proguard.y.a(Unknown Source)
|
||||
at proguard.y.a(Unknown Source)
|
||||
at proguard.ProGuard.c(Unknown Source)
|
||||
at proguard.ProGuard.a(Unknown Source)
|
||||
at proguard.ProGuard.main(Unknown Source)
|
||||
Caused by: java.io.IOException: No such file or directory
|
||||
at proguard.d.q.a(Unknown Source)
|
||||
... 7 more
|
||||
|
||||
We can still use the same command to recover the stack trace:
|
||||
|
||||
java -jar retrace.jar mapping.txt stacktrace.txt
|
||||
|
||||
The output will now list all alternative original method names for each
|
||||
ambiguous obfuscated method name:
|
||||
|
||||
java.io.IOException: Can't read [dummy.jar] (No such file or directory)
|
||||
at proguard.InputReader.execute(InputReader.java)
|
||||
readInput(InputReader.java)
|
||||
at proguard.InputReader.execute(InputReader.java)
|
||||
readInput(InputReader.java)
|
||||
at proguard.InputReader.execute(InputReader.java)
|
||||
readInput(InputReader.java)
|
||||
at proguard.InputReader.execute(InputReader.java)
|
||||
readInput(InputReader.java)
|
||||
at proguard.ProGuard.readInput(ProGuard.java)
|
||||
at proguard.ProGuard.execute(ProGuard.java)
|
||||
optimize(ProGuard.java)
|
||||
createPrintStream(ProGuard.java)
|
||||
closePrintStream(ProGuard.java)
|
||||
fileName(ProGuard.java)
|
||||
at proguard.ProGuard.main(ProGuard.java)
|
||||
Caused by: java.io.IOException: No such file or directory
|
||||
at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java)
|
||||
readFiles(DirectoryPump.java)
|
||||
|
||||
For instance, ReTrace can't tell if the method `a` corresponds to
|
||||
`execute` or to `readInput`, so it lists both. You need to figure it out
|
||||
based on your knowledge of the application. Having line numbers and
|
||||
unambiguous names clearly is a lot easier, so you should consider
|
||||
[preserving the line numbers](../configuration/examples.md#stacktrace) when you
|
||||
obfuscate your application.
|
||||
|
||||
|
||||
## Specifications {: #specifications }
|
||||
|
||||
A mapping file contains the original names and the obfuscated names of
|
||||
classes, fields, and methods. ProGuard can write out such a file while
|
||||
obfuscating an application or a library, with the option
|
||||
[`-printmapping`](../configuration/usage.md#printmapping). ReTrace requires the mapping file
|
||||
to restore obfuscated stack traces to more readable versions. It is a readable
|
||||
file with UTF-8 encoding, so you can also look up names in an ordinary text
|
||||
viewer. The format is pretty self-explanatory, but we describe its details
|
||||
here.
|
||||
|
||||
A mapping file contains a sequence of records of the following form:
|
||||
|
||||
classline
|
||||
fieldline *
|
||||
methodline *
|
||||
|
||||
A `classline`, with a trailing colon, specifies a class and its obfuscated
|
||||
name:
|
||||
|
||||
originalclassname -> obfuscatedclassname:
|
||||
|
||||
A `fieldline`, with 4 leading spaces, specifies a field and its obfuscated
|
||||
name:
|
||||
|
||||
originalfieldtype originalfieldname -> obfuscatedfieldname
|
||||
|
||||
A `methodline`, with 4 leading spaces, specifies a method and its obfuscated
|
||||
name:
|
||||
|
||||
[startline:endline:]originalreturntype [originalclassname.]originalmethodname(originalargumenttype,...)[:originalstartline[:originalendline]] -> obfuscatedmethodname
|
||||
|
||||
- An asterisk "*" means the line may occur any number of times.
|
||||
- Square brackets "\[\]" mean that their contents are optional.
|
||||
- Ellipsis dots "..." mean that any number of the preceding items may be specified.
|
||||
- The colon ":", the separator ".", and the arrow "->" are literal tokens.
|
||||
|
||||
### Example
|
||||
|
||||
The following snippet gives an impression of the structure of a mapping file:
|
||||
|
||||
com example.application.ArgumentWordReader -> com.example.a.a:
|
||||
java.lang.String[] arguments -> a
|
||||
int index -> a
|
||||
36:57:void <init>(java.lang.String[],java.io.File) -> <init>
|
||||
64:64:java.lang.String nextLine() -> a
|
||||
72:72:java.lang.String lineLocationDescription() -> b
|
||||
com.example.application.Main -> com.example.application.Main:
|
||||
com.example.application.Configuration configuration -> a
|
||||
50:66:void <init>(com.example.application.Configuration) -> <init>
|
||||
74:228:void execute() -> a
|
||||
2039:2056:void com.example.application.GPL.check():39:56 -> a
|
||||
2039:2056:void execute():76 -> a
|
||||
2236:2252:void printConfiguration():236:252 -> a
|
||||
2236:2252:void execute():80 -> a
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
3040:3042:void printConfiguration():243 -> a
|
||||
3040:3042:void execute():80 -> a
|
||||
3260:3268:void readInput():260:268 -> a
|
||||
3260:3268:void execute():97 -> a
|
||||
|
||||
|
||||
You can see the names of classes and their fields and methods:
|
||||
|
||||
- The fields and methods are listed in ProGuard configuration format (javap
|
||||
format), with descriptors that have return types and argument types but no
|
||||
argument names. In the above example:
|
||||
|
||||
void <init>(java.lang.String[],java.io.File)
|
||||
|
||||
refers to a constructor with a `String` array argument and a `File`
|
||||
argument.
|
||||
|
||||
- A method may have a leading line number range, if it is known from the
|
||||
original source code (see [Producing useful obfuscated stack
|
||||
traces](../configuration/examples.md#stacktrace) in the Examples section). Unlike method
|
||||
names, line numbers are unique within a class, so ReTrace can resolve lines
|
||||
in a stack trace without ambiguities. For example:
|
||||
|
||||
74:228:void execute()
|
||||
|
||||
refers to a method `execute`, defined on lines 74 to 228.
|
||||
|
||||
- The obfuscated method name follows the arrow. For example:
|
||||
|
||||
74:228:void execute() -> a
|
||||
|
||||
shows that method `execute` has been renamed to `a`. Multiple fields and
|
||||
methods can get the same obfuscated names, as long as their descriptors
|
||||
are different.
|
||||
|
||||
### Inlined methods
|
||||
|
||||
The mapping file accounts for the added complexity of inlined methods (as of
|
||||
ProGuard/ReTrace version 5.2). The optimization step may inline methods
|
||||
into other methods — recursively even. A single line in an obfuscated
|
||||
stack trace can then correspond to multiple lines in the original stack trace:
|
||||
the line that throws the exception followed by one or more nested method
|
||||
calls. In such cases, the mapping file repeats the leading line number range
|
||||
on subsequent lines. For example:
|
||||
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
3040:3042:void printConfiguration():243 -> a
|
||||
3040:3042:void execute():80 -> a
|
||||
|
||||
- The subsequent lines correspond to the subsequent lines of the original
|
||||
stack trace. For example:
|
||||
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
3040:3042:void printConfiguration():243 -> a
|
||||
3040:3042:void execute():80 -> a
|
||||
|
||||
refers to method `createPrintWriterOut` called from and inlined in
|
||||
`printConfiguration`, in turn called from and inlined in method `execute`.
|
||||
|
||||
- An original method name may have a preceding class name, if the method
|
||||
originates from a different class. For example:
|
||||
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
|
||||
shows that method `createPrintWriterOut` was originally defined in class
|
||||
`PrintWriterUtil`.
|
||||
|
||||
- A single trailing line number corresponds to an inlined method call. For
|
||||
example:
|
||||
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
3040:3042:void printConfiguration():243 -> a
|
||||
3040:3042:void execute():80 -> a
|
||||
|
||||
specifies that method `execute` called `printConfiguration` on line 80,
|
||||
and `printconfiguration` called `createPrintWriterOut` on line 243.
|
||||
|
||||
- A traling line number range corresponds to the final inlined method body.
|
||||
For example:
|
||||
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
|
||||
shows that method `createPrintWriterOut` covered lines 40 to 42.
|
||||
|
||||
- The leading line number range is synthetic, to avoid ambiguities with other
|
||||
code in the same class. ProGuard makes up the range, but tries to make it
|
||||
similar-looking to the original code (by adding offsets that are multiples
|
||||
of 1000), for convenience. For example:
|
||||
|
||||
3040:3042:java.io.PrintWriter com.example.application.util.PrintWriterUtil.createPrintWriterOut(java.io.File):40:42 -> a
|
||||
|
||||
created synthetic range 3040:3042 in the bytecode of class `Main` to be
|
||||
unique but still resemble source code range 40:42 in class
|
||||
`PrintWriterUtil`.
|
||||
|
||||
Tools that don't account for these repeated line number ranges, like older
|
||||
versions of ReTrace, may still degrade gracefully by outputting the subsequent
|
||||
lines without interpreting them.
|
18
proguard/docs/manual/troubleshooting/limitations.md
Normal file
18
proguard/docs/manual/troubleshooting/limitations.md
Normal file
@ -0,0 +1,18 @@
|
||||
When using ProGuard, you should be aware of a few technical issues, all of
|
||||
which are easily avoided or resolved:
|
||||
|
||||
- For best results, ProGuard's optimization algorithms assume that the
|
||||
processed code never **intentionally throws NullPointerExceptions** or
|
||||
ArrayIndexOutOfBoundsExceptions, or even OutOfMemoryErrors or
|
||||
StackOverflowErrors, in order to achieve something useful. For instance, it
|
||||
may remove a method call `myObject.myMethod()` if that call wouldn't have
|
||||
any effect. It ignores the possibility that `myObject` might be null,
|
||||
causing a NullPointerException. In some way this is a good thing: optimized
|
||||
code may throw fewer exceptions. Should this entire assumption be false,
|
||||
you'll have to switch off optimization using the `-dontoptimize` option.
|
||||
|
||||
- ProGuard's optimization algorithms currently also assume that the processed
|
||||
code never creates **busy-waiting loops** without at least testing on a
|
||||
volatile field. Again, it may remove such loops. Should this assumption be
|
||||
false, you'll have to switch off optimization using the `-dontoptimize`
|
||||
option.
|
628
proguard/docs/manual/troubleshooting/troubleshooting.md
Normal file
628
proguard/docs/manual/troubleshooting/troubleshooting.md
Normal file
@ -0,0 +1,628 @@
|
||||
While preparing a configuration for processing your code, you may bump
|
||||
into a few problems. The following sections discuss some common issues
|
||||
and solutions:
|
||||
|
||||
!!! tip
|
||||
Whenever you don't find the solution for your issue on this page, the [***Guardsquare Community***](https://community.guardsquare.com/) might be the place to check for an answer or post a question.
|
||||
|
||||
|
||||
|
||||
## Problems while processing {: #processing}
|
||||
|
||||
ProGuard may print out some notes and non-fatal warnings:
|
||||
|
||||
**Note: can't find dynamically referenced class ...** {: #dynamicalclass}
|
||||
: ProGuard can't find a class or interface that your code is accessing by
|
||||
means of introspection. You should consider adding the jar that contains
|
||||
this class.
|
||||
|
||||
**Note: ... calls '(...)Class.forName(variable).newInstance()'** {: #dynamicalclasscast}
|
||||
: Your code uses reflection to dynamically create class instances, with a
|
||||
construct like "`(MyClass)Class.forName(variable).newInstance()`". Depending
|
||||
on your application, you may need to keep the mentioned classes with an
|
||||
option like "`-keep class MyClass`", or their implementations with an option
|
||||
like "`-keep class * implements MyClass`". You can switch off these notes by
|
||||
specifying the [`-dontnote`](../configuration/usage.md#dontnote) option.
|
||||
|
||||
**Note: ... accesses a field/method '...' dynamically** {: #dynamicalclassmember}
|
||||
: Your code uses reflection to find a fields or a method, with a construct
|
||||
like "`.getField("myField")`". Depending on your application, you may need
|
||||
to figure out where the mentioned class members are defined and keep them
|
||||
with an option like "`-keep class MyClass { MyFieldType myField; }`".
|
||||
Otherwise, ProGuard might remove or obfuscate the class members, since it
|
||||
can't know which ones they are exactly. It does list possible candidates,
|
||||
for your information. You can switch off these notes by specifying the
|
||||
[`-dontnote`](../configuration/usage.md#dontnote) option.
|
||||
|
||||
**Note: ... calls 'Class.get...'**, **'Field.get...'**, or **'Method.get...'** {: #attributes}
|
||||
: Your code uses reflection to access metadata from the code, with an
|
||||
invocation like "`class.getAnnotations()`". You then generally need to
|
||||
preserve optional [class file attributes](../configuration/attributes.md), which ProGuard
|
||||
removes by default. The attributes contain information about annotations,
|
||||
enclosing classes, enclosing methods, etc. In a summary in the log, ProGuard
|
||||
provides a suggested configuration, like [`-keepattributes
|
||||
*Annotation*`](../configuration/usage.md#keepattributes). If you're sure the attributes are
|
||||
not necessary, you can switch off these notes by specifying the
|
||||
[`-dontnote`](../configuration/usage.md#dontnote) option.
|
||||
|
||||
**Note: the configuration refers to the unknown class '...'** {: #unknownclass}
|
||||
: Your configuration refers to the name of a class that is not present in
|
||||
the program jars or library jars. You should check whether the name is
|
||||
correct. Notably, you should make sure that you always specify
|
||||
fully-qualified names, not forgetting the package names.
|
||||
|
||||
**Note: the configuration keeps the entry point '...', but not the descriptor class '...'** {: #descriptorclass}
|
||||
: Your configuration contains a [`-keep`](../configuration/usage.md#keep) option to preserve
|
||||
the given method (or field), but no `-keep` option for the given class that
|
||||
is an argument type or return type in the method's descriptor. You may then
|
||||
want to keep the class too. Otherwise, ProGuard will obfuscate its name,
|
||||
thus changing the method's signature. The method might then become
|
||||
unfindable as an entry point, e.g. if it is part of a public API. You can
|
||||
automatically keep such descriptor classes with the `-keep` option modifier
|
||||
[`includedescriptorclasses`](../configuration/usage.md#includedescriptorclasses)
|
||||
(`-keep,includedescriptorclasses` ...). You can switch off these notes by
|
||||
specifying the [`-dontnote`](../configuration/usage.md#dontnote) option.
|
||||
|
||||
**Note: the configuration explicitly specifies '...' to keep library class '...'** {: #libraryclass}
|
||||
: Your configuration contains a [`-keep`](../configuration/usage.md#keep) option to preserve
|
||||
the given library class. However, you don't need to keep any library
|
||||
classes. ProGuard always leaves underlying libraries unchanged. You can
|
||||
switch off these notes by specifying the [`-dontnote`](../configuration/usage.md#dontnote)
|
||||
option.
|
||||
|
||||
**Note: the configuration doesn't specify which class members to keep for class '...'** {: #classmembers}
|
||||
: Your configuration contains a
|
||||
[`-keepclassmembers`](../configuration/usage.md#keepclassmembers)/[`-keepclasseswithmembers`](../configuration/usage.md#keepclasseswithmembers)
|
||||
option to preserve fields or methods in the given class, but it doesn't
|
||||
specify which fields or methods. This way, the option simply won't have any
|
||||
effect. You probably want to specify one or more fields or methods, as usual
|
||||
between curly braces. You can specify all fields or methods with a wildcard
|
||||
"`*;`". You should also consider if you just need the more common
|
||||
[`-keep`](../configuration/usage.md#keep) option, which preserves all specified classes *and*
|
||||
class members. The [overview of all `keep` options](../configuration/usage.md#keepoverview)
|
||||
can help. You can switch off these notes by specifying the
|
||||
[`-dontnote`](../configuration/usage.md#dontnote) option.
|
||||
|
||||
**Note: the configuration specifies that none of the methods of class '...' have any side effects** {: #nosideeffects}
|
||||
: Your configuration contains an option
|
||||
[`-assumenosideeffects`](../configuration/usage.md#assumenosideeffects) to indicate that the
|
||||
specified methods don't have any side effects. However, the configuration
|
||||
tries to match *all* methods, by using a wildcard like "`*;`". This includes
|
||||
methods from `java.lang.Object`, such as `wait()` and `notify()`. Removing
|
||||
invocations of those methods will most likely break your application. You
|
||||
should list the methods without side effects more conservatively. You can
|
||||
switch off these notes by specifying the [`-dontnote`](../configuration/usage.md#dontnote)
|
||||
option.
|
||||
|
||||
**Note: duplicate definition of program/library class** {: #duplicateclass}
|
||||
: Your program jars or library jars contain multiple definitions of the
|
||||
listed classes. ProGuard continues processing as usual, only considering the
|
||||
first definitions. The warning may be an indication of some problem though,
|
||||
so it's advisable to remove the duplicates. A convenient way to do so is by
|
||||
specifying filters on the input jars or library jars. You can switch off
|
||||
these notes by specifying the [`-dontnote`](../configuration/usage.md#dontnote) option.
|
||||
|
||||
**Warning: can't write resource ... Duplicate zip entry** {: #duplicatezipentry}
|
||||
: Your input jars contain multiple resource files with the same name.
|
||||
ProGuard continues copying the resource files as usual, skipping any files
|
||||
with previously used names. Once more, the warning may be an indication of
|
||||
some problem though, so it's advisable to remove the duplicates. A
|
||||
convenient way to do so is by specifying filters on the input jars. There is
|
||||
no option to switch off these warnings.
|
||||
|
||||
ProGuard may terminate when it encounters parsing errors or I/O errors,
|
||||
or some more serious warnings:
|
||||
|
||||
**Warning: can't find superclass or interface**<br/>**Warning: can't find referenced class** {: #unresolvedclass}
|
||||
: A class in one of your program jars or library jars is referring to a
|
||||
class or interface that is missing from the input. The warning lists both
|
||||
the referencing class(es) and the missing referenced class(es). There can be
|
||||
a few reasons, with their own solutions:
|
||||
|
||||
1. If the missing class is referenced from your own code, you may
|
||||
have forgotten to specify an essential library. Just like when
|
||||
compiling all code from scratch, you must specify all libraries
|
||||
that the code is referencing, directly or indirectly. If the
|
||||
library should be processed and included in the output, you
|
||||
should specify it with [`-injars`](../configuration/usage.md#injars), otherwise
|
||||
you should specify it with [`-libraryjars`](../configuration/usage.md#libraryjars).
|
||||
For example, if ProGuard complains that it can't find a
|
||||
`java.lang` class, you have to make sure that you are specifying
|
||||
the run-time library of your platform. For JSE, these are
|
||||
typically packaged in `lib/rt.jar` (`vm.jar` for IBM's JVM, and
|
||||
`classes.jar` in MacOS X) or as of Java 9, `jmods/java.base.jmod`.
|
||||
|
||||
2. If the missing class is referenced from a pre-compiled
|
||||
third-party library, and your original code runs fine without
|
||||
it, then the missing dependency doesn't seem to hurt. The
|
||||
cleanest solution is to [filter out](../configuration/usage.md#filters) the
|
||||
*referencing* class or classes from the input, with a filter
|
||||
like
|
||||
"`-injars myapplication.jar(!somepackage/SomeUnusedReferencingClass.class)`".
|
||||
DexGuard will then skip this class entirely in the input, and it
|
||||
will not bump into the problem of its missing reference.
|
||||
However, you may then have to filter out other classes that are
|
||||
in turn referencing the removed class. In practice, this works
|
||||
best if you can filter out entire unused packages at once, with
|
||||
a wildcard filter like
|
||||
"`-libraryjars mylibrary.jar(!someunusedpackage/**)`".
|
||||
|
||||
3. If you don't feel like filtering out the problematic classes,
|
||||
you can try your luck with the
|
||||
[`-ignorewarnings`](../configuration/usage.md#ignorewarnings) option, or even
|
||||
the [`-dontwarn`](../configuration/usage.md#dontwarn) option. Only use these
|
||||
options if you really know what you're doing though.
|
||||
|
||||
**Error: Can't find any super classes of ... (not even immediate super class ...)**
|
||||
**Error: Can't find common super class of ... and ...** {: #superclass}
|
||||
: It seems like you tried to avoid the warnings from the previous paragraph
|
||||
by specifying [`-ignorewarnings`](../configuration/usage.md#ignorewarnings) or
|
||||
[`-dontwarn`](../configuration/usage.md#dontwarn), but it didn't work out. ProGuard's
|
||||
optimization step and preverification step really need the missing classes
|
||||
to make sense of the code. Preferably, you would solve the problem by adding
|
||||
the missing library, as discussed. If you're sure the class that references
|
||||
the missing class isn't used either, you could also try filtering it out
|
||||
from the input, by adding a filter to the corresponding
|
||||
[`-injars`](../configuration/usage.md#injars) option: "`-injars
|
||||
myapplication.jar(!somepackage/SomeUnusedClass.class)`". As a final
|
||||
solution, you could switch off optimization
|
||||
([`-dontoptimize`](../configuration/usage.md#dontoptimize)) and preverification
|
||||
([`-dontpreverify`](../configuration/usage.md#dontpreverify)).
|
||||
|
||||
**Warning: can't find referenced field/method '...' in program class ...** {: #unresolvedprogramclassmember}
|
||||
: A program class is referring to a field or a method that is missing from
|
||||
another program class. The warning lists both the referencing class and the
|
||||
missing referenced class member. Your compiled class files are most likely
|
||||
inconsistent. Possibly, some class file didn't get recompiled properly, or
|
||||
some class file was left behind after its source file was removed. Try
|
||||
removing all compiled class files and rebuilding your project.
|
||||
|
||||
**Warning: can't find referenced field/method '...' in library class ...** {: #unresolvedlibraryclassmember}
|
||||
: A program class is referring to a field or a method that is missing from a
|
||||
library class. The warning lists both the referencing class and the missing
|
||||
referenced class member. Your compiled class files are inconsistent with the
|
||||
libraries. You may need to recompile the class files, or otherwise upgrade
|
||||
the libraries to consistent versions.
|
||||
|
||||
1. If there are unresolved references to class members in *program
|
||||
classes*, your compiled class files are most likely
|
||||
inconsistent. Possibly, some class file didn't get recompiled
|
||||
properly, or some class file was left behind after its source
|
||||
file was removed. Try removing all compiled class files and
|
||||
rebuilding your project.
|
||||
|
||||
2. If there are unresolved references to class members in *library
|
||||
classes*, your compiled class files are inconsistent with
|
||||
the libraries. You may need to recompile the class files, or
|
||||
otherwise upgrade the libraries to consistent versions.
|
||||
|
||||
Alternatively, you may get away with ignoring the inconsistency
|
||||
with the options [`-ignorewarnings`](../configuration/usage.md#ignorewarnings)
|
||||
or even [`-dontwarn`](../configuration/usage.md#dontwarn).
|
||||
|
||||
**Warning: can't find enclosing class/method** {: #unresolvedenclosingmethod}
|
||||
: If there are unresolved references to classes that are defined inside
|
||||
methods in your input, once more, your compiled class files are most likely
|
||||
inconsistent. Possibly, some class file didn't get recompiled properly, or
|
||||
some class file was left behind after its source file was removed. Try
|
||||
removing all compiled class files and rebuilding your project.
|
||||
|
||||
**Warning: library class ... depends on program class ...** {: #dependency}
|
||||
: If any of your library classes depend on your program classes, by
|
||||
extending, implementing or just referencing them, your processed code will
|
||||
generally be unusable. Program classes can depend on library classes, but
|
||||
not the other way around. Program classes are processed, while library
|
||||
classes always remain unchanged. It is therefore impossible to adapt
|
||||
references from library classes to program classes, for instance if the
|
||||
program classes are renamed. You should define a clean separation between
|
||||
program code (specified with [`-injars`](../configuration/usage.md#injars)) and library code
|
||||
(specified with [`-libraryjars`](../configuration/usage.md#libraryjars)), and try again.
|
||||
|
||||
**Warning: class file ... unexpectedly contains class ...** {: #unexpectedclass}
|
||||
: The given class file contains a definition for the given class, but the
|
||||
directory name of the file doesn't correspond to the package name of the
|
||||
class. ProGuard will accept the class definition, but the current
|
||||
implementation will not write out the processed version. Please make sure
|
||||
your input classes are packaged correctly. Notably, class files that are in
|
||||
the `WEB-INF/classes` directory in a war should be packaged in a jar and put
|
||||
in the `WEB-INF/lib` directory. If you don't mind these classes not being
|
||||
written to the output, you can specify the
|
||||
[`-ignorewarnings`](../configuration/usage.md#ignorewarnings) option, or even the
|
||||
[`-dontwarn`](../configuration/usage.md#dontwarn) option.
|
||||
|
||||
**Warning: ... is not being kept as ..., but remapped to ...** {: #mappingconflict1}
|
||||
: There is a conflict between a [`-keep`](../configuration/usage.md#keep) option and the
|
||||
mapping file specified with an [`-applymapping`](../configuration/usage.md#applymapping)
|
||||
option, in the obfuscation step. The given class name or class member name
|
||||
can't be kept by its original name, as specified in the configuration, but
|
||||
it has to be mapped to the other given name, as specified in the mapping
|
||||
file. You should adapt your configuration or your mapping file to remove the
|
||||
conflict. Alternatively, if you're sure the renaming won't hurt, you can
|
||||
specify the [`-ignorewarnings`](../configuration/usage.md#ignorewarnings) option, or even the
|
||||
[`-dontwarn`](../configuration/usage.md#dontwarn) option.
|
||||
|
||||
**Warning: field/method ... can't be mapped to ...** {: #mappingconflict2}
|
||||
: There is a conflict between some new program code and the mapping file
|
||||
specified with an [`-applymapping`](../configuration/usage.md#applymapping) option, in the
|
||||
obfuscation step. The given class member can't be mapped to the given name,
|
||||
because it would conflict with another class member that is already being
|
||||
mapped to the same name. This can happen if you are performing incremental
|
||||
obfuscation, applying an obfuscation mapping file from an initial
|
||||
obfuscation step. For instance, some new class may have been added that
|
||||
extends two existing classes, introducing a conflict in the name space of
|
||||
its class members. If you're sure the class member receiving another name
|
||||
than the one specified won't hurt, you can specify the
|
||||
[`-ignorewarnings`](../configuration/usage.md#ignorewarnings) option, or even the
|
||||
[`-dontwarn`](../configuration/usage.md#dontwarn) option. Note that you should always use the
|
||||
[`-useuniqueclassmembernames`](../configuration/usage.md#useuniqueclassmembernames) option in
|
||||
the initial obfuscation step, in order to reduce the risk of conflicts.
|
||||
|
||||
**Error: Unsupported class version number** {: #unsupportedclassversion}
|
||||
: You are trying to process class files compiled for a recent version of
|
||||
Java that your copy of ProGuard doesn't support yet. You should [check
|
||||
on-line](https://github.com/Guardsquare/proguard/releases) if there is a more
|
||||
recent release.
|
||||
|
||||
**Error: You have to specify [`-keep`](../configuration/usage.md#keep) options**
|
||||
: You either forgot to specify [`-keep`](../configuration/usage.md#keep) options, or you
|
||||
mistyped the class names. ProGuard has to know exactly what you want to
|
||||
keep: an application, an applet, a servlet, a midlet,..., or any combination
|
||||
of these. Without the proper seed specifications, ProGuard would shrink,
|
||||
optimize, or obfuscate all class files away.
|
||||
|
||||
**Error: Expecting class path separator ';' before 'Files\Java\\**...**'** (in Windows)
|
||||
: If the path of your run-time jar contains spaces, like in "Program Files",
|
||||
you have to enclose it with single or double quotes, as explained in the
|
||||
section on [file names](../configuration/usage.md#filename). This is actually true for all
|
||||
file names containing special characters, on all platforms.
|
||||
|
||||
**Error: Can't read [**...**/lib/rt.jar\] (No such file or directory)**
|
||||
: In MacOS X, the run-time classes may be in a different place than on most
|
||||
other platforms. You'll then have to adapt your configuration, replacing the
|
||||
path `<java.home>/lib/rt.jar` by `<java.home>/../Classes/classes.jar`.
|
||||
|
||||
As of Java 9, the runtime classes are packaged in
|
||||
`<java.home>/jmods/java.base.jmod` and other modules next to it.
|
||||
|
||||
**Error: Can't read ...** {: #cantread}
|
||||
: ProGuard can't read the specified file or directory. Double-check that the
|
||||
name is correct in your configuration, that the file is readable, and that
|
||||
it is not corrupt. An additional message "Unexpected end of ZLIB input
|
||||
stream" suggests that the file is truncated. You should then make sure that
|
||||
the file is complete on disk when ProGuard starts (asynchronous copying?
|
||||
unflushed buffer or cache?), and that it is not somehow overwritten by
|
||||
ProGuard's own output.
|
||||
|
||||
**Error: Can't write ...** {: #cantwrite}
|
||||
: ProGuard can't write the specified file or directory. Double-check that
|
||||
the name is correct in your configuration and that the file is writable.
|
||||
|
||||
**Internal problem starting the ProGuard GUI (Cannot write XdndAware property)** (in Linux)
|
||||
: In Linux, at least with Java 6, the GUI may not start properly, due to
|
||||
[Sun Bug \#7027598](http://bugs.sun.com/view_bug.do?bug_id=7027598). The
|
||||
work-around at this time is to specify the JVM option
|
||||
`-DsuppressSwingDropSupport=true` when running the GUI.
|
||||
|
||||
Should ProGuard crash while processing your application:
|
||||
|
||||
**OutOfMemoryError** {: #outofmemoryerror}
|
||||
: You can try increasing the heap size of the Java virtual machine, with the
|
||||
usual `-Xmx` option:
|
||||
|
||||
- In Java, specify the option as an argument to the JVM: `java -Xmx1024m`
|
||||
- In Ant, set the environment variable `ANT_OPTS=-Xmx1024m`
|
||||
- In Gradle, set the environment variable `GRADLE_OPTS=-Xmx1024m`
|
||||
- In Maven, set the environment variable `MAVEN_OPTS=-Xmx1024m`
|
||||
- In Eclipse, add the line `-Xmx1024m` to the file `eclipse.ini` inside
|
||||
your Eclipse install.
|
||||
|
||||
You can also reduce the amount of memory that ProGuard needs by
|
||||
removing unnecessary library jars from your configuration, or by
|
||||
filtering out unused library packages and classes.
|
||||
|
||||
**StackOverflowError** {: #stackoverflowerror}
|
||||
: This error might occur when processing a large code base on Windows
|
||||
(surprisingly, not so easily on Linux). In theory, increasing the stack size
|
||||
of the Java virtual machine (with the usual `-Xss` option) should help too.
|
||||
In practice however, the `-Xss` setting doesn't have any effect on the main
|
||||
thread, due to [Sun Bug
|
||||
\#4362291](http://bugs.sun.com/view_bug.do?bug_id=4362291). As a result,
|
||||
this solution will only work when running ProGuard in a different thread,
|
||||
e.g. from its GUI.
|
||||
|
||||
**Unexpected error** {: #unexpectederror}
|
||||
: ProGuard has encountered an unexpected condition, typically in the
|
||||
optimization step. It may or may not recover. You should be able to avoid it
|
||||
using the [`-dontoptimize`](../configuration/usage.md#dontoptimize) option. In any case,
|
||||
please report the problem, preferably with the simplest example that causes
|
||||
ProGuard to crash.
|
||||
|
||||
**Otherwise...** {: #otherwise}
|
||||
: Maybe your class files are corrupt. See if recompiling them and trying
|
||||
again helps. If not, please report the problem, preferably with the simplest
|
||||
example that causes ProGuard to crash.
|
||||
|
||||
## Unexpected observations after processing {: #afterprocessing}
|
||||
|
||||
If ProGuard seems to run fine, but your processed code doesn't look
|
||||
right, there might be a couple of reasons:
|
||||
|
||||
**Disappearing classes** {: #disappearingclasses}
|
||||
: If you are working on Windows and it looks like some classes have
|
||||
disappeared from your output, you should make sure you're not writing your
|
||||
output class files to a directory (or unpacking the output jar). On
|
||||
platforms with case-insensitive file systems, such as Windows, unpacking
|
||||
tools often let class files with similar lower-case and upper-case names
|
||||
overwrite each other. If you really can't switch to a different operating
|
||||
system, you could consider using ProGuard's
|
||||
[`-dontusemixedcaseclassnames`](../configuration/usage.md#dontusemixedcaseclassnames) option.
|
||||
Also, you should make sure your class files are in directories that
|
||||
correspond to their package names. ProGuard will read misplaced class files,
|
||||
but it will currently not write their processed versions. Notably, class
|
||||
files that are in the `WEB-INF/classes` directory in a war should be
|
||||
packaged in a jar and put in the `WEB-INF/lib` directory.
|
||||
|
||||
**Classes or class members not being kept** {: #notkept}
|
||||
: If ProGuard is not keeping the right classes or class members, make sure
|
||||
you are using fully qualified class names. If the package name of some class
|
||||
is missing, ProGuard won't match the elements that you might be expecting.
|
||||
It may help to double-check for typos too. You can use the
|
||||
[`-printseeds`](../configuration/usage.md#printseeds) option to see which elements are being
|
||||
kept exactly.
|
||||
|
||||
If you are using marker interfaces to keep other classes, the marker
|
||||
interfaces themselves are probably being removed in the shrinking
|
||||
step. You should therefore always explicitly keep any marker
|
||||
interfaces, with an option like
|
||||
"`-keep interface MyMarkerInterface`".
|
||||
|
||||
Similarly, if you are keeping classes based on annotations, you may
|
||||
have to avoid that the annotation classes themselves are removed in
|
||||
the shrinking step. You should package the annotation classes as a
|
||||
library, or explicitly keep them in your program code with an option
|
||||
like "`-keep @interface *`".
|
||||
|
||||
**Class names not being obfuscated** {: #classnamesnotobfuscated}
|
||||
: If the names of some classes in your obfuscated code aren't obfuscated, you
|
||||
should first check all your configuration files. Chances are that some
|
||||
`-keep` option is preserving the original names. These options may be hiding
|
||||
in your own configuration files or in configuration files from libraries.
|
||||
|
||||
**Field names not being obfuscated** {: #fieldnamesnotobfuscated}
|
||||
: If the names of some fields in your obfuscated code aren't obfuscated, this
|
||||
may be due to `-keep` options preserving the original names, for the sake of
|
||||
libraries like GSON. Such libraries perform reflection on the fields. If the
|
||||
names were obfuscated, the resulting JSON strings would come out obfuscated
|
||||
as well, which generally breaks persistence of the data or communication
|
||||
with servers.
|
||||
|
||||
**Method names not being obfuscated** {: #methodnamesnotobfuscated}
|
||||
: If the names of some methods in your obfuscated code aren't obfuscated, this
|
||||
is most likely because they extend or implement method names in the
|
||||
underlying runtime libraries. Since the runtime libraries are not obfuscated,
|
||||
any corresponding names in the application code can't be obfuscated either,
|
||||
since they must remain consistent.
|
||||
|
||||
**Variable names not being obfuscated** {: #variablenamesnotobfuscated}
|
||||
: If the names of the local variables and parameters in your obfuscated code
|
||||
don't look obfuscated, because they suspiciously resemble the names of their
|
||||
types, it's probably because the decompiler that you are using is coming up
|
||||
with those names. ProGuard's obfuscation step does remove the original names
|
||||
entirely, unless you explicitly keep the `LocalVariableTable` or
|
||||
`LocalVariableTypeTable` attributes.
|
||||
|
||||
## Problems while preverifying for Java Micro Edition
|
||||
|
||||
If ProGuard seems to run fine, but the external preverifier subsequently
|
||||
produces errors, it's usually for a single reason:
|
||||
|
||||
**InvalidClassException**, **class loading error**, or **verification error**
|
||||
: If you get any such message from the preverifier, you are probably working
|
||||
on a platform with a case-insensitive file system, such as Windows. The
|
||||
`preverify` tool always unpacks the jars, so class files with similar
|
||||
lower-case and upper-case names overwrite each other. You can use ProGuard's
|
||||
[`-dontusemixedcaseclassnames`](../configuration/usage.md#dontusemixedcaseclassnames) option
|
||||
to work around this problem. If the above doesn't help, there is probably a
|
||||
bug in the optimization step of ProGuard. Make sure you are using the latest
|
||||
version. You should be able to work around the problem by using the
|
||||
[`-dontoptimize`](../configuration/usage.md#dontoptimize) option. You can check the bug
|
||||
database to see if it is a known problem (often with a fix). Otherwise,
|
||||
please report it, preferably with the simplest example on which you can find
|
||||
ProGuard to fail.
|
||||
|
||||
Note that it is no longer necessary to use an external preverifier. With
|
||||
the [`-microedition`](../configuration/usage.md#microedition) option, ProGuard will
|
||||
preverify the class files for Java Micro Edition.
|
||||
|
||||
## Problems at run-time {: #runtime}
|
||||
|
||||
If ProGuard runs fine, but your processed application doesn't work,
|
||||
there might be several reasons:
|
||||
|
||||
**Stack traces without class names or line numbers** {: #stacktraces}
|
||||
: If your stack traces don't contain any class names or lines numbers, even
|
||||
though you are keeping the proper attributes, make sure this debugging
|
||||
information is present in your compiled code to start with. Notably the Ant
|
||||
javac task has debugging information switched off by default.
|
||||
|
||||
**NoClassDefFoundError** {: #noclassdeffounderror}
|
||||
: Your class path is probably incorrect. It should at least contain all
|
||||
library jars and, of course, your processed program jar.
|
||||
|
||||
**ClassNotFoundException** {: #classnotfoundexception}
|
||||
: Your code is probably calling `Class.forName`, trying to create the
|
||||
missing class dynamically. ProGuard can only detect constant name arguments,
|
||||
like `Class.forName("com.example.MyClass")`. For variable name arguments
|
||||
like `Class.forName(someClass)`, you have to keep all possible classes using
|
||||
the appropriate [`-keep`](../configuration/usage.md#keep) option, e.g. "`-keep class
|
||||
com.example.MyClass`" or "`-keep class * implements
|
||||
com.example.MyInterface`". While setting up your configuration, you can
|
||||
specify the option
|
||||
[`-addconfigurationdebugging`](../configuration/usage.md#addconfigurationdebugging) to help
|
||||
track down these cases at run-time and let the instrumented code suggest
|
||||
settings for them.
|
||||
|
||||
**NoSuchFieldException** {: #nosuchfieldexception}
|
||||
: Your code is probably calling something like `myClass.getField`, trying to
|
||||
find some field dynamically. Since ProGuard can't always detect this
|
||||
automatically, you have to keep the missing field using the appropriate
|
||||
[`-keep`](../configuration/usage.md#keep) option, e.g. "`-keepclassmembers class
|
||||
com.example.MyClass { int myField; }`". While setting up your configuration,
|
||||
you can specify the option
|
||||
[`-addconfigurationdebugging`](../configuration/usage.md#addconfigurationdebugging) to help
|
||||
track down these cases at run-time and let the instrumented code suggest
|
||||
settings for them.
|
||||
|
||||
**NoSuchMethodException** {: #nosuchmethodexception}
|
||||
: Your code is probably calling something like `myClass.getMethod`, trying to
|
||||
find some method dynamically. Since ProGuard can't always detect this
|
||||
automatically, you have to keep the missing method using the appropriate
|
||||
[`-keep`](../configuration/usage.md#keep) option, e.g. "`-keepclassmembers class
|
||||
com.example.MyClass { void myMethod(); }`". While setting up your
|
||||
configuration, you can specify the option
|
||||
[`-addconfigurationdebugging`](../configuration/usage.md#addconfigurationdebugging) to help
|
||||
track down these cases at run-time and let the instrumented code suggest
|
||||
settings for them. More specifically, if the method reported as missing is
|
||||
`values` or `valueOf`, you probably have to keep some methods related to
|
||||
[enumerations](../configuration/examples.md#enumerations).
|
||||
|
||||
**MissingResourceException** or **NullPointerException**
|
||||
: Your processed code may be unable to find some resource files. ProGuard
|
||||
simply copies resource files over from the input jars to the output jars.
|
||||
Their names and contents remain unchanged, unless you specify the options
|
||||
[`-adaptresourcefilenames`](../configuration/usage.md#adaptresourcefilenames) and/or
|
||||
[`-adaptresourcefilecontents`](../configuration/usage.md#adaptresourcefilecontents).
|
||||
Furthermore, directory entries in jar files aren't copied, unless you
|
||||
specify the option [`-keepdirectories`](../configuration/usage.md#keepdirectories). Note that
|
||||
Sun advises against calling `Class.getResource()` for directories (Sun Bug
|
||||
\#4761949](http://bugs.sun.com/view_bug.do?bug_id=4761949)).
|
||||
|
||||
**Disappearing annotations** {: #disappearingannotations}
|
||||
: By default, the obfuscation step removes all annotations. If your
|
||||
application relies on annotations to function properly, you should
|
||||
explicitly keep them with `-keepattributes *Annotation*`.
|
||||
|
||||
**Invalid or corrupt jarfile** {: #invalidjarfile}
|
||||
: You are probably starting your application with the java option `-jar`
|
||||
instead of the option `-classpath`. The java virtual machine returns with
|
||||
this error message if your jar doesn't contain a manifest file
|
||||
(`META-INF/MANIFEST.MF`), if the manifest file doesn't specify a main class
|
||||
(`Main-Class:` ...), or if the jar doesn't contain this main class. You
|
||||
should then make sure that the input jar contains a valid manifest file to
|
||||
start with, that this manifest file is the one that is copied (the first
|
||||
manifest file that is encountered), and that the main class is kept in your
|
||||
configuration,
|
||||
|
||||
**InvalidJarIndexException: Invalid index** {: #invalidjarindexexception}
|
||||
: At least one of your processed jar files contains an index file
|
||||
`META-INF/INDEX.LIST`, listing all class files in the jar. ProGuard by
|
||||
default copies files like these unchanged. ProGuard may however remove or
|
||||
rename classes, thus invalidating the file. You should filter the index file
|
||||
out of the input (`-injars in.jar(!META-INF/INDEX.LIST)`) or update the file
|
||||
after having applied ProGuard (`jar -i out.jar`).
|
||||
|
||||
**InvalidClassException**, **class loading error**, or **verification error** (in Java Micro Edition)
|
||||
: If you get such an error in Java Micro Edition, you may have forgotten to
|
||||
specify the [`-microedition`](../configuration/usage.md#microedition) option, so the
|
||||
processed class files are preverified properly.
|
||||
|
||||
**Error: No Such Field or Method**, **Error verifying method** (in a Java Micro Edition emulator)
|
||||
: If you get such a message in a Motorola or Sony Ericsson phone emulator,
|
||||
it's because these emulators don't like packageless classes and/or
|
||||
overloaded fields and methods. You can work around it by not using the
|
||||
options `-repackageclasses ''` and
|
||||
[`-overloadaggressively`](../configuration/usage.md#overloadaggressively).
|
||||
|
||||
**Failing midlets** (on a Java Micro Edition device)
|
||||
: If your midlet runs in an emulator and on some devices, but not on some
|
||||
other devices, this is probably due to a bug in the latter devices. For some
|
||||
older Motorola and Nokia phones, you might try specifying the
|
||||
[`-useuniqueclassmembernames`](../configuration/usage.md#useuniqueclassmembernames) option.
|
||||
It avoids overloading class member names, which triggers a bug in their java
|
||||
virtual machine. You might also try using the
|
||||
[`-dontusemixedcaseclassnames`](../configuration/usage.md#dontusemixedcaseclassnames) option.
|
||||
Even if the midlet has been properly processed and then preverified on a
|
||||
case-sensitive file system, the device itself might not like the mixed-case
|
||||
class names. Notably, the Nokia N-Gage emulator works fine, but the actual
|
||||
device seems to exhibit this problem.
|
||||
|
||||
**Disappearing loops** {: #disappearingloops}
|
||||
: If your code contains empty busy-waiting loops, ProGuard's optimization
|
||||
step may remove them. More specifically, this happens if a loop continuously
|
||||
checks the value of a non-volatile field that is changed in a different
|
||||
thread. The specifications of the Java Virtual Machine require that you
|
||||
always mark fields that are accessed across different threads without
|
||||
further synchronization as `volatile`. If this is not possible for some
|
||||
reason, you'll have to switch off optimization using the
|
||||
[`-dontoptimize`](../configuration/usage.md#dontoptimize) option.
|
||||
|
||||
**SecurityException: SHA1 digest error** {: #securityexception}
|
||||
: You may have forgotten to sign your program jar *after* having processed
|
||||
it with ProGuard.
|
||||
|
||||
**ClassCastException: class not an enum**<br/>**IllegalArgumentException: class not an enum type** {: #classcastexception}
|
||||
: You should make sure you're preserving the special methods of enumeration
|
||||
types, which the run-time environment calls by introspection. The required
|
||||
options are shown in the [examples](../configuration/examples.md#enumerations).
|
||||
|
||||
**ArrayStoreException: sun.reflect.annotation.EnumConstantNotPresentExceptionProxy** {: #arraystoreexception}
|
||||
: You are probably processing annotations involving enumerations. Again, you
|
||||
should make sure you're preserving the special methods of the enumeration
|
||||
type, as shown in the examples.
|
||||
|
||||
**IllegalArgumentException: methods with same signature but incompatible return types** {: #illegalargumentexception}
|
||||
: You are probably running some code that has been obfuscated with the
|
||||
[`-overloadaggressively`](../configuration/usage.md#overloadaggressively) option. The class
|
||||
`java.lang.reflect.Proxy` can't handle classes that contain methods with the
|
||||
same names and signatures, but different return types. Its method
|
||||
`newProxyInstance` then throws this exception. You can avoid the problem by
|
||||
not using the option.
|
||||
|
||||
**CompilerError: duplicate addition** {: #compilererror}
|
||||
: You are probably compiling or running some code that has been obfuscated
|
||||
with the [`-overloadaggressively`](../configuration/usage.md#overloadaggressively) option.
|
||||
This option triggers a bug in `sun.tools.java.MethodSet.add` in Sun's JDK
|
||||
1.2.2, which is used for (dynamic) compilation. You should then avoid this
|
||||
option.
|
||||
|
||||
**ClassFormatError: repetitive field name/signature** {: #classformaterror1}
|
||||
: You are probably processing some code that has been obfuscated before with
|
||||
the [`-overloadaggressively`](../configuration/usage.md#overloadaggressively) option. You
|
||||
should then use the same option again in the second processing round.
|
||||
|
||||
**ClassFormatError: Invalid index in LocalVariableTable in class file** {: #classformaterror2}
|
||||
: If you are keeping the `LocalVariableTable` or `LocalVariableTypeTable`
|
||||
attributes, ProGuard's optimizing step is sometimes unable to update them
|
||||
consistently. You should then let the obfuscation step remove these
|
||||
attributes or disable the optimization step.
|
||||
|
||||
**NullPointerException: create returned null** (Dagger)<br/>**IllegalStateException: Module adapter for class ... could not be loaded. Please ensure that code generation was run for this module.**<br/>**IllegalStateException: Could not load class ... needed for binding members/...** {:#dagger}
|
||||
: Dagger 1 relies on reflection to combine annotated base classes and their
|
||||
corresponding generated classes. DexGuard's default configuration already
|
||||
preserves the generated classes, but you still preserve the annotated base
|
||||
classes in your project-specific configuration. This is explained in some
|
||||
more detail in the [Dagger example](../configuration/examples.md#dagger).
|
||||
|
||||
**NoSuchMethodError** or **AbstractMethodError** {: #nosuchmethoderror}
|
||||
: You should make sure you're not writing your output class files to a
|
||||
directory on a platform with a case-insensitive file system, such as
|
||||
Windows. Please refer to the section about [disappearing
|
||||
classes](#disappearingclasses) for details.
|
||||
|
||||
Furthermore, you should check whether you have specified your
|
||||
program jars and library jars properly. Program classes can refer to
|
||||
library classes, but not the other way around.
|
||||
|
||||
If all of this seems ok, perhaps there's a bug in ProGuard (gasp!).
|
||||
If so, please report it, preferably with the simplest example on
|
||||
which you can find ProGuard to fail.
|
||||
|
||||
**VerifyError** {: #verifyerror}
|
||||
: Verification errors when executing a program are almost certainly
|
||||
the result of a bug in the optimization step of ProGuard. Make sure
|
||||
you are using the latest version. You should be able to work around
|
||||
the problem by using the
|
||||
[`-dontoptimize`](../configuration/usage.md#dontoptimize) option. You can check the
|
||||
bug database to see if it is a known problem (often with a fix).
|
||||
Otherwise, please report it, preferably with the simplest example on
|
||||
which ProGuard fails.
|
43
proguard/docs/results.md
Normal file
43
proguard/docs/results.md
Normal file
@ -0,0 +1,43 @@
|
||||
**ProGuard** successfully processes any Java bytecode, ranging from small
|
||||
applications to entire run-time libraries. It primarily reduces the
|
||||
size of the processed code, with some potential increase in efficiency as an
|
||||
added bonus. The improvements obviously depend on the original code. The table
|
||||
below presents some typical results:
|
||||
|
||||
| Input Program | Original size | After shrinking | After optim. | After obfusc. | Total reduction | Time | Memory usage
|
||||
|-----------------------------------------------------------------------------------------------------------------|---------------|-----------------|--------------|---------------|-----------------|--------|--------------
|
||||
| [Worm](http://www.oracle.com/technetwork/java/javame/index.html), a sample midlet from Oracle's JME | 10.3 K | 9.8 K | 9.6 K | 8.5 K | 18 % | 2 s | 19 M
|
||||
| [Javadocking](http://www.javadocking.com/), a docking library | 290 K | 281 K | 270 K | 201 K | 30 % | 12 s | 32 M
|
||||
| **ProGuard** itself | 648 K | 579 K | 557 K | 348 K | 46 % | 28 s | 66 M
|
||||
| [JDepend](http://www.clarkware.com/software/JDepend.html), a Java quality metrics tool | 57 K | 36 K | 33 K | 28 K | 51 % | 6 s | 24 M
|
||||
| [the run-time classes](http://www.oracle.com/technetwork/java/javase/overview/index.html) from Oracle's Java 6 | 53 M | 23 M | 22 M | 18 M | 66 % | 16 min | 270 M
|
||||
| [Tomcat](http://tomcat.apache.org/), the Apache servlet container | 1.1 M | 466 K | 426 K | 295 K | 74 % | 17 s | 44 M
|
||||
| [JavaNCSS](http://javancss.codehaus.org/), a Java source metrics tool | 632 K | 242 K | 212 K | 152 K | 75 % | 20 s | 36 M
|
||||
| [Ant](http://ant.apache.org/), the Apache build tool | 2.4 M | 401 K | 325 K | 242 K | 90 % | 23 s | 61 M
|
||||
|
||||
Results were measured with ProGuard 4.0 on a 2.6 GHz Pentium 4 with 512 MB of
|
||||
memory, using Sun JDK 1.5.0 in Fedora Core 3 Linux. All of this technology and
|
||||
software has evolved since, but the gist of the results remains the same.
|
||||
|
||||
The program sizes include companion libraries. The shrinking step produces the
|
||||
best results for programs that use only small parts of their libraries. The
|
||||
obfuscation step can significantly shrink large programs even further, since
|
||||
the identifiers of their many internal references can be replaced by short
|
||||
identifiers.
|
||||
|
||||
The Java 6 run-time classes are the most complex example. The classes perform
|
||||
a lot of introspection, interacting with the native code of the virtual
|
||||
machine. The 1500+ lines of configuration were largely composed by automated
|
||||
analysis, complemented by a great deal of trial and error. The configuration
|
||||
is probably not complete, but the resulting library successfully serves as a
|
||||
run-time environment for running applications like ProGuard and the ProGuard
|
||||
GUI.
|
||||
|
||||
For small inputs, timings are governed by the reading and parsing of the jars.
|
||||
For large inputs, the optimization step becomes more important. For instance,
|
||||
processing the Java 6 run-time classes without optimization only takes 2
|
||||
minutes.
|
||||
|
||||
Memory usage (the amount of physical memory used by ProGuard while processing)
|
||||
is governed by the basic java virtual machine and by the total size of the
|
||||
library jars and program jars.
|
17
proguard/examples/android-agp3-agp4/AndroidManifest.xml
Normal file
17
proguard/examples/android-agp3-agp4/AndroidManifest.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<application android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name="HelloWorldActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
75
proguard/examples/android-agp3-agp4/build.gradle
Normal file
75
proguard/examples/android-agp3-agp4/build.gradle
Normal file
@ -0,0 +1,75 @@
|
||||
// This build file illustrates how to apply ProGuard in the Android build
|
||||
// process with AGP < 7, by swapping the built-in version of ProGuard for a newer version.
|
||||
|
||||
// This process relies on setting `android.enableR8=false` in `gradle.properties`,
|
||||
// which is deprecated. For AGP7, please see the `android-plugin` example.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal() // For local testing
|
||||
google() // For the Android plugin.
|
||||
mavenCentral() // For anything else.
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
// Override the default version of ProGuard with the most recent one.
|
||||
dependencySubstitution {
|
||||
substitute module('net.sf.proguard:proguard-gradle') with module('com.guardsquare:proguard-gradle:7.3.0')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
storePassword 'android'
|
||||
keyAlias 'androiddebugkey'
|
||||
keyPassword 'android'
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 11
|
||||
targetSdkVersion 28
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['src']
|
||||
resources.srcDirs = ['src']
|
||||
aidl.srcDirs = ['src']
|
||||
renderscript.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
assets.srcDirs = ['assets']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
}
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
|
||||
proguardFile 'proguard-project.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google() // For the Android plugin.
|
||||
mavenCentral() // For anything else.
|
||||
}
|
BIN
proguard/examples/android-agp3-agp4/debug.keystore
Normal file
BIN
proguard/examples/android-agp3-agp4/debug.keystore
Normal file
Binary file not shown.
4
proguard/examples/android-agp3-agp4/gradle.properties
Normal file
4
proguard/examples/android-agp3-agp4/gradle.properties
Normal file
@ -0,0 +1,4 @@
|
||||
# Make sure that we use ProGuard instead of R8.
|
||||
|
||||
android.enableR8=false
|
||||
android.enableR8.libraries=false
|
BIN
proguard/examples/android-agp3-agp4/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
proguard/examples/android-agp3-agp4/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
proguard/examples/android-agp3-agp4/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
proguard/examples/android-agp3-agp4/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
183
proguard/examples/android-agp3-agp4/gradlew
vendored
Normal file
183
proguard/examples/android-agp3-agp4/gradlew
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
100
proguard/examples/android-agp3-agp4/gradlew.bat
vendored
Normal file
100
proguard/examples/android-agp3-agp4/gradlew.bat
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
127
proguard/examples/android-agp3-agp4/proguard-project.txt
Normal file
127
proguard/examples/android-agp3-agp4/proguard-project.txt
Normal file
@ -0,0 +1,127 @@
|
||||
###############################################################################
|
||||
# General settings.
|
||||
###############################################################################
|
||||
|
||||
-verbose
|
||||
|
||||
# We can debug the ProGuard configuration by instrumenting the code and
|
||||
# checking the log for feedback. Disable the option again for actual releases!
|
||||
|
||||
#-addconfigurationdebugging
|
||||
|
||||
# We can also disable the individual processing steps.
|
||||
|
||||
#-dontshrink
|
||||
#-dontoptimize
|
||||
#-dontobfuscate
|
||||
|
||||
# Specifically target Android.
|
||||
|
||||
-android
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Settings to handle reflection in the code.
|
||||
###############################################################################
|
||||
|
||||
# Preserve annotated and generated classes for Dagger.
|
||||
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@dagger.** *;
|
||||
}
|
||||
|
||||
-keep class **$$ModuleAdapter
|
||||
-keep class **$$InjectAdapter
|
||||
-keep class **$$StaticInjection
|
||||
|
||||
-if class **$$ModuleAdapter
|
||||
-keep class <1>
|
||||
|
||||
-if class **$$InjectAdapter
|
||||
-keep class <1>
|
||||
|
||||
-if class **$$StaticInjection
|
||||
-keep class <1>
|
||||
|
||||
-keepnames class dagger.Lazy
|
||||
|
||||
# Preserve annotated and generated classes for Butterknife.
|
||||
|
||||
-keep class **$$ViewBinder {
|
||||
public static void bind(...);
|
||||
public static void unbind(...);
|
||||
}
|
||||
|
||||
-if class **$$ViewBinder
|
||||
-keep class <1>
|
||||
|
||||
-keep class **_ViewBinding {
|
||||
<init>(<1>, android.view.View);
|
||||
}
|
||||
|
||||
-if class **_ViewBinding
|
||||
-keep class <1>
|
||||
|
||||
# Preserve fields that are serialized with GSON.
|
||||
|
||||
#-keepclassmembers class com.example.SerializedClass1,
|
||||
# com.example.SerializedClass2 {
|
||||
# <fields>;
|
||||
#}
|
||||
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
-keep,allowobfuscation @interface com.google.gson.annotations.**
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Further optimizations.
|
||||
###############################################################################
|
||||
|
||||
# If you wish, you can let the optimization step remove Android logging calls.
|
||||
|
||||
#-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(...);
|
||||
#}
|
||||
|
||||
# In that case, it's especially useful to also clean up any corresponding
|
||||
# string concatenation calls.
|
||||
|
||||
-assumenoexternalsideeffects class java.lang.StringBuilder {
|
||||
public java.lang.StringBuilder();
|
||||
public java.lang.StringBuilder(int);
|
||||
public java.lang.StringBuilder(java.lang.String);
|
||||
public java.lang.StringBuilder append(java.lang.Object);
|
||||
public java.lang.StringBuilder append(java.lang.String);
|
||||
public java.lang.StringBuilder append(java.lang.StringBuffer);
|
||||
public java.lang.StringBuilder append(char[]);
|
||||
public java.lang.StringBuilder append(char[], int, int);
|
||||
public java.lang.StringBuilder append(boolean);
|
||||
public java.lang.StringBuilder append(char);
|
||||
public java.lang.StringBuilder append(int);
|
||||
public java.lang.StringBuilder append(long);
|
||||
public java.lang.StringBuilder append(float);
|
||||
public java.lang.StringBuilder append(double);
|
||||
public java.lang.String toString();
|
||||
}
|
||||
|
||||
-assumenoexternalreturnvalues class java.lang.StringBuilder {
|
||||
public java.lang.StringBuilder append(java.lang.Object);
|
||||
public java.lang.StringBuilder append(java.lang.String);
|
||||
public java.lang.StringBuilder append(java.lang.StringBuffer);
|
||||
public java.lang.StringBuilder append(char[]);
|
||||
public java.lang.StringBuilder append(char[], int, int);
|
||||
public java.lang.StringBuilder append(boolean);
|
||||
public java.lang.StringBuilder append(char);
|
||||
public java.lang.StringBuilder append(int);
|
||||
public java.lang.StringBuilder append(long);
|
||||
public java.lang.StringBuilder append(float);
|
||||
public java.lang.StringBuilder append(double);
|
||||
}
|
BIN
proguard/examples/android-agp3-agp4/res/drawable/ic_launcher.png
Normal file
BIN
proguard/examples/android-agp3-agp4/res/drawable/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 898 B |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="primary">#4B7FCE</color>
|
||||
<color name="primary_dark">#4B7FCE</color>
|
||||
<color name="primary_light">#7BAFCE</color>
|
||||
<color name="accent">#4B7FCE</color>
|
||||
</resources>
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">HelloWorld Sample</string>
|
||||
</resources>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||
<item name="android:colorPrimary">@color/primary</item>
|
||||
<item name="android:colorPrimaryDark">@color/primary_dark</item>
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
</style>
|
||||
</resources>
|
0
proguard/examples/android-agp3-agp4/settings.gradle
Normal file
0
proguard/examples/android-agp3-agp4/settings.gradle
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Sample application to illustrate processing with ProGuard.
|
||||
*
|
||||
* Copyright (c) 2012-2020 Guardsquare NV
|
||||
*/
|
||||
package com.example;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Sample activity that displays "Hello world!".
|
||||
*/
|
||||
public class HelloWorldActivity extends Activity
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Display the message.
|
||||
TextView view = new TextView(this);
|
||||
view.setText("Hello World");
|
||||
view.setGravity(Gravity.CENTER);
|
||||
setContentView(view);
|
||||
}
|
||||
}
|
17
proguard/examples/android-plugin/AndroidManifest.xml
Normal file
17
proguard/examples/android-plugin/AndroidManifest.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<application android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name="HelloWorldActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
73
proguard/examples/android-plugin/build.gradle
Normal file
73
proguard/examples/android-plugin/build.gradle
Normal file
@ -0,0 +1,73 @@
|
||||
// This build file illustrates how to apply ProGuard in the Android build
|
||||
// process, with ProGuard's own plugin instead of the built-in minification
|
||||
// support of the Android Gradle plugin.
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal() // For local testing
|
||||
google() // For the Android Gradle plugin.
|
||||
mavenCentral() // For the ProGuard Gradle Plugin and anything else.
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.guardsquare:proguard-gradle:7.3.0'
|
||||
classpath 'com.android.tools.build:gradle:7.0.0'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.guardsquare.proguard'
|
||||
|
||||
repositories {
|
||||
google() // For the Android plugin.
|
||||
mavenCentral() // For anything else.
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
storePassword 'android'
|
||||
keyAlias 'androiddebugkey'
|
||||
keyPassword 'android'
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 11
|
||||
targetSdkVersion 29
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['src']
|
||||
resources.srcDirs = ['src']
|
||||
aidl.srcDirs = ['src']
|
||||
renderscript.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
assets.srcDirs = ['assets']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
// Disable the built-in minification
|
||||
minifyEnabled false
|
||||
}
|
||||
release {
|
||||
// Disable the built-in minification
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proguard {
|
||||
configurations {
|
||||
release {
|
||||
defaultConfiguration 'proguard-android-optimize.txt'
|
||||
configuration 'proguard-project.txt'
|
||||
}
|
||||
}
|
||||
}
|
BIN
proguard/examples/android-plugin/debug.keystore
Normal file
BIN
proguard/examples/android-plugin/debug.keystore
Normal file
Binary file not shown.
BIN
proguard/examples/android-plugin/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
proguard/examples/android-plugin/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
proguard/examples/android-plugin/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
proguard/examples/android-plugin/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
188
proguard/examples/android-plugin/gradlew
vendored
Normal file
188
proguard/examples/android-plugin/gradlew
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
100
proguard/examples/android-plugin/gradlew.bat
vendored
Normal file
100
proguard/examples/android-plugin/gradlew.bat
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
127
proguard/examples/android-plugin/proguard-project.txt
Normal file
127
proguard/examples/android-plugin/proguard-project.txt
Normal file
@ -0,0 +1,127 @@
|
||||
###############################################################################
|
||||
# General settings.
|
||||
###############################################################################
|
||||
|
||||
-verbose
|
||||
|
||||
# We can debug the ProGuard configuration by instrumenting the code and
|
||||
# checking the log for feedback. Disable the option again for actual releases!
|
||||
|
||||
#-addconfigurationdebugging
|
||||
|
||||
# We can also disable the individual processing steps.
|
||||
|
||||
#-dontshrink
|
||||
#-dontoptimize
|
||||
#-dontobfuscate
|
||||
|
||||
# Specifically target Android.
|
||||
|
||||
-android
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Settings to handle reflection in the code.
|
||||
###############################################################################
|
||||
|
||||
# Preserve annotated and generated classes for Dagger.
|
||||
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@dagger.** *;
|
||||
}
|
||||
|
||||
-keep class **$$ModuleAdapter
|
||||
-keep class **$$InjectAdapter
|
||||
-keep class **$$StaticInjection
|
||||
|
||||
-if class **$$ModuleAdapter
|
||||
-keep class <1>
|
||||
|
||||
-if class **$$InjectAdapter
|
||||
-keep class <1>
|
||||
|
||||
-if class **$$StaticInjection
|
||||
-keep class <1>
|
||||
|
||||
-keepnames class dagger.Lazy
|
||||
|
||||
# Preserve annotated and generated classes for Butterknife.
|
||||
|
||||
-keep class **$$ViewBinder {
|
||||
public static void bind(...);
|
||||
public static void unbind(...);
|
||||
}
|
||||
|
||||
-if class **$$ViewBinder
|
||||
-keep class <1>
|
||||
|
||||
-keep class **_ViewBinding {
|
||||
<init>(<1>, android.view.View);
|
||||
}
|
||||
|
||||
-if class **_ViewBinding
|
||||
-keep class <1>
|
||||
|
||||
# Preserve fields that are serialized with GSON.
|
||||
|
||||
#-keepclassmembers class com.example.SerializedClass1,
|
||||
# com.example.SerializedClass2 {
|
||||
# <fields>;
|
||||
#}
|
||||
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
-keep,allowobfuscation @interface com.google.gson.annotations.**
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Further optimizations.
|
||||
###############################################################################
|
||||
|
||||
# If you wish, you can let the optimization step remove Android logging calls.
|
||||
|
||||
#-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(...);
|
||||
#}
|
||||
|
||||
# In that case, it's especially useful to also clean up any corresponding
|
||||
# string concatenation calls.
|
||||
|
||||
-assumenoexternalsideeffects class java.lang.StringBuilder {
|
||||
public java.lang.StringBuilder();
|
||||
public java.lang.StringBuilder(int);
|
||||
public java.lang.StringBuilder(java.lang.String);
|
||||
public java.lang.StringBuilder append(java.lang.Object);
|
||||
public java.lang.StringBuilder append(java.lang.String);
|
||||
public java.lang.StringBuilder append(java.lang.StringBuffer);
|
||||
public java.lang.StringBuilder append(char[]);
|
||||
public java.lang.StringBuilder append(char[], int, int);
|
||||
public java.lang.StringBuilder append(boolean);
|
||||
public java.lang.StringBuilder append(char);
|
||||
public java.lang.StringBuilder append(int);
|
||||
public java.lang.StringBuilder append(long);
|
||||
public java.lang.StringBuilder append(float);
|
||||
public java.lang.StringBuilder append(double);
|
||||
public java.lang.String toString();
|
||||
}
|
||||
|
||||
-assumenoexternalreturnvalues class java.lang.StringBuilder {
|
||||
public java.lang.StringBuilder append(java.lang.Object);
|
||||
public java.lang.StringBuilder append(java.lang.String);
|
||||
public java.lang.StringBuilder append(java.lang.StringBuffer);
|
||||
public java.lang.StringBuilder append(char[]);
|
||||
public java.lang.StringBuilder append(char[], int, int);
|
||||
public java.lang.StringBuilder append(boolean);
|
||||
public java.lang.StringBuilder append(char);
|
||||
public java.lang.StringBuilder append(int);
|
||||
public java.lang.StringBuilder append(long);
|
||||
public java.lang.StringBuilder append(float);
|
||||
public java.lang.StringBuilder append(double);
|
||||
}
|
BIN
proguard/examples/android-plugin/res/drawable/ic_launcher.png
Normal file
BIN
proguard/examples/android-plugin/res/drawable/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 898 B |
7
proguard/examples/android-plugin/res/values/colors.xml
Normal file
7
proguard/examples/android-plugin/res/values/colors.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="primary">#4B7FCE</color>
|
||||
<color name="primary_dark">#4B7FCE</color>
|
||||
<color name="primary_light">#7BAFCE</color>
|
||||
<color name="accent">#4B7FCE</color>
|
||||
</resources>
|
4
proguard/examples/android-plugin/res/values/strings.xml
Normal file
4
proguard/examples/android-plugin/res/values/strings.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">HelloWorld Sample</string>
|
||||
</resources>
|
8
proguard/examples/android-plugin/res/values/styles.xml
Normal file
8
proguard/examples/android-plugin/res/values/styles.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||
<item name="android:colorPrimary">@color/primary</item>
|
||||
<item name="android:colorPrimaryDark">@color/primary_dark</item>
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
</style>
|
||||
</resources>
|
0
proguard/examples/android-plugin/settings.gradle
Normal file
0
proguard/examples/android-plugin/settings.gradle
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Sample application to illustrate processing with ProGuard.
|
||||
*
|
||||
* Copyright (c) 2012-2020 Guardsquare NV
|
||||
*/
|
||||
package com.example;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Sample activity that displays "Hello world!".
|
||||
*/
|
||||
public class HelloWorldActivity extends Activity
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Display the message.
|
||||
TextView view = new TextView(this);
|
||||
view.setText("Hello World");
|
||||
view.setGravity(Gravity.CENTER);
|
||||
setContentView(view);
|
||||
}
|
||||
}
|
65
proguard/examples/annotations/examples.pro
Normal file
65
proguard/examples/annotations/examples.pro
Normal file
@ -0,0 +1,65 @@
|
||||
#
|
||||
# This ProGuard configuration file illustrates how to use annotations for
|
||||
# specifying which classes and class members should be kept.
|
||||
# Usage:
|
||||
# java -jar proguard.jar @examples.pro
|
||||
#
|
||||
|
||||
# Specify the input, output, and library jars.
|
||||
# This is assuming the code has been compiled in the examples directory.
|
||||
|
||||
-injars examples(*.class)
|
||||
-outjars out
|
||||
|
||||
# Before Java 9, the runtime classes were packaged in a single jar file.
|
||||
#-libraryjars <java.home>/lib/rt.jar
|
||||
|
||||
# As of Java 9, the runtime classes are packaged in modular jmod files.
|
||||
-libraryjars <java.home>/jmods/java.base.jmod(!**.jar;!module-info.class)
|
||||
#-libraryjars <java.home>/jmods/.....
|
||||
|
||||
# Some important configuration is based on the annotations in the code.
|
||||
# We have to specify what the annotations mean to ProGuard.
|
||||
|
||||
-include lib/annotations.pro
|
||||
|
||||
#
|
||||
# We can then still add any other options that might be useful.
|
||||
#
|
||||
|
||||
# Print out a list of what we're preserving.
|
||||
|
||||
-printseeds
|
||||
|
||||
# Preserve all annotations themselves.
|
||||
|
||||
-keepattributes *Annotation*
|
||||
|
||||
# Preserve all native method names and the names of their classes.
|
||||
|
||||
-keepclasseswithmembernames,includedescriptorclasses class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# Preserve the special static methods that are required in all enumeration
|
||||
# classes.
|
||||
|
||||
-keepclassmembers,allowoptimization enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
# Explicitly preserve all serialization members. The Serializable interface
|
||||
# is only a marker interface, so it wouldn't save them.
|
||||
# You can comment this out if your application doesn't use serialization.
|
||||
# If your code contains serializable classes that have to be backward
|
||||
# compatible, please refer to the manual.
|
||||
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
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();
|
||||
}
|
23
proguard/examples/annotations/examples/Applet.java
Normal file
23
proguard/examples/annotations/examples/Applet.java
Normal file
@ -0,0 +1,23 @@
|
||||
import proguard.annotation.*;
|
||||
|
||||
/**
|
||||
* This applet illustrates the use of annotations for configuring ProGuard.
|
||||
*
|
||||
* You can compile it with:
|
||||
* javac -classpath ../lib/annotations.jar Applet.java
|
||||
* You can then process it with:
|
||||
* java -jar ../../../lib/proguard.jar @ ../examples.pro
|
||||
*
|
||||
* The annotation will preserve the class and its essential methods,
|
||||
* as a result of the specifications in lib/annotations.pro.
|
||||
*/
|
||||
@Keep
|
||||
public class Applet extends java.applet.Applet
|
||||
{
|
||||
// Implementations for Applet.
|
||||
|
||||
public void init()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
21
proguard/examples/annotations/examples/Application.java
Normal file
21
proguard/examples/annotations/examples/Application.java
Normal file
@ -0,0 +1,21 @@
|
||||
import proguard.annotation.KeepApplication;
|
||||
|
||||
/**
|
||||
* This application illustrates the use of annotations for configuring ProGuard.
|
||||
*
|
||||
* You can compile it with:
|
||||
* javac -classpath ../lib/annotations.jar Application.java
|
||||
* You can then process it with:
|
||||
* java -jar ../../../lib/proguard.jar @ ../examples.pro
|
||||
*
|
||||
* The annotation will preserve the class and its main method,
|
||||
* as a result of the specifications in lib/annotations.pro.
|
||||
*/
|
||||
@KeepApplication
|
||||
public class Application
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.out.println("The answer is 42");
|
||||
}
|
||||
}
|
57
proguard/examples/annotations/examples/Bean.java
Normal file
57
proguard/examples/annotations/examples/Bean.java
Normal file
@ -0,0 +1,57 @@
|
||||
import proguard.annotation.*;
|
||||
|
||||
/**
|
||||
* This bean illustrates the use of annotations for configuring ProGuard.
|
||||
*
|
||||
* You can compile it with:
|
||||
* javac -classpath ../lib/annotations.jar Bean.java
|
||||
* You can then process it with:
|
||||
* java -jar ../../../lib/proguard.jar @ ../examples.pro
|
||||
*
|
||||
* The annotations will preserve the class and its public getters and setters,
|
||||
* as a result of the specifications in lib/annotations.pro.
|
||||
*/
|
||||
@Keep
|
||||
@KeepPublicGettersSetters
|
||||
public class Bean
|
||||
{
|
||||
public boolean booleanProperty;
|
||||
public int intProperty;
|
||||
public String stringProperty;
|
||||
|
||||
|
||||
public boolean isBooleanProperty()
|
||||
{
|
||||
return booleanProperty;
|
||||
}
|
||||
|
||||
|
||||
public void setBooleanProperty(boolean booleanProperty)
|
||||
{
|
||||
this.booleanProperty = booleanProperty;
|
||||
}
|
||||
|
||||
|
||||
public int getIntProperty()
|
||||
{
|
||||
return intProperty;
|
||||
}
|
||||
|
||||
|
||||
public void setIntProperty(int intProperty)
|
||||
{
|
||||
this.intProperty = intProperty;
|
||||
}
|
||||
|
||||
|
||||
public String getStringProperty()
|
||||
{
|
||||
return stringProperty;
|
||||
}
|
||||
|
||||
|
||||
public void setStringProperty(String stringProperty)
|
||||
{
|
||||
this.stringProperty = stringProperty;
|
||||
}
|
||||
}
|
52
proguard/examples/annotations/examples/NativeCallBack.java
Normal file
52
proguard/examples/annotations/examples/NativeCallBack.java
Normal file
@ -0,0 +1,52 @@
|
||||
import proguard.annotation.*;
|
||||
|
||||
/**
|
||||
* This application illustrates the use of annotations for configuring ProGuard.
|
||||
*
|
||||
* You can compile it with:
|
||||
* javac -classpath ../lib/annotations.jar NativeCallBack.java
|
||||
* You can then process it with:
|
||||
* java -jar ../../../lib/proguard.jar @ ../examples.pro
|
||||
*
|
||||
* The annotation will preserve the class and its main method,
|
||||
* as a result of the specifications in lib/annotations.pro.
|
||||
*/
|
||||
@KeepApplication
|
||||
public class NativeCallBack
|
||||
{
|
||||
/**
|
||||
* Suppose this is a native method that computes an answer.
|
||||
*
|
||||
* The -keep option for native methods in the regular ProGuard
|
||||
* configuration will make sure it is not removed or renamed when
|
||||
* processing this code.
|
||||
*/
|
||||
public native int computeAnswer();
|
||||
|
||||
|
||||
/**
|
||||
* Suppose this method is called back from the above native method.
|
||||
*
|
||||
* ProGuard would remove it, because it is not referenced from java.
|
||||
* The annotation will make sure it is preserved anyhow.
|
||||
*/
|
||||
@Keep
|
||||
public int getAnswer()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The main entry point of the application.
|
||||
*
|
||||
* The @KeepApplication annotation of this class will make sure it is not
|
||||
* removed or renamed when processing this code.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
int answer = new NativeCallBack().computeAnswer();
|
||||
|
||||
System.out.println("The answer is " + answer);
|
||||
}
|
||||
}
|
89
proguard/examples/ant/applets.xml
Normal file
89
proguard/examples/ant/applets.xml
Normal file
@ -0,0 +1,89 @@
|
||||
<!-- This Ant build file illustrates how to process applets.
|
||||
Usage: ant -f applets.xml -->
|
||||
|
||||
<project name="Applets" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard verbose="true"
|
||||
printseeds="on"
|
||||
printmapping="out.map"
|
||||
renamesourcefileattribute="SourceFile">
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
<injar file="in.jar" />
|
||||
<outjar file="out.jar" />
|
||||
|
||||
<libraryjar file="${java.home}/lib/rt.jar" />
|
||||
|
||||
<!-- Optionally preserve line numbers in the obfuscated stack traces.
|
||||
<keepattribute name="LineNumberTable">
|
||||
<keepattribute name="SourceFile">
|
||||
-->
|
||||
|
||||
<!-- Preserve all annotations. -->
|
||||
|
||||
<keepattribute name="*Annotation*" />
|
||||
|
||||
<!-- Preserve all public applets. -->
|
||||
|
||||
<keep access="public" extends="java.applet.Applet" />
|
||||
|
||||
<!-- Preserve all native method names and the names of their classes. -->
|
||||
|
||||
<keepclasseswithmembernames includedescriptorclasses="true">
|
||||
<method access="native" />
|
||||
</keepclasseswithmembernames>
|
||||
|
||||
<!-- Preserve the methods that are required in all enumeration classes. -->
|
||||
|
||||
<keepclassmembers allowoptimization="true" type="enum">
|
||||
<method access="public static"
|
||||
type="**[]"
|
||||
name="values"
|
||||
parameters="" />
|
||||
<method access="public static"
|
||||
type="**"
|
||||
name="valueOf"
|
||||
parameters="java.lang.String" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Explicitly preserve all serialization members. The Serializable
|
||||
interface is only a marker interface, so it wouldn't save them.
|
||||
You can comment this out if your library doesn't use serialization.
|
||||
If your code contains serializable classes that have to be backward
|
||||
compatible, please refer to the manual. -->
|
||||
|
||||
<keepclassmembers implements="java.io.Serializable">
|
||||
<field access ="static final"
|
||||
type ="long"
|
||||
name ="serialVersionUID" />
|
||||
<field access ="static final"
|
||||
type ="java.io.ObjectStreamField[]"
|
||||
name ="serialPersistentFields" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="writeObject"
|
||||
parameters="java.io.ObjectOutputStream" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="readObject"
|
||||
parameters="java.io.ObjectInputStream" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="writeReplace"
|
||||
parameters="" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="readResolve"
|
||||
parameters="" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Your application may contain more items that need to be preserved;
|
||||
typically classes that are dynamically created using Class.forName -->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
15
proguard/examples/ant/applications1.xml
Normal file
15
proguard/examples/ant/applications1.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<!-- This Ant build file illustrates how to process applications,
|
||||
by including a ProGuard-style configuration file.
|
||||
Usage: ant -f applications1.xml -->
|
||||
|
||||
<project name="Applications" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard configuration="examples/applications.pro" />
|
||||
|
||||
</target>
|
||||
|
||||
</project>
|
76
proguard/examples/ant/applications2.xml
Normal file
76
proguard/examples/ant/applications2.xml
Normal file
@ -0,0 +1,76 @@
|
||||
<!-- This Ant build file illustrates how to process applications,
|
||||
by including ProGuard-style configuration options.
|
||||
Usage: ant -f applications2.xml -->
|
||||
|
||||
<project name="Applications" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard>
|
||||
|
||||
-verbose
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
-injars in.jar
|
||||
-outjars out.jar
|
||||
|
||||
-libraryjars ${java.home}/lib/rt.jar
|
||||
<!-- -libraryjars junit.jar -->
|
||||
<!-- -libraryjars servlet.jar -->
|
||||
<!-- -libraryjars jai_core.jar -->
|
||||
<!-- ... -->
|
||||
|
||||
<!-- Save the obfuscation mapping to a file, and preserve line numbers. -->
|
||||
|
||||
-printmapping out.map
|
||||
-renamesourcefileattribute SourceFile
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
<!-- Preserve all annotations. -->
|
||||
|
||||
-keepattributes *Annotation*
|
||||
|
||||
<!-- Preserve all public applications. -->
|
||||
|
||||
-keepclasseswithmembers public class * {
|
||||
public static void main(java.lang.String[]);
|
||||
}
|
||||
|
||||
<!-- Preserve all native method names and the names of their classes. -->
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
<!-- Preserve the methods that are required in all enumeration classes. -->
|
||||
|
||||
-keepclassmembers,allowoptimization enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
<!-- Explicitly preserve all serialization members. The Serializable
|
||||
interface is only a marker interface, so it wouldn't save them.
|
||||
You can comment this out if your library doesn't use serialization.
|
||||
If your code contains serializable classes that have to be backward
|
||||
compatible, please refer to the manual. -->
|
||||
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
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();
|
||||
}
|
||||
|
||||
<!-- Your application may contain more items that need to be preserved;
|
||||
typically classes that are dynamically created using Class.forName -->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
99
proguard/examples/ant/applications3.xml
Normal file
99
proguard/examples/ant/applications3.xml
Normal file
@ -0,0 +1,99 @@
|
||||
<!-- This Ant build file illustrates how to process applications,
|
||||
using a full-blown XML configuration.
|
||||
Usage: ant -f applications3.xml -->
|
||||
|
||||
<project name="Applications" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard verbose="true"
|
||||
printseeds="on"
|
||||
printmapping="out.map"
|
||||
renamesourcefileattribute="SourceFile">
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
<injar file="in.jar" />
|
||||
<outjar file="out.jar" />
|
||||
|
||||
<libraryjar file="${java.home}/lib/rt.jar" />
|
||||
<!-- libraryjar file="junit.jar" / -->
|
||||
<!-- libraryjar file="servlet.jar" / -->
|
||||
<!-- libraryjar file="jai_core.jar" / -->
|
||||
<!-- ... / -->
|
||||
|
||||
<!-- Preserve line numbers in the obfuscated stack traces. -->
|
||||
|
||||
<keepattribute name="LineNumberTable" />
|
||||
<keepattribute name="SourceFile" />
|
||||
|
||||
<!-- Preserve all annotations. -->
|
||||
|
||||
<keepattribute name="*Annotation*" />
|
||||
|
||||
<!-- Preserve all public applications. -->
|
||||
|
||||
<keepclasseswithmembers access="public">
|
||||
<method access ="public static"
|
||||
type ="void"
|
||||
name ="main"
|
||||
parameters="java.lang.String[]" />
|
||||
</keepclasseswithmembers>
|
||||
|
||||
<!-- Preserve all native method names and the names of their classes. -->
|
||||
|
||||
<keepclasseswithmembernames includedescriptorclasses="true">
|
||||
<method access="native" />
|
||||
</keepclasseswithmembernames>
|
||||
|
||||
<!-- Preserve the methods that are required in all enumeration classes. -->
|
||||
|
||||
<keepclassmembers allowoptimization="true" type="enum">
|
||||
<method access="public static"
|
||||
type="**[]"
|
||||
name="values"
|
||||
parameters="" />
|
||||
<method access="public static"
|
||||
type="**"
|
||||
name="valueOf"
|
||||
parameters="java.lang.String" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Explicitly preserve all serialization members. The Serializable
|
||||
interface is only a marker interface, so it wouldn't save them.
|
||||
You can comment this out if your library doesn't use serialization.
|
||||
If your code contains serializable classes that have to be backward
|
||||
compatible, please refer to the manual. -->
|
||||
|
||||
<keepclassmembers implements="java.io.Serializable">
|
||||
<field access ="static final"
|
||||
type ="long"
|
||||
name ="serialVersionUID" />
|
||||
<field access ="static final"
|
||||
type ="java.io.ObjectStreamField[]"
|
||||
name ="serialPersistentFields" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="writeObject"
|
||||
parameters="java.io.ObjectOutputStream" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="readObject"
|
||||
parameters="java.io.ObjectInputStream" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="writeReplace"
|
||||
parameters="" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="readResolve"
|
||||
parameters="" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Your application may contain more items that need to be preserved;
|
||||
typically classes that are dynamically created using Class.forName -->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
106
proguard/examples/ant/library.xml
Normal file
106
proguard/examples/ant/library.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<!-- This Ant build file illustrates how to process a program library,
|
||||
such that it remains usable as a library.
|
||||
Usage: ant -f library.xml -->
|
||||
|
||||
<project name="Library" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard verbose="true"
|
||||
printmapping="out.map"
|
||||
renamesourcefileattribute="SourceFile">
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
<injar file="library.jar" />
|
||||
<outjar file="library_out.jar" />
|
||||
|
||||
<libraryjar file="${java.home}/lib/rt.jar" />
|
||||
|
||||
<!-- Keep some useful attributes. -->
|
||||
|
||||
<keepattribute name="Signature" />
|
||||
<keepattribute name="Exceptions" />
|
||||
<keepattribute name="InnerClasses" />
|
||||
<keepattribute name="PermittedSubclasses" />
|
||||
<keepattribute name="EnclosingMethod" />
|
||||
<keepattribute name="Deprecated" />
|
||||
<keepattribute name="SourceFile" />
|
||||
<keepattribute name="LineNumberTable" />
|
||||
|
||||
<!-- Preserve all public classes, and their public and protected fields
|
||||
and methods. -->
|
||||
|
||||
<keep access="public">
|
||||
<field access="public protected" />
|
||||
<method access="public protected" />
|
||||
</keep>
|
||||
|
||||
<!-- Preserve all .class method names. -->
|
||||
|
||||
<keepclassmembernames access="public">
|
||||
<method type ="java.lang.Class"
|
||||
name ="class$"
|
||||
parameters="java.lang.String" />
|
||||
<method type ="java.lang.Class"
|
||||
name ="class$"
|
||||
parameters="java.lang.String,boolean" />
|
||||
</keepclassmembernames>
|
||||
|
||||
<!-- Preserve all native method names and the names of their classes. -->
|
||||
|
||||
<keepclasseswithmembernames includedescriptorclasses="true">
|
||||
<method access="native" />
|
||||
</keepclasseswithmembernames>
|
||||
|
||||
<!-- Preserve the methods that are required in all enumeration classes. -->
|
||||
|
||||
<keepclassmembers allowoptimization="true" type="enum">
|
||||
<method access="public static"
|
||||
type="**[]"
|
||||
name="values"
|
||||
parameters="" />
|
||||
<method access="public static"
|
||||
type="**"
|
||||
name="valueOf"
|
||||
parameters="java.lang.String" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Explicitly preserve all serialization members. The Serializable
|
||||
interface is only a marker interface, so it wouldn't save them.
|
||||
You can comment this out if your library doesn't use serialization.
|
||||
If your code contains serializable classes that have to be backward
|
||||
compatible, please refer to the manual. -->
|
||||
|
||||
<keepclassmembers implements="java.io.Serializable">
|
||||
<field access ="final"
|
||||
type ="long"
|
||||
name ="serialVersionUID" />
|
||||
<field access ="static final"
|
||||
type ="java.io.ObjectStreamField[]"
|
||||
name ="serialPersistentFields" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="writeObject"
|
||||
parameters="java.io.ObjectOutputStream" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="readObject"
|
||||
parameters="java.io.ObjectInputStream" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="writeReplace"
|
||||
parameters="" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="readResolve"
|
||||
parameters="" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Your application may contain more items that need to be preserved;
|
||||
typically classes that are dynamically created using Class.forName -->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
53
proguard/examples/ant/midlets.xml
Normal file
53
proguard/examples/ant/midlets.xml
Normal file
@ -0,0 +1,53 @@
|
||||
<!-- This Ant build file illustrates how to process J2ME midlets.
|
||||
Usage: ant -f midlets.xml -->
|
||||
|
||||
<project name="Midlets" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard verbose="true"
|
||||
microedition="on"
|
||||
printseeds="on"
|
||||
printmapping="out.map"
|
||||
overloadaggressively="on"
|
||||
repackageclasses=""
|
||||
allowaccessmodification="on"
|
||||
renamesourcefileattribute="SourceFile">
|
||||
|
||||
<!-- On Windows, you can't use mixed case class names,
|
||||
should you still want to use the preverify tool.
|
||||
usemixedcaseclassnames="false">
|
||||
-->
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
<injar file="in.jar" />
|
||||
<outjar file="out.jar" />
|
||||
|
||||
<libraryjar file="/usr/local/java/wtk2.5.2/lib/midpapi20.jar" />
|
||||
<libraryjar file="/usr/local/java/wtk2.5.2/lib/cldcapi11.jar" />
|
||||
|
||||
<!-- Optionally preserve line numbers in the obfuscated stack traces.
|
||||
<keepattribute name="LineNumberTable">
|
||||
<keepattribute name="SourceFile">
|
||||
-->
|
||||
|
||||
<!-- Preserve all public midlets. -->
|
||||
|
||||
<keep access="public" extends="javax.microedition.midlet.MIDlet" />
|
||||
|
||||
<!-- Preserve all native method names and the names of their classes. -->
|
||||
|
||||
<keepclasseswithmembernames includedescriptorclasses="true">
|
||||
<method access="native" />
|
||||
</keepclasseswithmembernames>
|
||||
|
||||
<!-- Your application may contain more items that need to be preserved;
|
||||
typically classes that are dynamically created using Class.forName -->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
109
proguard/examples/ant/proguard.xml
Normal file
109
proguard/examples/ant/proguard.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<!-- This Ant build file illustrates how to process ProGuard (including its
|
||||
main application, its GUI, its Ant task, and its WTK plugin), and the
|
||||
ReTrace tool, all in one go.
|
||||
Usage: ant -f proguard.xml -->
|
||||
|
||||
<project name="ProGuard" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard verbose="true"
|
||||
printmapping="proguard.map"
|
||||
overloadaggressively="on"
|
||||
repackageclasses=""
|
||||
renamesourcefileattribute="SourceFile">
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
<injar file="lib/proguard.jar" />
|
||||
<outjar file="examples/ant/proguard_out.jar" />
|
||||
|
||||
<!-- Before Java 9, the runtime classes were packaged in a single jar file. -->
|
||||
<!-- libraryjar file="${java.home}/lib/rt.jar" -->
|
||||
|
||||
<!-- As of Java 9, the runtime classes are packaged in modular jmod files. -->
|
||||
<libraryjar file="${java.home}/jmods/java.base.jmod" jarfilter="!**.jar" filter="!module-info.class" />
|
||||
<libraryjar file="${java.home}/jmods/java.sql.jmod" jarfilter="!**.jar" filter="!module-info.class" />
|
||||
|
||||
<libraryjar file="${user.home}/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.3.31/11289d20fd95ae219333f3456072be9f081c30cc/kotlin-stdlib-1.3.31.jar" />
|
||||
<libraryjar file="${user.home}/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.3.31/20c34a04ea25cb1ef0139598bd67c764562cb170/kotlin-stdlib-common-1.3.31.jar" />
|
||||
<libraryjar file="${user.home}/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-metadata-jvm/0.1.0/505481587ce23e1d8207734e496632df5c4e6f58/kotlinx-metadata-jvm-0.1.0.jar" />
|
||||
<libraryjar file="${user.home}/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.5/f645ed69d595b24d4cf8b3fbb64cc505bede8829/gson-2.8.5.jar" />
|
||||
|
||||
<!-- Don't print notes about reflection in GSON code, the Kotlin runtime, and our own optionally injected code. -->
|
||||
|
||||
<dontnote filter="kotlin.**" />
|
||||
<dontnote filter="kotlinx.**" />
|
||||
<dontnote filter="com.google.gson.**" />
|
||||
<dontnote filter="proguard.configuration.ConfigurationLogger" />
|
||||
|
||||
<!-- Preserve injected GSON utility classes and their members. -->
|
||||
|
||||
<keep name="proguard.optimize.gson._*" allowobfuscation="true" />
|
||||
<keepclassmembers name="proguard.optimize.gson._*">
|
||||
<field name="*" />
|
||||
<method name="*" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Obfuscate class strings of injected GSON utility classes. -->
|
||||
|
||||
<adaptclassstrings name="proguard.optimize.gson.**" />
|
||||
|
||||
<!-- Adapt the resource file names, based on the corresponding obfuscated
|
||||
class names. -->
|
||||
|
||||
<adaptresourcefilenames filter="**.properties,**.gif,**.jpg" />
|
||||
<adaptresourcefilecontents filter="proguard/ant/task.properties" />
|
||||
|
||||
<!-- Optionally preserve line numbers in the obfuscated stack traces.
|
||||
<keepattribute name="LineNumberTable">
|
||||
<keepattribute name="SourceFile">
|
||||
-->
|
||||
|
||||
<!-- The main seeds: ProGuard and its companion tool ReTrace. -->
|
||||
|
||||
<keep access="public" name="proguard.ProGuard">
|
||||
<method access ="public static"
|
||||
type ="void"
|
||||
name ="main"
|
||||
parameters="java.lang.String[]" />
|
||||
</keep>
|
||||
<keep access="public" name="proguard.gui.ProGuardGUI">
|
||||
<method access ="public static"
|
||||
type ="void"
|
||||
name ="main"
|
||||
parameters="java.lang.String[]" />
|
||||
</keep>
|
||||
<keep access="public" name="proguard.retrace.ReTrace">
|
||||
<method access ="public static"
|
||||
type ="void"
|
||||
name ="main"
|
||||
parameters="java.lang.String[]" />
|
||||
</keep>
|
||||
|
||||
<!-- If we have ant.jar, we can properly process the Ant task. -->
|
||||
|
||||
<keeppackagename name="proguard.ant" />
|
||||
<keep name="proguard.ant.*" allowobfuscation="true" />
|
||||
<keepclassmembers access="public" name="proguard.ant.*">
|
||||
<constructor parameters="org.apache.tools.ant.Project" />
|
||||
<method access="public" type="void" name="set*" parameters="***" />
|
||||
<method access="public" type="void" name="add*" parameters="***" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- If we have the Gradle jars, we can properly process the Gradle task. -->
|
||||
|
||||
<keep access="public" name="proguard.gradle.*">
|
||||
<method access="public" />
|
||||
</keep>
|
||||
|
||||
<!-- If we have kenv.zip, we can process the J2ME WTK plugin. -->
|
||||
|
||||
<keep access="public" name="proguard.wtk.ProGuardObfuscator" />
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
89
proguard/examples/ant/servlets.xml
Normal file
89
proguard/examples/ant/servlets.xml
Normal file
@ -0,0 +1,89 @@
|
||||
<!-- This Ant build file illustrates how to process servlets.
|
||||
Usage: ant -f servlets.xml -->
|
||||
|
||||
<project name="Servlets" default="obfuscate" basedir="../..">
|
||||
|
||||
<target name="obfuscate">
|
||||
<taskdef resource="proguard/ant/task.properties"
|
||||
classpath="lib/proguard.jar" />
|
||||
|
||||
<proguard verbose="true"
|
||||
printseeds="on"
|
||||
printmapping="proguard.map"
|
||||
renamesourcefileattribute="SourceFile">
|
||||
|
||||
<!-- Specify the input jars, output jars, and library jars. -->
|
||||
|
||||
<injar file="in.jar" />
|
||||
<outjar file="out.jar" />
|
||||
|
||||
<libraryjar file="${java.home}/lib/rt.jar" />
|
||||
|
||||
<!-- Optionally preserve line numbers in the obfuscated stack traces.
|
||||
<keepattribute name="LineNumberTable">
|
||||
<keepattribute name="SourceFile">
|
||||
-->
|
||||
|
||||
<!-- Preserve all annotations. -->
|
||||
|
||||
<keepattribute name="*Annotation*" />
|
||||
|
||||
<!-- Keep all public servlets. -->
|
||||
|
||||
<keep access="public" implements="javax.servlet.Servlet" />
|
||||
|
||||
<!-- Preserve all native method names and the names of their classes. -->
|
||||
|
||||
<keepclasseswithmembernames includedescriptorclasses="true">
|
||||
<method access="native" />
|
||||
</keepclasseswithmembernames>
|
||||
|
||||
<!-- Preserve the methods that are required in all enumeration classes. -->
|
||||
|
||||
<keepclassmembers allowoptimization="true" type="enum">
|
||||
<method access="public static"
|
||||
type="**[]"
|
||||
name="values"
|
||||
parameters="" />
|
||||
<method access="public static"
|
||||
type="**"
|
||||
name="valueOf"
|
||||
parameters="java.lang.String" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Explicitly preserve all serialization members. The Serializable
|
||||
interface is only a marker interface, so it wouldn't save them.
|
||||
You can comment this out if your library doesn't use serialization.
|
||||
If your code contains serializable classes that have to be backward
|
||||
compatible, please refer to the manual. -->
|
||||
|
||||
<keepclassmembers implements="java.io.Serializable">
|
||||
<field access ="static final"
|
||||
type ="long"
|
||||
name ="serialVersionUID" />
|
||||
<field access ="static final"
|
||||
type ="java.io.ObjectStreamField[]"
|
||||
name ="serialPersistentFields" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="writeObject"
|
||||
parameters="java.io.ObjectOutputStream" />
|
||||
<method access ="private"
|
||||
type ="void"
|
||||
name ="readObject"
|
||||
parameters="java.io.ObjectInputStream" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="writeReplace"
|
||||
parameters="" />
|
||||
<method type ="java.lang.Object"
|
||||
name ="readResolve"
|
||||
parameters="" />
|
||||
</keepclassmembers>
|
||||
|
||||
<!-- Your application may contain more items that need to be preserved;
|
||||
typically classes that are dynamically created using Class.forName -->
|
||||
|
||||
</proguard>
|
||||
</target>
|
||||
|
||||
</project>
|
6
proguard/examples/application-kotlin/.idea/compiler.xml
generated
Normal file
6
proguard/examples/application-kotlin/.idea/compiler.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="11" />
|
||||
</component>
|
||||
</project>
|
17
proguard/examples/application-kotlin/.idea/gradle.xml
generated
Normal file
17
proguard/examples/application-kotlin/.idea/gradle.xml
generated
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="$USER_HOME$/.sdkman/candidates/gradle/4.10.2" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
proguard/examples/application-kotlin/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
proguard/examples/application-kotlin/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ReplaceUntilWithRangeUntil" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
20
proguard/examples/application-kotlin/.idea/jarRepositories.xml
generated
Normal file
20
proguard/examples/application-kotlin/.idea/jarRepositories.xml
generated
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenRepo" />
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
6
proguard/examples/application-kotlin/.idea/kotlinc.xml
generated
Normal file
6
proguard/examples/application-kotlin/.idea/kotlinc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.7.21" />
|
||||
</component>
|
||||
</project>
|
7
proguard/examples/application-kotlin/.idea/misc.xml
generated
Normal file
7
proguard/examples/application-kotlin/.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
6
proguard/examples/application-kotlin/.idea/vcs.xml
generated
Normal file
6
proguard/examples/application-kotlin/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
67
proguard/examples/application-kotlin/.idea/workspace.xml
generated
Normal file
67
proguard/examples/application-kotlin/.idea/workspace.xml
generated
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="beb0481a-9fcb-40ec-a128-e9a0bc35ae01" name="Changes" comment="Add simple Kotlin example application" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="DefaultGradleProjectSettings">
|
||||
<option name="isMigrated" value="true" />
|
||||
</component>
|
||||
<component name="ExternalProjectsData">
|
||||
<projectState path="$PROJECT_DIR$">
|
||||
<ProjectState />
|
||||
</projectState>
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectId" id="2KGgLM0XNRr9GUCTrjtWmKoLSqY" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="autoscrollFromSource" value="true" />
|
||||
<option name="foldersAlwaysOnTop" value="false" />
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
<option name="showMembers" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"last_opened_file_path": "/home/james/Projects/jlox"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="beb0481a-9fcb-40ec-a128-e9a0bc35ae01" name="Changes" comment="" />
|
||||
<created>1673606278294</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1673606278294</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="Add simple Kotlin example application">
|
||||
<created>1673610276662</created>
|
||||
<option name="number" value="00001" />
|
||||
<option name="presentableId" value="LOCAL-00001" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1673610276662</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="2" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="Add simple Kotlin example application" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Add simple Kotlin example application" />
|
||||
</component>
|
||||
</project>
|
69
proguard/examples/application-kotlin/build.gradle
Normal file
69
proguard/examples/application-kotlin/build.gradle
Normal file
@ -0,0 +1,69 @@
|
||||
import proguard.gradle.ProGuardTask
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.guardsquare:proguard-gradle:7.3.1'
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.8.0'
|
||||
id 'application'
|
||||
}
|
||||
|
||||
group = 'org.example'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-test'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions.jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
compileTestKotlin {
|
||||
kotlinOptions.jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = 'AppKt'
|
||||
}
|
||||
|
||||
ext.baseCoordinates = "${project.name}-${project.version}"
|
||||
|
||||
tasks.register('proguard', ProGuardTask) {
|
||||
configuration file('proguard.pro')
|
||||
|
||||
injars(tasks.named('jar', Jar).flatMap { it.archiveFile })
|
||||
|
||||
// Automatically handle the Java version of this build.
|
||||
if (System.getProperty('java.version').startsWith('1.')) {
|
||||
// Before Java 9, the runtime classes were packaged in a single jar file.
|
||||
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
|
||||
} else {
|
||||
// As of Java 9, the runtime classes are packaged in modular jmod files.
|
||||
libraryjars "${System.getProperty('java.home')}/jmods/java.base.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
|
||||
//libraryjars "${System.getProperty('java.home')}/jmods/....."
|
||||
}
|
||||
|
||||
// This will include the Kotlin library jars
|
||||
libraryjars sourceSets.main.compileClasspath
|
||||
|
||||
verbose
|
||||
|
||||
outjars(layout.buildDirectory.file("libs/${baseCoordinates}-minified.jar"))
|
||||
}
|
1
proguard/examples/application-kotlin/gradle.properties
Normal file
1
proguard/examples/application-kotlin/gradle.properties
Normal file
@ -0,0 +1 @@
|
||||
kotlin.code.style=official
|
BIN
proguard/examples/application-kotlin/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
proguard/examples/application-kotlin/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
proguard/examples/application-kotlin/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
proguard/examples/application-kotlin/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
234
proguard/examples/application-kotlin/gradlew
vendored
Normal file
234
proguard/examples/application-kotlin/gradlew
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
89
proguard/examples/application-kotlin/gradlew.bat
vendored
Normal file
89
proguard/examples/application-kotlin/gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
8
proguard/examples/application-kotlin/proguard.pro
vendored
Normal file
8
proguard/examples/application-kotlin/proguard.pro
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
-verbose
|
||||
|
||||
-keepattributes *Annotation*
|
||||
|
||||
-keep class kotlin.Metadata { *; }
|
||||
|
||||
# Entry point to the app.
|
||||
-keep class com.example.AppKt { *; }
|
3
proguard/examples/application-kotlin/settings.gradle
Normal file
3
proguard/examples/application-kotlin/settings.gradle
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
rootProject.name = 'application-kotlin'
|
||||
|
@ -0,0 +1,9 @@
|
||||
package com.example
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("Hello World!")
|
||||
|
||||
// Try adding program arguments via Run/Debug configuration.
|
||||
// Learn more about running applications: https://www.jetbrains.com/help/idea/running-applications.html.
|
||||
println("Program arguments: ${args.joinToString()}")
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user