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.

After upgrading to kotlin 1.5.0, the kotlin-parcelize generated code started to be reported as public by binary-compatibility-validator

See original GitHub issue

Hi,

I’m using kotlin-parcelize plugin to generate the parcelable code in the internal data classes in my project.

Let’s consider the following kotlin data class, that is marked as internal.

@Parcelize
internal data class Country (
    val code: String,
    val name: String
) : Parcelable

I have made the following tests with binary-compatibility-validator 0.5.0. And there is a difference when using kotlin 1.5.0 and 1.4.32.

Before upgrading to kotlin 1.5.0, using kotlin 1.4.32, the command ./gradlew teleconsultationandroid:apiDump wouldn’t return any output related to the class Country. And to help debug this issue, here is the compiled code of Country in kotlin 1.4.32.

Compiled `Country` data class using kotlin 1.4.32. import android.os.Parcel; import android.os.Parcelable; import kotlin.Metadata; import kotlin.jvm.internal.Intrinsics; import kotlinx.parcelize.Parcelize; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;

@Parcelize @Metadata(…) /* compiled from: Country.kt */ public final class Country implements Parcelable { public static final Parcelable.Creator<Country> CREATOR = new Creator(); @NotNull private final String code; @NotNull private final String name;

@Metadata(bv = {1, 0, 3}, d1 = {}, d2 = {}, k = 3, mv = {1, 4, 2})
public static class Creator implements Parcelable.Creator<Country> {
    @Override // android.os.Parcelable.Creator
    @NotNull
    public final Country createFromParcel(@NotNull Parcel parcel) {
        Intrinsics.checkNotNullParameter(parcel, "in");
        return new Country(parcel.readString(), parcel.readString());
    }

    @Override // android.os.Parcelable.Creator
    @NotNull
    public final Country[] newArray(int i) {
        return new Country[i];
    }
}

public Country(@NotNull String str, @NotNull String str2) {
    Intrinsics.checkNotNullParameter(str, "code");
    Intrinsics.checkNotNullParameter(str2, "name");
    this.code = str;
    this.name = str2;
}

public static /* synthetic */ Country copy$default(Country country, String str, String str2, int i, Object obj) {
    if ((i & 1) != 0) {
        str = country.code;
    }
    if ((i & 2) != 0) {
        str2 = country.name;
    }
    return country.copy(str, str2);
}

@NotNull
public final String component1() {
    return this.code;
}

@NotNull
public final String component2() {
    return this.name;
}

@NotNull
public final Country copy(@NotNull String str, @NotNull String str2) {
    Intrinsics.checkNotNullParameter(str, "code");
    Intrinsics.checkNotNullParameter(str2, "name");
    return new Country(str, str2);
}

public int describeContents() {
    return 0;
}

public boolean equals(@Nullable Object obj) {
    if (this != obj) {
        if (obj instanceof Country) {
            Country country = (Country) obj;
            if (!Intrinsics.areEqual(this.code, country.code) || !Intrinsics.areEqual(this.name, country.name)) {
                return false;
            }
        }
        return false;
    }
    return true;
}

@NotNull
public final String getCode() {
    return this.code;
}

@NotNull
public final String getName() {
    return this.name;
}

public int hashCode() {
    int i = 0;
    String str = this.code;
    int hashCode = (str != null ? str.hashCode() : 0) * 31;
    String str2 = this.name;
    if (str2 != null) {
        i = str2.hashCode();
    }
    return hashCode + i;
}

@NotNull
public String toString() {
    return "Country(code=" + this.code + ", name=" + this.name + ")";
}

public void writeToParcel(@NotNull Parcel parcel, int i) {
    Intrinsics.checkNotNullParameter(parcel, "parcel");
    parcel.writeString(this.code);
    parcel.writeString(this.name);
}

}

But after upgrading to kotlin 1.5.0, the command ./gradlew teleconsultationandroid:apiDump started returing the following output.

