首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何编写sbt插件以使用代理启动应用程序

如何编写sbt插件以使用代理启动应用程序
EN

Stack Overflow用户
提问于 2014-04-12 03:41:24
回答 2查看 548关注 0票数 6

在开放源代码之前,我想为我的项目创建一个sbt插件。

该项目将Java代理附加到运行应用程序的开始,以便对其进行各种类型的分析。代理输出文本文件以供以后处理。

我希望能够编写一个sbt插件

  • 有一个名为run的替代方法,称为runWithProfiling,它启动一个新的java进程,将代理添加到参数列表中,并传递所有用户命令。
  • 在退出时,我想调用一些任意的后处理代码来生成一个HTML报告。

我大致知道如何创建新命令,但我不知道如何最好地实现run的替代方案。我不想通过复制run所做的所有代码来重新发明轮子。有什么方法可以调用run,但确保参数被传递(一次),并且它肯定是一个新的java进程?

而且,能够为测试做同样的事情也是很棒的。

UPDATE:这是我目前拥有的代码,但它遇到了一些问题,标记为TODO

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import sbt._
import Keys._
import sbt.Attributed.data

object LionPlugin extends Plugin {

  val lion = TaskKey[Unit]("lion", "Run a main class with lions-share profiling.")

  override val projectSettings = Seq(
    fork := true,
    javaOptions ++= Seq(
      "-Xloggc:gc.log", "-XX:+PrintGCDetails", "-XX:+PrintGCDateStamps",
      "-XX:+PrintTenuringDistribution", "-XX:+PrintHeapAtGC"
      // TODO: need to get hold of the local jar file for a particular artifact
      // IMPL: pass the jar as the agent
    ),
    lion <<= (
      runner,
      fullClasspath in Runtime,
      mainClass in Runtime,
      streams in Runtime
      ) map runLion
  )

  // TODO: update to a task that can take parameters (e.g. number of repeats, profiling settings)
  def runLion(runner: ScalaRun, cp: Classpath, main: Option[String], streams: TaskStreams): Unit = {
    assert(runner.isInstanceOf[ForkRun], "didn't get a forked runner... SBT is b0rk3d")
    println("RUNNING with " + runner.getClass)

    // TODO: ask user if main is None, like 'run' does
    val m = main.getOrElse("Scratch")

    // TODO: get the user's arguments
    val args = Nil

    runner.run(m, data(cp), args, streams.log)

    // IMPL: post-process and produce the report

    println("FINISHED")
  }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-13 12:01:09

插件作者需要遵守一条不成文的希波克拉底誓言,即“第一,不要伤害”。您的实现目前强制自己执行每个子项目,并更改默认行为的forkjavaOptions,我认为这是危险的。我认为您需要将作用域范围内的run参数复制到您的任务中,这样默认设置就不会受到损害。

// TODO:更新到可以接受参数的任务(例如重复次数、分析设置)

有关示例,请参阅插件最佳实践和现有插件(如sbt-应用程序引擎 )。

在sbt中,devServer是一个输入任务,可以设置一组参数.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
gae.devServer       := {
  val args = startArgsParser.parsed
  val x = (products in Compile).value
  AppEngine.restartDevServer(streams.value, (gae.reLogTag in gae.devServer).value,
    thisProjectRef.value, (gae.reForkOptions in gae.devServer).value,
    (mainClass in gae.devServer).value, (fullClasspath in gae.devServer).value,
    (gae.reStartArgs in gae.devServer).value, args,
    packageWar.value,
    (gae.onStartHooks in gae.devServer).value, (gae.onStopHooks in gae.devServer).value)
}

正如您所看到的,代码的本质实际上是在AppEngine对象下的一个方法中实现的,因此其他人可以重用您的东西。方法中的许多参数(在本例中为restartDevServer)的作用域是gae.devServer任务,如(mainClass in gae.devServer)

您打算如何由构建用户设置插件?他们是将其作为一个全局插件启用一次,并在任何地方使用相同的设置,还是为project/lion.sbt中的每个构建启用它?插件最佳实践的建议是提供baseLionSettingslionSettings,以便构建用户可以选择并选择启用lion任务的哪个子项目。

根据实际运行情况,您可能想看看如何重用来自sbt左轮手枪的代码,类似于我在sbt中所做的工作。

票数 1
EN

Stack Overflow用户

发布于 2014-04-12 07:27:30

请参阅http://www.scala-sbt.org/0.13.0/docs/faq.html上的“如何创建自定义运行任务,以及运行?”。在您的自定义任务中,您需要将fork设置为true,以便启动一个新的JVM。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23029910

复制
相关文章

相似问题

添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文