2009-09-05

Configuration Best Practice

So rattling around in my head is this idea of configuration. When should you configure? What should you configure? How much should you configure?

As a rule of thumb I need to perform a software task in three relevant contexts to spot the important patterns for the system. That is to say I need three unique implementations of a system to spot how to generically implement a framework around the problem domain. The same is true for configuration.

Until I see three distinct scenarios where a system will be used I usually can't rightly discern what is going to need to be configurable and what isn't. I can usually make a good guess as to what will be needed by the time I'm working on two implementations ... but it really takes the third one for things to gel.

So if I were to number from best to worst case for configurations... I would put them in this order:

  1. configuration by convention (as we see in Grails)

  2. dynamic configuration by environment

  3. explicit configuration by administrator



Once you figure out that part of a system is going to actually need to flex then you should refactor for just enough modularity to reach the changes you need see. When doing this work the best thing to do is to make your system self configure by convention. This way we provide the necessary configuration without increasing the load on the end developer or administrator.

Next best we can do configuration by picking up things from our environment and working out the values we might otherwise need configured. This allows the administrator of our application to merely move the application code base to the correct place in the "cloud" or the correct server.

The last thing we want is for the administrator to have to open a dialog and enter data about the environment for your system to use at run-time. This can be an error prone process and it is possible that the environmental factors will change forcing the administrator to always be conscious of additional variables in the system.

In the perfect world our software systems would have enough intelligence to ask the environment for what they need and the environment would be intelligent enough to compute those dependencies as they occurred.

Of course the real world is a long way from perfect.

2009-09-02

Working on a new Audit plugin release

I'm working on a new release for the Grails Audit Logging Plugin that deals with issues some people were having with transactional databases.

I'd like to test this on multiple databases and with multiple configurations. So I'm putting the word out that I'd like some help with testing this. I don't have more than four databases to test on so I'd like some help.

If you can help out let me know. Contact me through this blog, twitter, or carrier pigeon. Thanks.

2009-08-21

Groovy Automatic type casting tricks...

I've been working on a Domain Specific Language. We wanted to hide the fact that you were passing string parameters to methods... so you could say things like:


something 'foo'
something foo


...and they would be equivalent. As the project progressed I needed to make calls like these...

something 'foo.bar'
something foo.bar

... again we want the two calls to be equivalent. But then I needed to reference the implicit tree of properties created by calling 'foo.bar' and 'foo.bar.baz' when I was interpreting these statements. So I needed to start tracking the symbols.

So my text-book meta-programming trick ...

def propertyMissing(String name) {
return name
}

... stopped working since foo.bar would result in a property missing on the String object. I could do some meta-programming on the String object but I also wanted to preserve the tree relationship for other work later. So with that in mind I wrote a class to wrap the symbols.

But there's a problem with that. If I introduce this new class... there are many places I just want the symbol like 'foo.bar.baz' and not the complex relationship. And by this point in the project I've written a lot of code to deal with things as strings.

Wouldn't it be great if I could ignore the complex nature of the object most of the time... but pick out the complex bits when I wanted them? To that end I created this class ComplexSymbol to do that work. I empowered it to know how to turn itself into a string silently in all sorts of situations.

So I wrote some tests to express what I wanted to see...

assert symbol == "foo"
assert symbol.bar == "foo.bar"
assert symbol.baz.bing == "foo.baz.bing"
assert symbol.baz.blat == "foo.baz.blat"
assert symbol.bar.blat == "foo.bar.blat"

... and I wanted to see the class of Symbol silently swap in for String whenever the method that was being called was expecting a string and not a complex symbol.

Take a look at the class I came up with to do this job...

