Skip to content

Getting a private field using reflection fails when name-mangled for access #9306

@scabug

Description

@scabug

Test case below. Uncommenting the line makes the test throw:

scala.ScalaReflectionException: Scala field x  isn't represented as a Java field, neither it has a Java accessor method
note that private parameters of class constructors don't get mapped onto fields and/or accessors,
unless they are used outside of their declaring constructors.

Test case:

class FieldAccessTest {

  class TestClass {
    private val x = 123
    // Uncomment the following line to make the test fail
    // () => x
  }

  @Test
  def testFieldAccess(): Unit = {
    import scala.reflect.runtime.{universe => ru}
    val mirror = ru.runtimeMirror(getClass.getClassLoader)

    val obj = new TestClass
    val objType = mirror.reflect(obj).symbol.toType
    val objFields = objType.members.collect { case ms: ru.MethodSymbol if ms.isGetter => ms }

    Assert.assertEquals(123, mirror.reflect(obj).reflectField(objFields.head).get)
  }
}

The problem appears to be caused by name mangling, which is triggered by the presence of the anonymous function. The field is then named "FieldAccessTest$TestClass$$x" instead of "x" in the resulting bytecode, which causes reflection to fail.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions