dart icon indicating copy to clipboard operation
dart copied to clipboard

Dart can't find injector when using Proguard

Open sewerk opened this issue 8 years ago • 6 comments

After enabling minifyEnabled for release build, crashes start occurring. I have a proguard-rules:

-dontwarn com.f2prateek.dart.internal.**
-keep class **$$ExtraInjector { *; }
-keepclasseswithmembernames class * {
    @com.f2prateek.dart.* <fields>;
}

and seeing in log:

02-08 22:03:31.765 11321-11440/? D/Dart: Looking up extra injector for pl.srw.service.AService
02-08 22:03:31.767 11321-11440/? D/Dart: Not found. Trying superclass pl.srw.service.a
02-08 22:03:31.768 11321-11440/? D/Dart: Not found. Trying superclass android.app.IntentService
02-08 22:03:31.768 11321-11440/? D/Dart: MISS: Reached framework class. Abandoning search.

I'm on version 1.1.0

sewerk avatar Feb 08 '17 21:02 sewerk

It looks like your issue is that the ExtraInjector of the class pl.srw.service.AService can't be found. You can debug by trying to find out which injectors is not found after obfuscation: is it for the class itself, for its super class ? Should they be found ? Do superclasses have a ExtraInjector in the non obfuscated version, etc.

We don't have enough detail on this bug to help you and we don't use obfuscation in our app, so it's hard to help.

We would advise to use newer versions than 1.1.0, it's been a while we didn't work on it.

stephanenicolas avatar Feb 11 '17 18:02 stephanenicolas

ExtraInjector is generated for super class a. Without obfuscation there is one available and everything works fine. My IntentService super class has annotations on it and Dart.inject call:

public abstract class a extends IntentService {

    protected @InjectExtra(IntentCreator.A) String aExtra;
    protected @Optional @InjectExtra(IntentCreator.B) int bExtra;

    protected a(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(final Intent intent) {
        Dart.inject(this, intent.getExtras());
        // ...
    }

sewerk avatar Feb 11 '17 19:02 sewerk

It's really hard to say what happens. You need to investigate things like:

  • what is the name of a after obfuscation
  • how is ExtraInjector of a named
  • what does the call to it looks like after obfuscation, etc.

There is not enough information to answer your issue.

stephanenicolas avatar Feb 16 '17 03:02 stephanenicolas

Ok, so I looked into release (obfuscated) apk and my hierarchy: AService extends BaseService is AService extends a

The abstract BaseService class is the only one containing @InjectExtra annotations and so BaseService$$ExtraInjector is generated.

The problem is that Dart is looking for a$$ExtraInjector whereas in the obfuscated apk it can find only the BaseService$$ExtraInjector

sewerk avatar Feb 17 '17 20:02 sewerk

Hi, I see that after removing the last field with @Bind from my fragment, the fragment class is now obfuscated.

So I conclude that the proguard rule:

-keepclasseswithmembernames class * {
    @com.f2prateek.dart.* <fields>;
}

does not work and

-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}

works.

The diff between @Bind and @InjectExtra is that the first has CLASS retention and the second has SOURCE retention.

=> It is just an idea, but maybe @InjectExtra should have CLASS retention to fix this issue

Benoît

bmarty avatar Apr 05 '17 08:04 bmarty

@bmarty you are right, I changed it and it works. Here you can find the sources and PR: https://github.com/f2prateek/dart/pull/163

@stephanenicolas let me know any problems

luckpizza avatar Oct 04 '17 08:10 luckpizza