ProGuard


ProGuard is a Java obfuscator, like RetroGuard (from which it was originally developed). Unlike RetroGuard, it is fully open-source and currently supported.

I've put a copy of the ProGuard documentation on sage for speedier access.

To install ProGuard, download it from Sourceforge and unpack it in a convenient location (e.g. /usr/local/src).

The basic command to run ProGuard is:
java -jar /usr/local/src/proguard4.3/lib/proguard.jar options
There are lots of options that may be used - it's simplest to put some/all of them in a configuration file (called 'modsak.pro', say) and then use a command line like:
java -jar /usr/local/src/proguard4.3/lib/proguard.jar @modsak.pro

The most useful options are probably:

Option Description
-basedirectory directoryname Specifies the base directory for subsequent relative file names.
-injars class_path Specifies the program jars (or wars, ears, zips, or directories).
-outjars class_path Specifies the name of the output jars (or wars, ears, zips, or directories).
-libraryjars class_path Specifies the library jars (or wars, ears, zips, or directories).
-keep [,modifier,...] class_specification Preserve the specified classes and class members.
-printusage [filename] List dead code of the input class files, to the standard output or to the given file.
-printmapping [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 filename Reuse the given mapping, for incremental obfuscation.

My actual modsak.pro file contains:

-printusage proguard.unused
-printmapping proguard.map

# uk.co.wingpath.util.Installer calls the following method reflectively.
-keepclassmembers class com.sun.comm.Win32Driver {
    void initialize();
}

# uk.co.wingpath.util.Installer calls the following method reflectively.
-keep public class uk.co.wingpath.modsak.Modsak {
    public static void main(java.lang.String[]);
}

# The main method of the program.
-keep class uk.co.wingpath.modsak.Bootstrap {
    public static void main(java.lang.String[]);
}

# Preserve exception classes to make stack traces a bit more intelligible.
-keep class uk.co.wingpath.modbus.ModbusException
-keep class uk.co.wingpath.util.ValueException

# This bit of magic seems to be necessary for enums - see the ProGuard docs.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

and the command I use to run Proguard is (with simplified pathnames):

java -jar /usr/local/src/proguard4.3/lib/proguard.jar @modsak.pro -injars modsakC.jar -outjars modsak.jar -libraryjars /usr/local/jdk/jre/lib/rt.jar:comm.jar proguard.log