Hi i am developing an app with Javacv. The app works fine until i proguard the build. After proguarding, the app crashes at the place of jni function call.
-dontshrink
-dontoptimize
-dontpreverify
-dontwarn android.support.**
-keep class com.googlecode.javacv.**
-dontwarn com.googlecode.javacv.**
-keep class com.googlecode.javacpp.**
-dontwarn com.googlecode.javacpp.**
-keepclasseswithmembernames class * {
native <methods>;
}
-keepattributes *Annotation*
I can't find any answer that solves my problem. I am getting NoSuchMethodError. Anybody help me. I am using the latest version of Javacv library.
You have to keep your native methods (which you're already doing), as well as the Java methods called from native code.
You can keep all javacv and javacpp methods like so:
-keep class com.googlecode.javacv.**{ *; }
-keepclassmembers class com.googlecode.javacv.** {
<methods>;
}
-keep class com.googlecode.javacpp.**{ *; }
-keepclassmembers class com.googlecode.javacpp.** {
<methods>;
}
Also, if you want to cut down on warnings in the build output:
-dontwarn com.googlecode.javacv.**, com.googlecode.javacpp.**
-dontnote com.googlecode.javacv.**, com.googlecode.javacpp.**
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 have the following code that works fine before obfuscation
YouTube.LiveBroadcasts.List liveBroadcastsRequest =
mYouTube.liveBroadcasts().list("id,snippet,contentDetails,status");
liveBroadcastsRequest.setMine(true);
liveBroadcastsRequest.setBroadcastType("persistent");
LiveBroadcastListResponse broadcastResponse = liveBroadcastsRequest.execute();
List<LiveBroadcast> broadcasts = broadcastResponse.getItems();
LiveBroadcast broadcast = broadcasts.get(0);
But in release version with obfuscation the last line of the code throws the following exception
java.lang.ClassCastException: com.google.api.client.util.ArrayMap cannot be cast to com.google.api.services.youtube.model.LiveBroadcast
I suppose that the issue happens because my obfuscation somehow breaks gson deserialization in google api, but I cannot find how to modify my proguard rules to make it working.
Current obfuscation rules
-keep class sun.misc.Unsafe { *; }
-dontwarn sun.misc.Unsafe
-keepattributes *Annotation*
-keep class com.google.** { *; }
-keep class com.google.api.services.youtube.model.** { *; }
-dontwarn com.google.**
Any help will be appreciated
Found a correct answer here
I needed to keep the com.google.api.client.util.Key annotation from obfuscation.
-keepclassmembers class * {
#com.google.api.client.util.Key <fields>;
}
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
Thanks anyway.
I am using IBM's mobilefirst worklight version 6.3 for push notification. Everything works fine when i dont apply proguard.
When i apply proguard and run the build while subscribing for the push notification only i get the following exception.
java.lang.RuntimeException: Failed to find the icon resource. Add the icon file under the /res/drawable folder.
I have the push.png named file in the drawable folder.
Any suggestions on how to handle that on the proguard or is it a worklights bug?
had the same issue with another third party library but it was resolved when i added keep class com.classname.** {*;} i did the same for worklight as well -keep class com.worklight.** {*;} but it is of no use.
below is the proguard configuration that i have used
-keepclassmembers class * {
#android.webkit.JavascriptInterface <methods>;
}
-keep class com.google.gson.Gson
-keep class com.billdesk.** {*;}
-keep public class com.worklight.** {*;}
-dontwarn com.worklight.**
-dontwarn com.auth0.jwt.**
-dontwarn com.squareup.picasso.**
-dontwarn com.viewpagerindicator.**
-dontwarn org.bouncycastle.**
MobileFirst 6.3 does not officially support obfuscation using Proguard.
Even so, an Android project obfuscated using Proguard works fine without issues in most cases.
I am not able to recreate the issue you mention.I tested the MFP 6.3 Eventsource notifications sample after obfuscating with Proguard and the application worked fine. No runtime exceptions were seen.
Android SDK Tools : 25.1.1
Target API Level : 19
Proguard version : 4.7
To begin with:
Ensure that push.png is present in all drawable folders and not just the generic one.
Check the proguard obfusction logs to see if "push.png" is being crunched in all folders and look for error messages.
Modify the proguard configuration to contain-
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
-keep class org.apache.cordova.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin
-keep class com.worklight.androidgap.push.** { *; }
-keep class com.worklight.wlclient.push.** { *; }
-keep class com.worklight.common.security.AppAuthenticityToken { *; }
-keep class com.google.** { *;}
-dontwarn com.google.common.**
-dontwarn com.google.ads.**
-dontwarn com.worklight.androidgap.push.GCMIntentService
-dontwarn com.worklight.androidgap.plugin.WLInitializationPlugin
-dontwarn com.worklight.wlclient.push.GCMIntentService
-dontwarn org.bouncycastle.**
-dontwarn com.worklight.nativeandroid.common.WLUtils
-dontwarn com.worklight.wlclient.push.WLBroadcastReceiver
-dontwarn com.worklight.wlclient.push.common.*
-dontwarn com.worklight.wlclient.api.WLPush
I am building an application with android platform. Will like to design a server side akka application that will provide services in a distributed manner to the android application. Both systems are designed as separate applications. Will it be possible to connect the akka remote server with the android application. Please help me out cos I am new to both akka and android.
You can do this, but you will suffer.
You must somehow be able to access the class definitions for akka-remote and dependencies (netty, scala) from your android app. This can be problematic, since the sum of dependencies has more than 65536 methods which is Dalviks cap. (That is - your classes.dex file inside the apk cannot have more method definitions than 65536).
AFAIK, there's three main approaches:
Split up the dependencies into separate apklibs and make your apk depend on these.
I can't really recommend this since I haven't tried it.
Split up the dependencies into separate classes.dex files that you load programmatically from your app.
Probably doable. Never tried it.
Run proguard before packing your classes.dex
You'll have to battle with proguard to get the config right, and you may get strange runtime failures. My config is posted below.
Once you get akka-remote up and running on your android device you can connect to the server like in the examples in the docs. However, keep in mind that:
The IP of your Android device may or may not be available at boot time, so you may wan't to keep that part of your akka config dynamic (haven't done this myself).
The IP of your Android device may not be reachable from the server. So if you get into a state where the server needs to call the client back, it will never succeed.
My proguard.cfg (some lines are not needed - haven't bothered figure out which ones):
-dontoptimize
#-optimizationpasses 2
-dontobfuscate
-dontpreverify
-dontskipnonpubliclibraryclassmembers
-dontskipnonpubliclibraryclasses
-dontnote **
-verbose
-keep class com.typesafe.config.Config { *; }
-keep class com.typesafe.config.ConfigFactory { *; }
-keep class org.slf4j.Logger { *; }
-keep class org.slf4j.LoggerFactory { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
#Scala
-dontwarn scala.**
-keepclassmembers class * {
** MODULE$;
}
-keep class scala.Option
-keep class scala.Function1
-keep class scala.PartialFunction
#https://issues.scala-lang.org/browse/SI-5397
-keep class scala.collection.SeqLike {
public protected *;
}
-keep class scala.Tuple*
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
-keep class * implements org.xml.sax.EntityResolver
-keepclassmembers class * {
** MODULE$;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool { *; }
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
int base;
int sp;
int runState;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
int status;
}
-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue { *; }
#Akka
-dontwarn org.jboss.netty.logging.**
-dontwarn org.osgi.**
-dontwarn javax.servlet.**
#-dontwarn org.jboss.netty.channel.socket.http.**
## Unsafe is there at runtime
-dontwarn sun.misc.Unsafe
-keep class sun.misc.Unsafe{
*;
}
-keep class akka.** { *; }
-keep class com.google.protobuf.GeneratedMessage {
*;
}
-keep class org.javatuples.** { *; }
-keep class org.jboss.**
-dontwarn org.jboss.netty.handler.codec.marshalling.**
-dontwarn org.jboss.netty.channel.socket.nio.**
-dontwarn org.jboss.netty.handler.codec.compression.JdkZlibEncoder
-dontwarn org.jboss.netty.handler.codec.spdy.SpdyHeaderBlockZlibCompressor
-dontwarn org.jboss.netty.channel.socket.http.HttpTunnelingServlet
-dontwarn org.jboss.modules.**
-dontwarn __redirected.**
-dontwarn org.slf4j.LoggerFactory
-dontwarn org.slf4j.MarkerFactory
-dontwarn org.slf4j.MDC
-dontwarn org.slf4j.impl.AndroidLogger
-dontwarn org.slf4j.impl.AndroidLoggerFactory
Good luck.
I'm not sure if you were thinking of using the Akka remoting protocol, but if it were me, I would consider looking into the excellent HTTP+REST library Spray (http://spray.io/). I've played around with this library and it is very slick. It is well integrated with Akka and would allow you to provide REST APIs for your services. As a bonus, going REST also allows you to have services that will easily integrate with things other than your Android frontend.
I've included a couple of links as a starting point. The Google 2010 I/O talk on writing REST clients for Android apps is especially interesting:
http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
http://www.techrepublic.com/blog/app-builder/calling-restful-services-from-your-android-app/1076
I want to use Proguard mainly for obfuscation reasons.
My problem is that I have three libraries, Twitter4J and two signpost libraries. These libraries caused errors when I tried to create an signed APK. To get over this I put the following in the proguard.config file...
-dontwarn org.apache.commons.codec.binary.**
-dontwarn org.slf4j.**
-dontwarn com.sun.syndication.io.**
-dontwarn com.sun.syndication.feed.synd.*
While this got rid of the errors in the console, when i loaded my signed APK onto my mobile phone it instantly crashed. The DDMS said this was due to a class not found in Twitter4J.
Getting rid of the "dontwarns" above did not help. Neither did adding dontshrink dontoptimise.
I would like Proguard to completely ignore the libraries (as they are open source anyway). Is this possible?
Try this:
-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
Cf post from #CaspNZ:
Android Proguard with external jar
You should be able to add to the proguard.cfg the following lines to exclude all classes within a package (and subpackages)
-keep class org.apache.commons.codec.binary.**
-keep interface org.apache.commons.codec.binary.**
-keep enum org.apache.commons.codec.binary.**
-keep class org.slf4j.**
-keep interface org.slf4j.**
-keep enum org.slf4j.**
-keep class com.sun.syndication.io.**
-keep interface com.sun.syndication.io.**
-keep enum com.sun.syndication.io.**
-keep class com.sun.syndication.feed.synd.**
-keep interface com.sun.syndication.feed.synd.**
-keep enum com.sun.syndication.feed.synd.**
I'd like to add that you should sync your project with Gradle files after adding proguard rules, otherwise they may not work.