Tomer Gabel's annoying spot on the 'net RSS 2.0
# Monday, 11 February 2013

This is the second post of a two-parter. Please read part 1 for context and additional information.

3rd Party Libraries

As mentioned in part 1, Scala is not binary backwards-compatible between major releases. Although code compiled with 2.10 may work properly with libraries compiled against 2.9.x, this is hardly recommended and may result in a lot of subtle error conditions at runtime that are hard to track down. As a result, the recommended practice is to upgrade all Scala dependencies to versions compiled against 2.10. Fortunately the Scala ecosystem is very active, so most common libraries had 2.10 builds on announcement day, but you are still likely to encounter libraries that need to be upgraded because:

  • They're lagging behind the Scala release schedule and simply haven't released 2.10-compatible binaries (fortunately, this seems to be extremely rare; in practice all our dependencies were otherwise resolved);
  • The specific version you're using does not have a 2.10-compatible release and likely never will (Squeryl 0.9.5-2);
  • A 2.10-compatible official release is out but hasn't yet been published to the central repository (Scalatra 2.0.5).

My experience shows that with a bit of dilligence, practically all our (myriad) dependencies were fairly easy to migrate to 2.10. In most cases this simply entails switching to the appropriate artifact ID suffix (_2.10 instead of _2.9.2, see part 1 for associated rant), in other cases I had to upgrade to a later official release and in rare cases I had to dig in and replace a dependency with an appropriate fork or snapshot version. Here is a list of migration notes for some of our dependencies:

LibraryPreviousNew versionComments
Scala-Time0.6nscala-time 0.2 The original library appears to be abandoned and was forked on GitHub.
The package changed from org.scala-tools.time to com.github.nscala-time.time 
ScalaMock2.43.0.1The 3.x series runs natively on Scala 2.10 without proxy factories and the like. Syntax is a bit odd but works like a charm.
The ScalaTest integration is compiled against ScalaTest 2.0-M5b, which forced us to upgrade. 
ScalaTest1.82.0-M5b Minor API changes: SpecFunSpec, parameters changed in
Squeryl 0.9.5-2 0.9.5-6  
Argot 0.4 1.0.0  
Scala I/O 0.4.1-seq 0.4.2  
Lift JSON (+ext)2.4 2.5-M4  
Lift Facebook 2.4 2.5-SNAPSHOT Had to exclude net.liftweb:lift-webkit_2.10 to avoid dependency conflicts
Akka2.0.4 2.1 Scheduling now requires an implicit ExecutionContext. See migration guide for details. 
Scalatra2.0.4 2.0.5-SNAPSHOT Official 2.0.5 is out, but has not yet shown up on the central repository, so I ended up going with the (frozen) 2.0.5 snapshot artifacts
Scalatra 2.1.1 2.2.0 scalatra-akka module has been folded back into the core artifact as of 2.2.0.
Graph for Scala1.  


Scala Library Changes

The Scala class library itself has a number of changes you ought to be aware of before migrating to 2.10. The really big change is that Scala actors are deprecated in favor of Akka. You can still use them by importing the scala-actors artifact from the Scala 2.10 distribution, but it is recommended to migrate fully to the new actor system as this is also likely to be obsoleted by 2.10.1. The gentle folk at Typesafe have provided a very comprehensive migration guide to assist your efforts. 

The less prevasive API changes we ran into include:

  • List.elements is deprecated in favor of List.iterator;
  • TraversableOnce.toIndexedSeq no longer takes a type argument. This was actually quite pervasive in our codebase, causing plenty of compilation errors, and is easily worked around by removing the type parameter (which is extraneous to begin with);
  • Scala actors' Actor.receive method is now public (previously protected). This had to be rectified in pretty much all of our existing actors by removing the protected modifer;
  • Occasional subtle API changes requiring minor code fixes. For example, see this question on StackOverflow.


Opinions differ among members of our team - some predicted that the migration process will be much more complex whereas personally, given the relatively high level of maturity I've come to depend on in the 2.9 series, the migration process actually ended up being significantly harder than I anticipated. Particularly disconcerting were the occasional compiler failures which took a lot of time to track down. Practically speaking, though, the whole migration process took less than 3 days (including documentation), did not involve additional teammates, and all problems were either resolved or worked around rather quickly. The Typesafe compiler team has been very helpful in analyzing and resolving the single bona-fide compiler bug we've run into, and the community as a whole (on Stack Overflow, Google Groups and elsewhere) was also extremely supportive and helpful.

On the whole, am I happy with the process? So-so. There is nothing here an experienced Scala developer should have serious trouble with, but it will take a lot more stability and predictability for Scala to gain mainstream acceptance in the industry, and that includes a much easier and more robust migration path to upcoming releases (yes, that includes migrating from 2.10 to 2.11 when it comes along). That being said, Scala has been a terrific language to work with in the last couple of years, and the new features in 2.10 (particularly reflection, macros and string interpolation) should make this an extremely worthwhile upgrade. We still have a lot of regression testing to do on the new version, and if anything interesting pops up I'll be sure to post about it separately (or bitch about it on Twitter...)

Monday, 11 February 2013 16:33:11 (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Scala
Send mail to the author(s) Be afraid.
<2017 March>
All Content © 2017, Tomer Gabel
Based on the Business theme for dasBlog created by Christoph De Baene (delarou)