Reputation: 2080
I'm currently using sbt-native-packager to generate a start script for my scala application. I'm using packageArchetype.java_application
. I create the script in sbt:
sbt clean myproject/stage
and then "install" the application by copying the created lib
and bin
directories to the installation directory. I'm not distributing it to anyone, so I'm not creating an executable jar or tarball or anything like that. I'm just compiling my classes, and putting my jar and all the library dependency jars in one place so the start script can execute.
Now I want to add a second main class to my application, so I want a second start script to appear in target/universal/stage/bin
when I run sbt stage
. I expect it will be the same script but with a different name and app_mainclass
set to the different class. How would I do this?
Upvotes: 5
Views: 2134
Reputation: 1328522
Having multiple main classes is... supported now (Q4 2016, native package 1.2.0)
See "SBT Native Packager 1.2.0" by Muki Seiler
Single Project — Multiple Apps
A major pain point for beginners is the start script creation. The bash and bat start scripts are only generated when there is a either
- Exactly one main class
- Explicitly set main class with
mainClass in Compile := Some(“com.example.MainClass”)
For 1.2.x we will extends the implementation and support multiple main classes by default.
Native packager will generate a start script for each main class found on the classpath.
SBT provides them via thediscoveredMainClasses
inCompile
task.
If there is only one main class, SBT will assign it to themainClass
in Compile setting. This leads to three cases:
Exactly one main class.
In this case native-packager will behave like previous versions and just generate a single start script, using theexecutableScriptName
setting for the script name.Multiple main classes and mainClass in
Compile := None
.
This is the default behaviour defined by SBT. In this case native-packager will generate the same start script for each main class.Multiple main classes and mainClass in
Compile := Some(…)
.
The user has set a specific main class, which will lead to a main start script being generated using theexecutableScriptName
setting. For all other main classes native-packager generates forwarder scripts.
Upvotes: 3
Reputation: 557
The sbt-native-packager generated script allows you to pass in a -main
argument to specify the main class you want to run. Here's what I do for a project named foo
:
Create a run.sh
script with whatever common options you want that calls the sbt-native-packager generated script:
#!/bin/bash
./target/universal/stage/bin/foo -main "$@"
Then I create a separate script for each main class I want to run. For example first.sh
:
#!/bin/bash
export JAVA_OPTS="-Xms512m -Xmx512m"
./run.sh com.example.FirstApp -- "$@"
and second.sh
:
#!/bin/bash
export JAVA_OPTS="-Xms2048m -Xmx2048m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC"
./run.sh com.example.SecondApp -- "$@"
Upvotes: 3
Reputation: 1088
Having multiple main classes not supported now. As a workaround you could use single main class and check command line args. Starting your app:
myApp prog1
In your main class:
def main(args: Array[String]): Unit = {
if(args[0] == "prog1")
Programm1.start()
else
Programm2.start()
}
Upvotes: 2