When I use Proguard on project with OrmLite. I recieve this error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.package.name/com.package.name.activities.StartActivity}:
java.lang.IllegalStateException: Could not find OpenHelperClass because none of the generic parameters of class class com.package.name.activities.StartActivity extends OrmLiteSqliteOpenHelper. You should use getHelper(Context, Class) instead.
I've tried all recomendation from Proguard with OrmLite on Android and from others resources but without results
Put the below in both your proguard-project file and your proguard-optimization file (if you use optimization).
# Your application may contain more items that need to be preserved;
# typically classes that are dynamically created using Class.forName:
# ormlite uses reflection
-keep class com.j256.** { *; }
-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**
-keepclassmembers class * {
public <init>(android.content.Context);
}
-keepattributes *Annotation*
and for every model class:
-keep class com.xyz.components.**
-keepclassmembers class com.xyz.components.** { *; }
I don't like the last part one bit, but I'm tired of trying to find a better solution.
I asked much the same question crash using ORMLite on Android with proguard and the answer was to add
-keepattributes Signature
to the proguard configuration.
You can use the following proguard configuration to Keep all model classes that are used by OrmLite
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
# Add the ormlite field annotations that your model uses here
<init>();
}
Just a small addition for the latest version OrmLite 5.
You may want to add these rows to hide some new warnings:
-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**
Look for more details into this thread: "how can i write the config of proguard for ormlite?"
Related
I implemented a library on my gradle that uses Moshi as a dependency. When I tried to compile locally and also creating an android build through jenkins, it shows an error of
Use of generics not allowed for java type at '<1>_<2>_<3>JsonAdapter' in line 43 of file '\.gradle\caches\transforms-1\files-1.1\jetified-moshi-1.9.3.jar\76f6a6d7d5642e8be11f9d49dc24d752\META-INF\proguard\moshi.pro'
I already indicated rules on my proguard.pro file as stated on the documentation of the library I used but still errors are still encountering. I also tried the solution on the issues tab of moshi on github but I still received an error build.
Here's my proguard-rules.pro file
#ChatvisorLibrary
-keep class com.chatvisor.** {*;}
-dontwarn com.chatvisor.**
-dontwarn okhttp3.**
#Dependencies
#Protocol Buffers
-keep class com.google.**
-dontwarn com.google.**
#Moshi (https://github.com/square/moshi/blob/master/moshi/src/main/resources/META-INF/proguard/moshi.pro)
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
-keepclasseswithmembers class * {
#com.squareup.moshi.* <methods>;
}
-keep #com.squareup.moshi.JsonQualifier interface *
# Enum field names are used by the integrated EnumJsonAdapter.
# values() is synthesized by the Kotlin compiler and is used by EnumJsonAdapter indirectly
# Annotate enums with #JsonClass(generateAdapter = false) to use them with Moshi.
-keepclassmembers #com.squareup.moshi.JsonClass class * extends java.lang.Enum {
<fields>;
**[] values();
}
-ignorewarnings
-keep class * {
public private protected *;
}
I hope someone could help me and get resolved the issue. Thank you!
Already resolved this issue by upgrading my Proguard version
https://www.guardsquare.com/en/blog/proguard-61-released
I am having problems with GSON on Android with Proguard.
APK is compiled, installed on phone.
Application is not crashing, it is just not parsing object correctly.
I log all the data and it is like that:
I get correct string with data to parse.
(CookieValue is correct)
Token token = new Gson().fromJson(cookieValue, Token.class);
After this line, I am logging this object and it is having only null values inside.
My Proguard GSON:
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep public class com.google.gson
Token rules:
-dontwarn com.project.package.model.oauth.**
-keep,allowshrinking class com.project.package.oauth.Token { *; }
Yes, I have tried this configuration https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
Any suggestions?
In this line:
- keep,allowshrinking class com.project.package.oauth.Token { *; }
Do you actually have a space between the dash and keep? If so, take that out and see if it helps.
You might also want to remove the space after the dash in the previous dontwarn line, as well.
You can find it in my collection :
https://github.com/thientvse/awesome-mobile-collections/blob/master/README.md
It will help you config almost lib in proguard file.
I hope it will help your problem!
I have a few models that I want to obfuscate in my code.
I know that I could just ignore the whole model package but I don't want to do that.
I tried a few proguard tweaks and checked all relevant posts to no avail. ORMlite keeps throwing java.lang.RuntimeException: Unable to create application ...App: java.lang.IllegalArgumentException: Foreign field class ....f.p does not have id field. I checked that the annotation is still there with dex2jar and jd, and it is still there.
I have this proguard configuration (and a lot more that obfuscates other parts):
aggressive stuff :
-mergeinterfacesaggressively
-allowaccessmodification
-optimizationpasses 5
-verbose
-dontskipnonpubliclibraryclasses
-dontpreverify
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
keep information needed by various frameworks:
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes EnclosingMethod
ORMLITE related:
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
Am I missing something or is this just not possible?
As ORMLite uses reflection to save or retain your data, they want un-obfuscated name of entity (ie classes you are using to save or retain data).
This exception is thrown because ORMLite is trying to find the Entity classes for its tables and its not able to find the classes and members with similar name.
Just Ignore your entity classes from getting obfuscated using following code:
-keep class com.xyz.components.**
-keepclassmembers class com.xyz.components.** { *; }
where com.xyz.components is your package for Entity classes.
I hope this helps!
In addition to Vivek Soneja's answer:
There is a way to keep entity classes independently from their packages:
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
<init>();
}
It will keep all DatabaseTable annotated classes as well as their DatabaseField and ForeignCollectionField annotated fields
How should I use proguard with ormlite library on Android?
Trying this:
-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**
But I get:
03-23 20:23:54.518: E/AndroidRuntime(3032): java.lang.RuntimeException: Unable to start activity ComponentInfo{cz.eman.android.cepro/cz.eman.android.cepro.activity.StationsOverviewActivity}: java.lang.IllegalStateException: Could not find constructor that takes a Context argument for helper class class kb
I also tried to add this:
-keepclassmembers class * { public <init>(android.content.Context); }
But I get another classmembers errors.
Thank you a lot for posts like this that help us to advance step by step.
I've came up with other solution after i have tried the last one without success:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I hope it can help someone.
The accepted answer was not enough for my case, so I enhanced it and this is what I ended up with:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
# Keep the helper class and its constructor
-keep class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper {
public <init>(android.content.Context);
}
# Keep the annotations
-keepattributes *Annotation*
# Keep all model classes that are used by OrmLite
# Also keep their field names and the constructor
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
# Add the ormlite field annotations that your model uses here
<init>();
}
I don't have the solution but here are a couple of references to help:
Proguard support request around ORMLite
ORMLite proguard discussion #1
ORMLite proguard discussion #2
You may be missing:
-keepclassmembers class * {
public <init>(android.content.Context);
}
and/or
-keepattributes *Annotation*
A small addition to the configuration above - if you're trying to serialize / deserialize Joda's DateTime objects via ORMLite, you probably need this as well:
-keepclassmembers class **DateTime {
<init>(long);
long getMillis();
}
...since ORMLite's DateTimeType does everything via reflection.
In addittion to default necessary for reflection:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I needed to keep all my Entity classes:
-keep class com.example.db.Entities.** { *; }
Otherwise entity classes are stripped out.
I use predefined DB(generated earlier).
Is there an easier/better way to obfuscate. Maybe I'm keeping too many classes?
In my case this did the trick:
-keepattributes SourceFile,LineNumberTable,Signature,InnerClasses,*Annotation*
and
-keepclassmembers class * {public <init>(android.content.Context);}
-keep class com.j256.** { *; }
With obfucation and optimizations.
A small addition for the latest version OrmLite 5.
You may want to add these rows to hide some new warnings:
-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**
Warnings are like these:
Warning:com.j256.ormlite.android.OrmliteTransactionalProcessor: can't
find referenced class javax.lang.model.SourceVersion
Warning:com.j256.ormlite.logger.Slf4jLoggingLog: can't find referenced
class org.slf4j.LoggerFactory
Warning:com.j256.ormlite.misc.JavaxPersistenceImpl: can't find
referenced class javax.persistence.Column
I've came up with such solution (maybe will work for somebody too).
Made such changes to proguard.cfg:
Added -dontobfuscate option
Appended ,!code/allocation/variable to -optimization option
APK file size using such configuration reduced from 580 kB to 250 kB.
Though, no obfuscation is performed.
How should I use proguard with ormlite library on Android?
Trying this:
-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**
But I get:
03-23 20:23:54.518: E/AndroidRuntime(3032): java.lang.RuntimeException: Unable to start activity ComponentInfo{cz.eman.android.cepro/cz.eman.android.cepro.activity.StationsOverviewActivity}: java.lang.IllegalStateException: Could not find constructor that takes a Context argument for helper class class kb
I also tried to add this:
-keepclassmembers class * { public <init>(android.content.Context); }
But I get another classmembers errors.
Thank you a lot for posts like this that help us to advance step by step.
I've came up with other solution after i have tried the last one without success:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I hope it can help someone.
The accepted answer was not enough for my case, so I enhanced it and this is what I ended up with:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
# Keep the helper class and its constructor
-keep class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper {
public <init>(android.content.Context);
}
# Keep the annotations
-keepattributes *Annotation*
# Keep all model classes that are used by OrmLite
# Also keep their field names and the constructor
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
# Add the ormlite field annotations that your model uses here
<init>();
}
I don't have the solution but here are a couple of references to help:
Proguard support request around ORMLite
ORMLite proguard discussion #1
ORMLite proguard discussion #2
You may be missing:
-keepclassmembers class * {
public <init>(android.content.Context);
}
and/or
-keepattributes *Annotation*
A small addition to the configuration above - if you're trying to serialize / deserialize Joda's DateTime objects via ORMLite, you probably need this as well:
-keepclassmembers class **DateTime {
<init>(long);
long getMillis();
}
...since ORMLite's DateTimeType does everything via reflection.
In addittion to default necessary for reflection:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I needed to keep all my Entity classes:
-keep class com.example.db.Entities.** { *; }
Otherwise entity classes are stripped out.
I use predefined DB(generated earlier).
Is there an easier/better way to obfuscate. Maybe I'm keeping too many classes?
In my case this did the trick:
-keepattributes SourceFile,LineNumberTable,Signature,InnerClasses,*Annotation*
and
-keepclassmembers class * {public <init>(android.content.Context);}
-keep class com.j256.** { *; }
With obfucation and optimizations.
A small addition for the latest version OrmLite 5.
You may want to add these rows to hide some new warnings:
-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**
Warnings are like these:
Warning:com.j256.ormlite.android.OrmliteTransactionalProcessor: can't
find referenced class javax.lang.model.SourceVersion
Warning:com.j256.ormlite.logger.Slf4jLoggingLog: can't find referenced
class org.slf4j.LoggerFactory
Warning:com.j256.ormlite.misc.JavaxPersistenceImpl: can't find
referenced class javax.persistence.Column
I've came up with such solution (maybe will work for somebody too).
Made such changes to proguard.cfg:
Added -dontobfuscate option
Appended ,!code/allocation/variable to -optimization option
APK file size using such configuration reduced from 580 kB to 250 kB.
Though, no obfuscation is performed.