Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Quasar with Scala under sbt?

Tags:

scala

sbt

quasar

I wish to use Quasar in my SBT project. Since Scala is not yet supported the only viable option left is to have SBT compile some java classes that use of Quasar.

I tried putting

javaOptions += "-javaagent:PATH_TO_JAR/quasar-core-0.5.0.jar"

and

fork := true

as I read that for using e.g. JRebel one must insert both these statements into build.sbt

But it does not seem to work either as using a Quasarish class (QuasarExample) yields:

[error]    IllegalArgumentException: : Fiber class HelloWorldSpec$$anonfun$1$$anonfun$apply$3$$anon$1 has not been instrumented.  (Fiber.java:151)
[error] co.paralleluniverse.fibers.Fiber.<init>(Fiber.java:151)
[error] co.paralleluniverse.fibers.Fiber.<init>(Fiber.java:171)
[error] co.paralleluniverse.fibers.Fiber.<init>(Fiber.java:448)

A piece of code that's expected to be running without errors after successful instrumentation:

new Fiber<Integer>() {
    @Override
    protected Integer run() throws SuspendExecution, InterruptedException {
        return 0;
    }
}.start();

See also this repository for a starter.

like image 862
mjaskowski Avatar asked Jul 13 '14 11:07

mjaskowski


1 Answers

As per the comment from @mjaskowski, Dou you plan to instrument bytecode produced by Scala compiler?, Scala is not a supported language yet.

Short answer is: absolutely. Longer answer is, yes, but not very soon. Scala is a very (very, very, very, very) complex language (oh my god, it's so incredibly complex!), and it would take a long time to test Quasar with the many (many-many-many) Scala features. Given the relatively small number of Scala developers, and the heavy integration costs, this may take some time. We do, however support Clojure (much simpler integration), and will soon probably (or maybe we already do) support Kotlin (trivial integration).

Follow along to see the possible ways to have the javaagent set up in sbt.

This is my first encounter with Quasar so the steps are really basic however they should give you a head start.

Running Quasar's javaagent in JVM alone

It's only with the following command to be able to run Quasar's javaagent without any Scala/sbt's jars.

java -cp /Users/jacek/.ivy2/cache/org.ow2.asm/asm-util/jars/asm-util-5.0.1.jar:/Users/jacek/.ivy2/cache/org.ow2.asm/asm-commons/jars/asm-commons-5.0.1.jar:/Users/jacek/.ivy2/cache/org.ow2.asm/asm/jars/asm-5.0.1.jar -javaagent:/Users/jacek/.ivy2/cache/co.paralleluniverse/quasar-core/jars/quasar-core-0.5.0.jar -help

It appears it's not self-contained and needs additional jars on the CLASSPATH.

Running Quasar's javaagent with scala

The following command makes scala and Quasar's javaagent happy.

scala -debug -usebootcp -toolcp /Users/jacek/.ivy2/cache/org.ow2.asm/asm-tree/jars/asm-tree-5.0.1.jar:/Users/jacek/.ivy2/cache/org.ow2.asm/asm-util/jars/asm-util-5.0.1.jar:/Users/jacek/.ivy2/cache/org.ow2.asm/asm-commons/jars/asm-commons-5.0.1.jar:/Users/jacek/.ivy2/cache/org.ow2.asm/asm/jars/asm-5.0.1.jar:/Users/jacek/.ivy2/cache/org.ow2.asm/asm-analysis/jars/asm-analysis-5.0.1.jar -J-javaagent:/Users/jacek/.ivy2/cache/co.paralleluniverse/quasar-core/jars/quasar-core-0.5.0.jar

Initial attempts to run Quasar with sbt

Add the necessary dependencies of Quasar in build.sbt:

val quasarDeps = Seq(
  "quasar-core",
  "quasar-actors",
  "quasar-galaxy"
)

libraryDependencies := quasarDeps.map("co.paralleluniverse" % _ % "0.5.0")

It boils down to augmenting libraryDependencies with necessary jars. I chose all available.

I checked in Scala console that the libraries are available.

➜  quasar-sbt  xsbt
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to quasar-sbt (in build file:/Users/jacek/sandbox/quasar-sbt/)
> console
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import co.paralleluniverse.fibers._
import co.paralleluniverse.fibers._

scala> Fiber.DEFAULT_STACK_SIZE
res0: Int = 32

You will also have to add the java agent. Add the following to build.sbt:

// FIXME the path to quasar-core should be simpler
javaOptions in Test += "-javaagent:/Users/jacek/.ivy2/cache/co.paralleluniverse/quasar-core/jars/quasar-core-0.5.0.jar"

fork in Test := true

// only needed for Specs2 so I could test the test setup
libraryDependencies += "org.specs2" %% "specs2" % "2.3.13" % Test

scalacOptions in Test ++= Seq("-Yrangepos")

reload the build changes.

> reload
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to quasar-sbt (in build file:/Users/jacek/sandbox/quasar-sbt/)

Write a test to make sure all's set up properly. I used the HelloWorldSpec from [Specs2][2] with some changes:

import org.specs2.mutable._

import co.paralleluniverse.fibers._

class HelloWorldSpec extends Specification {

  "Quasar" should {
    "Fiber.DEFAULT_STACK_SIZE defaults to 32" in {
      Fiber.DEFAULT_STACK_SIZE === 32
    }
  }
}

It's not a very extensive test, so tweak it for your needs. Save the file under src/test/scala.

Execute test.

> test
objc[27427]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/bin/java and /Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
[info] HelloWorldSpec
[info]
[info] Quasar should
[info] + Fiber.DEFAULT_STACK_SIZE defaults to 32
[info]
[info] Total for specification HelloWorldSpec
[info] Finished in 40 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 4 s, completed Jul 13, 2014 2:04:13 PM

It works!

like image 104
Jacek Laskowski Avatar answered Nov 06 '22 17:11

Jacek Laskowski