Changing Ant Log Levels

I’ve never been a user of Ant’s <record> task. It has a few issues and I don’t find it convenient to use. Record does fill a definite need, however, where you want to debug just a small section of a build file.

I decided to approach this in a different way, with the following small Task

package com.codefeed.cmtasks;


import java.util.Vector;
import java.util.Iterator;

public class SetLogLevel extends Task {
    private int logLevel = -1;

    public void execute()
        if (logLevel == -1) {
            throw new BuildException("You must specify a log level");

        Vector listeners = this.getProject().getBuildListeners();
        for (Iterator i = listeners.iterator(); i.hasNext(); ) {
            BuildListener listener = (BuildListener);

            if (listener instanceof BuildLogger) {
                BuildLogger logger = (BuildLogger) listener;

    public void setLevel(Echo.EchoLevel level) {
        this.logLevel = level.getLevel();

This code simply finds any loggers listening to the build and changes their logging level. You can use it like this

    <setloglevel level="debug"/>
    <javac srcdir="${src.dir}"
    <setloglevel level="info"/>

This sets the logging level to debug for the compilation and then back to info. Note that there is currently no way to know what level was in effect when Ant is started, so if someone is running a quiet build you may not be popular.

I don’t know if there is anything out there that already does this but I don’t recall seeing it. I’ll probably put together a few of these utility tasks into a jar and make it available at some time in the future – mainly because I needed to play with the antlib feature in Ant.

Hail Storm

We had an amazing hail storm in Sydney yesterday afternoon. I’ve never seen anything like it in Sydney, having thankfully been missed by the really damaging storm of a few years ago. At one point, as the hail increased in size we went out to put something over our car and copped a few hailstones to the head. Man, they really hurt. I think this just serves to confirm my feelings about the changes to the climate.

I think that I, like many Sydneysiders, reached for the camera to record the oddity. As I’m still living in the age of film, I won’t get my shots for a little while, so I thought I’d point you all at James’ site which has a nice picture. Time to go digital?

VSIP Package Deployment

There is a rather timely article about VSIP package deployment on the Microsoft extensibility blog (Dr Ex). Due to some recent Clover.NET experiences I think there are a few additional points to be made.

Most of the problems we had revolved around the Microsoft.VisualStudio.VSIP.Helper.dll assembly. This assembly is not as well “controlled” as the VSIP interop assemblies. The beta versions of Clover.NET shipped with this assembly exactly as it comes with the VSIP Extras install – i.e. not modified at all. While it was not installed in Common7\IDE\PublicAssemblies, as Dr Ex. recommends, this dependency was a source of problems. In a few instances there was a conflict with an existing version of the assembly on the user’s machine.

In the end, we repackaged the whole Helper assembly into our own DLL to avoid conflicts with other VSIP packages. I’d be very careful about depending on the Helper DLL as it comes with VSIP Extras and would probably recommend you also repackage it, even if you do not change it.

Such assembly conflicts in a VSIP package are very difficult to diagnose because Visual Studio gives no indication whatsoever when a package fails to initialize. Some logging or an event viewer entry would be good. To diagnose these you need to have your user use debugCLR or the Visual Studio debugger to launch a separate Visual Studio instance. You need to trap any CLR exceptions and then try to initialize the package. VSIP packages are initialized on demand by the IDE, so you usually need to access some feature such as a menu item to activate the package. As the package initializes, the debugger will catch the CLR exception and you can sort out your package load errors.

Luckily for the Clover.NET development we had two cluey users who were able to help us isolate this issue.