Archive

Posts Tagged ‘maven’

Buildozer 1.0.0-alpha-5 released

May 23rd, 2010 1 comment

Next version of “buildozer” is out.
Buildozer is a tool for simplifying transitive builds on modules with SNAPSHOT dependencies. It especially simplifies propagation of code changes from changed module(s) to those depending on them, while skipping builds of unaffected ones.

Installation instructions are available here. Project main web is http://buildbox.sf.net/buildozer.

Changes since version 1.0.0-alpha-4

New features:

  • FAILED modules are not rebuilt unless changed (or their dependencies changed)
  • added command “doall” pretending that all modules have changed = full rebuild

Fixes:

  • stanalone jar installer – fixed NPE in artifact downloading
  • return nonzero exit code on failure

Improvements:

  • log file and failure indicator stored in subdir of repository’s installation target
  • added option –version, both in standard and in xml format
  • simplified the way of listing installed artifact of a module (not using special mojo on mvn commandline)

Feedback

Users can share their experience

or contribute any other way – some hints are here.

How to build a ZIP output artifact in Maven

October 22nd, 2009 2 comments

It’s quite a common situation that you have a bunch of files, most or all of them committed in svn, and need to make a release of this so that it can be reused with the Maven’s dependency mechanism.

There are several ways how to accomplish that:

  • use maven-assembly-plugin
  • use maven-antrun-plugin to build and build-helper-maven-plugin to attach
  • create custom plugin that handles both packaging and attaching

Each of them has its advantages in some situations, but my favorite is the second option for most cases.

Real life example – artifact with various svn output files

In some of my projects, I need to check that the code works properly with xml output files from Subversion. I could easily put such files among test resources, but the it would be there many times, and I would always have to check if it is “representative” enough etc.

So I decided to create a module, which will create the data during its build (see the maven-antrun-plugin).

These data are packaged into a zip file which is then marked as output artifact with type “zip” (see the build-helper-maven-plugin).

Look at this pom excerpt  (complete pom.xml is available here):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <groupId>net.sf.buildbox.testdata</groupId>
  <artifactId>svn-mvn-testdata</artifactId>
  <version>1-SNAPSHOT</version>
  <packaging>pom</packaging>
...
  <build>
    <outputDirectory>target/output</outputDirectory>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.3</version>
        <executions>
          <execution>
... phase=package, goal=run
            <configuration>
              <tasks>
                <mkdir dir="${project.build.outputDirectory}"/>
                <exec executable="svn" failonerror="true" dir="${project.build.outputDirectory}" taskname="svn-checkout">
...
                </exec>
...
                <zip destfile="${project.build.directory}/${project.build.finalName}.zip">
...
                </zip>
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.2</version>
        <executions>
... phase=package, goal=attach-artifact
            <configuration>
              <artifacts>
                <artifact>
                  <file>${project.build.directory}/${project.build.finalName}.zip</file>
                  <type>zip</type>
                </artifact>
              </artifacts>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

What are the advantages over other mentioned alternatives ?

  • extensibility – the “generator” part is straightforward, so, as long as ant is enough for us it costs just a few lines of ant code
  • compactness – we could reach similar result with several invocations of exec-maven-plugin for preparing data, plus maven-assembly-plugin to pack and attach it, but that would be far far more verbose and harder to maintain

Just for completenes, it’s good to say when using the other approaches is more relevant:

  • custom maven plugin – when the algorithm for generating data is too complex to be written in ant, or needs other sources that are not reachable from antrun, like dependencies
  • maven-assembly-plugin – when we need to control file permissions in tgz/gz packages while running the build on windows

Do you have experience in this area ? Then please post your comments…

Categories: Deldorado Tags: ,

Generating temporary files in junit tests

July 6th, 2009 8 comments

It is often useful to create some temporary files inside a unit test. Basically it is not a problem, because junit does not limit you in such thing; you might simply use a “current” directory to store such files, and it usually works. However, different frameworks invoking JUnit use different “current” directories, which makes it difficult to:

  • locate the temporary files for debugging purposes
  • remove them between test re-executions
  • reference static (committed) files using a relative path

I personally always use at least two such frameworks – Maven and an IDE – and I would really like to see the data always at the same place, and reference committed files using always the same relative path.
Besides that, I require that any intermediate data in my Maven modules are generated under the “target” subdirectory (or, more precisely, under ${project.build.directory}), because

  • this gives me the comfort of cleaning them as part of “mvn clean test” command without other manual specification of directories to erase
  • it does not bloat module directory structure with version-uncontrolled files.

To accomplish this, we cannot use the “current” directory; instead, we need to compute one that is always the same, and use in later in the unit test.

So it seems to be neccessary to write a method that somehow computes that “stable” directory:

public static File computeTestDataRoot()

How can it be implemented ? The key is that they execute tests from compiled classes stored in a directory, not in a jar file. We can therefore use a resource laying among these tests – which can even be one of test classes (there is always at least one, the one for which we need it), and we use it to locate root of the test classes. In Maven, it is by default “target/test-classes”. To extend this nice convention, we will make the method return “target/test-data”, a non-existent directory which can be used by tests to generate their stuff.

public static File computeTestDataRoot(Class anyTestClass) {
  final String clsUri = anyTestClass.getName().replace('.','/') + ".class";
  final URL url = anyTestClass.getClassLoader().getResource(clsUri);
  final String clsPath = url.getPath();
  final File root = new File(clsPath.substring(0, clsPath.length() - clsUri.length()));
  final File clsFile = new File(root, clsUri);
  return new File(root.getParentFile(), "test-data");
}

