Search code examples
androidproguardobfuscationsqlcipher

Android Proguard SqlCipher NoClassDefFoundError


Have been battling with Proguard all day and have tried many examples and solutions on the official Proguard site as well as StackOverflow.

I have a large project I need to obfuscate, which has a number of referenced library projects and Jars.

I am getting 725 warnings from proguard from 2 libs, com.google.common and twitter4j.

I can happily get the project to compile if I add the following:

-dontwarn com.google.common.**

-dontwarn twitter4j.**

However, the app crashes instantly on open, so this seems to just be a way of hiding an issue, not fixing it.

The proguard-project.txt is in the project root and its config is in the project.properties file as below.

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

Here is my proguard-project.txt file

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-dontshrink

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-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 * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
-keep class com.google.code.**  { *; }
-keep class java.lang.management.**  { *; }
-keep class com.google.common.** { *; }

-libraryjars C:/adt-bundle-windows/sdk/platforms/android-19/android.jar
-libraryjars C:/adt-bundle-windows/sdk/extras/android/support/v4/android-support-v4.jar
-libraryjars C:/svn/android/MyAppLib/trunk/libs/commons-codec.jar
-libraryjars C:/svn/android/MyAppLib/trunk/libs/sqlcipher.jar
-libraryjars C:/svn/android/MyAppLib/trunk/libs/twitter4j-core-3.0.3.jar
-libraryjars C:/svn/android/MyAppLib/trunk/libs/guava-r09.jar
-libraryjars C:/adt-bundle-windows/sdk/platforms/android-19/android.jar
-libraryjars C:/adt-bundle-windows/sdk/extras/android/support/v4/android-support-v4.jar
-libraryjars C:/adt-bundle-windows/sdk/add-ons/addon-google_apis-google-19/libs/maps.jar
-libraryjars C:/adt-bundle-windows/sdk/add-ons/addon-google_apis-google-19/libs/effects.jar
-libraryjars C:/adt-bundle-windows/sdk/add-ons/addon-google_apis-google-19/libs/usb.jar

-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*(...);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.content.Context {
   public void *(android.view.View);
   public void *(android.view.MenuItem);
}

