sbt-native-packager 可以为一个项目生成多个启动脚本吗?

Posted

技术标签:

【中文标题】sbt-native-packager 可以为一个项目生成多个启动脚本吗?【英文标题】:Can sbt-native-packager generate multiple start scripts for one project? 【发布时间】: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 设置为不同的类。我该怎么做?

【问题讨论】:

【参考方案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 可以找到一些文档

以上是关于sbt-native-packager 可以为一个项目生成多个启动脚本吗?的主要内容,如果未能解决你的问题,请参考以下文章

为使用 sbt-native-packager 创建的可执行文件设置 JVM 选项的推荐方法是啥?

如何使用 sbt-native-packager 创建基本项目设置

如何在多个项目中使用 sbt-native-packager

在 SBT 中为 sbt-native-packager 的 packageMappings 构建路径

新贵的 daemonUser 在 sbt-native-packager 中不起作用

如何在具有多个电源的单个模块项目中设置 sbt-native-packager