question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Kodein 7 Doesn't Protect Bound interface from R8 Dead Code Elimination

See original GitHub issue

Our Android app is using R8 in full mode for release builds, and we’ve run into issues with Kodein 7, where it marks some of our interfaces as dead code, which causes a crash at runtime. There is no issue with Kodein 6.

Neither AgeValidator nor AgeValidatorImpl are referenced anywhere other than in the kodein binding.

interface AgeValidator {
  fun validate(age: LocalDate): Boolean
}

internal class AgeValidatorImpl : AgeValidator {
  override fun validate(age: LocalDate) = true // not the actual implementation; condensed for clarity
}

val validatorModule = DI.Module("Validators") {
  bind<AgeValidator>() with provider {
    AgeValidatorImpl()
  }
}

class MyApp : Application(), DIAware {
  override val di = DI.lazy {
    import(validatorModule)
  }
}

The crash at runtime is:

Binding bind<Any>() with ? { ? } must not override an existing binding.

Digging into the bytecode on Kodein 6 yields the following for AgeValidator and AgeValidatorImpl:

// AgeValidator
.class public interface abstract LiK0;
.super Ljava/lang/Object;
.source "AgeValidator.kt"

// AgeValidatorImpl; note that validate is not present because R8 eliminated it
.class public final LjK0;
.super Ljava/lang/Object;
.source "AgeValidator.kt"

# interfaces
.implements LiK0;


# direct methods
.method public constructor <init>()V
    .registers 1

    .line 18
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

For Kodein 7, AgeValidator has been completely eliminated and reduced into Any, so that now AgeValidatorImpl simply extends Any:

// AgeValidatorImpl
.class public final LDE1;
.super Ljava/lang/Object;
.source "AgeValidator.kt"


# direct methods
.method public constructor <init>()V
    .registers 1

    .line 18
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

The crash makes sense, because AgeValidator gets replaced with Any which transforms validatorModule into:

val validatorModule = DI.Module("Validators") {
  bind<Any>() with provider {
    AgeValidatorImpl()
  }
}

which crashes the second time this happens because we try binding Any twice, and don’t allow overriding.

I’m not sure what changed in Kodein 7 that would cause R8 to not recognize usage of a class as a type parameter for bind, but something did.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:20 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
romainbslcommented, May 22, 2021

FYI Kodein-DI 7.6 is out !

1reaction
eygrabercommented, May 20, 2021

Looks like it’s working!

The following rules need to be added to proguard though:

-keep, allowobfuscation, allowoptimization class org.kodein.type.TypeReference
-keep, allowobfuscation, allowoptimization class org.kodein.type.JVMAbstractTypeToken$Companion$WrappingTest

-keep, allowobfuscation, allowoptimization class * extends org.kodein.type.TypeReference
-keep, allowobfuscation, allowoptimization class * extends org.kodein.type.JVMAbstractTypeToken$Companion$WrappingTest

It could be added on a project by project basis, but it would probably be easier if it was bundled with the library.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Kodein 7 Doesn't Protect Bound interface from R8 Dead Code ...
This specific error occurs when you are using modules or extending a container and you have declared the same binding in those modules/ ......
Read more >
Kodein - Bountysource
Kodein 7 Doesn't Protect Bound interface from R8 Dead Code Elimination $ 0 ... Our Android app is using R8 in full mode...
Read more >
FEDERAL REGISTER - GovInfo
SUMMARY: The Environmental Protection. Agency (EPA) is amending the Code of. Federal Regulations (CFR) to reflect a.
Read more >
Release Notes: Junos® OS Release 18.4R3 for the ACX ...
Tunneling-encapsulated packets are dropped on Layer 3 VPN MPLS PE-CE interface. PR1451032. • DHCP snooping static binding does not take effect after ...
Read more >
Bug listing with status RESOLVED with resolution WONTFIX ...
... web interface to portage" status:RESOLVED resolution:WONTFIX severity:normal ... Bug:14222 - "Galeon-1.2.7 doesn't honour default fonts with moz-2.1.2 + ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found