Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desugaring failure with bridge method when using default method interface in android project #15144

Closed
oliviernotteghem opened this issue Mar 30, 2022 · 3 comments
Assignees
Labels
P2 We'll consider working on this in future. (Assignee optional) team-Android Issues for Android team type: bug

Comments

@oliviernotteghem
Copy link

Description of the problem / feature request:

Android binary project will fail to compile due to java desugaring issue, if project has a dependency on a library meeting the following criteria :

  • library was compiled with -Xjvm-default=all. Note: this option is not available in bazel (kotlin) rules yet, so this is typically a library built with Gradle.
  • library contains a kotlin interface with default interface method(s)
  • the code in one of the default method body forces kotlin compiler to create a bridge method. This happens typically when using generics / lambdas.

In these conditions, compilation failure observed is :


ERROR: /Users/oliviern/github_repro/examples/android/firebase-cloud-messaging/app/BUILD:32:11: Desugaring app/_aar/lib_repro/classes_and_libs_merged.jar for Android failed: (Exit 1): desugar_java8 failed: error executing command bazel-out/darwin-opt-exec-2B5CBBC6/bin/external/bazel_tools/tools/android/desugar_java8 @bazel-out/android-armeabi-v7a-fastbuild/bin/app/_dx/lib_repro/classes_and_libs_merged.jar_desugared.jar-0.params
java.lang.IllegalStateException: com/repro/InterfaceWithDefaultMethodGenerics is an interface and shouldn't need bridge to com/repro/InterfaceWithDefaultMethodGenerics.dummy$lambda-0(Ljava/lang/Class;Ljava/lang/String;)Z (6 itf)
	at com.google.common.base.Preconditions.checkState(Preconditions.java:824)
	at com.google.devtools.build.android.desugar.LambdaDesugaring.queueUpBridgeMethodIfNeeded(LambdaDesugaring.java:243)
	at com.google.devtools.build.android.desugar.LambdaDesugaring.access$200(LambdaDesugaring.java:56)
	at com.google.devtools.build.android.desugar.LambdaDesugaring$InvokedynamicRewriter.visitInvokeDynamicInsn(LambdaDesugaring.java:413)
	at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(MethodVisitor.java:462)
	at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(MethodVisitor.java:462)
	at com.google.devtools.build.android.desugar.strconcat.IndyStringConcatDesugaring$IndifiedStringConcatInvocationConverter.visitInvokeDynamicInsn(IndyStringConcatDesugaring.java:141)
	at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(MethodVisitor.java:462)
	at org.objectweb.asm.ClassReader.readCode(ClassReader.java:2451)
	at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1491)
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:721)
	at com.google.devtools.build.android.desugar.Desugar.desugarClassesInInput(Desugar.java:549)
	at com.google.devtools.build.android.desugar.Desugar.desugarOneInput(Desugar.java:326)
	at com.google.devtools.build.android.desugar.Desugar.desugar(Desugar.java:246)
	at com.google.devtools.build.android.desugar.Desugar.processRequest(Desugar.java:1019)
	at com.google.devtools.build.android.desugar.Desugar.runPersistentWorker(Desugar.java:979)
	at com.google.devtools.build.android.desugar.Desugar.main(Desugar.java:957)

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

  1. Clone https://github.com/oliviernotteghem/examples/tree/repro_interface_default_method_generics
  2. cd examples/android/firebase-cloud-messaging
  3. USE_VERSION=last_green bazelisk build app

Please note this branch include a pre-compilted 'aar', since to repro the issue, (external) lib need to be compiled with Gradle (see above)

Current workaround

We found that reverting to using kotlin compiler option -Xjvm-default=enable + tagging default method @JvmDefault will work around the issue, and while preserve java callers compatibility.

What operating system are you running Bazel on?

MacOsx 12.2

Have you found anything relevant by searching the web?

No

Any other information, logs, or outputs that you want to share?

  • Issue occurs on bazel master (~5.1) too. Issue occurs irrespective of kotlin jvm_target
  • Example of kotlin interface source code that reproduces the issue (used to generate the gradle-built aar archive used in sample project) :
package com.repro

import io.reactivex.Observable

interface InterfaceWithDefaultMethodGenerics {

  fun dummy(): Observable<String>

  fun <T> dummy(clazz: Class<T>): Observable<T> {
    return dummy()
      .filter { obj -> clazz.isAssignableFrom(obj.javaClass) }
      .cast(clazz)
  }
}
  • In the code above, commenting the call to filter() method will avoid the bridge method creation and avoid the issue.
@ckolli5 ckolli5 added team-Android Issues for Android team untriaged labels Mar 30, 2022
@ahumesky ahumesky added type: bug P2 We'll consider working on this in future. (Assignee optional) and removed untriaged labels Oct 25, 2022
@ahumesky
Copy link
Contributor

we're moving away from the "classic" desugarer to D8-based desugaring in bazel 6.0 (and released in recent pre-releases) so this might not be an issue with the D8 desugarer

@oliviernotteghem
Copy link
Author

@ahumesky : issue reproes also on Bazel 5.1

@ahumesky
Copy link
Contributor

We moved to the D8-based desugarer now in bazel 6 / 7, and now in the Starlark rules

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 We'll consider working on this in future. (Assignee optional) team-Android Issues for Android team type: bug
Projects
None yet
Development

No branches or pull requests

3 participants