"IllegalAccessError" with protected inline reified functions


#1

Hey all, I’m running into an issue regarding an “IllegalAccessError” exception at runtime when invoking inline reified-type lambdas that access a protected member of the class the original declaration is in. For example, take the following abstract class:

package com.example

abstract class A {
  protected val hello: String = "hello"

  protected inline fun <reified T> helloType(): () -> Unit = {
    println("$hello ${T::class.java}")
  }
}

And the following class that inherits from A:

package com.example2

class B: A() {
  val result = helloType<String>()
}

When I invoke the lambda like:

fun main(args: Array<String>) {
  B().result()
}

Then I get the IllegalAccessError:

Exception in thread "main" java.lang.IllegalAccessError: tried to access method example.A.getHello()Ljava/lang/String; from class B$$special$$inlined$helloType$1

However, if I take out the reified T type parameter like:

abstract class A {
  protected val hello: String = "hello"

  protected inline fun helloType(): () -> Unit = {
    println(hello)
  }
}

It will work. The function doesn’t need to be marked as inline anymore, either, but it will just compile with a warning. If I remove the inline it also works as well.

Also, I can remove the protected visibility modifier of A.hello but I would prefer to keep it protected, if possible.

This is a simplified example, of course, as in my use case I actually do need the reified T so I can access the class of T via T::class.java but I’m just confused as to why the reified T seems to cause this issue. Is this intended or is there a work-around/proper way of doing it that I am missing?

Thanks!


#2

Too bad this topic haven’t got enough attention. Would be nice to resolve this issue or at least fail at compile time.


#3

There is a bug in compiler, please file an issue.
Just note, next code should also fail:

abstract class A {
  protected val hello: String = "hello"

  protected inline fun helloType(param: () -> String): () -> Unit = {
    println(param() + hello)
  }
}

#4

https://youtrack.jetbrains.com/issue/KT-22625