kotlin field foo and isFoo clash: The following declarations have the same JVM signature

2.5k views Asked by At
data class Bar(
  var foo: String = "",
  var isFoo: String = ""
)

compiler reports error:

Platform declaration clash: The following declarations have the same JVM signature (setFoo(Ljava/lang/String;)V): public final fun (<set-?>: String?): Unit defined in com.example.Bar public final fun (<set-?>: String?): Unit defined in com.example.Bar

how to tip the compiler use original field name for setters? (setFoo and setIsFoo) NOTICE: the code is generated by jooq(from database schema), so manually change the code is not a good way

2

There are 2 answers

0
Lukas Eder On BEST ANSWER

This is a bug in jOOQ's code generator, which should generate the @set:JvmName annotation for such cases, as suggested by Михаил Нафталь. The bug number is #11912, fixed for 3.15.0 and 3.14.12.

You can work around this problem by overriding the KotlinGenerator.generatePojo() method (requires copying the entire code and patching the relevant bits), or by using a hack: You can override the KotlinGenerator.printColumnJPAAnnotation() method and implement your logic there:

// Example implemented in Java:
@Override
protected void printColumnJPAAnnotation(JavaWriter out, ColumnDefinition column) {
    super.printColumnJPAAnnotation(out, column);

    String member = getStrategy().getJavaMemberName(column, Mode.POJO);
    if (member.startsWith("is") && ((ColumnDefinition) column)
            .getContainer()
            .getColumns()
            .stream()
            .anyMatch(c -> member.equals("is" + 
                StringUtils.toUC(getStrategy().getJavaMemberName(c, Mode.POJO))
            ))) {
        out.println("@set:JvmName(\"%s\")", 
            getStrategy().getJavaSetterName(column, Mode.POJO));
    }
}
1
Михаил Нафталь On

You need to annotate setter with @JvmName:

data class BarFoo(
    var foo: String = "",
    @set:JvmName("setIsFoo") var isFoo: String = ""
)

There is not a compiler bug, but a documented behavior (see https://kotlinlang.org/docs/java-to-kotlin-interop.html#properties), to adjust it without modifying code, you'd have to write some compiler plugin.

Maybe there is a way to make jooq generate code like this?