SBT multi-project build classpath problems - scala

I have a SBT project I'm trying to separate into a multi-project build.
For some reason, there are a few tests I can't get to work when running the tests from the root build.
These tests use Akka, and it looks something is wrong with the class path - the config is not loaded properly and I get this error:
[error] com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'akka' (SimpleConfig.java:152)
The dependency is configured for the sub-project, and works fine when I run the tests from within the project itself, and not from the root build.
Does someone know how can I get this to work?
Thanks for your help

Just been having this problem myself, we managed to solve it by enabling forking in the project:
ThisBuild / fork := true

Related

SBT AutoPlugins conflict that shouldn't be there

I have a sbt project using FlyWay. It's disabled in most projects because we're only running the evolutions from a specific project.
So I have something like this:
lazy val master = project
.disablePlugins(FlywayPlugin)
.aggregate(common)
.dependsOn(common)
The project works fine. It compiles, works, tests pass, etc.
Now I want to add Twirl, so I do this (in addition to plugins.sbt of course):
lazy val master = project
.enablePlugins(SbtTwirl)
.disablePlugins(FlywayPlugin)
.aggregate(common)
.dependsOn(common)
And I end up with this error:
[error] sbt.AutoPluginException: Error determining plugins for project 'master' in /opt/app/master:
[error] Contradiction in selected plugins. These plugins were both included and excluded: org.flywaydb.sbt.FlywayPlugin
[error] Use 'last' for the full log.
Which I don't really understand because I didn't change anything about FlyWay.
What could cause that?
This is a known problem. FlywayPlugin gets automatically enabled on all (sub)projects and when you try to disable it, it causes the conflict.
See sbt/sbt#1926. Citing #jsuereth:
Yeah, this is a known issue in our logic system (and the translation of enablement/disablement into it). I'm working on a mechanism to fix it.
PRs welcome if you have time.
There is also an open issue in the Flyway repository: flyway/flyway#1329 which suggests not to enable it automatically. But so far there is no solution or a workaround there.

Unit tests using Spark do not run any more from IntelliJ IDEA

I had to re-import my SBT project into IDEA, cleaned it thoroughly (git clean -fdx) and even did an "Invalidate caches / restart". Now, all my unit tests using the Spark context fail with:
java.lang.SecurityException: class "javax.servlet.FilterRegistration"'s signer information does not match signer information of other classes in the same package
I already searched and dug around and found out that I have to exclude dependencies on javax.servlet on my dependencies on hadoop-common. I did this, but it did not help.
When running the tests from the console with sbt test, everything runs fine.
What can I additionally check?
EDIT: I even re-imported everything from scratch, including deletion of the .ivy2 folder, and it did not help.
I had to add the exclude for javax.servlet to ALL my Hadoop dependencies!

In an sbt 0.13.7 project, compile the compiler-interfaces without compiling the project code

In a freshly checked out sbt ( 0.3.7 ) project and empty ivy cache, is it possible to trigger compilation of the compiler-interface(s) needed without compiling the project itself? I have poked around but haven't found a way.
Currently if a compiler-interface is required it will be created during compilation of the project. I would like to have this compiled directly in a separate command if possible. This would allow CircleCi to cache it saving 1-3 minutes with every build because it could be cached in the dependencies section of the circle.yml.
In sbt 0.13.12 compile:compileIncremental seems to do the trick. I ran inspect compile and inspected its dependencies to find the command.

Real SBT Classpath at Runtime

I have some test cases that need to look at the classpath to extract the paths of some files/directories in there. This works fine in the IDE.
The problem is that, when running SBT test, Properties.javaClassPath gives me /usr/share/sbt-launcher-packaging/bin/sbt-launch.jar.
The classpath is fine when I run show test:dependency-classpath. Is there a way to obtain that information from inside the running Scala/Java program? Or is there a way to toss it into a system property or environment variable?
By default the tests are run inside of the SBT process, so the classpath will look like it did when you started sbt (I guess sbt does some trixery to dynamicly load the classes for the tests, not sure). One way to do what you want is to run your tests in a forked jvm, that way sbt will start a new jvm to run the test suite and that should have the expected class path:
fork in Test := true
I have been working on understanding how the EmbeddedCassandra works in the spark-cassandra-connector project which uses the classpath to start up and control a Cassandra instance. Here is a line from their configuration that gets the correct classpath.
(compile in IntegrationTest) <<= (compile in Test, compile in IntegrationTest) map { (_, c) => c }
The entire source can be found here: https://github.com/datastax/spark-cassandra-connector/blob/master/project/Settings.scala
Information on the <<= operator can be found here: http://www.scala-sbt.org/0.12.2/docs/Getting-Started/More-About-Settings.html#computing-a-value-based-on-other-keys-values. I'm aware that this is not the current version of sbt, but the definition still holds.

Using sbt 0.13.1, tests won't compile using the generated externalIvyFile

For our Scala development we currently use ivy + ant, but we are also trying to use sbt for our development workflow. This would be for the continuous incremental compilation when not using an IDE.
sbt uses ivy, so in theory this should work. But when using an ivy external file the tests won't compile.
To reproduce this you can even use the generated ivy.xml file from any sbt project.
Here are the steps to reproduce the error on a sbt project with tests,
from the sbt console run deliverLocal (deliver-local in previous versions of sbt)
copy the generated ivy file into your project home and rename it to 'ivy.xml'. From my understanding using this file should be equivalent to declaring the dependencies in build.sbt.
edit the build.sbt, add externalIvyFile() on one line and then comment all dependencies declarations
in the console, run reload, then test
compile will run just fine, but test will fail at compile time. None of the dependencies will be honoured, not even the production code of the current project.
What am I missing?
In my case it worked with the following build.sbt:
externalIvyFile()
classpathConfiguration in Compile := Compile
classpathConfiguration in Test := Test
classpathConfiguration in Runtime := Runtime
You just need the extra three lines in the end. Here is a link for more info: http://www.scala-sbt.org/release/docs/Detailed-Topics/Library-Management.html#ivy-file-dependency-configuration
Look for the Full Ivy Example. I hope it helps!
EDIT: Just to be complete - here is what pointed me to the above link: https://github.com/sbt/sbt/issues/849.