Finally trying out Maven 2

While many people are saying that Maven 2 is really a terrible terrible tool and stupid for great, great many reasons, recently I have finally been trying out Maven when I had to reorganize a generic algorithm into a separate library and I wanted to end up with a nice build process and managed dependencies.

On Mac OS X, Maven 2 can be installed easily via MacPorts. I started with the getting started guide and created my library project called mylib from the command line

$ mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.mycompany.mylib -DartifactId=mylib

This has created a directory named mylib for the new project, and this directory contains a file named pom.xml. After moving my sources to ${basedir}/src/main/java, I had to resolve some external dependencies. My library is only dependent on Commons IO, Commons Lang and Commons Logging, so I added the following to the pom.xml under dependencies.

<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
<scope>compile</scope>
</dependency>

For Java 5 source compatibility you will have to add the following lines to your pom.xml:

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>

Note that when compiling the application sources for the first time with

$ mvn compile

Maven will need to download all the plugins and related dependencies.

After successfully compiling the library’s sources, I’ve put my JUnit tests in the directory ${basedir}/src/test/java. They can be executed with

$ mvn test

In order to use Log4J logging during tests, put the log4j.xml file in the ${basedir}/src/test/config directory. Then add the following lines to the build/testResources element in your pom.xml:

<testResources>
<testResource>
<directory>src/test/config</directory>
<includes>
<include>log4j.xml</include>
</includes>
</testResource>
</testResources>

A final tip: if you are using Eclipse, Maven can create Eclipse projects for you with

$ mvn eclipse:eclipse

which can then be imported into Eclipse as existing projects.

So far I’m quite pleased with Maven: I managed to create a new project for my library in no time (< 5 minutes), with a nice build process and dependency management. IMO much better than manually copying build.xml files from other projects and third-party jars around. 🙂

ZGRViewer, a GraphViz/DOT Viewer

Description from the homepage: “ZGRViewer is a 2.5D graph visualizer implemented in Java and based upon the Zoomable Visual Transformation Machine. It is specifically aimed at displaying graphs expressed using the DOT language from AT&T GraphViz and processed by programs dot, neato or others such as twopi.”

Occasionally I have to deal with large graphs for some recursive automatons in the context of a dynamic programming algorithm. My automaton class is able to return a dot-style representation which describes the finite automaton, and it turns out that ZGRViewer excels in handling such large graphs by providing smooth zooming and easy navigation in the visualized graph. I found that because of the use of SVG it is much less memory consuming than, say, converting it to PNG bitmap graphics.

Here is a screenshot of ZGRViewer showing my DOT file opened with neato. Visit the ZGRViewer homepage for more screenshots and videos.

Building Mingw executables using Cygwin

Recently I wanted to compile a quick UDP test program on Windows and be able to ship it as a single stand-alone binary. I’ve compiled the source with GCC on Cygwin, and as you might already know, the executable is dependent on cygwin1.dll. This can be checked with the following command:

$ objdump -p udptest.exe | fgrep cygwin1.dll

It is possible to use the Cygwin development tools to build MinGW applications that do not depend on the Cygwin DLL and only depend on runtime libraries distributed as part of Windows.

The MinGW FAQ provides an answer on how use the Cygwin environment for development, yet generate non-Cygwin-dependant executables.

Adding the line

PATH=/cygdrive/c/MinGW/bin:$PATH

in /etc/profile before exporting PATH will have the effect that within the Cygwin environment the instance of GCC used is the MinGW version.

Note that the MinGW toolchain is gcc/g++ based but it’s using the WinAPI. If you want to use the UNIX Socket API by using the cygwin headers and libs, you have to supply the Cygwin DLL with your program. If this is not an option, you will need to rewrite specific parts of the project to conform with the winsock API.

Look here for some notes about Windows sockets versus Unix sockets. I did a rewrite by including the winsock2.h header file, like e.g.

#ifdef MINGW
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif

I’ve built the executable with

gcc -DMINGW -o udptest udptest.c -lws2_32

and verified the dependencies with