public final class com/sample/project/Country$Creator : android/os/Parcelable$Creator {
	public fun <init> ()V
	public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
	public final fun createFromParcel (Landroid/os/Parcel;)L com/sample/project/Country;
	public synthetic fun newArray (I)[Ljava/lang/Object;
	public final fun newArray (I)[Lcom/sample/project/Country;
}

And here is the output of the compiled code in kotlin 1.5.0.

Compiled `Country` data class using kotlin 1.5.0. import android.os.Parcel; import android.os.Parcelable; import kotlin.Metadata; import kotlin.jvm.internal.Intrinsics; import kotlinx.parcelize.Parcelize; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;

@Parcelize @Metadata(…) /* compiled from: Country.kt */ public final class Country implements Parcelable { @NotNull public static final Parcelable.Creator<Country> CREATOR = new Creator(); @NotNull private final String code; @NotNull private final String name;

@Metadata(bv = {1, 0, 3}, d1 = {}, d2 = {}, k = 3, mv = {1, 5, 1})
/* compiled from: Country.kt */
public static final class Creator implements Parcelable.Creator<Country> {
    @Override // android.os.Parcelable.Creator
    @NotNull
    public final Country createFromParcel(@NotNull Parcel parcel) {
        Intrinsics.checkNotNullParameter(parcel, "parcel");
        return new Country(parcel.readString(), parcel.readString());
    }

    @Override // android.os.Parcelable.Creator
    @NotNull
    public final Country[] newArray(int i) {
        return new Country[i];
    }
}

public Country(@NotNull String str, @NotNull String str2) {
    Intrinsics.checkNotNullParameter(str, "code");
    Intrinsics.checkNotNullParameter(str2, "name");
    this.code = str;
    this.name = str2;
}

public static /* synthetic */ Country copy$default(Country country, String str, String str2, int i, Object obj) {
    if ((i & 1) != 0) {
        str = country.code;
    }
    if ((i & 2) != 0) {
        str2 = country.name;
    }
    return country.copy(str, str2);
}

@NotNull
public final String component1() {
    return this.code;
}

@NotNull
public final String component2() {
    return this.name;
}

@NotNull
public final Country copy(@NotNull String str, @NotNull String str2) {
    Intrinsics.checkNotNullParameter(str, "code");
    Intrinsics.checkNotNullParameter(str2, "name");
    return new Country(str, str2);
}

public int describeContents() {
    return 0;
}

public boolean equals(@Nullable Object obj) {
    if (this == obj) {
        return true;
    }
    if (!(obj instanceof Country)) {
        return false;
    }
    Country country = (Country) obj;
    if (!Intrinsics.areEqual(this.code, country.code)) {
        return false;
    }
    return Intrinsics.areEqual(this.name, country.name);
}

@NotNull
public final String getCode() {
    return this.code;
}

@NotNull
public final String getName() {
    return this.name;
}

public int hashCode() {
    return (this.code.hashCode() * 31) + this.name.hashCode();
}

@NotNull
public String toString() {
    return "Country(code=" + this.code + ", name=" + this.name + ')';
}

public void writeToParcel(@NotNull Parcel parcel, int i) {
    Intrinsics.checkNotNullParameter(parcel, "out");
    parcel.writeString(this.code);
    parcel.writeString(this.name);
}

}

Is this as issue of binary-compatibility-validator? Thanks

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
4brunucommented, May 31, 2021

Here is the sample project

https://github.com/4brunu/kotlin-binary-compatibility-validator-issue

To dump the API, just run make or ./gradlew mylibrary:apiDump and check the result file under mylibrary/api/mylibrary.api.

Here is the api file with kotlin 1.4.32

Commit

mylibrary.api

Here is the api file with kotlin 1.5.0

Commit

mylibrary.api

0reactions
qwwdfsadcommented, Nov 21, 2022

Please open a new one with a reproducer as well

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issues · Kotlin/binary-compatibility-validator - GitHub
After upgrading to kotlin 1.5.0, the kotlin-parcelize generated code started to be reported as public by binary-compatibility-validator.
Read more >
Upgrading Android kotlin version to 1.5.0 throwing error ...
This issue resurfaced for me after upgrading my project to Kotlin 1.6.0. In my case it's because of the Moshi JSON serialization lib....
Read more >
Kotlin 1.5.0 parcelize compilation fails in new backend when ...
0 parcelize compilation fails in new backend when using TypeParceller with nested generics. Compiling project with new backend causes failure while working ...
Read more >
Compatibility guide for Kotlin 1.6
Compatibility guide for Kotlin 1.6. Keeping the Language Modern and Comfortable Updates are among the fundamental principles in Kotlin ...
Read more >
Lint fails to resolve some kotlin intrinsics with Kotlin 1.5.0-RC
When we run lint with Kotlin 1.5.0-RC, we see strange and surprising errors about Java 8 APIs. /mnt/tmp/android-dev-unit-lint- ...
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