»
S
I
D
E
B
A
R
«
Maven with included Dependencies
Sep 4th, 2009 by Mike

One of the most common, and, in my opinion, valid criticism’s of Apache Maven is the way it handles dependencies.

The default way of doing dependencies in Maven is for a build to look for dependency jars in one of a specified number of places. If you don’t specify a location, it will start with your local Maven repository, then a stock set of online repositories (such as ibiblio).

What this means is that you can quickly and easily add a dependency to your project by just listing it in the POM, and Maven will frequently just go get it for you as required. For dependencies that don’t change rapidly (which is generally a bad idea for entirely separate reasons), the local copy is always used, so after the first download you don’t go get the jar again unless it changes.

The downside of this (and hence the basis for the criticism) is that your local repository is considered a cache, and is not checked in to your source control system. Maven aficionados believe that source control should be for what the name implies: source, not jars (which are an artifact, not source code). This is good, except in situations where the local repository is removed (as it’s a cache, and not “backed up” by being in source control) and you want to rebuild your project. Normally, no problem: Maven will simply go back out into the wilds of the internet and get your jars for you again. Except when it can’t, which is where the problem starts.

Let’s say your project depends on foo-1.0.jar, for the sake of discussion. Foo-1.0.jar is found in a repository at http://baz.com. No problem. Two months from now, you come back and make a change to your project, and your local repo doesn’t have foo-1.0.jar in it. Maven goes to get it for you, but baz.com has gone offline. Oops. Now you can’t build your project at all. Worse, let’s say you *do* find foo-1.0.jar, but it’s been updated. Granted, this is a gross violation of the version scheme, but as baz.com is not under your control, it *can* happen – and Murphy was an optimist.

The first level of defense against this is to have a local jar proxy that *is* backed up, like Nexus. Nexus not only provides a safe haven for the exact versions of Jars you need to build your project, but also proxies new jars automatically, when set up correctly. That way, once you use that external dependency, it’s available on the local proxy immediately forever more, in precisely the correct version.

This solution is so good, that I always consider Nexus and Maven to be two parts of one solution – as you don’t really have reliable and repeatable builds without Nexus in the mix.

Another way to go, however, is perhaps even more straightforward, and might be appropriate if you have a limited number of “internal” binary dependencies – that is, binary dependencies that you generate within your organization between projects.

This is the option I want to describe in this blog, and it takes a form very similar to the old Ant style of having a “lib” directory in your project, and checking jars into source control.

You simply create a directory (called lib or whatever you wish, but “lib” might be more standard), and put your jar dependencies in it. Then you refer to each dependency in your pom.xml file with a special syntax, like so:

    <dependency>
      <groupId>mygroup</groupId>
      <artifactId>myjar</artifactId>
      <version>1.0.0</version>
      <scope>system</scope>
      <systemPath>${basedir}/src/main/resources/lib/myjar-1.0.0.jar</systemPath>
    </dependency>

Now the myjar-1.0.0.jar will be on my classpath during compilation, easy as that. I can then check in that nicely versioned jar file, and have a fully self-contained project, while at the same time being able to leverage the power of Maven and it’s rich ecosystem of plugins. If you’re using the shade plugin, this is an excellent way to create a self-contained executable jar file containing all of your necessary dependencies in one shot, rather than having to worry about classpaths at runtime.

In web applications, you can do even better. By placing the dependency in the correct spot in your source tree, you can have it automatically included in the finished .war file, while at the same time finding it in your classpath during compile time, like so:

    <dependency>
      <groupId>xstream</groupId>
      <artifactId>xstream</artifactId>
      <version>1.3.1</version>
      <scope>system</scope>
      <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/xstream-1.3.1.jar</systemPath>
    </dependency>

This includes the xstream jar in my webapp. Every IDE that can digest a POM file (which include my 3 main ones, IntelliJ IDEA, Eclipse IDE and Netbeans) also automagically find the dependencies.

One minor constraint here is that you must use a *versioned* jar file – e.g. it must be named according to the artifact-version.jar pattern. I consider this a feature, not a limitation, as I’m a firm believer that all artifacts should be properly versioned, so I can tell what source code originally created them. Yes, I know that can be done internally, in a manifest or such, but I like to see the label on the outside of the box, so to speak.

As one colleague put it, now you can be assured of coming back to your project months or years later, even if you don’t have internet connectivity, and be able to build the darn thing again, without going off on a wild jar chase all over the internet.

This pattern can overcome a serious and legitimate objection to Maven, and might be appropriate in many situations. Give it a try, let me know what you think!

Scala and Java Together
May 18th, 2009 by Mike

