Friday, January 4, 2008

I'll try to provide a mini-guide about maven for scala's project. For more info, go to maven home or plugin's home.

Introduction to maven

Maven is a builder like make or ant, written in java. It's a commande line tool, IDE (Eclipse, Netbeans, IDEA) have plugins to handle and integrate project powered by maven. It could be used to create lib (jar), webapps (ear) and any other type of "artifact". It prefers convention over configuration, and configuration over instruction. What that mean exactly ?

every action have a default configuration (= the convention).

every action is a goal defined into a plugin (aka mojo), and for common case, you will try to use existing plugin instead of calling (more) low level instruction (like copy file,...)

Your first scala project with maven

In the following, we will run maven for the first time. Maven download what it need to work from remote repositories, and cache the downloaded artifact into its local repository (default is $HOME/.m2/repository). It only download what it need for the requested phases/goals (lazy downloading). So the first runs could be very long.

Step 1: create a project

You could create a project skeleton with your favorite file system tools (following directory layout as below) or you could use archetypes. Maven Archetypes are project'skeleton that could be used to create new project.

In fact, the project is not empty it contains an helloworld application (App.scala) and a JUnit test (AppTest.scala).In the next step, you will request phase (or goals). The results will be put under your-proj-id/target directory. The target directory is the working directory where every plugin put the result of computation. If you want to clean up, request the goal "clean"

mvn clean

Step 2: compile the project

# only compilemvn compile

If it's the first time you use maven with scala, the build should failed with a message like

...[ERROR] FATAL ERROR[INFO]------------------------------------------------------------------------[INFO] The PluginDescriptor for the plugin Plugin [org.scala-tools:maven-scala-plugin] was not found.[INFO]...

Cause :

the pom.xml (autogenerated) doesn't specify wish version to use for maven-scala-plugin, so maven try to use the latest available localy, and none was previously downloaded.

Please refer to /home/dwayne/tmp/your-proj-id/target/surefire-reports for the individual test results.

BUILD FAILURE, it's not good! So read the log on console :

there is 2 tests and one of them failed

the failed test is the method testKO from the class your.proj.gid.AppTest

see the content of the directory .../your-proj-id/target/surefire-reports for details

So you could read the problem in .../your-proj-id/target/surefire-reports/your.proj.gid.AppTest.txt

...testKO(your.proj.gid.AppTest) Time elapsed: 0.01 sec <<< FAILURE!junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:47) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertTrue(Assert.java:27) at your.proj.gid.AppTest.testKO(AppTest.scala:26) at your.proj.gid.AppTest.testKO(AppTest.scala:26)...

So edit the test and fix it (it's easy), and rerun test until it pass.Why the empty project is created with a failed test? to check that test are running and are used.

Step 4: generate the jar

# compile + run test + generate the jarmvn package

If you fixed the test in Step 3, then a jar should be generated under the target directory. The jar doesn't contains the test classes, only the classes from src/main/scala/...

Step 5: start coding

add scala file under src/main/scala/... or src/test/scala/...

run the phases or goal you wish,...

if you need more lib (dependencies), edit the pom.xml and add <dependecy> node. By default you could declare dependency available on central repo (I suggest to use mvnrepository as a search engine in central repo), or in http://scala-tools.org/repo-releases/ (browse the directory, no search engine available :()

Conclusion

I expect this overlook and quick tutorial could help you to start playing with maven and scala. I plan to write other articles about "maven for scala" (about, the pom.xml and repositories). If you want to know more about maven and don't want to wai futur article, I suggest you browse the documentation of maven. I also suggest you to take a look at the maven-scala-plugin 2.x documentation, you'll see how to generate scaladoc, choose the scala version, or run a scala console with the project dependencies.

If you have question ask, If you want I detail some point here or in a futur article, ask.

short : Don't worry, this is a "normal" warning.long : archetype use velocity to generate project template. Velocity try replace ${...} by a "predefined/evaluated" value/expression. Maven also use the ${...} syntax in pom.xml to evaluate properties when you build. So when the pom.xml to generate use "properties", the archetype warn about undef expression when it try to generate the pom.xml. Those value are evaluate after the project generation, when you'll use the pom.xml to build your project.

I don't think maven can using sbaz repository. But it's possible to developpe an extension to maven to allow it to use sbaz.

I fact, I don't know a lot sbaz (IMHO, the doc a little obscur), so I can't really do a comparison and I could be wrong.So yes, there is probably a overlap between maven's repository and sbaz (maven's repository are older, and allow access to java library see mvnrepository.com as example).

I don't agree, when you say sbaz manage dependencies, from my understanding, sbaz allow you to upload/dowload library but doesn't manage dependencies. If in the pom.xml of my project, I say I need lib X in version vX, maven take care of the (transitive) dependencies of X, And I don't need to search in the doc or the Manifest of the lib, which other lib I need to install. And if later I upgrade to vX+1 and some dependencies are not more required by lib X, they'll be not added (and I don't need to remove then like with a ant build (without ivy)).