How to specify "fork in Test := false" from command line rather than from build.sbt in a play framework based project - scala

To keep the question as short as possible I just need to know if there's a way to set fork to false directly from the command line when launching activator instead of hard coding it as follows "fork in Test := false" from under build.sbt in a play-framework 2.4 based project.
__________________All below is for further context___________________
I'm maintaining a "legacy" project based on play framework version 2.4, and been trying to configure my IntelliJ environment to enable debugging with unit tests. To achieve this I created 2 run configurations, the first launches activator in debug mode and pipes all its output to IntelliJ console, the second attaches the debugger to the formerly launched jvm. I'm then free to run and debug any tests as I please from activator's prompt.
In order for the debugger to work though, I have to add the following to my build.sbt:
fork in Test := false
which allows for debugging with my IntelliJ project setup, since I have it properly configured to take my "conf/test-config.conf" into consideration when launching activator. But when I simply run "activator test" from a native command line console, with the fork option set to false, activator ignores my test-config.conf file (obviously with configurations tuned for unit tests) and instead loads the original app config file "application.conf" causing my tests to fail with all sorts of conflicts. This happens even with the below configuration in my build.sbt:
javaOptions in Test += "-Dconfig.file=conf/test-application.conf"
Commenting out "fork in Test := false" fixes the problem when I launch the tests from a native console (the unit tests run properly), my IntelliJ launch configuration also succeeds to run the tests but the problem is it loses its ability to debug the code, which is actually the whole point in the first place.
Here's the command I'm currently using from IntelliJ to launch activator in debug mode:
java -Dactivator.home=<activator-home-path> -Xms1024m -Xmx1024m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -Dsbt.override.build.repos=true -Dconfig.file=conf/test-application.conf -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9990 -jar <activator-jar-path>

Simply use the following command when using sbt:
sbt "set fork in Test := false" test
For activator, you can try the following:
Add this to your build.sbt:
fork in Test := Option(System.getProperty("fork")) match {
case Some("false") => false
case _ => true
}
And then sumply run the following command:
activator -Dfork=false test

Related

IntelliJ print test run dependencies

I am working on a scala project which uses sbt for build tools. When we run unit tests on command line 'sbt test', the tests are running fine. However, when I run unit tests in IntelliJ, it seems to be picking up incorrect version of a dependency as well.
I was wondering if there is a way for me to print the classpath that IntelliJ is running the unit tests with?
IntelliJ IDEA already does that, actually, for each test run.
Tests are run as an invocation of JVM with the classpath passed to command-line parameter.
You need to press on the ellipsis to see the whole command line.
Classpath will be there after -classpath argument.
It's better to copy it to another window and enable line wrapping for the further digging.

Scala / sbt: How to stop at breakpoints in Eclipse

I am trying to debug my Scala application when running tests using sbt. I have added the following lines to build.sbt:
javaOptions in test ++= Seq(
"-Xdebug",
"-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001"
)
I have also set breakpoints in Eclipse and configured a remote debugger for that port 8001.
When launching the tests from command line, the remote debugger is start correctly:
Listening for transport dt_socket at address: 8001
But then the execution of the tests does not suspend, as expected, and so I am not able to connect the remote debugger. Instead, the tests are simply run.
Any ideas what I might be doing wrong here? How can I debug the sbt tests using breakpoints in Eclipse?
The following worked for me (not tested in test, but probably work the same way). In this example, I used a project generated by udash-generator (0.3.1).
$ sbt
> set fork := true
> set javaOptions ++= Seq("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001")
> run
I used eclipse (Neon with ScalaIDE 4.4.1, Scala 2.11) (sbt eclipse with-source=true) and added a breakpoint to the com.example.rpc.ExposedRpcInterfaces.hello(name: String) method.
Created a run configuration:
Started the launch configuration (the eclipse debugger) and opened browser with http://localhost:8080/#/rpc, started typing to the textfield and eclipse stopped at the breakpoint.
I am not sure what was different for you, as it seems you were also forking a new JVM for tests. I can try your setup if you provide more details which test framework you were using.

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.

How make Intellij Idea debug a Play 2.1 app's source code files, instead of project definition only

