Per task JVM settings in SBT 0.9

902 views
Skip to first unread message

ijuma

unread,
May 21, 2011, 1:38:44 PM5/21/11
to simple-b...@googlegroups.com
Hi,

In SBT 0.7.x, I had defined the following in the base trait used by all my projects:

def forkTestRunTask(className: String, jvmArgs: Seq[String]) = task { args =>
  runTask(Some(className), testClasspath, args)(new ForkRun(
    forkRun(Some(info.projectDirectory), jvmArgs).get.asInstanceOf[ForkScalaRun])) dependsOn (testCompile, copyResources, copyTestResources)
}

And then I could define named run tasks with custom JVM args relatively easily, e.g:

lazy val runFoo = forkTestRunTask("foo.Foo", Seq("-Xmx6144m"))

How should I go about doing the same (or better) in SBT 0.9.x? Something like the following, I guess, but how do I get the classpath and logger?

def forkRun(mainClassName: String, jvmArgs: Seq[String]) =
  new ForkRun(ForkOptions(runJVMOptions = jvmArgs)).run(mainClassName, classpath, Seq(), loggerl)

Best,
Ismael

Mark Harrah

unread,
May 21, 2011, 2:41:33 PM5/21/11
to simple-b...@googlegroups.com

fork in run := true

javaOptions in run += "-Xmx6144m"

A basic run task is created by:

// this lazy val has to go in a full configuration
lazy val myRunTask = TaskKey[Unit]("my-run-task")

myRunTask <<= runTask(Test, "foo.Foo", "arg1", "arg2")

or, if you don't need to refer to myRunTask (this can be in a basic one):

TaskKey("my-run-task") <<= runTask(Test, "foo.Foo", "arg1", "arg2")

If you want to be able to supply arguments on the command line, replace TaskKey with InputKey and runTask with runInputTask.

The 'Test' part can be replaced with another configuration, such as Compile.

-Mark

ijuma

unread,
May 21, 2011, 3:49:50 PM5/21/11
to simple-b...@googlegroups.com
Hi Mark,

Thanks. Comments below.

On Saturday, 21 May 2011 19:41:33 UTC+1, Mark Harrah wrote:

 fork in run := true

 javaOptions in run += "-Xmx6144m"

I came across this, but I thought this meant that all the tasks forked from that project would get those JVM settings. Is that not true? The code I was using in SBT 0.7.x allowed me to set a different -Xmx for each task. Some of my projects have a bunch of tools where each requires different settings and it's handy for one person to configure it once in the build file making it easy to launch by invoking a name later on.

A basic run task is created by:

  // this lazy val has to go in a full configuration
  lazy val myRunTask = TaskKey[Unit]("my-run-task")

  myRunTask <<= runTask(Test, "foo.Foo", "arg1", "arg2")

or, if you don't need to refer to myRunTask (this can be in a basic one):

  TaskKey("my-run-task") <<= runTask(Test, "foo.Foo", "arg1", "arg2")

If you want to be able to supply arguments on the command line, replace TaskKey with InputKey and runTask with runInputTask.

The 'Test' part can be replaced with another configuration, such as Compile.

I had indeed figured this part out. Although when I tried using TaskKey inline in a Full Configuration, it complained about duplicate keys (I guess it was being invoked more than once). Memoising them in my build file fixed that though.

Best,
Ismael

Mark Harrah

unread,
May 21, 2011, 11:34:58 PM5/21/11
to simple-b...@googlegroups.com
On Sat, 21 May 2011 12:49:50 -0700 (PDT)
ijuma <ism...@juma.me.uk> wrote:

> Hi Mark,
>
> Thanks. Comments below.
>
> On Saturday, 21 May 2011 19:41:33 UTC+1, Mark Harrah wrote:
> >
> > fork in run := true
> >
> > javaOptions in run += "-Xmx6144m"
> >
> I came across this, but I thought this meant that all the tasks forked from
> that project would get those JVM settings. Is that not true? The code I was
> using in SBT 0.7.x allowed me to set a different -Xmx for each task. Some of
> my projects have a bunch of tools where each requires different settings and
> it's handy for one person to configure it once in the build file making it
> easy to launch by invoking a name later on.

