Butterknife: Bindings fail after file changes using jack compiler and java 8

Created on 11 Aug 2016  路  17Comments  路  Source: JakeWharton/butterknife

Using Android Studio 2.2 Beta running on Mac OSX 10.10.5
and butterknife 8.1.0 (I couldn't get the latest build to work due to issue #673)

I opened this issue on https://code.google.com/p/android/issues/detail?id=219768 but I'm unsure if this is something going on with Android Studio or something going on with this library, maybe you can point me in the right direction.

Steps to Reproduce bug:

  1. open and build the project https://github.com/bennmapes/android_bug
  2. deploy it to device
  3. change the string in the RandomClass
  4. deploy to device again
  5. should get null pointer when binding fails
  6. to fix this rebuild the whole project and it should work again

Most helpful comment

I confirm this problem. I'm crazy about it. I spent a lot of time for rebuilding my project again and again. When I use ButterKnife.setDebug(true) to view logcast, it show like:

D/ButterKnife: Looking up view binder for vn.vimo.ui.fragments.SplashFragment
D/ButterKnife: Not found. Trying superclass vn.vimo.ui.BaseFragment
D/ButterKnife: Not found. Trying superclass nucleus.view.NucleusSupportFragment
D/ButterKnife: Not found. Trying superclass android.support.v4.app.Fragment
D/ButterKnife: MISS: Reached framework class. Abandoning search.

But when I look at the build directory in my project, I could find the generated file ViewBinder (in my situation is: SplashFragment$$ViewBinder) in the "apt" directory.

I use Java8, Jack compiler and AndroidStudio 2.2 Beta. I use "annotationProcessor" in my gradle config:

compile 'com.jakewharton:butterknife:8.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0'

UPDATE: The problem only happen when I change my Java code, (change the resource is ok)

All 17 comments

I confirm this problem. I'm crazy about it. I spent a lot of time for rebuilding my project again and again. When I use ButterKnife.setDebug(true) to view logcast, it show like:

D/ButterKnife: Looking up view binder for vn.vimo.ui.fragments.SplashFragment
D/ButterKnife: Not found. Trying superclass vn.vimo.ui.BaseFragment
D/ButterKnife: Not found. Trying superclass nucleus.view.NucleusSupportFragment
D/ButterKnife: Not found. Trying superclass android.support.v4.app.Fragment
D/ButterKnife: MISS: Reached framework class. Abandoning search.

But when I look at the build directory in my project, I could find the generated file ViewBinder (in my situation is: SplashFragment$$ViewBinder) in the "apt" directory.

I use Java8, Jack compiler and AndroidStudio 2.2 Beta. I use "annotationProcessor" in my gradle config:

compile 'com.jakewharton:butterknife:8.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0'

UPDATE: The problem only happen when I change my Java code, (change the resource is ok)

I know exactly what you mean about having to wait ages for things to rebuild. It's driving me crazy as well.

So sad, nobody reply. I think this problem come from Android Studio and Jack compiler, because generated files of ButterKnife annotations already existed, but something was wrong while building them to APK file.

It's not this issue. Your issue only happen in v2.8.1 and it cause build processing end with a exception. My problem only appear at runtime, because the Butterknife Annotation not working, it make a NullPointerException at runtime when I try to access a View.

But the issue seems to be the cause during runtime as well. My existing issue is the same as yours actually and it's only happening when it's not using APT. Probably a lot of com.sun.* Exceptions are just being bypassed and are just realized when the app is actually running.

Edit: I'll let you see the code:
https://github.com/JakeWharton/butterknife/blob/master/butterknife-compiler/src/main/java/butterknife/compiler/ButterKnifeProcessor.java

Check for the method scanForRClasses. If the trees (com.sun.source.util.Trees) instance is null the rest of the R.id mapping will not happen.

My problem do not appear when I update my AndroidStudio to v2.2 Beta 2 (until now, I still haven't encounter it yet). Maybe, this problem come from build tool.

hnvn, had that problem yesterday and it worked by adding the butterknife-compiler key on dependencies section of my gradle module's project.
I realized that issue appears when you are using other annotation packages like Realm, Retrofit and so on.

marco, you mean like:

compile 'com.jakewharton:butterknife:' + butterknifeVersionCode
annotationProcessor 'com.jakewharton:butterknife-compiler:' + butterknifeVersionCode

Of course, you must add the butterknife-compiler when use customized annotations

Yes, but in my case my dependencies came:

    compile 'com.jakewharton:butterknife:8.2.1'
    compile 'com.jakewharton:butterknife-compiler:8.2.1'

Just check your package options adding the path to processor like:

android {
    packagingOptions {
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }
}

@marcosrocha85 Your workaround seems to fix our issue as well. 馃憤
@JakeWharton Can you confirm if this method is also okay?

Edit: Sadly this implies the following on proguard:

Butterknife specific

-dontwarn com.sun.source.*
-dontwarn com.sun.tools.
*
-dontwarn javax.annotation.processing.**

Edit 2: There are too much warnings on the release build. I wouldn't advice using this route:

Warning: butterknife.compiler.ButterKnifeProcessor: can't find referenced field 'javax.annotation.processing.ProcessingEnvironment processingEnv' in program class butterknife.compiler.ButterKnifeProcessor
Warning: com.google.auto.common.BasicAnnotationProcessor: can't find referenced field 'javax.annotation.processing.ProcessingEnvironment processingEnv' in program class com.google.auto.common.BasicAnnotationProcessor
Warning: com.google.auto.service.processor.AutoServiceProcessor: can't find referenced field 'javax.annotation.processing.ProcessingEnvironment processingEnv' in program class com.google.auto.service.processor.AutoServiceProcessor
Warning: com.squareup.javapoet.JavaFile: can't find referenced method 'java.nio.file.Path toPath()' in library class java.io.File

@marcosrocha85 You should be using apt for your compiler, not compile

compile 'com.jakewharton:butterknife:8.3.0'
apt 'com.jakewharton:butterknife-compiler:8.3.0'

I can confirm as well that I haven't seen this issue after updating to Android Studio 2.2 Beta 2

The issue must have been with Android Studio 2.2 Preview and Beta 1 only.

@hnvn I'm encoutering the same issue as you mentioned with Android Studio 2.2.2 (Stable channel), and I had to rebuild on approximately every build. Did you encounter it again? How did you solve it?

I'm seeing the same issue as well @DreaminginCodeZH with build tools and studio 2.2.2. Definitely seems to be a build issue rather than butterknife though as it affects other annoations as well. Pretty sure it's caused by the new packaging tool introduced with this version.

Adding android.useOldPackaging=true to my gradle.properties file seems to be working as a temporary workaround.

UPDATE - after working with this for a little while it seems as though this didn't actually help.

In my opinion, the best practice of using Lambda expression in Android is using RetroLamda. Jack toolchain is not good enough now. Buiding time of Jack is larger than Javac

Facing the same issue with AS 2.2.3 and ButterKnife 8.4.0, with Jack enabled & Java 8.

Hope anyone can share the final solution if any.

UPDATE:
Disable Jack and Use RetroLambda instead. ButterKnife recovered.

Was this page helpful?
0 / 5 - 0 ratings