Proguard for Android with Maven without shooting yourself in the foot

So with the introduction with the Android License Validation Library and now with the SDK tools revision 8 and the integrated options, Proguard has gained more and more interest in the Android developer community and users of the Android Maven Plugin are certainly not left behind. Of course Proguard is a fairly powerful tool that overs plenty of opportunity to get yourself into trouble or long debugging sessions. With this post I am going to show you how to best set up proguard usage in your Maven based Android application build. So lets get started.

For the impatient you can go and check it all out in my github clone of the Maven Android Plugin Samples module Morseflash that I have created and keep maintaining and expanding. Otherwise you can just read on and download it later to play around after you know what it is all about.

Because the task of running proguard can take a while and the potentially obfuscated stack traces hinder during development the whole process is only activated when a release build is created. Therefore the definition of the Maven Proguard plugin is located in the release profile of the application module pom.xml file only. This profile also contains the jarsigning and zipaligning definitions that are also only useful during a release build. To run such a release build you would run the command

mvn clean install -P release

If you run this command you should be able to observe proguard logs running past in your command line window. You can see that the plugin is the first one in the build section of the release profile. Lets have a look at the definition.

<build>
  <plugins>
    <plugin>
      <groupId>com.pyx4me</groupId>      
      <artifactId>proguard-maven-plugin</artifactId>
      <executions>
        <execution>
          <phase>process-classes</phase>
          <goals><goal>proguard</goal></goals>
        </execution>
      </executions>

This definition means that the plugin is set up to run the proguard goal in the process-classes Maven build lifecycle phase. In a Maven Android project this is after everything is prepared and compiled including R.java generation and so on, but before the apk is created. With the following definition

 <dependencies>
  <dependency>
    <groupId>net.sf.proguard</groupId>
    <artifactId>proguard</artifactId>
    <version>4.4</version>
    <scope>runtime</scope>
  </dependency>
</dependencies>

we upgrade the plugin to use version 4.4. of the proguard tool, which has some features for optimizations that will help us for Android projects. Following are the general setup parameters for the plugin.

<configuration>
  <proguardVersion>4.4</proguardVersion>
  <maxMemory>256m</maxMemory>
  <injar>android-classes</injar>
  <libs>
    <lib>${rt.jar.path}</lib>
    <lib>${jsse.jar.path}</lib>
  </libs>
  <skip>false</skip>
  <obfuscate>true</obfuscate>
  <addMavenDescriptor>false</addMavenDescriptor>
  <options>
...

Important configurations in this section are the general activation of the plugin (skip false) as well as the activation of the obfuscation (obfuscate true). In this case both are activated. You will also notice that the jsse.jar and rt.jar files are referenced as properties. The values for these file paths differ from operating system to operating system and therefore profiles were introduced that automatically get activated depending on what operating system you are running on. This will allow you to run the build unmodified on Linux, Mac and Windows machines without needing to create symlinks in the filesystem to take care of the different paths and is therefore a much eleganter and more team suitable solution. You can check these profiles out in the bottom of the same pom.xml file.

You will also see that at the bottom of the snippet above the important options section start. This section contains the meat of your proguard configuration and I will go into more detail about the various parameters and some tips about dealing e.g. with annotations and other problems in an upcoming post.

Last but not least you can find an important configuration of the build helper plugin towards the end of the release profile:

<artifact>
  <file>${project.build.directory}/proguard_map.txt</file>
  <type>map</type>
  <classifier>release</classifier>
</artifact>

By default the proguard plugin will create a mapping file between source and obfuscated names called proguard_map.txt in the build directory. This configuration with the build helper plugin ensures that when you create a release build with

mvn clean deploy -P release

your obfuscated, signed and zipaligned release apk as well as the mapping file are deployed to your local repository or even better your repository server. This way you will always be able to retrace any stack traces you receive via Android Market so that you can fix those pesky bugs in your application. Of course that is only important if you application has any bugs, which of course is does not 😉