Fixed
Status Update
Comments
ry...@idevicesinc.com <ry...@idevicesinc.com> #2
A couple notes here.
A couple of ways to stop the failure:
1. Remove the onEvent implementation in MyListener. I'd rather not do this. I implement it so that I can set javadoc for that method (there are several interfaces which extend GenericListener).
2. Move the MyListener interface into the app module.
3. Don't implement MyListener as a lambda in the application.
None of these are really good "fixes". I hope with this project you can hunt down the problem and fix it.
A couple of ways to stop the failure:
1. Remove the onEvent implementation in MyListener. I'd rather not do this. I implement it so that I can set javadoc for that method (there are several interfaces which extend GenericListener).
2. Move the MyListener interface into the app module.
3. Don't implement MyListener as a lambda in the application.
None of these are really good "fixes". I hope with this project you can hunt down the problem and fix it.
ry...@idevicesinc.com <ry...@idevicesinc.com> #3
Also, if the library doesn't use Java 8 (I don't set the compileOptions in the build.gradle for the library), then the problem goes away as well.
uc...@google.com <uc...@google.com>
te...@gmail.com <te...@gmail.com> #4
I can confirm this. I have also exactly the same issues
ry...@idevicesinc.com <ry...@idevicesinc.com> #5
Just an update here. Updated to AS 3.1, with newest gradle plugin, and gradle version, and this still happens.
xa...@google.com <xa...@google.com>
ga...@google.com <ga...@google.com> #6
We do not pass --copy_bridges_from_classpath flag to Desugar, which causes the issue.
With this flag, bridge methods are copied to the classes implementing the functional interface from the classpath. Because the interface is in a separate module, it is the classpath when desugaring application module. That is why when you move MyListener to app module things start to work. In your specific case:
- GenericListener is a generic class, so MyListener will have a bridge method generated by javac
- in MainActivity, postEvent method accepts GenericListener, and invokes onEvent method
- this invocation will look for onEvent(Event) method, which will not exist for MainActivity$$Lambda$0 class that implements the MyListener interface; it will only have onEvent(MyListener.MyEvent)
- method to be invoked will resolve to GenericListener.onEvent(Event) which is abstract
With this flag, bridge methods are copied to the classes implementing the functional interface from the classpath. Because the interface is in a separate module, it is the classpath when desugaring application module. That is why when you move MyListener to app module things start to work. In your specific case:
- GenericListener is a generic class, so MyListener will have a bridge method generated by javac
- in MainActivity, postEvent method accepts GenericListener, and invokes onEvent method
- this invocation will look for onEvent(Event) method, which will not exist for MainActivity$$Lambda$0 class that implements the MyListener interface; it will only have onEvent(MyListener.MyEvent)
- method to be invoked will resolve to GenericListener.onEvent(Event) which is abstract
ga...@google.com <ga...@google.com> #7
This will issue will be fixed in 3.2.0-alpha11.
ag/I1355c66a7e633f6c78eeab9d769029027db4f8dd
ag/I1355c66a7e633f6c78eeab9d769029027db4f8dd
Description
AI-171.4408382, JRE 1.8.0_152-release-915-b08x64 JetBrains s.r.o, OS Mac OS X(x86_64) v10.12.6 unknown, screens 1440x900, 1920x1200, 1920x1080; Retina
I run a library for android, and ran into this issue when updating to Java 8, and using lambdas. It's pretty specific, so I'll do my best to describe the issue.
So there's a generic listener interface that other interfaces extend. This makes it easier for the library to post to several listeners without needing separate methods to do so. In the extending interface, we also implement the method of the base one, in order to put javadoc on the method (if this isn't done, the problem doesn't happen).
Now, when an app implements one of these listeners as a lambda, the app will crash with an AbstractMethodError. If the interface is contained in the app module, it works, it only seems to cause the crash when the interface is in another module.
I've attached a simple project to show how to get it to fail.
I'm not sure if this is an AS bug, gradle, or java problem, but I figured I'd start with AS.