7

So using Scala Play Framework. I have a single codebase but need to launch it 2 ways. One way will launch with Play Netty as the main class, and run a webserver. A second way will run my own main class and do different things.

If I do play dist (https://www.playframework.com/documentation/2.3.x/ProductionDist)

It ends up using the sbt-native plugin, and make a new zip. Inside that zip is a script that calls java with a mainclass of Netty. This is ultimately coming from

  mainClass in (Compile, run) := Some("play.core.server.NettyServer"),

inside of PlaySettings.scala.

I want to keep all of this, but add a second artifact to dist.. that has the only different of a different main class.

I started trying to make subprojects.. but not sure this is what I really even want. Something like:

lazy val root = Project(
  id = "root",
  base = file("."),
  librar
  aggregate = Seq(web, backend)

).dependsOn(web, worker)

lazy val web = Project(
  id = "web",
  base = file("."),
  settings = packageArchetype.java_server ++ Seq(
    name := "web",
    mainClass in Compile := Some("play.core.server.NettyServer")
  )
).enablePlugins(PlayScala)

lazy val backend= Project(
  id = "backend",
  base = file("."),
  settings = packageArchetype.java_server ++ Seq(
    name := "backend",
    mainClass in Compile := Some("com.foobar.BackendMain")
  )
)

But I only end up with a single artifact still. What other options are there?

I could hack up bash-template and add mainClass as a parameter and pass it through to the launch script...

bwawok
  • 14,898
  • 7
  • 32
  • 43

1 Answers1

4

You could use one main class as a default one and pass -main you.another.class.Name parameter to bash script to run another main class.

kardapoltsev
  • 1,053
  • 8
  • 14
  • I think this works with real sbt-native-packager. But as far as I can tell, the play start script is stripping out the -main param. Down inside my play generated start script I have ```declare -r app_mainclass="play.core.server.NettyServer" ```. So one option is to try and figure out where this is being generated in play, and take the mainclass as a param like sbt-native normally does.. – bwawok May 20 '15 at 15:32
  • 1
    In run() function you should have `if [ -n "$custom_mainclass" ]; then` `mainclass="$custom_mainclass"` `else` `mainclass="$app_mainclass"` `fi` and declared `app_mainclass` will be ignored during start up with `-main` option – kardapoltsev May 20 '15 at 20:28
  • that is not in my run function made by play 2.3.9 via ```play dist``` .. but I am not seeing how they took that out, thus not seeing how I would hack it back to the normal play-native-package style.. what you posted is quite ideal. – bwawok May 20 '15 at 20:57
  • Take a look to [bash-template](https://github.com/sbt/sbt-native-packager/blob/master/src/main/resources/com/typesafe/sbt/packager/archetypes/bash-template) lines from 237 to 255. – kardapoltsev May 21 '15 at 05:52
  • This is what the play generated file looks like: ``` # check java version if [[ ! $no_version_check ]]; then java_version_check fi # Now we check to see if there are any java opts on the environemnt. These get listed first, with the script able to override them. if [[ "$JAVA_OPTS" != "" ]]; then java_opts="${JAVA_OPTS}" fi ``` – bwawok May 21 '15 at 11:41
  • Did you try pass -main parameter? Could you post your bash script? – kardapoltsev May 22 '15 at 09:22
  • Not sure what main will do if the script isn't using it. Here is the script play 2.3.9 generates for my app: https://gist.github.com/brianwawok/22714eef3860ddce2477 – bwawok May 22 '15 at 15:25
  • Do you use any native packager specific build options? What version do you use? – kardapoltsev May 23 '15 at 21:35
  • This is what ships with Play 2.3.9, I do not set anything outside of play. Download a play sample app and do "play dist" and you can see or yourself. – bwawok May 23 '15 at 22:36
  • think I fixed this by updating the SBT native plugin to 1.0, so then we had a mainclass option to pass in – bwawok May 25 '15 at 00:53