andriydruk / RxDNSSD

Android version of mDNSResponder
Apache License 2.0
297 stars 75 forks source link

Issue when starting Release APK (not in debug/staging) #32

Open alissongodoi opened 6 years ago

alissongodoi commented 6 years ago

After compiling the app and installing it on the Android Emulator 6.0 it crashes with the following error on startup:

java.lang.InternalError: cannot instantiate DNSSDjava.lang.ClassNotFoundException: com.github.druk.dnssd.AppleDNSSD
                                                                           at com.b.a.a.h.<clinit>(Unknown Source)
                                                                           at com.b.a.a.b.<init>(Unknown Source)
                                                                           at com.b.a.a.b.<init>(Unknown Source)
                                                                           at com.b.a.a.c.<init>(Unknown Source)
                                                                           at com.yourock.digitaltv.coordinator.CoordinatorService.<clinit>(Unknown Source)
                                                                           at java.lang.Class.newInstance(Native Method)
                                                                           at android.app.ActivityThread.handleCreateService(ActivityThread.java:2859)
                                                                           at android.app.ActivityThread.-wrap4(ActivityThread.java)
                                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                           at android.os.Looper.loop(Looper.java:148)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

This is the implementation settings at gradle:

    implementation 'com.github.andriydruk:dnssd:0.9.5'
    implementation('com.github.andriydruk:rxdnssd:0.9.5')
    implementation 'io.reactivex:rxjava:1.3.0'
    implementation 'io.reactivex:rxandroid:1.2.1'

In proguard rules I had the following which I removed:

# Removing references to RxDnssd
# -dontwarn com.github.druk.**

I guess it is falling into this piece of code being null?

String name = System.getProperty( "com.github.druk.dnssd.DNSSD" );

Observe that this just happens when I compile for Release. It is working ok for other releases. These are my proguard rules:

# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/alissongodoi/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

# Proguard configuration for Jackson 2.x (fasterxml package instead of codehaus package)
-keep class com.fasterxml.jackson.databind.ObjectMapper {
    public <methods>;
    protected <methods>;
}
-keep class com.fasterxml.jackson.databind.ObjectWriter {
    public ** writeValueAsString(**);
}
-keepnames class com.fasterxml.jackson.** { *; }
-dontwarn com.fasterxml.jackson.databind.**

#Proguard for okio
-dontwarn okhttp3.*
-dontwarn okio.**

#ProGuard for EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

#Configuration for jodatime
#-keep class org.joda.** { *; }
-dontwarn org.joda.convert.FromString
-dontwarn org.joda.convert.ToString

# Removing references to RxDnssd
-dontwarn com.github.druk.**

#Retrofit ProGuard
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions

# Retrofit Retan Classes that are Models
-keep class com.yourock.digitaltv.model.** { *; }
alissongodoi commented 6 years ago

I have noticed that the issue goes away when minify is disabled. I have no idea why minify is causing this issue in the release build.

alissongodoi commented 6 years ago

It looks like it solves the issue by forcing minify to not remove the druk classes

Minify was removing the druk classes for some reason

Forcing it to stay in the release package.

-dontwarn com.github.druk. -keep class com.github.druk. { *; }

andriydruk commented 6 years ago

@alissongodoi Proguard make obfuscation of all you classes. It's rename all of them to a.b.c.d.etc. You are not first person who face this problem #19.

Maybe I should ship AAR with proguard rules inside. I'm going to investigate if it's possible

G00fY2 commented 6 years ago

@andriydruk: Should be possible with consumerProguardFiles. Otherwise I would recommend maybe put the rules in the readme (like in retrofit).

skykelsey commented 6 years ago

As mentioned by @G00fY2, you should be able to just add a file called consumer-proguard-rules.pro in the same directory as your build.gradle. Then, add this line in build.gradle in defaultConfig:

consumerProguardFiles 'consumer-proguard-rules.pro'

I can open a PR if you'd like.

skykelsey commented 6 years ago

The above proguard rules work, but they are overly broad. For my app, I noticed the following method counts on com.github.druk when using proguard to minify:

Without rules: 106 With rules: 394

I tried adding individual rules for each JNI reference, but I gave up. I would suggest moving all the JNI stuff into its own package so you can take care of it with a single proguard rule like -keep com.github.druk.dnssd.jni.** { *; } without needlessly keeping all the rest of the code.

Abu-Abdullah commented 5 years ago

i believe you need to keep rx.* as well:

-keep class com.github.druk.** { *; }
-keep class rx.** { *; }
tmm1 commented 3 years ago

I can open a PR if you'd like.

Please do this.

leohuangyi commented 3 years ago

-keep class com.github.druk.dnssd.* { ; }

work well!