Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Thursday, 28 May 2009

IVY

One of the things I have been using lately is Ivy.

In the past I have had to use Maven on various projects - and must admit, I hated it. Whilst it might be really trendy at the moment to use "convention over configuration" to me doesn't sit well in a build system. Several times what I've needed to do hasn't fit into the Maven model and I really dislike having to "wedge things in" to appease a tool.

But one thing I did like was the dependency management.

Well Ivy gives you this, without all the other stuff you don't need. You use it from Ant, its clean and easy to manage dependencies, and it leverages the existing Maven repositories.

And something else neat is the ability to bootstrap it from Ant, so you don't have to rely on someone having Ivy already installed, you can install it from within your Ant build and use it on the fly.

What I do is this, create an install-ivy.xml with the following contents:

<project ivy="antlib:org.apache.ivy.ant">
  <property name="ivy.install.version" value="2.1.0-rc1">
  <property name="ivy.jar.dir" value="${basedir}/.ivy">
  <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar">

  <target name="download-ivy" unless="skip.download">
    <mkdir dir="${ivy.jar.dir}">
    <get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/>
  </target>

  <target name="install-ivy" depends="download-ivy">
    <path id="ivy.lib.path">
      <fileset dir="${ivy.jar.dir}" includes="*.jar">
    </path>
    <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path">
  </target>

  <target name="clean-ivy">
    <delete dir="${ivy.jar.dir}">
  </target>

  <target name="clean-ivy-cache" depends="install-ivy">
    <ivy:cleancache>
  </target>

 </project>
Then in the build.xml I add an:

    <import file="install-ivy.xml">
Then have a target like:

  <target name="resolve" depends="prepare,install-ivy">
    <ivy:retrieve>
  </target>
Then its just a matter of setting up your ivy.xml with your dependencies, which could be something simple like:

<ivy-module version="2.0">
  <info organisation="org.apache" module="hello-ivy">
  <dependencies>
    <dependency org="com.thoughtworks.xstream" name="xstream" rev="1.3.1">
    <dependency org="commons-lang" name="commons-lang" rev="2.4">
    <dependency org="junit" name="junit" rev="4.5">
    <dependency org="org.mockito" name="mockito-all" rev="1.7">
  </dependencies>
</ivy-module>

One of the good things I find is that, I work on a variety of machines, and I don't need to install ivy, my build scripts do it for me as and when.

Wednesday, 22 April 2009

URIPlay is now OpenSource

A little late but URIplay is now available as OpenSource, the BBC RAD Team has made the code available under the Apache 2.0 license

URIplay is a name service for media content, giving each file a URI and a simple description. Think of it as DNS for media. The service is not intended to be used directly by viewers. Like DNS, it works behind the scenes to make things easier.

You can see a simple demo here: http://open.bbc.co.uk/rad/projects/uriplay

The code has been picked up and is already evolving here:
http://uriplay.org

Tuesday, 14 April 2009

Fluent Java Interface for generating HTML

Am very happy to see that Alistair Jones (of How Big is my Potato fame) has produced a neat Fluent Interface for generating HTML from Java: http://code.google.com/p/hypirinha/wiki/Tutorial

Monday, 2 March 2009

Using Groovy and GUnit to test Java 'privately'

Normally if I am writing a class and find I need access to a private field in order to test correctly then I take it as a smell - something not quite right with the design. But every now and then I fail to find a way to change the design without corrupting its intent.

Now I know you can use reflection in Java to access private fields, but its a bit clunky. But recently I have been reading about Groovy, and found that it gives you full access to all your Java objects, but allows you to ignore private specifiers.
So as an example, say I have a counter class, one which allows users to get the next value of the counter, but cannot provide anyway of altering the counter for that would invalidate its purpose.

package net.usersource.example;

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
   private final AtomicInteger counter;

   public Counter() {
       counter = new AtomicInteger(0);
   }

   public int getNext() {
       return ensuringValueDoesNotRollIntoNegativeValues(counter.incrementAndGet());
   }

   private int ensuringValueDoesNotRollIntoNegativeValues(int value) {
       if( value < 0 ) {
            if( counter.compareAndSet(value, 0) ) {
                return 0;
            }
            else {
                return getNext();
            }
        }
        return value;
    }
}
Now, how do I test this without calling getNext() until it reaches Integer.MAX_VALUE? Do you know just how big MAX_VALUE really is, and how long that will take? Thats not really an option - so I need somehow to change the underlying counter.

Now I could do that with reflection, but I can do it much simpler using Groovy (which if you look closely, especially the way I have written it, looks like java) ...

package net.usersource.example

import org.junit.Test;
import org.junit.Assert;
import java.lang.Integer;

public class CounterTest {
    @Test
    public void verifyFirstObtainedCounterValueIsOne() {
        Counter c = new Counter();
        Assert.assertEquals( c.getNext(), 1 );
    }

    @Test
    public void verifyThatAtMaxIntTheNextValueIsZero() {
        Counter c = new Counter();
        c.counter.set(Integer.MAX_VALUE-1);
        Assert.assertEquals( Integer.MAX_VALUE, c.getNext() );
        Assert.assertEquals( 0, c.getNext() );
    }
}
This was TDD'd so I only knew the solution thanks to the test.

Unfortunately I have found some issues with the Eclipse Groovy Plugin - its auto-completion is a bit zealous in someways (wants to try and match everything bringing your machine to a crawl) and ignorant in others (not matching in imports). Also the GUnit results were reporting exceptions the line above the line with the issue - which caused me some confusion initially, and I need to investigate that further.

But to me this is a neat way of testing Java code, by stepping out of Java to something that makes it easier, whilst staying on the JVM.