-keepclassmembers class * implements android.os.Parcelable {
    static ** CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

-dontwarn android.support.**

And Here is the truncated error log

[2014-01-13 14:00:07 - MyApp] Proguard returned with error code 1. See console
[2014-01-13 14:00:07 - MyApp] Note: there were 9032 duplicate class definitions.
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.management.APIStatisticsOpenMBean: can't find superclass or interface javax.management.DynamicMBean
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalence: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalence: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalence: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalences$Impl$1: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalences$Impl$1: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalences$Impl$1: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalences$Impl$2: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalences$Impl$2: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Equivalences$Impl$2: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Function: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Function: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Functions: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Functions: can't find referenced class javax.annotation.Nullable
[2014-01-13 14:00:07 - MyApp] Warning: com.google.common.base.Functions$ConstantFunction: can't find referenced class javax.annotation.Nullable

*********************************** ANOTHER 500 LINES OF com.google.common ERRORS ******************************************

[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class java.lang.management.ManagementFactory
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.ObjectName
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.ObjectName
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanServer
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.InstanceAlreadyExistsException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.InstanceAlreadyExistsException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.InstanceAlreadyExistsException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanRegistrationException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanRegistrationException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanRegistrationException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.NotCompliantMBeanException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.NotCompliantMBeanException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.NotCompliantMBeanException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MalformedObjectNameException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MalformedObjectNameException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MalformedObjectNameException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class java.lang.management.ManagementFactory
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanServer
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.ObjectName
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.ObjectName
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanServer
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.InstanceAlreadyExistsException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MBeanRegistrationException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.NotCompliantMBeanException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.TwitterAPIMonitor: can't find referenced class javax.management.MalformedObjectNameException
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.CommonsLoggingLoggerFactory: can't find referenced class org.apache.commons.logging.LogFactory
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.CommonsLoggingLoggerFactory: can't find referenced class org.apache.commons.logging.LogFactory
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Level
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Level
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLogger: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLoggerFactory: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.Log4JLoggerFactory: can't find referenced class org.apache.log4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLogger: can't find referenced class org.slf4j.Logger
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLoggerFactory: can't find referenced class org.slf4j.LoggerFactory
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.internal.logging.SLF4JLoggerFactory: can't find referenced class org.slf4j.LoggerFactory
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.management.APIStatisticsOpenMBean: can't find referenced class javax.management.openmbean.CompositeType
[2014-01-13 14:00:07 - MyApp] Warning: twitter4j.management.APIStatisticsOpenMBean: can't find referenced class javax.management.openmbean.CompositeType

*********************************** ANOTHER 500 LINES OF twitter4j ERRORS ******************************************

[2014-01-13 14:00:07 - MyApp]       You should check if you need to specify additional program jars.
[2014-01-13 14:00:07 - MyApp] Warning: there were 725 unresolved references to classes or interfaces.
[2014-01-13 14:00:07 - MyApp]          You may need to specify additional library jars (using '-libraryjars').
[2014-01-13 14:00:07 - MyApp] java.io.IOException: Please correct the above warnings first.
[2014-01-13 14:00:07 - MyApp]   at proguard.Initializer.execute(Initializer.java:321)
[2014-01-13 14:00:07 - MyApp]   at proguard.ProGuard.initialize(ProGuard.java:211)
[2014-01-13 14:00:07 - MyApp]   at proguard.ProGuard.execute(ProGuard.java:86)
[2014-01-13 14:00:07 - MyApp]   at proguard.ProGuard.main(ProGuard.java:492)

EDIT** Stack trace from crash, clearer now that it is linked to sqlcipher

E/Database(18203): Can't find SQLiteDatabase.mNativeHandle
E/Cursor(18203): Can't find net/sqlcipher/database/SQLiteCompiledSql
E/Cursor(18203): Can't find net/sqlcipher/database/SQLiteQuery
E/Cursor(18203): Can't find net/sqlcipher/database/SQLiteProgram
E/Cursor(18203): Can't find net/sqlcipher/database/SQLiteStatement
E/CursorWindow(18203): Can't find net/sqlcipher/CursorWindow
 D/AndroidRuntime(18203): Shutting down VM
 W/dalvikvm(18203): threadid=1: thread exiting with uncaught exception (group=0x415e9ba8)
E/AndroidRuntime(18203): FATAL EXCEPTION: main
E/AndroidRuntime(18203): Process: com.mycompany.android.myapp, PID: 18203
E/AndroidRuntime(18203): java.lang.NoClassDefFoundError: net/sqlcipher/CursorWindow
E/AndroidRuntime(18203):    at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime(18203):    at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime(18203):    at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime(18203):    at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime(18203):    at net.sqlcipher.database.SQLiteDatabase.a(Unknown Source)
E/AndroidRuntime(18203):    at net.sqlcipher.database.SQLiteDatabase.a(Unknown Source)
E/AndroidRuntime(18203):    at com.mycompany.android.myapplib.sqlite.MyProvider.onCreate(Unknown Source)
E/AndroidRuntime(18203):    at android.content.ContentProvider.attachInfo(ContentProvider.java:1591)
E/AndroidRuntime(18203):    at android.content.ContentProvider.attachInfo(ContentProvider.java:1562)
E/AndroidRuntime(18203):    at android.app.ActivityThread.installProvider(ActivityThread.java:4790)
E/AndroidRuntime(18203):    at android.app.ActivityThread.installContentProviders(ActivityThread.java:4385)
E/AndroidRuntime(18203):    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4325)
E/AndroidRuntime(18203):    at android.app.ActivityThread.access$1500(ActivityThread.java:135)
E/AndroidRuntime(18203):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
E/AndroidRuntime(18203):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(18203):    at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(18203):    at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime(18203):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(18203):    at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime(18203):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime(18203):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime(18203):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(18203): Caused by: java.lang.NoClassDefFoundError: net/sqlcipher/database/SQLiteStatement
E/AndroidRuntime(18203):    ... 22 more
E/AndroidRuntime(18203): Caused by: java.lang.NoClassDefFoundError: net/sqlcipher/database/SQLiteProgram
E/AndroidRuntime(18203):    ... 22 more
E/AndroidRuntime(18203): Caused by: java.lang.NoClassDefFoundError: net/sqlcipher/database/SQLiteQuery
E/AndroidRuntime(18203):    ... 22 more
E/AndroidRuntime(18203): Caused by: java.lang.NoClassDefFoundError: net/sqlcipher/database/SQLiteCompiledSql
E/AndroidRuntime(18203):    ... 22 more
E/AndroidRuntime(18203): Caused by: java.lang.NoSuchFieldError: no field with name='mNativeHandle' signature='I' in class Lnet/sqlcipher/database/SQLiteDatabase;
E/AndroidRuntime(18203):    ... 22 more

Solution

  • These are the config I've used in the past for SQLcipher

    -keep public class net.sqlcipher.** {
        *;
    }
    
    -keep public class net.sqlcipher.database.** {
        *;
    }