From 67211737daa9b3f6d24ed63563efc78fc9945fef Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Tue, 4 Jun 2024 13:56:37 +0200 Subject: [PATCH] fix: improve workaround for Scala3 bug 18248 (#1349) Towards #325 --- .../actor/typed/internal/ExtensionsImpl.scala | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/internal/ExtensionsImpl.scala b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/internal/ExtensionsImpl.scala index 09854cd264b..0c0d5d5cdfc 100644 --- a/actor-typed/src/main/scala/org/apache/pekko/actor/typed/internal/ExtensionsImpl.scala +++ b/actor-typed/src/main/scala/org/apache/pekko/actor/typed/internal/ExtensionsImpl.scala @@ -38,44 +38,43 @@ private[pekko] trait ExtensionsImpl extends Extensions { self: ActorSystem[_] wi * Hook for ActorSystem to load extensions on startup */ def loadExtensions(): Unit = { + loadExtensionsFor("pekko.actor.typed.library-extensions", throwOnLoadFail = true) + loadExtensionsFor("pekko.actor.typed.extensions", throwOnLoadFail = false) + } - /* - * @param throwOnLoadFail Throw exception when an extension fails to load (needed for backwards compatibility) - */ - def loadExtensionsFor(key: String, throwOnLoadFail: Boolean): Unit = { - - settings.config.getStringList(key).asScala.foreach { extensionIdFQCN => - // it is either a Scala object or it is a Java class with a static singleton accessor - val idTry = dynamicAccess.getObjectFor[AnyRef](extensionIdFQCN).recoverWith { - case _ => idFromJavaSingletonAccessor(extensionIdFQCN) - } + /* + * @param throwOnLoadFail Throw exception when an extension fails to load (needed for backwards compatibility) + */ + private def loadExtensionsFor(key: String, throwOnLoadFail: Boolean): Unit = { - idTry match { - case Success(id: ExtensionId[_]) => registerExtension(id) - case Success(_) => - if (!throwOnLoadFail) log.error("[{}] is not an 'ExtensionId', skipping...", extensionIdFQCN) - else throw new RuntimeException(s"[$extensionIdFQCN] is not an 'ExtensionId'") - case Failure(problem) => - if (!throwOnLoadFail) - log.error(s"While trying to load extension $extensionIdFQCN, skipping...", problem) - else throw new RuntimeException(s"While trying to load extension [$extensionIdFQCN]", problem) - } + settings.config.getStringList(key).asScala.foreach { extensionIdFQCN => + // it is either a Scala object or it is a Java class with a static singleton accessor + val idTry = dynamicAccess.getObjectFor[AnyRef](extensionIdFQCN).recoverWith { + case _ => idFromJavaSingletonAccessor(extensionIdFQCN) } - } - def idFromJavaSingletonAccessor(extensionIdFQCN: String): Try[ExtensionId[Extension]] = - dynamicAccess.getClassFor[ExtensionId[Extension]](extensionIdFQCN).flatMap[ExtensionId[Extension]] { - (clazz: Class[_]) => - Try { - val singletonAccessor = clazz.getDeclaredMethod("getInstance") - singletonAccessor.invoke(null).asInstanceOf[ExtensionId[Extension]] - } + idTry match { + case Success(id: ExtensionId[_]) => registerExtension(id) + case Success(_) => + if (!throwOnLoadFail) log.error("[{}] is not an 'ExtensionId', skipping...", extensionIdFQCN) + else throw new RuntimeException(s"[$extensionIdFQCN] is not an 'ExtensionId'") + case Failure(problem) => + if (!throwOnLoadFail) + log.error(s"While trying to load extension $extensionIdFQCN, skipping...", problem) + else throw new RuntimeException(s"While trying to load extension [$extensionIdFQCN]", problem) } - - loadExtensionsFor("pekko.actor.typed.library-extensions", throwOnLoadFail = true) - loadExtensionsFor("pekko.actor.typed.extensions", throwOnLoadFail = false) + } } + private def idFromJavaSingletonAccessor(extensionIdFQCN: String): Try[ExtensionId[Extension]] = + dynamicAccess.getClassFor[ExtensionId[Extension]](extensionIdFQCN).flatMap[ExtensionId[Extension]] { + (clazz: Class[_]) => + Try { + val singletonAccessor = clazz.getDeclaredMethod("getInstance") + singletonAccessor.invoke(null).asInstanceOf[ExtensionId[Extension]] + } + } + final override def hasExtension(ext: ExtensionId[_ <: Extension]): Boolean = findExtension(ext) != null final override def extension[T <: Extension](ext: ExtensionId[T]): T = findExtension(ext) match {