Main 中不允许覆盖修饰符,但是当我在 Scala 中扩展 App 特征时允许覆盖修饰符
Override modifier is not allowed in Main however it is allowed when I extend App trait in scala
我正在尝试为我的应用程序创建启动器程序,并且正在通过 App
特征和 main
方法来决定使用哪一个。我在两者之间发现的唯一 difference 是:
(1) Threaded code that references the object will block until static initialization is complete. However, because the entire execution of an object extending Application takes place during static initialization, concurrent code will always deadlock if it must synchronize with the enclosing object.
在我的例子中,我有一个 Launcher
,它基本上初始化了一个 Kafka
加载器对象,该对象保持 运行 kafka
轮询。下面是我的 Launcher
特征:
trait Launcher extends LazyLogging {
val config: Config
val actorSystem: ActorSystem
val sourceMessagesType = config.getString("app.source.dataType")
val targetTopic = config.getString("app.kafka.targetTopic")
val targetTopicPartitions =config.getInt("app.kafka.targetTopicPartitions")
val routingManager = HashedPartitionRoutingManager(targetTopic, targetTopicPartitions)
logger.info(s"Initializing MorpheusStreamDataLoader for $sourceMessagesType type")
sourceMessagesType.toLowerCase match {
case "json" => JSonDataLoader(config, routingManager)
case "avro" => AvroDataLoader(config, routingManager)
case _ => throw new IllegalArgumentException
s"Messages of type ${sourceMessagesType.toLowerCase} are not supported.\n"
}
}
现在启动我的应用程序,我试图找到最适合使用的方法,App
或 main
方法。但是 main
方法实现根本不起作用:
object ClientLauncher extends Launcher {
def main(args: Array[String]): Unit = {
override val config=ConfigFactory.load(args(0))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
}
当我这样做时,我在 override
修饰符 override modifier is not allowed here
上出错。但是,如果我使用 App
特性,它不会给我任何编译时错误。
object ClientLauncher extends App with Launcher {
override val config=ConfigFactory.load(args(0))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
我在阅读了几篇关于 App
trait 和 main
的帖子后得到的信息是,除了我们使用 App
trait 时发生的延迟初始化外,没有其他区别.为什么 override
不适用于 main
方法而适用于 App
?我启动应用程序的最佳方式是什么?
您需要将它们移到方法之外,使它们成为对象字段而不是局部变量。
object ClientLauncher extends Launcher {
override val config=ConfigFactory.load()
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
def main(args: Array[String]): Unit = {
/*code*/
}
}
尽管如此,您将无法访问命令行参数或 main 本地的任何其他内容。
如果您需要访问它并且不想扩展应用程序,另一种方法是使用单独的 class 来扩展启动器。
class ClientLauncher(configFile: String) extends Launcher {
override val config=ConfigFactory.load(configFile)
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
object Main {
def main(args: Array[String]): Unit = {
new ClientLauncher(args(0))
}
}
或者将这些参数作为系统属性而不是命令行参数传递。
object ClientLauncher extends Launcher {
override val config=ConfigFactory.load(sys.props("configFile"))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
def main(args: Array[String]): Unit = {
/*code*/
}
}
并在您运行您的代码
时传入系统属性
java -DconfigFile="config.conf" -jar myJar.jar
我正在尝试为我的应用程序创建启动器程序,并且正在通过 App
特征和 main
方法来决定使用哪一个。我在两者之间发现的唯一 difference 是:
(1) Threaded code that references the object will block until static initialization is complete. However, because the entire execution of an object extending Application takes place during static initialization, concurrent code will always deadlock if it must synchronize with the enclosing object.
在我的例子中,我有一个 Launcher
,它基本上初始化了一个 Kafka
加载器对象,该对象保持 运行 kafka
轮询。下面是我的 Launcher
特征:
trait Launcher extends LazyLogging {
val config: Config
val actorSystem: ActorSystem
val sourceMessagesType = config.getString("app.source.dataType")
val targetTopic = config.getString("app.kafka.targetTopic")
val targetTopicPartitions =config.getInt("app.kafka.targetTopicPartitions")
val routingManager = HashedPartitionRoutingManager(targetTopic, targetTopicPartitions)
logger.info(s"Initializing MorpheusStreamDataLoader for $sourceMessagesType type")
sourceMessagesType.toLowerCase match {
case "json" => JSonDataLoader(config, routingManager)
case "avro" => AvroDataLoader(config, routingManager)
case _ => throw new IllegalArgumentException
s"Messages of type ${sourceMessagesType.toLowerCase} are not supported.\n"
}
}
现在启动我的应用程序,我试图找到最适合使用的方法,App
或 main
方法。但是 main
方法实现根本不起作用:
object ClientLauncher extends Launcher {
def main(args: Array[String]): Unit = {
override val config=ConfigFactory.load(args(0))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
}
当我这样做时,我在 override
修饰符 override modifier is not allowed here
上出错。但是,如果我使用 App
特性,它不会给我任何编译时错误。
object ClientLauncher extends App with Launcher {
override val config=ConfigFactory.load(args(0))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
我在阅读了几篇关于 App
trait 和 main
的帖子后得到的信息是,除了我们使用 App
trait 时发生的延迟初始化外,没有其他区别.为什么 override
不适用于 main
方法而适用于 App
?我启动应用程序的最佳方式是什么?
您需要将它们移到方法之外,使它们成为对象字段而不是局部变量。
object ClientLauncher extends Launcher {
override val config=ConfigFactory.load()
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
def main(args: Array[String]): Unit = {
/*code*/
}
}
尽管如此,您将无法访问命令行参数或 main 本地的任何其他内容。
如果您需要访问它并且不想扩展应用程序,另一种方法是使用单独的 class 来扩展启动器。
class ClientLauncher(configFile: String) extends Launcher {
override val config=ConfigFactory.load(configFile)
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
}
object Main {
def main(args: Array[String]): Unit = {
new ClientLauncher(args(0))
}
}
或者将这些参数作为系统属性而不是命令行参数传递。
object ClientLauncher extends Launcher {
override val config=ConfigFactory.load(sys.props("configFile"))
override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")
def main(args: Array[String]): Unit = {
/*code*/
}
}
并在您运行您的代码
时传入系统属性java -DconfigFile="config.conf" -jar myJar.jar