Handling multiple .scala build files for a project - scala

I'm trying to figure out how does sbt work. I read sbt online documentation and still have an unanswered question.
How does sbt behave when it discovers multiple .scala files in the < root >/project folder each one containing a Build trait implementation?
I performed experiment and discovered that sbt find this situation correct if there is no interference between the build implementations. I call it "interference" but I have no precise picture of what are correct and incorrect cases and how multiple Build definitions actually flattened into single sbt project.

Related

How to isolate libraries in an unmanaged dependency .jar file so they don't conflict with others

I need to add a .jar as an unmanaged dependency to an sbt Scala project (it is the java-stellar-sdk). Everything works well as long as I don't run sbt test. There seems to be a Mockito version in the .jar file that conflicts with the one I am using in the project. I get a lot of errors that certain Mockito matchers are not found but everything works fine without the .jar in the lib folder.
Is there a way to tell sbt that it should ignore certain libraries in the .jar or that managed dependencies take precedence? I also found this related question but obviously it didn't help me.
An alternative workaround would also help a lot. Is it possible to isolate the libraries in the jar in a way that allows me to just make a certain package visible to the outside?
Update: The .jar contains Mockito 2 but my project uses Mockito 1, so this is a very simple and obvious conflict, that I can solve by upgrading to Mockito 2 (which I tried and it works). However, the question remains: Is there another reasonable way to isolate the Mockito dependency in the .jar to not interfere with my project in case I can't or don't want to resolve the conflict buy switching to a newer version of the library in question. Maybe altering the .jar to rename the conflicting packages? I don't know. Something like that.
I know that this is a very general question that has likely been discussed somewhere else in depth. However, I didn't find anything that really satisfied me. Links to relevant discussions of the topic are of course appreciated as well.
I can think of 3 ways for you to do it (ordered from simple to difficult):
delete mockito 2 manually from the jar file.
Since the jar is just a zip file, you can extract it, delete all the conflicting files, and pack it again.
compile that jar from source by yourself, and set mockito as a test dependency (as it should be). If you do that, consider opening a PR with your change, to fix the problem for the community
Shade the mockito files in the jar.
shading is the process of renaming all files in a jar file by certain rules. you can either use jarjarlinks or with sbt assembly plugin. see this answer to get you started with sbt assembly: https://stackoverflow.com/a/47974750/245024
You should be able to arrange for your Mockito 1 classes to appear before the Mockito 2 classes on the classpath. That will cause your classes to win any conflicts.

sbt multi project: create resource in another sub-project

I have an sbt project with two sub-projects, A and B. A produces a standalone scala-based executable exe. When exe is run, it will produce a file out.xml. I want this file to be part of resources for project B. I do not want B to include any references to A's code, all I want is the out.xml file to be part of it. I suspect that http://www.scala-sbt.org/0.13.5/docs/Howto/generatefiles.html should be a good starting point, but I can't get my head around on how to split it between two projects. Any takers?
Since A is a dependency of the build process, which needs to run the executable to generate your xml file you would list it as a libraryDepencency in project/[something].sbt or project/project/[something].scala. This would make it available to code you put in build.sbt or project/[something].scala but not make it a transitive dependency of the resulting artifact of project B.
(Or you could of course make project A a sbt-plugin itself, or create yet another project which is a plugin depending on A that runs the executable.)

Generate a JAR from one Scala source file

I have no Scala experience, but I need to create a JAR to include on a project's classpath from a single Scala source file.
I'm thinking there is a relatively straightforward way to do this, but I can't seem to figure it out.
The Scala file is here: http://pastebin.com/MYqjNkac
The JAR doesn't need to be executable, it just needs to be able to be referenced from another program.
The most convenient way is to use some build tool like Sbt or Maven. For maven there is the maven-scala-plugin plugin, and for Sbt here is a tutorial.
If you don't want to use any build tool, you may want to compile the code with scalac and then create the jar file manually by using zip on the resulting class files and renaming it to jar. But you have to preserve the directory structure. In your pastebin you use the package org.apache.spark.examples.pythonconverters, so make sure the directories match.
Btw, if you want to just integrate this piece of code with your java project, and using maven, you can have the scala code in your 1 project as well (in src/main/scala). Just use the maven-scala-plugin plugin and hook it to the compile phase, or some sooner phase if your Java code depends on it. However, I don't recommend mixing multiple languages in one project, I would split it into two separate ones.

What is Scala's Simple Build Tool (sbt) and why is it used?

I am new in Scala and I have to learn Scala and SBT, I read the sbt tutorial but i am unable to understand the use of sbt, for what purpose its been used.After reading this tutorial
I am still confused can any one will explain it in simple words, also suggest me if there is some tutorial for simple build tool
When you write small programs that consist of only one, or just two or three source files, then it's easy enough to compile those source files by typing scalac MyProgram.scala in the command line.
But when you start working on a bigger project with dozens or maybe even hundreds of source files, then it becomes too tedious to compile all those source files manually. You will then want to use a build tool to manage compiling all those source files.
sbt is such a tool. There are other tools too, some other well-known build tools that come from the Java world are Ant and Maven.
How it works is that you create a project file that describes what your project looks like; when you use sbt, this file will be called build.sbt. That file lists all the source files your project consists of, along with other information about your project. Sbt will read the file and then it knows what to do to compile the complete project.
Besides managing your project, some build tools, including sbt, can automatically manage dependencies for you. This means that if you need to use some libraries written by others, sbt can automatically download the right versions of those libraries and include them in your project for you.

How to compile just some files with sbt?

I've come pretty well along with sbt, the Scala Build Tool. If you only have small problems in the code, it's easy.
Now, after a major feature add, much of my code is broken and I sbt seems to be confused as to how the dependencies are. I could help it, compiling the fundamental modules first, but it does not seem to let me.
It's help system is... notorious.
> help compile
Compiles sources.
Yeah, well. I guessed that.
What I wanted to hear was: how do I compile only - say - src/module/A.scala.
This might not even be possible (hello again, make, never abandoned you!). At least I cannot find any reference on the Internet to applying sbt compile just to a single file.
I'm using sbt from the command line prompt, not an IDE.
UPDATE:
It was my fault. :/ Had split a source file into multiple, but forgot to copy a package clause to each of the new ones. Oooops.
Will keep this open for a while, since compiling just a single file (i.e. something like sbt compile filename) would imho not be a bad thing.
You could define a Multi-Project Build where the files you want to compile separately are encapsulated in a project. According to the docs, the following is then possible:
At the sbt interactive prompt, type projects to list your projects and project to select a current project. When you run a task like compile, it runs on the current project. So you don't necessarily have to compile the root project, you could compile only a subproject.
I just wanted to mention here that I came across sbt-compile-quick-plugin (https://github.com/etsy/sbt-compile-quick-plugin). It does what it says on the tin, just add addSbtPlugin("com.etsy" % "sbt-compile-quick-plugin" % "1.3.0") to your project/plugins.sbt, then you can just start up sbt and run compileQuick /path/to/your/file
(See https://stackoverflow.com/a/46849619/1358677)