0

I have a Scala project that contains both Scala classes/objects as well as scripts. I am trying to run the scripts (that use the classes/objects to perform various actions) from command line. The way I am looking to do this is to create a shell that would be passed as argument the name of the script, as well as the arguments that the script itself takes.

My folder structure is as follows:

runner.sh -> script I am trying to implement to run the Scala scripts
bin/ -> script I am trying to implement to run the Scala scripts
lib/ -> -> rest of scala project, packed as multiple jars 

I am currently creating a variable LIB_CLASSPATH in the shell script that contains the contents of the lib/ folder and I am trying to run my scrips as follows:

java -cp $LIB_CLASSPATH ./bin/<name_of_script.scala> <parameters of the script>

I always get back the same error:

Could not find or load main class: ..lib/<name of jar> 
-- <name of jar> is actually the first jar in the lib/ folder

I could use some guidance :)

Thanks

1
  • You seem to be passing to java a script of Scala source. It doesn't know what to do with it. Either use scala instead of java, or compile your script first. Commented Jan 19, 2017 at 12:03

3 Answers 3

2

You can use Ammonite (written by @lihaoyi).

It's a combination of a better Scala REPL, Shell, OPs library, and Script runner. See the docs here - https://ammonite.io/

10 min talk showing how is it better for scripting & shell - https://www.youtube.com/watch?v=wk2-ZsQU358

I think it can be a good starting point as well. Talk was given by me :)

Sign up to request clarification or add additional context in comments.

4 Comments

Can't use Ammonite, unfortunately
@AdrianDanielCulea why?
Not firm approved
Above Ammonite link is no more valid
0

I would recommend using sbt native packager. See:

https://github.com/sbt/sbt-native-packager

You add this line to build.sbt:

enablePlugins(JavaAppPackaging)

And define a main class:

mainClass in Compile := Some("org.shapelogic.sc.javafx.ViewGui")

To run:

sbt stage

It create startup script located in a place like this:

target/universal/stage/bin/shapelogic

Here is an example of how I used the script:

target/universal/stage/bin/shapelogic -- -i image/440px-Lenna.png 

If you want to run another class you can do this:

target/universal/stage/bin/shapelogic -main "org.shapelogic.sc.script.Threshold" -- i image/440px-Lenna.png 

4 Comments

I cannot use sbt, unfortunately
You could try to take a look at the start script that sbt native packager builds and make a simplified version.
sbt native packager creates a little bash script that declares the needed variables: They call your LIB_CLASSPATH for app_classpath Here is the start of that: declare -r app_classpath="$lib_dir/org.shapelogic.sc.shapelogic-0.4.1.jar:$lib_dir/org.scala-lang.scala-library-2.11.8.jar:...
I created a Gist with the whole bash startup script: gist.github.com/sami-badawi/82c303502d761db12aec11bb76d1e67d
0

Here's a script that will do what you want. It's based on a script I use, but stripped down for clarity:

#!/bin/bash

# copies of or symlinks to all required jar files
# must be in one of the directories referenced by CP

if [ $# -eq 0 ]; then
  echo "usage: ${0##*} <scala-script-path>" 1>&2
  exit 1
fi

REQUIRED_JAR_DIRECTORIES=(
"/usr/local/olib/*"
"/usr/local/jlib/*"
)
CP=$(echo "${REQUIRED_JAR_DIRECTORIES[@]}" | tr ' ' ':')
case `uname` in
CYGWIN*)
  CP=`cygpath -p -w "$CP"`
  ;;
esac
scala -deprecation -feature -classpath "$CP" "$@"

The easiest way to use this script is to place it in your PATH, and then add the following hash-bang line to the top of your scala script. Assuming you call this script 'scalaRunner', here's a standalone working scala script:

#!/usr/bin/env scalaRunner

println("Hello World!")

Here's one that's slightly more elaborate:

#!/usr/bin/env scalaRunner

if( args.isEmpty ){
  printf("usage: <arg1> [<arg2> ..]\n")
  sys.exit(1)
}
for( (arg,i) <- args.zipWithIndex ){
  printf("arg %d: %s\n",i,arg)
}

If you import anything, just make sure all required jars are in the REQUIRED_JAR_DIRECTORIES.

In practice, you may want something more flexible than this script, especially with regard to specifying where required jars reside.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.