Skip to content

@eed3si9n eed3si9n released this Mar 20, 2015 · 3300 commits to develop since this release

Changes with compatibility implications

  • Disable publishing on implicitly created root project by not enabling IvyPlugin by default (-Dsbt.root.ivyplugin=true will revert this behavior). #1871/#1869 by @dwijnand
  • Rolls back XML parsing workaround. See below.
  • Enables cross-version support for Scala sources. See below.


  • Adds Maven resolver plugin. See below.
  • Adds project-level dependency exclusions. See below.
  • Adds sequential tasks. See below.
  • Discovered main classes will be sorted. #1180 by @kretes
  • Implemented a new mechanism of forking javac, whereby errors are captured. Also more likely to run in-process. #1702 by @jsuereth
  • evicted will display all evictions (including the ones not suspected of binary incompatibility). #1615 by @eed3si9n
  • Better abstration to track new kinds of dependencies for incremental compiler. #1340 by @Duhemm
  • Source dependency uses --depth 1 for git clone. #1787 by @xuwei-k
  • Facilitate nicer ways of declaring project settings. See below. #1902 by @dwijnand


  • Javac warnings are treated as warnings. #1702/#875 by @jsuereth
  • compilerReporter is fed to javac during incremental compilation. #1542 by @jsuereth
  • Ignores hidden build files from the build. #1746 by @j-keck
  • Fixes build.sbt parsing of multiple import. #1741 by @ajozwik
  • Fixes ANSI escape code for overwriting lines on Windows. #1771 by @dwickern
  • Adds null check in incremental compiler's type tree extraction. #1754/#1655 by @Duhemm
  • sbt doesn't honor Maven's uniqueVersions (use sbt-maven-resolver to fix). #1322 by @jsuereth
  • sbt doesn't see new SNAPSHOT dependency versions in local maven repos (use withLatestSnapshots + sbt-maven-resolver to fix) #321 by @jsuereth
  • Property in pom's version field results to wrong dependency resolution (use sbt-maven-resolver to fix). #647 by @jsuereth
  • Maven local resolver with parent POM (use sbt-maven-resolver). #1616 by @jsuereth
  • Fixes eviction warning being too noisy. #1615 by @eed3si9n
  • Issues warning if multiple dependencies to a same library is found with different version. #1634 by @eed3si9n
  • Removes "No main class detected" warning. #1766 by @eed3si9n
  • Fixes sporadic ConcurrentModificationException from JUnitXmlTestsListener. #1881 by @aerskine
  • Fixes handling of ANSI CSI codes. #1885 by @jsuereth
  • Exempt org.scala-lang:scala-actors-migration and org.scala-lang:scala-pickling from scala binary version checks. #1818/#1899 by @dwijnand
  • Fixes cached resolution handling of internal depdendencies. #1711 by @eed3si9n
  • Fixes cached resolution being too verbose. #1752 by @eed3si9n
  • Fixes cached resolution not evicting modules transitively. #1760 by @eed3si9n

Rolling back XML parsing workaround

sbt 0.13.7 implemented natural whitespace handling by switching build.sbt parsing to use Scala compiler, instead of blank line delimiting. We realized that some build definitions no longer parsed due to the difference in XML handling.

val a = <x/><y/>
val b = 0

At the time, we thought adding parentheses around XML nodes could work around this behavior. However, the workaround has caused more issues, and since then we have realized that this is a compiler issue SI-9027, so we have decided to roll back our workaround. In the meantime, if you have consecutive XML elements in your build.sbt, enclose them in <xml:group> tag, or parentheses.

val a = <xml:group><x/><y/></xml:group>
val b = 0

#1765 by @ajozwik

Cross-version support for Scala sources

When crossPaths setting is set to true (it is true by default), sbt 0.13.8 will include
src/main/scala-<scalaBinaryVersion>/ to the Compile compilation in addition to
src/main/scala. For example, it will include src/main/scala-2.11/ for Scala 2.11.5, and
src/main/scala-2.9.3 for Scala 2.9.3. #1799 by @indrajitr

Maven resolver plugin