When I create a new Play 2.1 project, Intellij Idea insists on debugging the project configuration files only. That is, lines in ./project/Build.scala, and no other files.
How do I tell Idea to debug stuff in ./app/ instead?
I've generated Idea project files like so: [project-name] $ idea with-sources=yes (in Play's console).
(I cannot remember this ever happening before with Play 2.0 or earlier versions of 2.1)
There were 2 causes for this issue: one "interesting" and one stupid.
The interesting cause:
Play 2.1 and SBT seems to fork tests (and thus run them in a separate process). Therefore breakpoints in my unit test code were never hit.
One way to "fix" this, is to add this config settinig:
Keys.fork in Test := false
The stupid cause:
I had not yet compiled any "real" source code files in the new project. So therefore Idea never activated breakpoints on those lines. But the project configuration Build.scala file was compiled when I launched Play's SBT console I think, so Idea activated breakpoints in Build.scala directly. — So there was never a problem really: I just had to hit run in the Play console and then the breakpoints came alive (after Play had compiled my sources).
I'm running Intellij, with remote debug on port 9999
1. ~apatzer> play debug
2. Then start my Remote configuration in Intellij
3. [playproject] $ run
==> Successful at hitting breakpoints and debugging.
Because of forking, I was unable to hit breakpoints in any of my tests. For example:
[playproject] $ test-only com.mydomain.pkg.MyTest
==> FAIL different process. Breakpoints not hit in IDE.
Here's what worked:
import sbt._
import Keys._
import play.Project._
object MyBuild extends Build {
...
lazy val main = play.Project(appName, appVersion, appDependencies).settings(
Keys.fork in testOnly := false,
libraryDependencies ++= deps,
...

How to specify JVM maximum heap size "-Xmx" for running an application with "run" action in SBT?

My application does large data arrays processing and needs more memory than JVM gives by default. I know in Java it's specified by "-Xmx" option. How do I set SBT up to use particular "-Xmx" value to run an application with "run" action?
For forked processes you should look at Build.scala
To modify the java options for forked processes you need to specify them in the Build.scala (or whatever you've named your build) like this:
val buildSettings = Defaults.defaultSettings ++ Seq(
//…
javaOptions += "-Xmx1G",
//…
)
This will give you the proper options without modifying JAVA_OPTS globally, and it will put custom JAVA_OPTS in an sbt generated start-script
For non forked processes it's most convenient to set the config via sbtopts or sbtconfig depending on your sbt version.
Since sbt 0.13.6 .sbtconfig is deprecated. Modify /usr/local/etc/sbtopts along these lines:
-J-Xms512M
-J-Xmx3536M
-J-Xss1M
-J-XX:+CMSClassUnloadingEnabled
-J-XX:+UseConcMarkSweepGC
-J-XX:MaxPermSize=724M
-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
You can also create an .sbtopts file in the root of your SBT project using the same syntax as in the /usr/local/etc/sbtopts file. This makes the project self-contained.
Before sbt 0.13.6 you could set the options in .sbtconfig for non forked processes:
Check where sbt is:
$ which sbt
/usr/local/bin/sbt
Look at the contents:
$ cat /usr/local/bin/sbt
#!/bin/sh
test -f ~/.sbtconfig && . ~/.sbtconfig
exec java ${SBT_OPTS} -jar /usr/local/Cellar/sbt/0.12.1/libexec/sbt-launch.jar "$#"
Set the correct jvm options to prevent OOM (both regular and PermGen):
$ cat ~/.sbtconfig
SBT_OPTS="-Xms512M -Xmx3536M -Xss1M
-XX:+CMSClassUnloadingEnabled
-XX:+UseConcMarkSweepGC -XX:MaxPermSize=724M"
If you want to set SBT_OPTS only for the current run of sbt you can use env SBT_OPTS=".." sbt as suggested by Googol Shan. Or you can use the option added in Sbt 12: sbt -mem 2048. This gets unwieldy for longer lists of options, but it might help if you have different projects with different needs.
Note that CMSClassUnloadingEnabled in concert with UseConcMarkSweepGC helps keep the PermGen space clean, but depending on what frameworks you use you might have an actual leak on PermGen, which eventually forces a restart.
In sbt version 12 onwards there is an option for this:
$sbt -mem 2048
If you run sbt on linux shell, you can use:
env JAVA_OPTS="-Xmx512m" sbt run
This is my usually used command to run my sbt project.
.sbtconfig is deprecated starting with SBT 0.13.6. Instead, I configured these options in /usr/local/etc/sbtopts in the following way:
-J-Xms512M
-J-Xmx3536M
-J-Xss1M
-J-XX:+CMSClassUnloadingEnabled
-J-XX:+UseConcMarkSweepGC
-J-XX:MaxPermSize=724M
-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
Try this:
class ForkRun(info: ProjectInfo) extends DefaultProject(info) {
override def fork = Some(new ForkScalaRun {
override def runJVMOptions = super.runJVMOptions ++ Seq("-Xmx512m")
override def scalaJars = Seq(buildLibraryJar.asFile, buildCompilerJar.asFile)
})
}
There's one way I know of. Set the environment variable JAVA_OPTS.
JAVA_OPTS='-Xmx512m'
I have not found a way to do this as a command parameter.
Use JAVA_OPTS for setting with environment variable.
Use -J-X options to sbt for individual options, e.g. -J-Xmx2048 -J-XX:MaxPermSize=512
Newer versions of sbt have a "-mem" option.
The javaOptions += "-XX:MaxPermSize=1024" in our build.sbt as referenced by #iwein above worked for us when we were seeing a java.lang.OutOfMemoryError thrown while running Specs2 tests through sbt.
The environment variable is _JAVA_OPTIONS, which needs to be set.
Once you set _JAVA_OPTIONS, and when you sbt, sbt will show the message using JAVA_OPTIONS and the values.
Alternatively you could set javaOption in the sbt or .scala file
e.g
javaOptions += "-Xmx1G"
From sbt shell you could run show javaOptions to see the values that are set.
sbt lets you list the JVM options you need to run your project on a file named
.jvmopts
in the root of your project.
then add the java options that you want
cat .jvmopts
-Xms512M
-Xmx4096M
-Xss2M
-XX:MaxMetaspaceSize=1024M
it is tested and works in windows 10
https://www.lagomframework.com/documentation/1.4.x/scala/JVMMemoryOnDev.html
javaOptions in Test += "-Xmx1G"
This sets the JVM options for tests. Works also with jvm forking (fork in Test := true).