Running Scala Script in sbt project - scala

How can i run a scala script inside a sbt project which can access all classes of the sbt project and typesafe config as well? Basically I want the script to run in a similar way as the sbt console.

one option is to assemble a jar using sbt-assembly
you would need to add the following to a .sbt file to your project directory
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
and add a minimum of two lines to your build file.
assemblyJarName in assembly := "something.jar"
mainClass in assembly := Some("com.example.Main")
then you can run the 'assembly' task from sbt, this will build and executable "fat" jar with all your dependencies and configuration.

You can use the launcher and the command system to implement an interactive appliation with autocomplete etc.
Here is a tutorial:
http://www.scala-sbt.org/0.13/docs/Command-Line-Applications.html
You have to invoke the application separately, though; I don't think it is possible to run it directly from the sbt prompt within the application directory.

Related

How to run sbt assembly by excluding integration test

I am looking to create fat jar by 'sbt assembly' but i dont wan to run integration test in sbt assembly. I want only jar file.
You can either disable tests in your build.sbt using assembly / test := {} as suggested by #laughedelic, or if you're executing from a terminal and want to skip to the tests for that build use: sbt 'set test in assembly := {}' assembly.
If you have set the value in your build.sbt file you can check that its value is as expected by running sbt show assembly / test which should return something like ().

SBT Compile for uber jar

What is the best way to make a SBT project work in offline environment?
There is any ways to compile it outside (in network env),
e.g uber jar with all its dependencies, and then in the offline env
just run it?
For example in Java Maven,
We can compile it with uber jar with all dependencies,
and then in the offline env just java -jar MyJar.jar ...
Thanks.
Best bet for creating an uber/fat jar is the sbt assembly plugin. Include it in your project by putting something like the following in project/assembly.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
Then just running sbt assembly should create a jar with all the dependencies in target/scala_$SCALA_VERSION. You may need to designate a main class for the jar if you want to run it with java -jar (as opposed to java -cp $jarfile $mainclass):
mainClass in assembly := Some("package.mainClass")

How to create executable jar in scala which can run on jvm?

