7 min read

Apache Maven 3 Cookbook

Apache Maven 3 Cookbook

Over 50 recipes towards optimal Java Software Engineering with Maven 3

       

Java has been the dominant enterprise programming platform for over a decade and a half. In many ways, it has shaped the way the industry does business, especially with the advent of the Internet and followed by cloud computing. It is very evolved and mature, and has good infrastructure support.

For all its successes, however, it has some serious problems competing with modern dynamic programming languages in the context of ease of programming, especially while getting started in the initial stages of a project.

An advantage that Java traditionally enjoyed over the likes of Python, Ruby, and so on is that a lot of enterprises were committed to Java Virtual Machine (JVM) as their platform due to its inherent advantages. This always worked in favor of the Java programming language.

However, all this has changed with modern languages such as Scala, Groovy, and so on supporting JVM bytecode, which made them compatible with existing enterprise infrastructure and assets. Furthermore, RIA (Rich Internet Applications) technology, such as Flex, never faced the JVM challenge in the first place due to the widespread adoption of the Flash Player.

Apache Maven’s flexible plugin-based architecture allows the tools to evolve with time and lends its benefits to developers and development teams that are keen to leverage this new breed of modern programming languages.

Integrating Scala development with Maven

Scala stands for “Scalable Language”. It is defined as a multi-paradigm programming language and has integrated support for object-oriented programming and functional programming.

It runs on the JVM and on Android. Furthermore, it can read existing Java libraries which give it a huge advantage in cases where there is a lot of existing code infrastructure in Java.

The Scala bytecode is in many ways, identical to the Java bytecode. In many cases, Scala generates more optimal byte-code than Java.

Twitter, Foursquare, and a whole bunch of exciting software startups have adopted Scala. Scala helped Twitter get over its scalability issues when the micro blogging pioneer first hit the mainstream and needed to scale-up as it served millions of new users each day

This is, of course, not to say that scalable applications can’t be built in pure Java. However, the Scala programming language features itself (such as pattern matching, concurrency, and Actors) and frameworks built on top of Scala (for example, Akka, GridGain, and so on.) allow application scalability with ease.

Below is an example of a popular sorting algorithm implemented in Scala:

def qsort: List[Int] => List[Int] = {
case Nil => Nil
case pivot :: tail =>
val (smaller, rest) = tail.partition(_ < pivot)
qsort(smaller) ::: pivot :: qsort(rest)
}


The creator of Scala, Martin Odersky, has given a number of popular talks and presentations examining Scala’s comparability. When Scala code is up against comparable code in other programming languages including Java, C#, Ruby, and so on, the conciseness of Scala really stands out.

The Scala implementation of quicksort in the preceding code demonstrates this very conciseness of Scala code.

While the Scala community recommends SBT (Simple Built Tool) for pure Scala projects, often you’ll be implementing modules in Scala while other modules of the project would have been built with Java. This is one of the strongest cases for using Maven in a multi-modular project with Java and Scala-based modules. It is probably the reason why SBT is more or less compatible with Maven’s conventions and even provides a feature for “Mavenizing” an existing SBT project.

Getting ready

You’ll need Apache Maven installed. The Maven version preferably should be Maven 3 but Maven 2.0.7 or higher is supported. JDK 1.5 or higher is recommended. Do note, installation of Scala is not required. Apache Maven will take care of the Scala dependency.

How to do it…

Generate the Scala project archetype:

$ mvn archetype:generate


This will show a list of available archetypes in which you need to select the archetype for a simple Scala project, which is scala-archetype-simple.

Maven interactive mode will also ask you for archetype version, groupId, artifactId, and other Maven project coordinates. This is the same step we’ve encountered in previous recipes. You can choose reasonable values for groupId, artifactId, and package. For me, the groupId was net.srirangan.packt.maven, artifactId was scalaexample, version was the default value, and package was the same as groupId. On completion, your terminal will look similar to the following lines:

[INFO] ————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————
[INFO] Total time: 1:38.142s
[INFO] Final Memory: 10M/114M
[INFO] ————————————————————


The completion of this operation has created a project folder with the same name as the project artifact ID. The project directory tree structure would look similar to this:

Folder PATH listing for volume OS
Volume serial number is 7C69-DF5D
C:.
└───src
├───main
│ └───scala
│ └───net
│ └───srirangan
│ └───packt
│ └───maven
│ └───App.scala
└───test
└───scala
└───samples
└───junit.scala
└───scalatest.scala
└───specs.scala


Also generated is a simple Hello World! Scala application–App.scala:

package net.srirangan.packt.maven
object App {
def foo(x : Array[String]) = x.foldLeft(“”)((a,b) => a + b)
def main(args : Array[String]) {
println( “Hello World!” )
println(“concat arguments = ” + foo(args))
}
}


The pom.xml file is configured in a way that integrated the build lifecycle with the Maven Scala plugin:

<build>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>

</plugin>
</plugins>
</build>


To compile the project, run:

$ mvn compile


To run the tests, use the default project lifecycle command:

$ mvn test


How it works…

If you inspect the Scala project pom.xml file that was generated, you would see dependencies defined for Scala: library, testing, specs, and scalatest.

<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.9.0-1
</version>
</dependency>
<dependency>
<groupId>org.scala-tools.testing</groupId>
<artifactId>specs_2.9.0-1</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
</dependencies>


The first dependency listed here is the Scala programming language itself, that is, org. scala-lang.scala-library. The other two dependencies are for running Scala tests. There may also be a fourth dependency which is not listed in the preceding code for I. It is unrelated to Scala.

Looking at the build settings and plugin configuration hereafter, we see that the source and test directories are being set to src/main/scala and src/test/scala respectively. The plugin execution is being bound to the compile and testCompile build phases.

<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.15.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-make:transitive</arg>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</
arg>
</args>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>


There’s more…

In addition to what was described up to now, the Maven Scala plugin has more features which meet the needs of most developers and development situations. The following table lists all goals made available by the Maven Scala plugin, their respective Apache Maven console commands, and brief explanations:

 

Goal

Maven command

Details

scala:compile

$ mvn scala:compile

Compiles the Scala source directory

scala:console

$ mvn scala:console

Launches the Scala REPL with all project dependencies made available

scala:doc

$ mvn scala:doc

Generates the documentation for all Scala sources

scala:help

$ mvn scala:help

Displays the Scala compiler help

scala:run

$ mvn scala:run

Executes a Scala class

scala:script

$ mvn scala:script

Executes a Scala script

scala:testCompile

$mvn scala:testCompile

Compiles the Scala test sources

LEAVE A REPLY

Please enter your comment!
Please enter your name here