Running multiple applications with sbt - scala

I have my directory structure set up as such.
src/main/scala/main/Main.scala
src/main/scala/scripts/MainScript.scala
The script is a background job that will be running.
I've used sbt-assembly before to package up the main file into a jar to be deployed but I'm not sure how to create the two separate jars with sbt-assembly or sbt-native-packager. How would I go about doing that and what would be the best approach for this problem?
I would be looking to do something similar to this.
java -jar main.jar $PORT
java -jar scriptMain.jar

One way to solve this only with native-packager would be the following.
Put all your main classes in src/main/scala
Define a mainClass in Compile := Some("foo.bar.Main") that should run as default
add additional scripts in src/universal/bin that you would like to provide. These scripts can call the main script generated by native-packager and set the -main parameter to the class you want to call.
Now you have an output package (e.g. a zip, rpm, deb) that has the following structure. Assuming your app is called myApp and you provided to other bin scripts called otherApp1 / otherApp2
lib/ (jars live here)
conf/ (configuration files here, if any)
bin/
myApp
otherApp1
otherApp2
Unfortunately I have no example for the script (my bash-foo isn't good enough for instant magic on SO). In the end the scripts (otherApp1,otherApp2) should just pass the parameters they receive to the native-packager script (myApp).
There is an issue #633 that provides an automated way to generate scripts like this.
hope that helps,
Muki

Related

Run gatling project from an executable jar

I have a small Gatling project which I would like to package through sbt and then run on different Linux/Windows machines with different JVM parameters. I tried already the sbt package command but that didn't work out. Anyone has done something similar before?
Package doesn't include the dependencies of your project.
You need something like sbt-assembly, sbt-pack or sbt-native-packager.
Then you can start your tests from within a main method (depending on the type of your package, e.g. java -jar fat-jar-name.jar).

Tell SBT to not use staging area

I want to be able to compile my project once and pass it through multiple build steps on a CI server. But SBT puts files in a staging area like the one below.
/home/vagrant/.sbt/0.13/staging/
This means the project is not stand-alone and for every CI step it is going to compile it again.
How can I tell SBT to keep things simple and stand-alone and to make sure everything it needs is inside the project directory?
FYI, the staging area is used for the target files when the source folder is not read/write. Making the source folder read/write should fix this.
If you pass -Dsbt.global.staging=./.staging to sbt when starting it up, the staging directory will be .staging in the project's directory.
I figured that out by looking at the sbt source and patching that together with how Paul P's sbt runner passes the value for the sbt boot path.
If that doesn't accomplish what you want, then you might be able to make something go with a custom resolver. The sbt Build Loaders page talks about creating a custom resolver that lets you specify more detail about where dependencies are written. If my solution doesn't get you what you want, you'd probably need to do something like that.

Call sbt externally

I am designing a tool, that takes an sbt project path as a parameter. I would like to be able to build that given project on the fly, and be able to get its classpath.
I previously designed my tool as a sbt plugin to achieve this but it is not flexible enough for my purpose: I don't want to have to parameter anything in the sbt config files of the project I am studying.
I would like to use sbt externally, construct a project (from a sbt directory path) and compile it externally in my scala code without invoking sbt in a console. This is a reproduction in code of what happens when "sbt" is typed in a given directory in the console. Is there a straightforward way to achieve this?
I think you need to look at SBT jar file and source code. Find the "Main" class and call it programmatically. The code is here: https://github.com/sbt/sbt. The main class is: xsbt.boot.Boot. I got it from sbt jar file by unzipping it and looking at META-INF/MANIFEST.MF. So you can see how SBT passes command line arguments to it and take it from there. Here is the Boot class just in case: https://github.com/sbt/sbt/blob/0.13/launch/src/main/scala/xsbt/boot/Boot.scala. Have fun! :)
p.s. in your code just call Boot.main(<your sbt commands>).
I have a vaguely similar requirement. I produce a command-line tool as one of the deliverables from my project. The script launches the Scala runtime itself and naturally needs the effective class-path for the project's dependencies. To get that in an external form, I use the SBT-Start-Script plug-in. While that plug-in does produce an actual launcher, I need to do more than it provides, so I just use it to externalize the project's (current) class-path, which I extract into a shell array initialization in a separate source file that may be source-ed by the main launcher script.

Where to put wrapper scripts in Buildr?

I'm developing a set of command line tools in Scala, using Apache Buildr as my build system. I'd like to include a wrapper script for each tool. Something like this:
#!/bin/sh
scala myclass $#
These scripts should be installed alongside my jar when I type buildr install. Is there a special directory Buildr recognizes for wrapper scripts like this? If not, how can I make Buildr install the scripts? I've tried putting the scripts in src/main/resources, but this packages them inside the jar, which is not what I want.
As commented, there are ways to make this happen by creating a separate packaging to encompass the scripts and the tool. Here is an example that bundles a jar and a set of scripts to run the jar with parameters.

Loading resources off the classpath in Jython using 'classpath:'

I've got a relatively large Java application that would benefit from a bit of Python love. To that end I've been working on getting it up and running in Jython. My current roadblock is getting the classpath right.
I've taken two approaches to setting the classpath:
Using a shell script, I've built up a list of jars and executed java -cp ${CP} -jar jyton.jar where $CP is a list of the jars needed for my app. This doesn't seem to work. I'm unable to import any classes from these jars, getting only ImportError: No module named apache instead.
Using a bootstrap python script, i've created a list of paths using glob, and appended them to the current path using [sys.path.append(path) for path in JAR_LIST]. This seems to work correctly; I can now import any of the classes I need to from the included jars.
The above is a bit confusing as most information I've been able to find has steered towards using $CLASSPATH and -cp to added your jars, but I can't get that to work. So the question so far: Is #2 the proper way to add dependancies to your classpath when using Jython?
The main reason I question my methods is because I'm still having problems fully utilizing my application. A number of places in my app reverences resources using relative URLs : classpath:some-critical-file.xml
some-critical-file.xml and a number of my classes reside within the same jar. I'm able to import classes from that jar, but any attempts to load my xml with classpath:some-critical-file.xml results in a java.io.FileNotFoundException
Any insight as to why my classes are available but relative paths to resources using classpath: are not would be much appreciate. I'm at a loss at this point.
I've run into a little classpath weirdness myself lately. Have you tried the old school approach of:
CLASSPATH = ${CLASSPATH}:your.jar
export CLASSPATH
jython your_script.jy
If you're invoking the standalone jar using java -jar then from the Java Documentation ...
-jar
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
So it it not possible to add anything to the classpath when using -jar. See this answer for a solution - basically add the jython.jar to the classpath (either using -cp or CLASSPATH) and run the org.python.util.jython class directly.