在Main中不允许使用覆盖修饰符但是当我在scala

时间:2017-10-10 19:13:07

标签: scala traits

我正在尝试为我的应用程序创建一个Launcher程序,并且正在通过App特征和main方法来决定使用哪个。我在两者之间找到的唯一difference是:

  

(1)引用该对象的线程代码将阻塞,直到静态初始化完成。但是,因为扩展Application的对象的整个执行都是在静态初始化期间进行的,所以如果并发代码必须与封闭对象同步,它们将始终处于死锁状态。

在我的情况下,我有一个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" 
 }
}

现在要启动我的应用程序,我试图找到最适合使用的方法,Appmain方法。但是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特征和main的帖子后得到的信息是,除了使用App特征时发生的延迟初始化之外,没有区别。为什么override不适用于main方法,适用于App?我启动申请的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

您需要将它们移出方法之外,以便它们是对象字段而不是局部变量。

object ClientLauncher extends  Launcher {

  override val config=ConfigFactory.load()
  override val actorSystem: ActorSystem=ActorSystem("ClientActorSystem")

  def main(args: Array[String]): Unit = {
    /*code*/
  }
}

虽然你不能以这种方式访问​​命令行参数或其他任何本地的参数。

如果您需要访问它并且不想扩展App,另一种方法是使用单独的类来扩展启动器。

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