Given a need to work towards more scalable systems, and to increase concurrency, many developers working in Java wonder what’s on the other side of the fence.

Languages such as Erlang and Haskell bring the functional programming style to the fore, as they essentially force you to think and write functionally – they simply don’t support (well, at least not easily) doing things in a non-functional fashion very easily.

The mental grinding of gears, however, can be considerable for developers coming from the Java (or C/C++) worlds in many cases, who have become familiar with the Object-oriented paradigm. An excellent solution might be to consider the best of both worlds: Scala.

I had the opportunity this weekend to renew my acquaintance with Scala, and to work on blending it with the old mainstay, Java. Scala runs on the JVM, so as you might expect, it can be combined pretty readily with Java – more cleanly than before, given some new Maven and IDE plugins.


IDE Support for Scala

My IDE of choice lately has been Netbeans, and sure enough, there’s a (beta) Scala plugin for Netbeans.

Installing this plugin gives me syntax-aware editing of Scala source, along with basic refactoring support. Here’s the obligatory “Hello, World” in Scala sitting happily in my Netbeans window, color-highlighted syntax and all:

Hello World in Scala inside Netbeans

Maven plugin
In order to organize my code, tests, and generally make life easier, I’ve used Maven to first generate the project, then created the code above (and some more, as we’ll see in a minute). I started with the regular “mvn archetype:generate” command to build my source directories just as for a Java project, then added a bit of Maven magic to the generated POM to use the Maven Scala plugin. Here’s the full POM:

POM Part 1

Lines 21-25 tell Maven where to find the actual Scala plugin
29-33 add the Scala libraries to our list of dependencies

POM Part 2

Lines 44 thru 48 add the Scala plugin itself to our build lifecycle

POM Part 3

Lines 58 thru 75 specify the lifecycle events we bind to for actually compiling first the Scala production code, then the tests.

When we open this POM with Netbeans, you’ll see we’ve got a folder defined for both our Scala sources and tests, and our regular folders for Java sources and tests:
POM Part 3

Calling Scala code from Java code

Now that we’ve got our project defined to contain both Scala and Java, let’s put them to work together. We can call our Scala code directly from Java just as if the objects involved were Java, like so:

HelloWorld.main(null)

The only class we’ve got defined with the name HelloWorld is the Scala version – but it looks like Java as far as our Java classes are concerned. (There are some things to keep in mind when doing more advanced types between the two, but if you keep your interfaces straightforward these edge cases don’t arise very often).

Calling Java code from Scala code

The reverse is also true: we can make use of the entire library of existing Java code out there from Scala, even easier than in the reverse direction, as the more sophisticated type system of Scala handles anything Java can throw at it. Let’s look at a good example: Using JUnit4 (a Java library) to test both Scala and Java code.

Using JUnit4 to test Scala

The simple and expressive JUnit library has implementations in a number of other languages, but in the case of Scala and Java, the connection is so close we don’t really need a Scala version at all – we can use JUnit directly from a test written in Scala, as described below.

With the test written in Scala…

Here we see a Scala test, DogTest, running from within Netbeans (using Maven).

Dog Test

(Yes, the DogTest class is actually defined in a file called AppTest.scala – perfectly valid in Scala)

The results can be seen in the lower window (printing “Hello, World”).

As you can see, we’re using JUnit4, even with it’s Annotations, despite the fact the test is written in Scala.

With the test written in Java…

Now let’s go the other way: This is simply a matter of writing a regular Java Junit4 test, except instead of calling a Java class we’re actually calling our Scala class again.

In this example, you can see we’re using JUnit 4 in the usual way, but on line 20 and 25 we make reference directly to Scala classes, just as if they were regular Java classes. (The IDE shows them underlined due to a classpath issue, but they compile just fine in any case – the Netbeans Scala support is still Beta, after all).

As you can see, these two languages blend very smoothly in many respects, even more so than one of my other favorite combinations, Java and JRuby.

Although it is cool to see Scala and Java in a single project, I probably wouldn’t do it this way for production code. A cleaner approach might be to write a pure Scala module that is then a dependency of the Java project (or vice-versa), using Mavens ability to handle cross-project SNAPSHOT dependencies to break our work up into more manageable chunks.

We can then call Scala functionality from any Java application, even webapps, while still working with all of the exact same tools and procedures we’re used to for pure Java projects. Of course, we can also go the other way: write Scala web applications (perhaps with the excellent Lift framework) and call existing Java functionality, just as easily.

I predict Scala will be used in more and more Java (and other JVM-based language) projects where the advantages of functional programming and high concurency are necessary, while at the same time preserving the massive investment in Java many of us already have.

Long live the happy couple!

»  Substance: WordPress   »  Style: Ahren Ahimsa