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

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?

Related

Running Scala Script in sbt project

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.

How to download sbt plugin source jars in a common sbt project?

It's nature to download the dependencies source jars in a sbt project, using sbt gen-idea or idea's autoimport feature
but how can I download the sbt plugin source jars which I declared in project/plugins.sbt
IDEA
IDEA should already do this*.
When you import a project and have Download sbt sources checked in Preferences > Build, Execution, Deployment > Build Tools > sbt then it will run the updateSbtClassifiers sbt task.
* Read the Troubleshooting section as there are several known issues with this.
sbt
As mentioned above, you can run the following sbt task:
sbt> updateSbtClassifiers
This command is somewhat special in that it knows to resolve the classifiers for the plugins. It also uses settings that are scoped to that task. See the caveat about sbt/sbt#3432.
Longer way
It is important to understand that sbt is recursive.
Dependencies declared in build.sbt will be for the proper build.
Dependencies declared in project/plugins.sbt will be for the meta-build.
When you just run updateSbtClassifiers it is running this on the proper build, however the dependencies are actually for the meta-build. That is why I said that this task is a little special.
Another way (which can achieve different results) is to run the updateClassifiers task directly on the meta-build.
First switch over to the meta-build:
sbt> reload plugins
Now that you are in the meta-build run:
sbt:project> updateClassifiers
This will retrieve the src and doc for your dependencies (it may not actually do this for some plugins). Run libraryDependencies to see the dependencies of the meta-build.
To get back to the proper
sbt:project> reload return build run:
Troubleshooting
Download failed
You may see in the sbt logs that it failed to download either the src or doc. For example:
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: FAILED DOWNLOADS ::
[warn] :: ^ see resolution messages for details ^ ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: rocks.muki#sbt-graphql;0.5.0!sbt-graphql.jar(doc)
[warn] :: rocks.muki#sbt-graphql;0.5.0!sbt-graphql.jar(src)
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
If you look just above you will see all the resolvers that it tried. You should see one for sbt-plugin-releases which is where most sbt plugins are published to. See predefined resolvers for more details.
If you do not see that it tried sbt-plugin-releases then chances are you have encountered sbt/sbt#3432.
updateSbtClassifiers does not use the correct resolvers. Add the following to your build.sbt file:
updateSbtClassifiers / dependencyResolution := IvyDependencyResolution((updateSbtClassifiers / ivyConfiguration).value)
Sources not attaching
Even if the updateSbtClassifiers successfully downloads and resolves the src and doc IDEA may not attach them.
This seems to be a bug in the sbt-structure plugin. See SCL-13619 for details.
No attempt at downloading
If for some reason this doesn't download the sources (there is no failed download message) then have a look in your .ivy2/exclude_classifiers file. I'm not entirely sure what this file is for but I do know that sbt will exclude anything that is in here.
In my case it had a whole lot of things that I didn't want excluded so I deleted it and then it worked. Delete at your own risk.
You can use reload plugins to go into the project that contains the plugins. If you type libraryDependencies you can (for example) see the list of plugin dependencies. Use reload return to return to your normal sbt console.
More information here: Commands for managing the build definition

How to use external dependencies in sbt's .scala files?

This is for Scala 2.11.1 and sbt 0.13.5.
Say I have a Scala/sbt project with the following directory structure:
root/
build.sbt
src/ ..
project/
plugins.sbt
build.properties
LolUtils.scala
and I want to use some external library in LolUtils.scala. How is this generally accomplished in sbt?
If I simply add the libs I need into build.sbt via libraryDependencies += .. then it doesn't find them and fails on the import line with not found: object ...
If I add a separate project/build.sbt, for some reason it starts failing to resolve my plugins, plus I need to manually specify the Scala version in the nested project/build.sbt, which is unnecessary duplication.
What's the best way to accomplish this?
sbt is recursive which means that it uses itself to compile a build definition, i.e. *.sbt files and *.scala files under project directory. To add extra dependencies to use them in the build definition you have to declare them in a project/build.sbt.
There is one caveat to that. You can set any scalaVersion to your project, that is in build.sbt, but you should not modify scalaVersion in the project/build.sbt as it might conflict with the version sbt itself uses (that may or may not lead to binary incompatibility for plugins).
Sbt 0.13.5 is using Scala 2.10.4, and the library you're going to use must be compatible with that particular version of Scala.
> about
[info] This is sbt 0.13.5
...
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4

