wgx731's Technical Blog

Programmer @ National University Of Singapore.

More Experience From Play!

| Comments

I have been working on Play! for more than 1 month, so it’s time for me to blog about some new issues I have faced so far.

The dependency issue

For any software engineering project, one of the biggest issues for developers is to resolve dependency. Play! uses sbt to as the build tool. Therefore build.sbt file is where you can specify what other 3rd party libraries you want to use in your project. Sometimes, it’s really hard for you to figure out which 3rd party library has added problem to your project. Then you will need help from sbt-dependency-graph plugin. what-depends-on <organization> <module> <revision> command is very useful. :)

Let’s take a look at the 2 build.sbt files below, see if you can spot any difference?

build.sbt-1
1
2
3
4
5
6
7
8
9
libraryDependencies ++= Seq(
    javaJdbc,
    javaJpa,
    cache,
    "org.apache.hadoop" % "hadoop-common" % "2.0.0-cdh4.4.0",
    "org.mockito" % "mockito-core" % "1.9.5" % "test" exclude("org.hamcrest", "hamcrest-core"),
    "com.github.dreamhead" % "moco-core" % "0.9.2" % "test" exclude("org.slf4j", "slf4j-simple"),
    "com.github.dreamhead" % "moco-runner" % "0.9.2" % "test"
)
build.sbt-2
1
2
3
4
5
6
7
8
9
libraryDependencies ++= Seq(
    javaJdbc,
    javaJpa,
    cache,
    "org.apache.hadoop" % "hadoop-common" % "2.0.0-cdh4.4.0" intransitive(),
    "org.mockito" % "mockito-core" % "1.9.5" % "test" exclude("org.hamcrest", "hamcrest-core"),
    "com.github.dreamhead" % "moco-core" % "0.9.2" % "test" exclude("org.slf4j", "slf4j-simple"),
    "com.github.dreamhead" % "moco-runner" % "0.9.2" % "test"
)

The interesting part is that, if you use build.sbt-1 file, you will get a famous NoSuchMethodError: org.hamcrest.Matcher.describeMismatch Error when your test fails, but build.sbt-2 works fine. So what’s the magic here? Seems like intransitive() saves me. Please check more details about intransitive here. And by the way, the pom.xml for "org.apache.hadoop" % "hadoop-common" % "2.0.0-cdh4.4.0" must have some wrong settings which caused the hamcrest issue I mentioned above. And if you take a look at source code of JavaHamcrest here, it’s also interesting how CoreMatchers class is created from a xml file, I think that might be the source issue of NoSuchMethodError. Luckily, this issue has been solved after playing around with the built.sbt file.

jacoco4sbt parallel issue

Actually, it’s not really an issue, but rather a wrong setting from my side. As stated on jacoco4sbt wiki page, by default, parallelExecution is set to true, but this will cause problem during Play! test which need to start a TestServer, as you may encounter problems like java.net.BindException: Address already in use. The tip is to add parallelExecution in jacoco.Config := false in your build.sbt file. Read the documentation carefully before you use the library.

At last, I have a small question about the compile process for Play! and sbt, it usually uses up to around 300% CPU (from top) on my Intel i5 4 core computer, and it really takes a long time (around 1 minute) to compile for a small project. Is this sbt issue or Scala issue or Play! issue? Anyone knows the answer please add a comment below. Thank you very much.

Comments