October 29, 2009, 9:31 pm
I really enjoy coding in Grails. When working with dynamic languages, there is always a bit more uncertainty to what the type of particular variable is – especially when calling code that someone else has written. Now, you can always just fire up the debugger to find out but often times it is overkill. Groovy has great support for finding out all about your object using dump(), inspect(), and toString() usually returns something useful from a GDK class. Usually a quick println is just the right thing for me to figure out what is going on, and then I remove the statement.
The problem with a quick println is that it is often difficult to quickly differentiate your log lines from that of Grails or Hibernate. Of course you can turn those log levels off, but always like to see the SQL Hibernate is generating during development. In order to make my logging stand out, I have started adding this to BootStrap.groovy:
1: def init = { servletContext ->
2: ...
3: Object.metaClass.printlnRed = { s ->
4: def ansi = new Ansi(Ansi.Attribute.BRIGHT, Ansi.Color.RED, Ansi.Color.BLACK);
5: ansi.outln(s);
6: }
7: ...
8: }
This will allow me to call “printlnRed ‘Some String’ from any Groovy object in my Grails application. The Ansi class comes from the LGPL licensed jibs library. Of course you will want to find out what colors work the best for you. Don’t forget to remove your println’s – you don’t want to clutter up your code for others. If it is something worth keeping in the application, use Log4J instead. You can still get colors by configuring your appenders to use Ansi colors as well – there are numerous examples of how to do this including one in Ant. FYI, I doubt this works in Windows.
October 26, 2009, 9:00 pm
In the scope of a much larger project I am working on, I needed to convert a large number of Ant builds to Maven. Having done this in the past, I know that it is certainly a tedious process – particularly regarding depending resolution. So, I decided to make an attempt at scripting that process and ant2maven was born:
1: usage: groovy ant2maven.groovy
2: -?,--help Prints help
3: -a,--antfile <a> The ant build file, defaults to build.xml
4: -aid,--artifactId <aid> The artifactId of the new project, defaults to
5: current directory
6: -g,--groovy Enable groovy support
7: -gid,--groupId <gid> The groupId of the new project
8: -n,--name <n> The name of the new project, defaults to
9: current directory
10: -o,--output <o> Name of the POM file, defaults to pom.xml
11: -p,--paths <p> The ant paths to parse
12: -t,--testpaths <t> The ant paths to parse for the test scope
13: -u,--nexusurl <u> Base URL for Nexus repository to search against
14: -v,--version <v> The version of the new project, defaults to
15: 1.0-SNAPSHOT
The script requires at least two parameters, the groupId you want for your generated POM and the name of the Ant path that you want to convert to Maven dependencies. An Ant path normally looks something like this:
1: <path id="build.classpath">
2: <fileset dir="./lib/">
3: <include name="xbean-spring-3.4.jar" />
4: <include name="camel-*-2.0.0.jar" />
5: <include name="spring-*.jar" />
6: <include name="jetty-*.jar" />
7: <include name="mysql-connector*.jar" />
8: <include name="log4j*.jar" />
9: </fileset>
10: </path>
There are a number of ways that you can define your paths in Ant, and you may not even have an Ant path defined, i.e. you have directly define your path under a <javac /> task. In those cases, you can just create a path and copy your elements for the script to work.
Once the script finds your dependencies, it searches the public Nexus repository using the REST API to find all of your dependencies. The script also attempts to reduce your POM bloat by not listing repeating transitive dependencies as dependencies in your pom. If the script cannot find a particular dependency, it will go ahead and list it commented out in your POM so that you can resolve it. Since the public Nexus repository does not have all Maven repositories that you are probably using (Java.net, JBoss, etc), I would recommend setting up your own Nexus instance to achieve the best results. You can also upload any of your corporate dependencies to your Nexus repository so that they can be resolved by the script as well.
I hacked this together quickly over a few hours this weekend, so there are lots of room for improvements:
- Better error handling when things go wrong
- Automatically install missing artifacts to your own Nexus repository
- Suggest dependencies by name when the checksum search fails
- Add excludes when two artifacts have conflicting version of transitive dependencies
One thing to note is that when you start the script for the first time, it may appear unresponsive. That is because Groovy is downloading the necessary Grapes for the script – so be patient on the first run.
I have made the script available at GitHub, so feel free to fork for improvements.
October 18, 2009, 5:14 pm
Groovy builders are great for consuming and creating formats like JSON and XML. However, I could not easily find an example how to write out an XML document with the XML declaration using the MarkupBuilder. To do this, you need to use the StreaingMarkupBuilder instead. Here’s an example that returns the last 10 transactions as XML from a Grails controller:
1: def index = {
2: def xml = new groovy.xml.StreamingMarkupBuilder()
3: xml.encoding = "UTF-8"
4: render xml.bind {
5: mkp.xmlDeclaration()
6: Transactions {
7: Transaction.findAllByDate(new Date(), [max: 10, sort: "date", order: "desc").each {
8: Transaction {
9: ID(it.id)
10: Date(it.date)
11: Total(it.total)
12: }
13: }
14: }
15: }.toString()
16: }
With this, you will get a nice well formed XML document:
1: <?xml version="1.0"?>
2: <Transactions>
3: <Transaction>
4: <ID>193710</TD>
5: <Date>2009-10-18 17:09:24</Date>
6: <Total>123.12</Total>
7: </Transaction>
8: ...
9: </Transactions>