sbt 0.13.8 adds an extension point in the dependency resolution to customize Maven resolvers.
This allows us to write sbt-maven-resolver auto plugin, which internally uses Eclipse Aether
to resolve Maven dependencies instead of Apache Ivy.

To enable this plugin, add the following to project/maven.sbt (or project/plugin.sbt the file name doesn't matter):


This will create a new ~/.ivy2/maven-cache directory, which contains the Aether cache of files.
You may notice some file will be re-downloaded for the new cache layout.
Additionally, sbt will now be able to fully construct
maven-metadata.xml files when publishing to remote repositories or when publishing to the local ~/.m2/repository.
This should help erase many of the deficiencies encountered when using Maven and sbt together.

Notes and known limitations:

  • sbt-maven-resolver requires sbt 0.13.8 and above.
  • The current implementation does not support Ivy-style dynamic revisions, such as "2.10.+" or "latest.snapshot". This
    is a fixable situation, but the version range query and Ivy -> Maven version range translation code has not been migrated.
  • The current implementation does not support Maven-style range revisions if found on transitive dependencies. #1921

#1793 by @jsuereth

Project-level dependency exclusions

sbt 0.13.8 adds experimental project-level dependency exclusions:

excludeDependencies += "org.apache.logging.log4j"
excludeDependencies += "com.example" %% "foo"

In the first example, all artifacts from the organization "org.apache.logging.log4j" are excluded from the managed dependency.
In the second example, artifacts with the organization "com.example" and the name "foo" cross versioned to the current scalaVersion are excluded.

Note: This feature currently does not translate to pom.xml!

#1748 by @eed3si9n

Sequential tasks

sbt 0.13.8 adds a new Def.sequential function to run tasks under semi-sequential semantics.
Here's an example usage:

lazy val root = project.
    testFile := target.value / "test.txt",
    sideEffect0 := {
      val t = testFile.value
      IO.append(t, "0")
    sideEffect1 := {
      val t = testFile.value
      IO.append(t, "1")
    foo := Def.sequential(compile in Compile, sideEffect0, sideEffect1, test in Test).value

Normally sbt's task engine will reorder tasks based on the dependencies among the tasks,
and run as many tasks in parallel (See Custom settings and tasks for more details on this).
Def.sequential instead tries to run the tasks in the specified order.
However, the task engine will still deduplicate tasks. For instance, when foo is executed, it will only compile once,
even though test in Test depends on compile. #1817/#1001 by @eed3si9n

Nicer ways of declaring project settings

Now a Seq[Setting[_]] can be passed to Project.settings without the needs for "varargs expansion", ie. : _*

Instead of:

lazy val foo = project settings (sharedSettings: _*)

It is now possible to do:

lazy val foo = project settings sharedSettings

Also, Seq[Setting[_]] can be declared at the same level as individual settings in Project.settings, for instance:

lazy val foo = project settings (
  version := "1.0",

#1902 by @dwijnand

Bytecode Enhancers

sbt 0.13.8 adds an extension point whereby users can effectively manipulate java bytecode (.class files) before the
incremental compiler attempts to cache the classfile hashes. This allows libraries like ebean to function with sbt
without corrupting the compiler cache and rerunning compile every few seconds.

This splits the compile task into several subTasks:

  1. previousCompile: This task returns the previously persisted Analysis object for this project.
  2. compileIncremental: This is the core logic of compiling Scala/Java files together. This task actually does the
    work of compiling a project incrementally, including ensuring a minimum number of source files are compiled.
    After this method, all .class files that would be generated by scalac + javac will be available.
  3. manipulateByteCode: This is a stub task which takes the compileIncremental result and returns it.
    Plugins which need to manipulate bytecode are expected to override this task with their own implementation, ensuring
    to call the previous behavior.
  4. compile: This task depends on manipulateBytecode and then persists the Analysis object containing all
    incremental compiler information.

Here's an example of how to hook the new manipulateBytecode key in your own plugin:

manipulateBytecode in Compile := {
  val previous = (manipulateBytecode in Compile).value
  doManipulateBytecode(previous)  // Note: This must return a new Compiler.CompileResult with our changes.

See #1714 for the full details of the implementation.

Assets 2
You can’t perform that action at this time.