public class ComplexSymbol {
ComplexSymbol parent
String symbol
Map symbols = [:]
ComplexSymbol(String str) { symbol = new String(str) }
ComplexSymbol(String str, ComplexSymbol other) {
symbol = new String(str);
parent = other
}
String toString() {
if(parent) {
return parent.toString() + "." + this.symbol
}
return symbol
}
def propertyMissing(String sym) {
if(symbols.containsKey(sym)) {
return symbols[sym]
}
def obj = new ComplexSymbol(sym,this)
symbols[sym] = obj
return obj
}
def asType(Class clazz) {
Object obj = null
switch(clazz) {
case java.lang.String:
obj = this.toString()
break
}
return obj
}

boolean equals(Object other) {
this.toString().equals(other.toString())
}

}


I've got lots of explicit typing in places to document the use of the class since I expect this class to show up in Java and Groovy code. The typing is really for documentation as it should be.

In the class where I want ComplexSymbol to stand in for naked strings I now do this:

def propertyMissing(String name) {
return new ComplexSymbol(name)
}

... which sets things up nicely so that the following works ...

someMethod foo.bar.baz

... and someMethod should get called with a string "foo.bar.baz" but before we get to that point I need to sanity check things.

Now to test the class with some methods... I just dumped the text for the above class into a file called symbols.groovy and stuck these methods at the end of the script so I could call them.


boolean stringify(String str) {
return str != null
}


This one should just see if it gets a string and I'll pass my ComplexSymbol to it and see if it gets the string.


boolean stringify(ComplexSymbol sym) {
return stringify(sym as String)
}


This method explicitly takes the complex symbol and uses the asType explict cast on it. This should show that the cast works.


boolean implicitlyCast(String sym) {
return sym != null
}


The implicit cast is my holy grail. If I can get the type system to see String whenever it asks for a String or the full ComplexSymbol type when it can handle that then I've got the whole enchilada.



/** Here's the tests again **/

def symbol = new ComplexSymbol("foo")
assert symbol == "foo"
assert symbol.bar == "foo.bar"
assert symbol.baz.bing == "foo.baz.bing"
assert symbol.baz.blat == "foo.baz.blat"
assert symbol.bar.blat == "foo.bar.blat"
assert stringify(symbol)

println "-" * 40
println symbol
println "-" * 40
println symbol as String
println "-" * 40
println symbol.toString()
println "-" * 40

assert implicitlyCast(symbol)


... command line output of this ...


$ groovy symbol.groovy
----------------------------------------
foo
----------------------------------------
foo
----------------------------------------
foo
----------------------------------------
Caught: groovy.lang.MissingMethodException: No signature of method: symbol.implicitlyCast() is applicable for argument types: (ComplexSymbol) values: [foo]
at symbol.run(symbol.groovy:71)


Notice that the last assert (my holy grail) fails. What I have is a very nice taco if not the whole enchilada.

Methods like print and println are going to implicitly handle the ComplexSymbol properly since they'll call the toString() on the object. And for methods that don't call ".toString()" we can either call it for them or explicitly cast to a String just before calling them.

All and all, it's a nice compromise with static and dynamic typing that allows me to use this class in plain Java code or in Groovy code very easily.

If someone has some thoughts on how I can get assert implicitlyCast(symbol) to work I'd love to hear them. With out it though, it's simple enough to spot the problem in a test case and put "as String" in the call like so...


assert implicitlyCast(symbol as String)


... and as I have incorporated this class into my work I've found points where I don't want the implicit cast to work all the time! I actually want to go into ComplexSymbol and ask for the symbol property directly. It turns out I actually need to hold the leaf nodes by their leaf node value sometimes and having them automatically resolve to their whole name would cause problems.

So in the end I'm glad the implicitlyCast test doesn't work the way I imagined.

2009-08-05

Grails in a J2EE world - RMI @ GroovyMag

In this month's GroovyMag I talk about using Grails code from a J2EE application using RMI. It's some practical work with the remoting plugin. Thanks again to Craig Wickesser for editing.

This is my last installment in the Grails in a J2EE world series. I had specifically been inspired to write these articles by several developers I had met over the last year that are interested in introducing Grails but who are also maintaining infrastructures that are built on EJB2. Yes, that's right... EJB2. I did not have time or space to cover every aspect that I wanted to, but, I hope that those of you that are in that particular boat and are interested in Grails can use these articles as a starting point for bringing Grails into your organizations.