Yes, that is correct. You can do it in 0.9.x as well, but it could be simpler. You can see the implementation of runTask and runInputTask here:

https://github.com/harrah/xsbt/blob/0.9/main/Defaults.scala#L875

What needs to be changed to be able to use the runTask/runInputTask methods is for the runner to be scoped per individual run-like task instead of the 'run' task itself. This is something I plan to change, but haven't decided how to do it yet.

-Mark

ijuma

unread,
May 22, 2011, 11:02:49 AM5/22/11
to simple-b...@googlegroups.com
On Sunday, 22 May 2011 04:34:58 UTC+1, Mark Harrah wrote:

Yes, that is correct.  You can do it in 0.9.x as well, but it could be simpler.  You can see the implementation of runTask and runInputTask here:

https://github.com/harrah/xsbt/blob/0.9/main/Defaults.scala#L875

Thanks, that example clarified it for me. I have the core build ported now. Next stop: plugins (sbt-idea and junit_xml_listener are the essential ones).

What needs to be changed to be able to use the runTask/runInputTask methods is for the runner to be scoped per individual run-like task instead of the 'run' task itself.  This is something I plan to change, but haven't decided how to do it yet.

Sounds good.

Best,
Ismael

Mark Harrah

unread,
May 24, 2011, 5:29:36 PM5/24/11
to simple-b...@googlegroups.com

This is added in 0.9.8. There is a new method fullRunTask, which is like runTask but takes as the first argument the task key. It will configure the runner using the specific scope for that key. You can then apply settings to only that key:

val myRun = TaskKey[Unit]("my-run", "Custom run task.")

fullRunTask(myRun, Compile, "pkg.Main", "arg1", "arg2")

fork in myRun := true

javaOptions in myRun += ...


Something that might be helpful if you have groups of tasks is defining delegation for tasks.

val aRun = TaskKey[Unit]("a-run", "A run task.")

// Specifies that myRun delegates to aRun
// for any uninitialized settings
// (the last parameter is a repeated one)
val myRun = TaskKey[Unit]("my-run", "Custom run task.", aRun)

// Make the run task as before.
fullRunTask(myRun, Compile, "pkg.Main", "arg1", "arg2")

// If fork in myRun is not explicitly set,
// then this also configures myRun to fork.
// If fork in myRun is set, it overrides this setting
// because it is more specific.
fork in aRun := true

// Appends "-Xmx2G" to the current options for myRun.
// Because we haven't defined them explicitly,
// the current options are delegated to aRun.
// So, this says to use the same options as aRun
// plus -Xmx2G.
javaOptions in myRun += "-Xmx2G"

ijuma

unread,
May 24, 2011, 8:52:58 PM5/24/11
to simple-b...@googlegroups.com
Hi Mark,

On Tuesday, 24 May 2011 22:29:36 UTC+1, Mark Harrah wrote:

This is added in 0.9.8.  There is a new method fullRunTask, which is like runTask but takes as the first argument the task key.  It will configure the runner using the specific scope for that key.  You can then apply settings to only that key:

Thanks! This is nicer than what I had and I am now using the new approach. 

Something that might be helpful if you have groups of tasks is defining delegation for tasks.

Yes, this is handy. I am also using it.

Best,
Ismael

ijuma

unread,
May 25, 2011, 12:22:42 AM5/25/11
to simple-b...@googlegroups.com
On Saturday, 21 May 2011 20:49:50 UTC+1, ijuma wrote:
I had indeed figured this part out. Although when I tried using TaskKey inline in a Full Configuration, it complained about duplicate keys (I guess it was being invoked more than once). Memoising them in my build file fixed that though.

For future reference, this was a bug in my build file where I was reusing settings and causing the same TaskKey to be created multiple times.

Best,
Ismael

Reply all
Reply to author
Forward
0 new messages