Nov 30

Checking my maven repository with Groovy

Builds, Groovy, Tech 8 Comments »

I am finding myself grabbing Groovy rather than Perl for some of those small scripting tasks that you run into.

One I ran into recently revolved around my maven repository.

We setup our own Maven repo (we don’t want to keep hitting the poor ibiblio site!), and whenever we add dependencies, we grab the files from ibiblio and put them in our own repo.

However, it is easy to forget, so I whipped up a script that will check the dependencies in our project.xml and make sure those files exist in the repo, else it will shout at me to do the move.

It would also be cool to have it automatically do the copy itself!

I really like how you can whip through XML

Groovy Maven Script

#!/bin/env groovy
# -----------------------------------------------------------------------------
# mavenTestRepository.g: Take a given project.xml and a Maven repo, shout out
#                        which files are there, and which are not
# -----------------------------------------------------------------------------

import groovy.util.XmlParser
import java.io.File

# -- Enforce the project.xml and dir
if (args.length < 2) {
println """
Usage: mavenTestRepository.g project.xml mavenRepoDir

e.g. mavenTestRepository.g /foo/project.xml /www/adigio/maven
"""
System.exit(1)
}

# -- Variables
projectxml   = args[0]
mavenRepoDir = args[1]
badFiles     = []

# -- Open up the file and do the work
project = new XmlParser().parse(projectxml)

project.dependencies.dependency.each {
groupId    = it.groupId[0].text()
artifactId = it.artifactId[0].text()
version    = it.version[0].text()

println "-----------------------------------------------------------------------"
println " Group ID    : ${groupId}"
println "  Artifact ID: ${artifactId}"
println "  Version    : ${version}"

boolean fileExists = true
try {
new File("${mavenRepoDir}/${groupId}/jars/${artifactId}-${version}.jar").eachLine { }
} catch (Exception e) {
fileExists = false
}

if (fileExists) {
println "Good: File exists in repo"
} else {
badFiles += ["${groupId}: ${artifactId}-${version}"]
println "Bad: File DOES NOT exist in repo"
}
}

# -- Print out the bad ones
if (badFiles.size() > 0) {
println "\n-----------------------------------------------------------------------"
println "Dependencies not in the repository:\n"
badFiles.each { println it }
}
Nov 29

Pure Java Subversion (SVN) Client Library

Tech 2 Comments »

Dain told me about a Pure Java Subversion (SVN) Client Library.

About JavaSVN

JavaSVN is a pure java Subversion (SVN) client library. This means that users of the library, i.e. java applications do not have to include svn native binaries or javahl bindings to work with subversion repository. JavaSVN library is not only a 100% java replacement for javahl bindings, but also a library that provides high level of control over subversion repository operations.

Now we can programatically talk to SVN. If this works, then it will be good for ant plugins, IDE plugins, etc.

Nov 29

How closures and the like make me think differently

Groovy, Tech 118 Comments »

Each language and environment that you program in tends to have a feel. When you are deep into one community, you take on its “slang”.

This can be good, as you can learn a lot, and it can be a good way to communicate. However, it is good to visit other countries and learn other cultures.

Here is one small example of how I may write different code in Java, now that I also live in other communities such as Groovy, LISP, etc.

I was looking at a project, which had a lot of conversion code, to pretty-print contents of arrays, collections, and the like.

The way the team handled it was to have a bunch of methods on the model objects which would iterate through their collections/arrays and would built a nice String.

I would think of this problem differently:

  • What is consistent? The formatting of the elements is always the same
  • What varies? The actual data that you want to display

Now, you could of course, grab a Jakarta Commons library to spew the info out for you, but if you want to control it yourself I would do the following:

Put the common code in one place

PrettyPrinter.java has methods such as:

String convertCollectionToString(Collection theCollection, StringConversionFormatter formatter);

String convertArrayToString(Collection theCollection, StringConversionFormatter formatter);

Put the varied code in via a closure

The StringConversionFormatter interface encapsulates the variety. So, to do a conversion of a Role domain object I would have something like:

String result = PrettyPrinter.convertCollectionToString(roles, new StringConversionFormatter() {
public String format(Object o) {
return ((Role)o).getName();
}
});

Man I wish we could have PrettyPrinter.convertCollectionToString(roles, { return o.name })

;)

Nov 28

Aspen Thanksgiving: A big detour

Personal 3 Comments »

I had a fun turkey-day, going to Aspen with friends. It started off rough though. There was a rock-slide on I-70 up in the mountains. The result was that there was no way for us to get through to our destination (Aspen).

Well, you can just drive around the problem right? Sure. However, the detour was > 230 miles as we went up to Steamboat Springs and down on the other side. Ouch.

The extra 4 hours in a car WERE worth it though. We had an amazing weekend in the mountains!

Nov 25

preGoal/postGoal vs. depends=

Tech 1 Comment »

One thing I really like about Maven is the pre and postGoals support.

I find this functionality MUCH better than hacking around with targets in ant, and having to setup the correct depends=”…” path.

With pre/postGoals I don’t have to go to the goal which I want to add functionality too. I can intercept it. This is infinitely nicer.

It also makes a lot more sense in Maven, as you have so many predefined goals, and many more plugins ready for you to install.

Example One: Tweaking the way your war is built

Out of the box maven can package a war (in various ways). What if you want to do something “different” than the standard packaging? Well, we wanted to make sure a certain file was put in the classes directory, so we simply use a preGoal:

<preGoal name="war:init">
<copy todir="${build.webinf.classes}">
<fileset dir="${basedir}/../../">
<include name="project.properties"/>
</fileset>
</copy>
</preGoal>

Example Two: Kicking off a pre-compile step

