I’ll keep this short and sweet. Dan Galpin covered in a recent blog post how to drop in Proguard & Ant to easily do Android app builds. One hitch is that it doesn’t work for apps that have third party external jars. The simple fix to get this working is to change the libraryjars line from:
-libraryjars ${libraryjarpath}
to
-libraryjars ${external.libs.dir}:${libraryjarpath}
p.s. why are all the Android dev blogs posted only by Tim Bray and not the authors directly? p.p.s. why can’t we leave comments on the blog posts?
One Trackback to “Proguard, Android, Ant, and 3rd party external JARs”
17 Comments to “Proguard, Android, Ant, and 3rd party external JARs”
-
eric franchomme Says:
September 24th, 2010 at 16:37Apparently, Dan changed the add-proguard-release.xml to support external libraries. Howerver, the change is now breaking projects which don’t have external library. I had to remove the change back to original: -libraryjars ${libraryjarpath}
-
Dan Galpin Says:
September 27th, 2010 at 09:40Sorry about that! I suspect that the change broke Windows machines. I’ve uploaded a new version that should behave correctly. The change looks like this:
-
eric franchomme Says:
September 28th, 2010 at 14:15where did you upload the new file?
-
eric franchomme Says:
September 28th, 2010 at 14:15also I do not see the change on that page…
-
Dan Galpin Says:
September 28th, 2010 at 14:18Sorry.. that’s what I get when I paste XML and it doesn’t get quoted. The file replaced the original file, and I need to get Tim to note the change in the blog post.
-
eric franchomme Says:
September 28th, 2010 at 15:05thanks!
Is there a way to verify the obfuscation is successful?
Also, is there a way to hide my native library (.so file built with NDK) so it is not extractable from the APK?
-
Dave Says:
October 2nd, 2010 at 08:53I have tried every option I could find to get proguard to work but no luck. My app builds but force closes when I run on my droid x phone after run through proguard. The app works fine exported from eclipse and just signed.
I followed the directions at: http://android-developers.blogspot.com/2010/09/proguard-android-and-licensing-server.html
I added my two classes to the keep list and no luck still force close. Then I searched for every article on proguard and disabled/tried all options including dontshtrink, dontoptimize and even dontobfuscate with no luck
-
Dan Galpin Says:
October 2nd, 2010 at 12:57When the app force-closes, what exception (or stack trace) is being shown in logcat?
-
Tertium Organum Says:
October 4th, 2010 at 08:33I have such error: Failed to locateorg.apache.tools.ant.Main ant.home: c:\Tertium\!!android\ant Classpath: c:\Tertium\!!android\ant\lib\ant-launcher.jar;c:\Program Files\Java\jdk1.6.0_10\lib\tools.jar Launcher JAR: C:\Tertium Launcher Directory: C:\
Heard it’s because old version of ant in Eclipse. It seems strange to me. Have anybody solution for this? OS: WinXP sp2 x64, Win 7 x64 (2 machines)
Can I somehow use internal eclipse ant? It compiles project although sais “Default target help does not exist in this project” but there are no result files.
-
Stephen Lau Says:
October 4th, 2010 at 18:15@Dan: One thing that might be worth updating which I ran into is that Proguard obfuscating Parcelables can cause errors where BadParcelableException gets thrown, e.g.:
Caused by: android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR
I had to put the following into my procfg.txt:
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -
Benoit Essiambre Says:
October 5th, 2010 at 06:55“Is there a way to verify the obfuscation is successful?”
Same question. Everything seems to be working except I don’t see anything about progard or obfuscation in the ant output. Is this normal?
-
Benoit Essiambre Says:
October 5th, 2010 at 07:17Ok I figured it out, I wasn’t using the latest tools SDK.
-
Charles Stearns Says:
October 6th, 2010 at 23:37I have found the the default procfg.txt suggested has a number of issues, particularly with more complex apps. It doesn’t correctly support custom Views referenced from layout. It also doesn’t correctly support onclick methods referenced from the xml that exist in the Activity. I don’t have time to do a proper write up of my own, but for sake of sharing here is a improved starting point. If your app has any level of complexity using reflection using views etc. you will need to plan on tweaking this and sending your obfuscated app through a complete test cycle. I also added keeping the line numbers for stack traces, but prior to shipping you probably want to remove that as well, it is just very helpful in getting things working.
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/,!class/merging/
-keep public class * extends android.app.Activity{ public void *(android.view.View); } -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * { native ; }
-keepclasseswithmembernames class * { public (android.content.Context, android.util.AttributeSet); }
-keepclasseswithmembernames class * { public (android.content.Context, android.util.AttributeSet, int); }
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
-keep public class * extends android.view.View { public (android.content.Context); public (android.content.Context, android.util.AttributeSet); public (android.content.Context, android.util.AttributeSet, int); public void set*(…); }
-keep public class **.R
-renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable
-
Charles Stearns Says:
October 6th, 2010 at 23:42Trying again to fix the formatting, sorry if this doesn’t format correct. [sourcecode] -optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/,!class/merging/
-keep public class * extends android.app.Activity{ public void *(android.view.View); } -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * { native ; }
-keepclasseswithmembernames class * { public (android.content.Context, android.util.AttributeSet); }
-keepclasseswithmembernames class * { public (android.content.Context, android.util.AttributeSet, int); }
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
-keep public class * extends android.view.View { public (android.content.Context); public (android.content.Context, android.util.AttributeSet); public (android.content.Context, android.util.AttributeSet, int); public void set*(…); }
-keep public class **.R
-renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable [/sourcecode]
-
Simon Says:
October 15th, 2010 at 01:24Sorry, this is the last try, think I got it now, please remove my previous double posts
Also if you have problems with folder name that contain spaces, you should surround paths with apostroph as stated in Proguard documentation.
Just change the libraryjarpath property so that it surrounds each path with apostroph…
<!-- <property name="libraryjarpath" refid="fullclasspath"/> --> <pathconvert property="libraryjarpath"> <path refid="fullclasspath"/> <mapper> <globmapper from="" to="''"/> </mapper> </pathconvert>…and add apostrophes to the path properties passed to proguard…
<proguard> @'${proguard-conf}' -injars '${android-jar-preobfuscate}' -outjars '${android-jar-postobfuscate}' -libraryjars ${libraryjarpath} -dump '${obfuscate.absolute.dir}/dump.txt' -printseeds '${obfuscate.absolute.dir}/seeds.txt' -printusage '${obfuscate.absolute.dir}/usage.txt' -printmapping '${obfuscate.absolute.dir}/mapping.txt' </proguard> -
Brad Says:
October 20th, 2010 at 17:23I ran into some problems on Windows as well. I have an external JAR in the project’s lib folder. I was able to get it to work using a variant of Simon’s method.
First, I added this property:
<property name="targetclasspath" refid="android.target.classpath"/
Then, I changed the text in the proguard tag to look like this:
<proguard> @'${proguard-conf}' -injars '${android-jar-preobfuscate}' -outjars '${android-jar-postobfuscate}' -libraryjars '${targetclasspath}';'${external.libs.dir}' -dump '${obfuscate.absolute.dir}/dump.txt' -printseeds '${obfuscate.absolute.dir}/seeds.txt' -printusage '${obfuscate.absolute.dir}/usage.txt' -printmapping '${obfuscate.absolute.dir}/mapping.txt' </proguard>Hopefully this helps others on Windows.
-
Brad Says:
October 21st, 2010 at 12:38Additionally, I also had issues with onClick methods getting zapped by Proguard. I used Charles Stearns’ example, but had to modify it a bit. It looks like the site mangled the code. Here is what worked for me:
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/,!class/merging/ -keep public class * extends android.app.Activity{ public void *(android.view.View); } -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class com.android.vending.licensing.ILicensingService -keepclasseswithmembernames class * { native <methods>; } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); } -keep public class **.R -renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable
Leave a Reply
Recent posts
- Gesture Lock
(Saturday, Nov 13. 2010 – 12 Comments) - ConnectIn 1.1.1 & HTC Sense UI
(Tuesday, Sep 28. 2010 – 38 Comments) - ConnectIn
(Saturday, Sep 25. 2010 – 62 Comments) - Proguard, Android, Ant, and 3rd party external JARs
(Wednesday, Sep 22. 2010 – 18 Comments)
Categories
- Android
- Cars
- ChinaBlog
- Code
- Computers
- Development
- Food
- Football
- Grommit
- Linkage
- Movies&TV
- Music
- Musings
- OpenSolaris
- OpenSource
- Outdoors
- Pets
- Photos
- Quotage
- Rdio
- Songbird
- Sun
- Travel
Grommit
Mozilla
OpenSolaris
- alan burlison
- bonnie corwin
- eric boutilier
- glynn foster
- jim grisanzio
- mark nelson
- mike kupfer
- planet opensolaris
- stephen hahn
Songbird
Archives
- November 2010
- September 2010
- August 2010
- June 2010
- May 2010
- February 2010
- January 2010
- December 2009
- October 2009
- September 2009
- August 2009
- June 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- June 2005
- May 2005
- April 2005
- March 2005
- February 2005
- January 2005
- December 2004
- November 2004
- October 2004
- September 2004
- August 2004
- July 2004
- June 2004
- May 2004
- April 2004
- March 2004
- February 2004
- January 2004
- December 2003
- November 2003
- October 2003
- September 2003
- August 2003
- July 2003
- June 2003
- May 2003
- April 2003
- March 2003
- February 2003
- January 2003
- December 2002
- November 2002
- October 2002
- September 2002
- August 2002
- July 2002
- June 2002
- May 2002
- April 2002
- March 2002

October 4th, 2010 at 19:04