multi-project sbt build - package all dependent JARs in one directory - scala

I have a multi-project SBT build: some projects are dependent on each other, some are dependent on third-party JARs, and there's a "main" project which depends on everything .
When I sbt package it, I get one JAR in each target/ directory.
What I want to achieve is getting all relevant JARs (mine and external) is one directory. Very similar to the way you package a WAR with Maven.
(And to clarify - I'm not interested in an assembled "FAT JAR" that contains all the dependencies in a single file. Just one directory with all JARs in it)

Im not 100% sure about the suprobject dependencies but I think SBT native packager should help you do something like that, and will also provide a start-script for windows and unixes:
http://www.scala-sbt.org/sbt-native-packager/GettingStartedApplications/MyFirstProject.html

I would recommend sbt-pack for creating self-contained JARs:
https://github.com/xerial/sbt-pack
I use it and haven't seen a glitch so far.
It also generates both OS X/Linux as well as Windows .bat entry scripts for the main classes/objects you choose.

Related

how to keep jar dependancy while checking in code

I have a scala project built with dependancy on a locally built jar file (java code). Once I need to check in my scala code into a different environment for building and deployment, what's the best way to keep my jar file in the dependancy?
I know that if I use the sbt dependancy from online modules, I don't need to worry, it will download the version and build, but what if I want to use my own jar file for this purpose?
This is in OSX, and code will be checked into linux machines, I am using intellij and sbt to manage my scala project. I also used intellij to build my external java lib into jar file and added dependancy of this specific path.
I hope there should be some generic solution, but I am new in JAVA and SBT
I got it figured out. Add the jar files under the lib directory right under the project will solve the problem. SBT will pick it up automatically and you can certainly check in the jar files like source code.

Adding library dependency in play 2.3.8

I'm trying to add the apache commons email library to my Play project and I'm having trouble.
Firstly I have both build.sbt and plugins.sbt in my project and I'm not sure which one I should be putting the import into, does anyone know?
Also, I'm not sure why there even is the separate project module in my project, intelliJ created it as part of the project. Could anyone explain the purpose of the two separate modules and why they are there?
Thanks!
So, in sbt, you have your project. This is specified in build.sbt (or more correctly, any *.sbt file in your projects base directory). Any libraries that your applications code needs, for example, if your application needs to send emails using the commons email library, go in to the librarDependencies seeing in here.
But build.sbt itself is Scala code that needs to be compiled, but it's not part of your applications runtime. So in sbt, your projects build is a project itself, one that has to be compiled. It has its own classpath, which consists of the sbt plugins you're using, so for example, if you need a less compiler to compile your less files, that's not something that gets done at runtime, so you don't want your application code depending on that, it goes into your project builds libraryDependencies, which gets specified in project/plugins.sbt (or in fact any *.sbt in the project directory). So, once you add it there, you can use the Scala code it provides from build.sbt. IntelliJ imports this project for you so that you can have syntax highlighting and other IDE features in build.sbt.
But it doesn't stop there. How does project/plugins.sbt get compiled, where is its classpath? Well, your projects builds projects builds project is also an sbt project itself too... It keeps going down. IntelliJ stops at that point though, it doesn't keep importing these meta sbt projects because it's actually very rare to need additional sbt plugins for your projects builds projects builds project, so it just uses the same classpath as your projects build project for syntax highlighting in project/plugins.sbt.

Sbt's gen-idea always creates two IntelliJ projects

I am new to SBT. Just be curious that why does sbt's gen-idea always generate two IntelliJ projects:
.idea
.idea_modules
When I open the generated project, the "project" directory is always there as a separate project different with the top level project. The name is "myproject-build".
Just wondering whether this is normal?
Thanks.
Yes this is normal, this is the default behavior. You can change it by excluding some folders (see the doc available here : https://github.com/mpeltonen/sbt-idea at Exclude some folders)
So what is the difference between .idea and .idea_modules?
.idea_module generates an IDEA module while .idea generates an IDEA project.
In short a project can be multi-module or single-module and also contains IntelliJ libraries.
In longer version from the doc (http://confluence.jetbrains.com/display/IDEADEV/Structure+of+IntelliJ+IDEA+Project)
Project
In IntelliJ IDEA, a project encapsulates all your source code,
libraries, build instructions into a single organizational unit.
Everything you do in IntelliJ IDEA, is done within the context of a
project. A project defines some collections referred to as modules and
libraries. Depending on the logical and functional requirements to the
project, you can create a single-module or a multi-module project.
Module
A module is a discrete unit of functionality that can be run, tested,
and debugged independently. Modules includes such things as source
code, build scripts, unit tests, deployment descriptors, etc. In the
project, each module can use a specific SDK or inherit SDK defined on
the project level (see the SDK section later in this document). A
module can depend on other modules of the project.
Yes, it is ok for that SBT plugin for IDEA.
Usually IDEA project consists of top-level .idea directory (which contains configuration common to the project) and several *.iml files, one for each module in the project (module-specific configuration, like facets, excluded directories, custom dependencies). These files are usually located in the top-level directories of corresponding modules.
On the other hand, SBT plugin does something unusual. It creates standard .idea directory, but it stores all project modules in one location, namely .idea_modules directory in the top-level directory of the project. This is fully supported by IDEA project structure, which is a set of XMLs after all.
As for project directory/module, it is a standard feature of SBT builds. It contains your build configuration. See SBT manual on this.
The foregoing was about SBT plugin which is currently present in plugins repo. There is an official SBT plugin in active development which keeps familiar modules structure (no .idea_modules directory) and has higher integration with SBT. The latter is most prominent in dependency management - official plugin extracts dependencies, even unmanaged, and makes them available for the IDE; current SBT plugin cannot do that.

Gradle eclipse classpath - Switching between SNAPSHOT and project dependency

We have a multiple modules in our Java project and each module publishes SNAPSHOT jar files to Nexus repository. All the sub-modules are directly dependent on the SNAPSHOT jar files.
During development, we want to depend on the Eclipse project rather than SNAPSHOT jars. So we introduced a flag which switches between the dependencies as shown below.
if(System.properties.'setupProject'){
compile project(':Core')
compile project(':Module1')
compile project(':Module2')
}else{
compile 'com.test:core:0.1-SNAPSHOT'
compile 'com.test:module1:0.1-SNAPSHOT'
compile 'com.test:module2:0.1-SNAPSHOT'
}
Executing the following command generates the .classpath file as expected.
gradle eclipse -DsetupProject=true
Is there a better way to do this? Can we use Gradle configurations to achieve the same?
I could not find good examples for the same.
At the moment this is the way to go. You might tweak this even more and instead of using a System property to mark a project as available you can check if the project folder is available (project is checked out)
cheers,
René

scala sbt cache x eclipse build path

I'm added a dependence to my build.sbt (casbah). I did a sbt update, I did check my ~/.ivy2/cache directory and all jars are there. Do I have to add this ~/.ivy/cache directory to my Build Path and add the casbah as external Jar to my project? If no, probably no because I did try it, what should I do to be able to use this jar in my scala project?
EDIT
I found this instructions that helped me, but still a hack
Establish a simple project (general/project) named "IvyCache"
located at your ".ivy2/cache" folder just for library reference
purposes.
Establish a Scala project located at your "project" folder.
Add the following libraries to the Scala project by means of "Add
JARs" to the "Java Build Path":
3.a) All jars from "/IvyCashe/org.scala-tools.sbt" filterred by
"*2.9.1-0.11.2" or any other Scala/SBT version numbers.
3.b) A single sbinary_*.jar from "/IvyCache/org.scala-tools.sbinary".
3.c) A single test-interface*.jar from "/IvyCache/org.scala-
tools.testing".
Now your build files should compile within Eclipse.
The easiest way to manage this is to use the eclipse plugin for sbt. Then you can just say sbt eclipse on the command line any time you change the dependencies in build.sbt, and the Eclipse files will be automatically updated for you.
Doing it this way means that you will never have to manually configure your Eclipse build path. After all, sbt already knows how to construct the build path, so there's no reason you would have to do it manually.