We use XDoclet to generate Hibernate mappings, and can use a simple preGoal around the standard java:compile goal:

<preGoal name="java:compile">
<taskdef name="hibernatedoclet" classname="xdoclet.modules.hibernate.HibernateDocletTask" classpathref="maven.dependency.classpath" />
<hibernatedoclet destdir="${build.webinf.classes}" excludedtags="@version,@author,@todo" force="true" verbose="true">
<hibernate version="2.0" validateXML="true"/>
<fileset dir="${maven.src.dir}/java">
<include name="project/model/*.java"/>
</fileset>
</hibernatedoclet>
</preGoal>

I haven’t checked, but it would be really nice to be able to have the preGoal STOP the processing of the actual goal etc. Much nicer.

Nov 24

Why it can be so frustrating getting things to work…

Tech 61 Comments »

I just spent too long tweaking my build to use XDoclet with the Hibernate Doclet.

At first, I thought I would try the Maven plugin, which has you setup, what makes sense in the XML files into a scary set of properties:

# —————————————————————————–
# XDoclet Hibernate Doclet
# —————————————————————————–

maven.xdoclet.hibernatedoclet.destDir=${build.web.dir}
maven.xdoclet.hibernatedoclet.excludedTags=@version,@author,@todo
maven.xdoclet.hibernatedoclet.force=false
maven.xdoclet.hibernatedoclet.verbose=false

maven.xdoclet.hibernatedoclet.hibernate.0.Version=2.0
maven.xdoclet.hibernatedoclet.hibernate.0.validateXML=true

maven.xdoclet.hibernatedoclet.fileset.0=true
maven.xdoclet.hibernatedoclet.fileset.0.dir=${maven.src.dir}/java
maven.xdoclet.hibernatedoclet.fileset.0.include=foo/model/*.java

Then I could add:

<preGoal name=”java:compile”>
<attainGoal name=”xdoclet:hibernatedoclet”/>
</preGoal>

To get this right takes a few peeks into the plugin.jelly *just* to make sure. Anyway, after this was all setup, no Hibernate files were getting generated.

Lots of futzing around later (make sure the dirs were right etc) and I ended up taking a step back. I moved from the Maven plugin to just use the hibernatedoclet “manually” in the preGoal.

This also didn’t work.

I took the smart step back and setup a minimal build.xml which was JUST going to do the mapping.

I ran ant and got an error message saying that the WebDocletTask wasn’t found. Surely I read this wrong… it means HibernateDocletTask right?

I guess not. I grabbed the xdoclet web module and everything worked fine.

Gotta love not getting any error messages that make sense!

Nov 23

TheServerSide is born again. No more Middleware Company

Tech 100 Comments »

It has been in the works for awhile, but now TheServerSide announced that they have been bought by TechTarget.

What does this mean? Well, Tech Target is an online media company, so they came in for TSS.com and family. This means that for the first time ever, TSS will not have a parent in which it has to help out.

So, no research studies from TMC, no selling training from TMC, etc.

Nov 23

Starting a new project: Where to put config files?

Tech 9 Comments »

Whenever I am with a new project team, one of the early questions arise around the issue of “where to put stuff”.

With typical J2EE projects you end up with various config files that AT DEPLOMENT want to be in different places.

For example:

  • WEB-INF: At the root you will have a web.xml, and other beasts such as sitemesh.xml
  • WEB-INF/classes: This covers the “has to be in the classpath” issue. Here you will often find an applicationContext.xml, log4j.xml, message bundles, and more.
  • META-INF: Here you will have some EJB-ish stuff (if you are using EJB ;)
  • Spread out: Your Hibernate .xml files may be in various locations, etc

I normally run across two styles on how to handle this:

One Place For Dev. Then Build To The Right Place

In this mode, there is a /src/config, or something like it, which has ALL of the XML, and properties files. This makes things very simple to find when you need to get to a config file, as you don’t find yourself hunting around in all of the various places that it could be.

The responsibility of putting these files in the correct places falls on the build master. In your source control you don’t even HAVE a WEB-INF directory. The build creates this and sets it all up for you on the fly.

The problem is that if you are debugging, you often find yourself “checking out what is on the deployed server”. Here there is no longer a nice config directory, and you are slower at finding the files as you don’t really know where they are meant to go.

Mimic The Deployment Structure

In this scenario you simply mimic the end structure. You cringe when you check-in a directory called WEB-INF/classes to source control, which has config files that need to be in the classpath.

Although the files are spread out all over the shop, they do mimic the Real World, and hence you can find things quickly in that world.

A Bit Of Both

The scary scenario is when you see projects that do a bit of both. At this point you don’t have a clue where anything is :)

Smart Folder

Maybe you can get a bit of the best of both worlds if you had a Smart Folder. Then, the config directory could aggregate the config files from everywhere else, but they would just be symlinks. WinFS can make this easy. On *NIX you can just have a script which generates the symlinks for you!

Nov 22

Handling Dependencies: A generation tool, or something smarter in Maven

Builds, Java, Tech 5 Comments »

How long does it take to setup your Maven >dependency<’s for a project that uses a lot of open source?

You find yourself following a chain of “X needs Y…” as you keep adding your dependencies.

What would be nice is to be able to write a script that takes high level tools (e.g. Spring) and builds the dependencies for all of the sub projects.

What would be even cooler is to have maven give it a go. You could say “I want Spring version X”, and maven will download all of the items that Spring needs automagically.

No more following the breadcrumbs.

Nov 19

JavaJobs.com

Tech 5 Comments »

I saw a new jobs site called JavaJobs just opened its doors.

It will be interesting to see the difference between looking for gigs on a site dedicated to Java, versus trying to filter at a Monster/Dice/…

I hope they do well!