Disambiguate Kotlin access of property in Java class

I am encountering an issue with Kotlin (version 1.5.31) and how it accesses Java class properties. My kotlin class is using Eclipse SWT, specifically the class org.eclipse.swt.graphics.FontData and the name property in FontData. The issue is that the Linux implementation of SWT has a public name field as well as a public getter and setter for the name field. The getter is a simple getter, returning the name field. In contrast the Windows implementation of FontData only has the getter and setter for name, IE. it does not have the public name field.

My kotlin class uses property notation (IE. fontData.name) to access the name property of the FontData class. When compiling my class on Linux, it seems like Kotlin optimises the bytecode so as to access the public name field of FontData directly. When compiling my class on Windows against the Windows SWT jar, Kotlin produces bytecode calling getname().

This gives me a problem as my CI/CD server compiles using a Linux docker image and the Linux SWT jar. Any Windows user of my application gets a java.lang.NoSuchFieldError as the Windows SWT does not have the name field in FontData.

Is there any way to disambiguate whether Kotlin should use the public field or the getter when both exist? I have tried changing my Kotlin code to use the getter (IE. fontData.getName()) but that still gets optimised by the Kotlin compiler to use the name field directly. Is this a bug in the Kotlin compiler?

Hmm, this is weird, I get different results. Maybe I miss something:

public class JavaClass {
    public String name;

    public String getName() {
        return name;
    }
}
fun test1(obj: JavaClass) = obj.name
fun test2(obj: JavaClass) = obj.getName()

Then javap -c Test1Kt.class:

public final class Test1Kt {
  public static final java.lang.String test1(JavaClass);
    Code:
       0: aload_0
       1: ldc           #9                  // String obj
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: getfield      #21                 // Field JavaClass.name:Ljava/lang/String;
      10: areturn

  public static final java.lang.String test2(JavaClass);
    Code:
       0: aload_0
       1: ldc           #9                  // String obj
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: invokevirtual #27                 // Method JavaClass.getName:()Ljava/lang/String;
      10: areturn
}

test1() uses field, but test2() uses getter, as you expected. I compiled the code with Kotlin 1.5.30.

I will have to do some further testing of my own, may be a minimal example like you did. My kotlin class is much more involved at the point of doing the property access, its within a lambda passed as a predicate to a method processing a list (the kotlin any extension funtion for collections), so may be the compiler is doing something there when doing the inlining.