Please head over to GroovyMag and check out the article. Feel free to give me some feedback below about the article. Together we can help cover this topic area better.

Thanks.

2009-06-04

Grails in a J2EE world - The Database @ GroovyMag

In this month's GroovyMag I talk about sharing a database between a J2EE application and a Grails application that is using GORM. If you haven't spent anytime working with concurrency in database applications you will really want to check this out. If you have a Container Managed Persistence (CMP) application that you are working with and you have a green-light on using Grails you might consider moving directly from EJB2 to GORM in a phased manner sharing parts of the database on the way.

Thanks again to Craig Wickesser for editing.

Please head over to GroovyMag and check out the article and give me some feedback.

EDIT
I'll also be giving out 5 free PDF copies of GroovyMag to the first five people who can Direct Message me on Twitter the answer to this riddle: What do you call an organized body of related information?

EDIT
That went fast! Congrats to @vintagedance, @evanbooth, @paulk_asert, @iansari, and @unixfudotnet

@unixfudotnet has offered his coupon up to the first person who wants it. Congrats to @dferrand.

Our answer? A database

2009-05-01

Grails in a J2EE world - The Web @GroovyMag

The new GroovyMag is available. This month I've made a contribution titled "Grails in a J2EE world - The Web" as I've been exploring ways that Grails and J2EE applications can interact I've found that the topic area is so rich that I can't possibly cover the whole thing in just one article. Instead I'll be making contributions in installments on the topic.

This particurlar article is inspired by the Kevin Kelly TED talk: Predicting the next 5,000 days of the web and how that has caused me to reevaluate my attitude toward software design and construction.

The article also covers some of the techniques I've found involving Java platform web technologies. I had a much longer narrative in mind but, honestly, I've come to enjoy some of writing of the authors who are much more succinct. I'm trying to emulate that style in my work. So for me writing involves one long session of pouring out followed by a session of cutting down. So in the end half of what I write gets deleted.

In addition, I had worked out a few more techniques that I could not fit in for time concerns. Every example code listing and technique comes from real working code. Often I have to address the issues of clarity and code ownership so I don't always get to share everything that I know.

I would like to thank my editors who helped with this month's article. Thanks to both Darryl Bloch and Craig Wickesser your feedback was very helpful and I really appreciate it. You both helped me tighten up my writing style quite a bit.

Please head over to GroovyMag and pick up a copy! As always your feed back is appreciated and will only go toward making me a better author and developer. Thanks!

2009-04-27

Grails 1.1, JBoss 4.2.x, and Oracle xmlparserv2.jar

If you want to use Grails 1.1 and the XMLType from oracle (the class is found in the Oracle jar xdb.jar) then you're going to need the Oracle xmlparserv2.jar in your Grails project. The problem is that Grails 1.1 will die if you just drop xdb.jar and xmlparserv2.jar into the lib directory of Grails. Why?

Well it turns out that this post tells you why. It was not cheap to find this answer at all... it cost me days of web surfing!

When you use JBoss in the $JBOSS_HOME/lib directory you'll find and endorsed sub-directory in there are two jars of particular interest to us. The xalan.jar and the xercesImpl.jar these provide the following services defined in their META-INF/services directories... xercesImpl.jar provides javax.xml.parsers.DocumentBuilderFactory and javax.xml.parsers.SAXParserFactory and the xalan.jar provides javax.xml.transform.TransformerFactory.

These three services are also supplied by the Oracle provided jar file xmlparserv2.jar and will effectively evict the JBoss provided implementations of these Java services. So what you have to do is replace the class references inside the xmlparserv2.jar with the same ones inside JBoss's endorsed libraries.

In short, explode xmlparserv2.jar then copy over the javax.xml.parsers.DocumentBuilderFactory and javax.xml.parsers.SAXParserFactory from xercesImpl.jar and the javax.xml.transform.TransformerFactory from the xalan.jar... re-jar the archive and redeploy.