Question

object Reflects {

  def mirror() = universe.runtimeMirror(getClass.getClassLoader)

  def caseFields(x: AnyRef) = {
    val instanceMirror = mirror().reflect(x)
    instanceMirror.symbol.typeSignature.members.collect {
      case m: MethodSymbol if (m.isCaseAccessor) => m.name.toString -> instanceMirror.reflectMethod(m).apply()
    }
  }

}

I define an object Reflects, when I invole caseFields method within other class

Sometimes this method throws following exception

java.lang.UnsupportedOperationException: tail of empty list
at scala.collection.immutable.Nil$.tail(List.scala:339) ~[scala-library.jar:na]
at scala.collection.immutable.Nil$.tail(List.scala:334) ~[scala-library.jar:na]
at scala.reflect.internal.SymbolTable.popPhase(SymbolTable.scala:172) ~[scala-reflect.jar:na]

And other strange exception.

What's wrong with this method

Was it helpful?

Solution

In 2.10.3 (and probably in 2.10.4, because it doesn't look like we're going to have time to backport the fix from 2.11.0-M7), runtime reflection isn't thread-safe: http://docs.scala-lang.org/overviews/reflection/thread-safety.html. Your stack trace is one of the multitude of possible manifestations of the problem.

Bad news is that in 2.10.x there's no workaround for the thread-unsafety issue apart from putting all reflective operations in a synchronized block. Good news is that in 2.11.0 the problem should be gone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top