$ objdump -p udptest.exe | fgrep DLL

The output

DLL Name: KERNEL32.dll
DLL Name: msvcrt.dll
DLL Name: WS2_32.DLL

shows that the executable is no longer dependent on the Cygwin DLL.

MapServer 5.0 with AGG rendering

Previous MapServer versions used GD as the primary raster rendering backend. Because GD is not very capable of high quality output with regards to anti-aliasing, MapServer 5.0 has been released with a new rendering backend.

Anti-Grain Geometry (AGG) is a High Quality Rendering Engine for C++. Key features include rendering of arbitrary polygons with Anti-Aliasing and Subpixel Accuracy.

I’m testing this on Mac OS X 10.4.11 (sorry, no Leopard), and this time we are using MacPorts to install AGG.

$ sudo port install antigraingeometry

This puts AGG in /opt/local.

Now, to enable support for AGG in mapserver, download the MapServer 5.0.0 Source distribution from here and then continue with

$ tar zxvf mapserver-5.0.0.tar.gz
$ cd mapserver-5.0.0
$ ./configure -mandir=/usr/local/share/man -with-proj=/usr/local -with-gdal=/usr/local/bin/gdal-config -with-ogr -with-gd=/usr/local -with-xpm=/usr/X11R6 -with-wfs -with-wcs -with-wfsclient -with-wmsclient -with-agg=/opt/local/ -with-freetype
$ make

-with-agg=/opt/local/ -with-freetype is the part that is necessary for AGG suport.

The easiest way to test AGG rendering is by using the demo application which has been ported to MapServer 5.0. Download it from here and upack the workshop archive in your apache document root.

Apply this patch to the map file and edit the index.html to match your setup.

This screenshot shows what it looks like (note the antialiasing). Pretty, isn’t it? 😎

Community Mapbuilder

During my research of the current state of the open source GIS community and the viability of the surrounding software, I discovered Community Mapbuilder. It is a powerful AJAX-enabled geographic mapping client that runs in a web browser and supports the Open Geospatial consortium (OGC) standards.

It renders maps from Web Map Services (WMS), so we can integrate it easily with UMN MapServer configured as a WMS server. MapServer is an open source development environment for building spatially-enabled web mapping applications and services.

Using the latest stable Community Mapbuilder 1.0.1 release, I managed to get it running against my MapServer installation on Mac OS X.

btw, to check if your MapServer is built as WMS server, check what mapserv -v reports:

$ ./mapserv40 -v
MapServer version 4.10.3 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER INPUT=EPPL7 INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE

Access SQL Server with Perl DBI

Using the Perl DBI interface, you must first download and install the DBI module (latest version is 1.601). Installing using the cpan command-line tool is the easiest as it will install the dependencies for you.

$ sudo cpan install DBI

Next we are going to build and install FreeTDS. FreeTDS is a set of libraries for Unix and Linux that allows your programs to natively talk to Microsoft SQL Server and Sybase databases. I’m testing this on Mac OS X, so I’m going to install it via MacPorts.

$ sudo port install freetds

Before configuring and installing the DBD::Sybase driver module, make sure that the environment variable SYBASE reflects the path of the FreeTDS installation. MacPorts per default installs FreeTDS in /opt/local.

$ export SYBASE=/opt/local/
$ sudo cpan install DBD::Sybase

To configure FreeTDS to talk to your SQL Server database, edit the configuration file called freedts.conf. In this post, it is located in /opt/local/etc/freetds/freetds.conf.
Finally, here is a simple example to test your installation.

#!/opt/local/bin/perl
use DBI;
my $user = "sa";
my $passwd = "";
my $dbh = DBI->connect( "DBI:Sybase:server=MyServerName",
$user, $passwd, { RaiseError => 1 } )
or die $DBI::errstr;
my $sth = $dbh->prepare("select \@\@servername");
if ( $sth->execute ) {
while ( @dat = $sth->fetchrow ) {
print "servername is @dat\n";
}
}
exit(0);

Independent software consultant and contractor