fix: improve workaround for Scala3 bug 18248 (#1349)

Towards #325
This commit is contained in:
Arnout Engelen 2024-06-04 13:56:37 +02:00 committed by GitHub
parent 92b38e72d6
commit 67211737da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -38,44 +38,43 @@ private[pekko] trait ExtensionsImpl extends Extensions { self: ActorSystem[_] wi
* Hook for ActorSystem to load extensions on startup
*/
def loadExtensions(): Unit = {
/*
* @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)
}
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)
}
}
}
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]]
}
}
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)
*/
private 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)
}
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)
}
}
}
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 {