Maven tips and Tricks: Avoid running tests twice

Sometimes you may find that your tests are run twice, once to make
the report for the site (thus not breaking the build if they fail) and
second time to create a jar, war or any other artifact, and probably in
this step you want the build to break if tests don’t succeed. This is
very common in a continuous integration scenario where the machine with
CruiseControl or any other CI tool deploys the site and generated
artifacts.

My suggestion is to create a goal in your maven.xml like this

    <goal name="continuousintegration">
        <attainGoal name="clean"/>
        <attainGoal name="site:deploy"/>
        <!-- avoid running tests again -->
        <j:if test="${maven.test.failure}">
          <fail message="There were test failures."/>
        </j:if>
        <j:set var="maven.test.skip" value="true"/>
        <attainGoal name="jar:deploy"/>
        <j:set var="maven.test.skip" value="false"/>
    </goal>

The trick is checking the maven.test.failure property after creating
the site, if it’s true the build has to fail and if it’s false you can
skip tests in next steps.

Maven tips and Tricks: Perforce

Lately I had the bad time to use the Perforce SCM system. I created a maven goal to sync (=cvs update) my sources from the SCM.

You need:

  • jakarta oro as a dependency in your project.xml and loaded by the root classloader.
        <!--
         | Oro is needed by the Perforce tasks and needs to be loaded
         | by the root classloader
         +-->
        <dependency>
            <groupId>oro</groupId>
            <artifactId>oro</artifactId>
            <version>2.0.8</version>
            <properties>
                <classloader>root</classloader>
            </properties>
        </dependency>
  • The actual goal in maven.xml
        <!-- perforce -->
        <goal name="p4sync">
            <p4sync view="//depot/whatever/..." />
        </goal>

You can check all the perforce ant tasks you can use besides p4sync.

Cobertura, an open source alternative to Clover

Cobertura is a free Java tool that calculates the percentage of code
accessed by tests. It can be used to identify which parts of your
Java program are lacking test coverage. It is based on jcoverage, but more actively developed.

I will talk about the maven cobertura plugin,
after releasing the first two versions (7/11 and 7/21) you can have
cool reports about test coverage and the ability to see all the classes
that don’t meet your minimum coverage criteria, both at line and branch
level.

The first report about code coverage is pretty similar to the one provided by Clover, but the second one
makes the difference, not provided by clover and in fact neither by
cobertura ant tasks, just the maven plugin. Another interested feature
to be used for instance in conjuction with a continuos integration tool
as CruiseControl is the option to make the build fail if any of the
classes test coverage fails below a threshold you can set. AFAIK clover
only allows to fail the test if the overall code coverage doesn’t meet
the requirements, not class by class, which is very convenient.

To use it in your maven projects you can add the dependency to the plugin
        <dependency>
            <groupId>maven-plugins</groupId>
            <artifactId>maven-cobertura-plugin</artifactId>
            <version>1.1</version>
            <type>plugin</type>
        </dependency>
and the report
        <report>maven-cobertura-plugin</report>

I hope you find it useful.

Inheriting annotations from implemented interfaces

In relation to Rick Hightower entry on annotations and inheritance I also checked if annotations on implemented interfaces are accesible
from the class implementing them. The answer is NO, neither using the
@Inherited annotation on the annotation class. The only way is getting
the implemented interfaces and iterate over them to see if they have
annotations.

public class AnnotationTest extends TestCase {

    @Retention(RetentionPolicy.RUNTIME) // This makes the annotation available at runtime
    @Inherited
    public static @interface Developer {
        String name();

        String email() default “somebody@somewhere.com”;

        int rank() default 1;
    }

    // Using the annotation to decorate a class and a method
    @Developer(name = “RickHightower”)
    interface MyInterface {
        @Developer(name = “ScottFauerbach”, email = “foobar@foo.com”)
        void myMethod();
    }

    class MyClassSub implements MyInterface {
        
        public void myMethod() {
            // …
        }
    }

    // Testing the annotation
    public void testAnnotation() throws Exception {
        assertFalse (MyClassSub.class.isAnnotationPresent(Developer.class));
        Method method2 = MyClassSub.class.getMethod(“myMethod”, (Class[]) null);
        assertFalse (method2.isAnnotationPresent(Developer.class));
        
        Class[] interfaces = MyClassSub.class.getInterfaces();
        boolean annotationPresent = false;
        for (Class iClass : interfaces) {
            if (iClass.isAnnotationPresent(Developer.class)) {
                   
annotationPresent = true;
                    break;
            }
        }
        assertTrue(annotationPresent);
    }
}

Spring Framework 1.2.2 released

Juergen has annonced the release of Spring 1.2.2, which I’ll make
available for maven users in a few hours through the central repository
at ibiblio. This has came out before having time to finish the Maven 2
POMs for 1.2.1, so I’ll try to update them to 1.2.2 asap.

Dear Spring community,

I’m pleased to announce that Spring 1.2.2 has just been released. This is a
bugfix and minor enhancement release. It also provides a unified basis for
the upcoming Spring WebFlow release candidate.

Besides refinements in the JTA transaction synchronization and SQLException
translation, this release introduces a variety of internal refactorings and
new helper classes. Furthermore, support for JDK 1.5’s XML-based properties
format has been added to all relevant Spring classes.

We have also extended our reference documentation in various areas. Most
importantly, it covers JDO, TopLink, OJB, and JCA CCI now.

Cheers,

Juergen