Installing sbteclipse

i have problems top use sbteclipse
What I have done:
went to my global sbt folder.
created a plugins folder
created the file plugins.sbt with addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
went to my eclipse project and created a build.sbt file
it contains:
name := "foo"
version := "1.0"
scalaVersion := "2.9.2"
libraryDependencies += "net.java.dev.jna" % "jna" % "3.4.0"
I am selecting the project folder in my cmd. and type sbt eclipse
But I always get the following error
[error] Not a valid command: eclipse (similar: help, alias)
[error] Not a valid project ID: eclipse
[error] Expected ':'
[error] Not a valid key: eclipse (similar: deliver, licenses, clean)
[error] eclipse
[error] ^
ps: I am using Windows. I am also using sbt 0.12
Your global sbt folder is at %USERPROFILE%\.sbt (C:\Users\<username>\.sbt most likely). So your plugins should be defined at %USERPROFILE%\.sbt\plugins\plugins.sbt
Failing this you can add it to your project directly. Add the file path is <project_root>\project\plugins.sbt. If the project directory doesn't exist you will need to create it.
I think that I might have found a solution. First, the default directory checked for plugins configuration is 'USER_HOME/.sbt/plugins' and NOT 'USER_HOME/.sbt/0.13/plugins'.
Secondly, the sbt version specified seems to matter. In 'PROJECT_HOME/project/build.properties', there's an 'sbt.version' property. If the version of sbt specified in this file is different from the actually installed version of sbt, there's likely to be an issue. I think I was affected more so by this because I'm using an Activator template and it already had 'sbt.version' specified in this 'build.properties' file.
While nosing around, I came across this
"Support for plugin configuration in project/plugins/ has been removed. It was deprecated since 0.11.2" from sbt website at http://www.scala-sbt.org/0.13.0/docs/Community/ChangeSummary_0.13.0.html. I still see a lot of guys pointing that it should be configured in 'PROJECT_HOME/projects/plugins.sbt'. I think this is very confusing.
I had similar a issue and answered to a similar question.
I tried "everything" and, eventually, I just had to update my sbt from 0.13.1 to 0.13.9.

Global sbteclipse plugin not found/loaded

I am having some serious difficulty installing sbteclipse as a global plugin. It seams like the global plugins are not being loaded. I created the .sbt directory and added a plugins directory. In the plugins directory I added the following build.sbt definition:
resolvers += Classpaths.typesafeSnapshots
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0-SNAPSHOT")
the above definition is in the ~/.sbt/plugins directory. When I search online I see plenty of sbt startups that look like the following: (notice the global plugin load and the project definition path)
Now here is an example of my sbt startup and my attempt to run eclipse:
Any thoughts on what I am doing wrong. I have been working on this for hours.
EDIT:
The error I get for not running sbt as superuser:
> mkemnetz#ubuntu:~/git/GymWebApp$ sbt
bash: /bin/sbt: Permission denied
mkemnetz#ubuntu:~/git/GymWebApp$
EDIT2:
mkemnetz#ubuntu:~/git/GymWebApp$ sbt
[info] Loading global plugins from /home/mkemnetz/.sbt/plugins
[info] Set current project to default-18287a (in build file:/home/mkemnetz/git/GymWebApp/)
> eclipse
[info] About to create Eclipse project files for your project(s).
[error] java.io.FileNotFoundException: /home/mkemnetz/git/GymWebApp/target/streams/$global/project-descriptors/$global/out (Permission denied)
[error] Use 'last' for the full log.
This is the current error I am getting. Still not working but much improved thanks to darwin
Instead of build.sbt in my ~/.sbt/plugins dir I have plugins.sbt with the content like in your example. And everything works fine for me.
UPD:
The problem occurs because of you run sbt command under superuser's environment so sbt conf is not resolved properly.
Just run sbt under your user after removing project target dir.
This is my ~/.sbt/plugins/build.sbt:
resolvers += Classpaths.typesafeResolver
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")
Quoting sbteclipse github
For sbt 0.13 and up Add sbteclipse to your plugin definition file. You
can use either: the global file (for version 0.13 and up) at
~/.sbt/0.13/plugins/plugins.sbt the project-specific file at
PROJECT_DIR/project/plugins.sbt
AND I want to comment on this "backward compatibility is very important!"