【问题标题】:Can sbt-native-packager generate multiple start scripts for one project?sbt-native-packager 可以为一个项目生成多个启动脚本吗?
【发布时间】:2014-09-23 10:33:54
【问题描述】:

我目前正在使用sbt-native-packager 为我的 scala 应用程序生成启动脚本。我正在使用packageArchetype.java_application。我在 sbt 中创建脚本:

sbt clean myproject/stage

然后通过将创建的libbin 目录复制到安装目录来“安装”应用程序。我不会将它分发给任何人,所以我不会创建可执行的 jar 或 tarball 或类似的东西。我只是在编译我的类,并将我的 jar 和所有库依赖 jar 放在一个地方,以便启动脚本可以执行。

现在我想向我的应用程序添加第二个主类,因此我希望在运行sbt stage 时在target/universal/stage/bin 中出现第二个启动脚本。我希望它将是相同的脚本,但名称不同,app_mainclass 设置为不同的类。我该怎么做?

【问题讨论】:

    标签: scala sbt-native-packager


    【解决方案1】:

    sbt-native-packager 生成的脚本允许你传入一个-main 参数来指定你想要运行的主类。这是我为名为@9​​87654322@ 的项目所做的:

    使用您想要调用 sbt-native-packager 生成的脚本的任何常用选项创建一个 run.sh 脚本:

    #!/bin/bash
    
    ./target/universal/stage/bin/foo -main "$@"
    

    然后,我为要运行的每个主类创建一个单独的脚本。例如first.sh:

    #!/bin/bash
    
    export JAVA_OPTS="-Xms512m -Xmx512m"
    
    ./run.sh com.example.FirstApp -- "$@"
    

    second.sh:

    #!/bin/bash
    
    export JAVA_OPTS="-Xms2048m -Xmx2048m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC"
    
    ./run.sh com.example.SecondApp -- "$@"
    

    【讨论】:

      【解决方案2】:

      现在支持拥有多个主类(2016 年第四季度,本机包 1.2.0)

      参见 Muki Seiler

      的“SBT Native Packager 1.2.0

      单个项目 — 多个应用

      初学者的一个主要痛点是创建启动脚本。 bash 和 bat 启动脚本仅在存在时生成

      • 正好是一个主类
      • 显式设置主类
           mainClass in Compile := Some(“com.example.MainClass”)
      

      对于 1.2.x,我们将扩展实现并默认支持多个主类。

      本机打包程序将为类路径中的每个主类生成一个启动脚本
      SBT 通过discoveredMainClasses in Compile 任务提供它们
      如果只有一个主类,SBT 会将其分配给编译设置中的mainClass。这导致了三种情况:

      • 正好是一个主类
        在这种情况下,native-packager 将像以前的版本一样运行,并且只生成一个启动脚本,使用 executableScriptName 设置脚本名称。

      • Compile := None中的多个主类和mainClass
        这是 SBT 定义的默认行为。在这种情况下,native-packager 将为每个主类生成相同的启动脚本。

      • Compile := Some(…)中的多个主类和mainClass
        用户设置了特定的主类,这将导致使用executableScriptName 设置生成主启动脚本。对于所有其他主要类,native-packager 生成转发器脚本。

      【讨论】:

      • 当有多个主类和mainClass in Compile := Some(…)时,可以防止生成转发器脚本吗?
      • @AndrewBate 我不知道:你能把这个问题作为一个独立的问题提出来,让其他人看看吗?
      • 感谢您还提到了在哪个版本上开始支持它(1.2.0),因为我使用的是旧版本,但这不起作用
      【解决方案3】:

      现在不支持多个主类。作为一种解决方法,您可以使用单个主类并检查命令行参数。 启动您的应用:

      myApp prog1
      

      在你的主课中:

      def main(args: Array[String]): Unit = {
        if(args[0] == "prog1")
          Programm1.start()
        else 
          Programm2.start()
      }
      

      【讨论】:

      • 感谢您的信息和建议。我刚刚在我的“安装”脚本中添加了一行,该脚本通过sed 运行生成的启动脚本,以制作修改app_mainclass 行的副本。
      • 近期有计划支持这个吗?
      • Sbt 原生打包器现在支持 bash 脚本中的 -main 参数。 app_name -main some.other.Main.
      • @kardapoltsev 怎么样?任何文档链接?
      • 只需将 -main 参数传递给您的启动脚本。在scala-sbt.org/sbt-native-packager/archetypes 可以找到一些文档
      猜你喜欢
      • 2016-12-27
      • 2017-10-31
      • 2016-10-21
      • 2014-07-03
      • 2015-01-30
      • 2017-02-17
      • 2017-03-21
      • 2016-07-16
      • 2014-02-22
      相关资源
      最近更新 更多