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
Related
I know there is an answer on another thread but I feel it is unrelated.
(Or it might be, but I'd appreciate a more elaborate answer)
So I have these in my proguard.rules:
-dontwarn com.google.android.instantapps.supervisor.InstantAppsRuntime
-keep class com.google.android.instantapps.supervisor.InstantAppsRuntime
-dontwarn com.google.android.gms.ads.AdView
-keep class com.google.android.gms.ads.AdView
-dontwarn com.google.android.gms.tagmanager.TagManagerService
-keep class com.google.android.gms.tagmanager.TagManagerService
-dontwarn io.grpc.netty.NettyChannelProvider
-keep class io.grpc.netty.NettyChannelProvider
-dontwarn io.opencensus.impl.tags.TagsComponentImpl
-keep class io.opencensus.impl.tags.TagsComponentImpl
-dontwarn io.opencensus.impllite.tags.TagsComponentImplLite
-keep class io.opencensus.impllite.tags.TagsComponentImplLite
-dontwarn io.opencensus.impl.stats.StatsComponentImpl
-keep class io.opencensus.impl.stats.StatsComponentImpl
-dontwarn io.opencensus.impllite.stats.StatsComponentImplLite
-keep class io.opencensus.impllite.stats.StatsComponentImplLite
But when compiling the app, I still get these warnings for all of them:
W/ProGuard: The class 'io.opencensus.stats.Stats' is calling Class.forName to retrieve
the class 'io.opencensus.impllite.stats.StatsComponentImplLite', but the latter could not be found.
It may have been obfuscated or shrunk.
You should consider preserving the class with its original name,
with a setting like:
-keep class io.opencensus.impllite.stats.StatsComponentImplLite
(that is an example)
Why is that happening? Is ProGuard actually keep the classes or did it not process by proguard.rules?
It is probably because you are missing the opencensus library dependency from your project.
Add below line to your gradle dependencies, e.g.
dependencies {
implementation 'io.opencensus:opencensus-api:0.18.0'
}
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!
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.
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?"
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.