Note that we need to pass an argument to our method – the calling test class. It is a little price for getting consistent test data directory – and probably unavoidable.

Categories: Deldorado Tags: , ,

bbx:1.0.0-alpha-5 released – BuildoZER, colorado and the others

July 3rd, 2009 No comments

The cross-platform development tool suite “bbx”, has been recently released in version 1.0.0-alpha-5.
It contains several development-oriented tools, supporting especially Maven builds:

  • BuildoZER (zer) – a tool to perform transitive builds of Maven modules
  • colorado – simple log output colorizer (Linux only for now)
  • zcd – to navigate through directories by module name (artifactId from pom.xml)
  • bbx – an extensible ant frontend with argument parsing, pom-based dependency support and more

It is still an alpha-quality release, but the tools are already very handy.

Categories: Deldorado Tags: ,

How to force explicit version specification

January 30th, 2009 6 comments
It is often necessary to reproduce older builds. Either because you need to branch it and make a small bugfix, or to perform sanity check of your constantly evolving build infrastructure.

Then you often discover that Maven’s cool feature, to automagically use LATEST version of plugins by default, is not that cool… new versions may be incompatible with your specific usecase, or broken completely, etc etc (I suffered this experience with maven-war-plugin version 2.1-alpha-2 as I reported in [#MWAR-181]).

Yes, you can work hard and define a corporate pom that presets version of all plugins you use. That’s good, but who will remember to do that when a new plugin will be added to build ? Most people won’t.

Fortunately, there is a way to keep you reminded: forbid download of “*metadata.xml” files and that’s it. Maven uses this file to determine list of available versions, whenever you use a non-specific version like RELEASE or LATEST, which is the case of plugin artifacts. Without such metadata, maven fails,saying that it cannot find any version – so you immediately know that your build would be irreproducible otherwise and that it is time to extend your corporate pom.

On Apache server, you can accomplish that using mod_rewrite – just add something like this to httpd.conf:

...
RewriteEngine on

# strict repo:
RewriteRule ^/maven2-strict/.*metadata\.xml$ - [G,L]
RewriteRule ^/maven2-strict/(.*) http://my.physical.repo:8081/nexus/content/groups/public/$1    [P,L]
...

and, of course, use this in your settings.xml:

...
 <mirror>
   <id>internalRepository</id>
   <mirrorOf>*</mirrorOf>
   <name>inhouse aggregated repo</name>
   <url>http://my.intranet.server/maven2-strict</url>
 </mirror>
...

Update:

As Brian Fox from Sonatype noted, there are better alternatives to reach reproducibility:

  • Nexus users can use directly its own administration interface to setup the redirect
  • even better is, to use maven-enforcer-plugin with its requirePluginVersions rule; it has no impact on using commandline mojos with abbreviations

Read comments for more details.

Categories: Deldorado Tags: , ,

buildbox@mvnrepository

January 18th, 2008 No comments

Very good news today: the internal repository of the buildbox project is now automatically rsynced to Maven Central Repository. This gives me an option to release artifacts in a way that allows others to use them without any special configuration in Maven.
I am going to publish only releases that make sense, so there will not be new versions from me every second day. I am just happy that I have a way to publish my artifacts :)
To see the buildbox artifacts, click here.

Categories: Deldorado Tags: ,

Why it is good to declare your dependencies

July 29th, 2007 No comments

When you build an application, with complexity exceeding “Hello, World” example, you usually need to use classes and other resources from another library. Then you have several options how to do it:

  1. (worst one) copy the sources of this library to your project. This is extremely bad idea; id disconnects you from the development of original code. Fortunately, AFAIK, this is not widely used practice
  2. (very bad too) copy the necessary libraries in binary form to your version control. This practice is widely used and is main subject of this article.
  3. the best and only right one is, to declare your dependency using a logical identification, and leave the rest up to your build tool.

The advantages of declaring dependencies instead of copying them into your project might be obvious to people who already use it, but the others might appreciate that:

  • you can easily switch used version, without having to download any jar and properly place the resources
  • you don’t waste your version control server’s disk space by abusing it for binaries
  • you know and use the version of such a dependency in “live” form – you control it
  • you can even define or use some transitive algorithm to select the right version, if multiple of your dependencies depend on various versions of the same artifact
  • you can be very sure that you use a version published by its vendor, and not one hacked or tweaked somehow

Maven is a build tool using this approach. However, if you prefer ant, you can still work with Maven artifacts in the huge Maven repository, by using Ant tasks for Maven.

Another option seems to be using Ivy. I personally don’t have any experience with this, but AFAIK they use dependency declarations and reuse the Maven central repository mentioned above.

And of course, there are (were) DevTools with its “ante”, a build tool based on ant. It uses project descriptor with identity, dependencies, tests, and other necessary build stuff described in a declarative way. It’s a proprietary tool and only ex-Eurotel people have the chance to know it.

Personally, what I find best at explicitly declaring dependencies is that it allows other build-related tools to use that information and produce effective build schedules, reports etc. This might be offtopic if you work on your diploma task, but in serious long-term software development, it soon becomes unavoidable.

So my recommendation is: declare your dependencies in a project descriptor. Never store it as a binary under your project directory!

Categories: Deldorado Tags: