This is an automated email from the ASF dual-hosted git repository. He-Pin pushed a commit to branch refactor/reflect-stackwalker in repository https://gitbox.apache.org/repos/asf/pekko.git
commit bfa367cdf9182baf4f5ec91e21aa210fa18a0470 Author: 虎鸣 <[email protected]> AuthorDate: Tue Jun 23 13:04:20 2026 +0800 refactor: replace sun.reflect.Reflection with StackWalker in Reflect Motivation: Reflect.getCallerClass uses sun.reflect.Reflection.getCallerClass via reflection, a JDK 8 internal API that was moved to jdk.internal.reflect.Reflection in JDK 9+. On JDK 17+ without --add-opens for jdk.internal.reflect, this always falls back to None. Modification: Replace with java.lang.StackWalker (JDK 9) with RETAIN_CLASS_REFERENCE option, which is the official supported API for accessing caller class information. The API contract is preserved: given a frame depth index, returns the Class at that depth (or null if beyond stack). Result: Official JDK API instead of internal reflection hack. StackWalker was already established in the codebase (LoggerClass.scala, TestKitUtils.scala). The findClassLoader fallback now works reliably on JDK 17+. Tests: sbt "actor/compile" — passed References: Refs #3136 --- actor/src/main/scala/org/apache/pekko/util/Reflect.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/actor/src/main/scala/org/apache/pekko/util/Reflect.scala b/actor/src/main/scala/org/apache/pekko/util/Reflect.scala index 14d7850590..5bca579dde 100644 --- a/actor/src/main/scala/org/apache/pekko/util/Reflect.scala +++ b/actor/src/main/scala/org/apache/pekko/util/Reflect.scala @@ -36,15 +36,17 @@ private[pekko] object Reflect { * This optionally holds a function which looks N levels above itself * on the call stack and returns the `Class[_]` object for the code * executing in that stack frame. Implemented using - * `sun.reflect.Reflection.getCallerClass` if available, None otherwise. + * `java.lang.StackWalker` (JDK 9+). * * Hint: when comparing to Thread.currentThread().getStackTrace, add two levels. */ val getCallerClass: Option[Int => Class[?]] = { try { - val c = Class.forName("sun.reflect.Reflection") - val m = c.getMethod("getCallerClass", Array(classOf[Int]): _*) - Some((i: Int) => m.invoke(null, Array[AnyRef](i.asInstanceOf[java.lang.Integer]): _*).asInstanceOf[Class[?]]) + val walker = java.lang.StackWalker.getInstance( + java.util.Set.of(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE)) + Some((i: Int) => + walker.walk((s: java.util.stream.Stream[java.lang.StackWalker.StackFrame]) => + s.skip(i.toLong).map[Class[?]](_.getDeclaringClass).findFirst().orElse(null))) } catch { case NonFatal(_) => None } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