I am using scala version 2.11.4, I have tried various options like sbt-assembly, build artifact (Intellij Idea feature), sbt package. Unfortunately, none of them worked form me.
I attempted following things :
With sbt-assembly :
Created assembly.sbt file and added following line :
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
build.sbt :
scalaVersion in ThisBuild := "2.11.4"
resolvers += Resolver.url("bintray-sbt-plugins", url("http://dl.bintray.com/sbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)
ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }
I got the following error
[warn] Note: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.
[warn] com.eed3si9n:sbt-assembly:0.12.0 (sbtVersion=0.13, scalaVersion=2.11)
With 'build artifact' feature using Intellij Idea 15
Able to create a jar. However, not able to execute it. Was getting following error:
Invalid or corrupt jarfile
For this I tried the command : java -jar JAR_FILE
With sbt package :
Able to create JAR. However, not able to execute it. Was getting following error :
java.lang.NoClassDefFoundError scala/Function0
I was trying with the command :
java -cp scala-library.jar -jar JAR_FILE
Resolved
I am able to create jar by switching to scala version 2.10.5 and then used sbt-assembly plugin. Slightly disappointed with the fact that there is no available solution to create executable jar with latest version of scala.
If you are using sbt-assembly plugin, the correct task to perform is called assembly. When using IntelliJ IDEA, sbt assembly needs to be performed from a command line, the IDE is still unable to perform such SBT tasks.
The resulting jar, which includes all dependencies, is usually called a fat jar - if you need some more searching, this is what to search for.
Since I can't comment yet, I'll use answer, but more of a question - I have been using sbt package extensively for exactly this. I cd into the directory that holds src/main/scala|java and running sbt package, and then pushing jar/war file to the desired destination, in my case jetty.
Can you explain exactly what you're doing, the output and details on the issue?

How to add a scala library to eclipse

I am trying to add this Scala Library into Eclipse so as to add available functions I can use on Actors.
I've downloaded the file and extracted it and tried adding it to my workspace in the project explorer, but when I try, Eclipse tells me it can't find any projects in the file. I'm sure that there is a tutorial or something online that explains exactly how to do this, but like I said, I'm not sure about all the terminology, so I don't know what to search for to get the result I want.
The easiest way is to create an sbt project and use the sbteclipse plugin.
Your project structure should look like this:
build.sbt
project/build.properties
project/eclipse.sbt
build.sbt
(note that lines of code should be separated by a white line)
name := "ProjectName"
libraryDependencies += "org.scala-lang.modules" %% "scala-async" % "0.9.2"
build.properties
sbt.version=0.13.5
eclipse.sbt
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")
Then from the root directory execute sbt and within the sbt command line execute eclipse or eclipse with-sources=true
You can use sbt-extras or activator to get a specialized version that will automatically download the correct sbt version based on the build.properties file.
You could add the sbteclipse plugin as a default plugin, making it available in all projects by creating eclipse.sbt in the ~/.sbt/0.13/plugins directory instead of the project directory
If you created your project via sbt, please follow the instruction on the github page of async. Namely, add this libraryDependencies += "org.scala-lang.modules" %% "scala-async" % "0.9.2" to build.sbt, run sbt, regenerate eclipse files with "eclipse" command and finally re-import project into eclipse

What's the Scala + sbt workflow equivalent of Ruby + Bundler with a Gemfile?

I'm having a good time learning Scala, but I'm having the hardest time grasping how to set up a development environment.
In Ruby
File hierarchy
my_app/
|
+-- Gemfile
+-- app.rb
Gemfile
source :rubygems
gem "mechanize"
app.rb
require "mechanize"
agent = Mechanize.new
page = agent.get("http://google.com")
Install dependencies and run it
$ bundle install
$ ruby app.rb
What's the Scala equivalent with sbt?
I'm reading about sbt and how packages/imports/jar dependencies work in Java/Scala, but I can't seem to filter out the bare bones necessities.
What's the minimal file hierarchy to replicate the above with Scala?
Here's the Java Mechanize lib available on Maven: http://search.maven.org/#search|ga|1|mechanize
Once you run sbt and download the Mechanize dependencies, how to you discern the necessary import statements you need to get this to work?
val agent = new MechanizeAgent
val page: HtmlDocument = agent.get("http://www.google.com")
I got the above working in Eclipse by manually importing the .jars and then importing packages from the libraries until the compiler/runtime errors stopped and the agent worked. But that experience was discouraging and I've come here to repent.
Intent of this question: The Java ecosystem/workflow is overwhelming to me as someone that's used to Ruby's effortless, IDEless workflow. I think a bare bones equivalent would give me a place to start building upon.
Ideally, I'd like to get Scala development working with just Vim and the command line before becoming dependent on Eclipse.
sbt uses a library called ivy to import projects from the main maven repository. There are a few repositories sbt is preconfigured to work with, including the main maven repository.
Once these libraries are "resolved" (downloaded to your computer and hooked up to your project), the eclipse plugin will create dependencies to each jar in the eclipse project generated.
Here is how you configure it.
sbt Managed Dependencies
http://www.scala-sbt.org/release/docs/Getting-Started/Basic-Def.html#adding-library-dependencies
Add a dependency in your project's build.sbt file. If you add a dependency that depends on a specific version of scala, use two %% between the group and artifact name. Don't forget to add an empty line between each command in your build.sbt file.
libraryDependencies += "com.gistlabs" % "mechanize" % "0.11.0"
libraryDependencies += "org.scalatest" %% "scalatest" % "1.6.1" % "test"
Update the dependencies by running the update command:
$ sbt update
sbt Eclipse Plugin
https://github.com/typesafehub/sbteclipse/wiki/Installing-sbteclipse
You can install the sbt eclipse plugin globally by creating a file at ~/.sbt/plugins/plugins.sbt and putting this line into it:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
Whenever you add or update a dependency, run the following command and refresh your eclipse project:
$ sbt eclipse
I'd like to go a step farther than ffk's answer, do much more hand-holding, and actually provide the direct translation of the Ruby example to Scala + sbt.
File hierarchy
Crawler/
+- build.sbt
+- src/
+- main/
+- scala/
+- Crawler.scala
build.sbt
libraryDependencies += "com.gistlabs" % "mechanize" % "0.11.0"
Crawler.scala
import com.gistlabs.mechanize.MechanizeAgent
import com.gistlabs.mechanize.document.Document
object Crawler extends App {
val agent = new MechanizeAgent
val page: Document = agent.get("http://google.com")
}
Install dependencies and run it
$ sbt run
To make the project importable into Eclipse or IntelliJ, you need the sbteclipse-plugin or sbt-idea plugin. But rather than having to declare these plugins in every build.sbt for every new project, you can declare them in a global build.sbt:
// in ~/.sbt/plugins/build.sbt
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0")
Then, back in your Scala app's root directory:
$ sbt eclipse
or
$ gen-idea
Afterwards, you should be able to open it in the respective IDE.
Note: Whenever you add dependencies in your build.sbt, you'll need to rerun the sbt eclipse/gen-idea command so the IDE can pick it up.