2011-07-24

The one about scope. And tacos.

Consider the following paragraph.

Mary and Sally are friends. Mary gives Sally a gift for her birthday. Mary hangs up the telephone.


Are there any syntax problems in the above paragraph? Are there any grammar problems? What is wrong with this paragraph exactly? The problem is non-technical in nature. The paragraph references a relationship between Mary and Sally and then describes an interaction that occurs between them. Finally it describes Mary ending a phone conversation. However, we have no idea when or how Mary began talking on the phone. We don't even have a prior reference to a phone conversation.

Consider the following code:

def exchangeIfRelated(def mary, def sally) {
  if( canRelate(mary,sally) ) {
    mary.exchange(sally)
  }
  mary.closeConnection()
}


What is wrong here? The isn't anything technically wrong provided whatever connection we just closed was not in use after this method finishes. What is the likely hood this call is made from a different part of the program like this?

public void friends(FooService mary, BarService sally) {
   mary.openConnection()
   sally.openConnection()
   exchangeIfRelated(mary,sally)
   sally.closeConnection()
}


Anything wrong here? No. Not really. It will compile, it will run. In this method we have implicitly taken responsibility for opening and closing whatever these connection things are. In a more concrete example, we might be opening and closing a database connection. In that kind of example, we are allowing concerns to bleed between methods. Ideally, I want one unit of code to be concerned with one thing. That thing (whatever it is) is hopefully easily abstracted for use by other units of code without their having to become experts in that other abstract thing (whatever that is). The following code is better and will likely lead to fewer misunderstandings.
public void friends(FooService mary, BarService sally) {
   mary.openConnection()
   sally.openConnection()
   exchangeIfRelated(mary,sally) 
   mary.closeConnection()
   sally.closeConnection() 
}

Knowing how an ignition system works does not aid my ability to drive a car in rush hour traffic. When I start my car I do not need to have knowledge of what happens when in my car's engine, nor do I need to know how a camshaft functions in order to drive my car down the road. The driver is insulated from these automotive inner workings. In the same way when we build software we want to insulate the layer above us from details about the layer beneath us.

Mixing the scope of when and where you do things is like changing the subject of a paragraph. There are fish in the sea. Nothing is really wrong with it from the stand point of the compiler which really only understands the mechanics of phrases in the programming language. There are tacos in a truck. However, just as properly formed sentences that have little to do with the core thought of a paragraph are disruptive and confusing. I like kites. Similarly, such disruptive code phrases in our code leads to confusion and in a program that kind of thing leads to bugs. And tacos.

2011-03-23

GR8Conf

I'm very pleased to be speaking at GR8Conf this year. I'll be covering two topics. I hope the Groovy communities find them interesting.

The first up, how to use Domain Specific Languages in order to reduce accidental complexity. I have a very long post that I'm holding on to based on this topic (inspired by my trip to Manhattan and Google NYC earlier this year). In this talk I'll really take time to explore this idea practically. I will create a Domain Specific Language before your eyes as I do live coding with Test Driven Development. It's performance art with Unit Tests!

The second topic is on Grails and the JPA. I'm currently working on a lab for this topic. We'll explore some of the nastier Object Relational Mapping problems I've encountered working with Grails and with JPA in isolation and together. If time permits I'll work in some performance troubleshooting in this lab too. In this format we'll have the chance to work together and really get a deep understanding of what's going on with Grails persistence and how you can use GORM and/or the JPA in places you may have thought were impossible. I really enjoy the lab format and I hope to see a good turnout.

For me, getting the opportunity to speak at the GR8Conf is a major milestone and I'm very pleased that Open Software Integrators is allowing me to participate. The fine folks at Open Software Integrators have an experienced consulting staff that can help you with all things JVM related. I've had a great time working with the other consultants here over the last few months learning a great deal about performance tuning and scalability.

So please check me out at GR8Conf and I look forward to seeing you there!

2011-02-16

Groovy/Grails: How to disable a controller



Let's say you have a plugin. That plugin includes a controller. You don't want to use the controller provided by the plugin (for whatever reason) but instead you want use your own controller.

What do you do?

Filters my friend. Filters.

Next to your Config.groovy file in the grails-app/conf directory create for your self a file called DisableFilters.groovy and then add a class definition. Here's a filter definition that disables everything in the application... (making your grails application headless).

class DisableFilters {

def filters = {
all(controller:'*', action:'*') {
before = {
// return false
}
after = {
}
afterView = {
}
}
}
}

Now you'll notice there is a before closure and it returns false. This closure fires before the request is passed to its destined controller/action. The * means match all. So if you had a specific controller name or specific controller name pattern you wanted to disable you could easily disable all these by matching the name here.

Notice the nifty after which would execute after the controller and action complete. Finally you have the afterView closure which would execute after the entire call chain was done and the browser has left. I'll leave the uses for these up to your imagination.

In the filter body you have access to everything you have in a grails controller so you have a great deal of flexibility here with what you can do. You could look at usernames, session data, whatever your heart desires. You can even redirect the request to another URL using the same conventions as you would have in a controller. So have at it!

2011-02-09

double entendre

I have said "The Future of Java is Groovy" and I meant it deliberately as a double entendre. The future of Java is indeed groovy and is indeed Groovy. This does not mean Java will be supplanted by Groovy, or some other language. Instead, the future of the JVM and the technology stack that calls the JVM home is tied more to technological off-shoots like Groovy than it is to any other purist re-engineering of the JVM or the core Java language.

Java is what it is at this point. Tools like Groovy give developers the chance to get a gentle introduction to new techniques such as Functional Programming, Parallel Computing, Domain Specific Langauges, Runtime Metaprogramming, and Compiletime Metaprogramming, as well as a whole host of other techniques and technologies.

The beauty of Groovy as a programming language is how accessible it makes all these advanced techniques to a beginner and how readily it will get out of the way of an expert. This is a beautiful balance of the elegant and the ugly that few other languages manage to pull off well.

Do I think Groovy will supplant Java on the JVM? No, not really. Do I think any other language will make that claim? I seriously doubt it. Do I think Java needs a successor? No. No I do not.

The closest ecosystems that we can draw analogies to for the modern JVM are the .Net ecosystem and the C/C++ ecosystem. The C/C++ ecosystem is probably a better environment to draw lessons from since C/C++ long ago shed its lock-in with a single vendor (that being AT&T long long ago).

I think Java is growing up the same way the C/C++ ecosystem did and C hasn't really changed much over the years. I think Java needs to become the same kind of solid foundation. If other languages come and go on the JVM that needs to be groovy with everyone.

I don't steer any ships in the Groovy navy, I don't direct any plans or strategies, so what I say here is just what I say, and what I say is:
Groovy allows rapid access to advanced computing concepts with a minimum extraneous cognitive load.
This is the Groovy language's strength. It is immediately accessible to anyone with any programming background. This accessibility is the vital engine for the success we are seeing in Groovy adoption. It is also the weakness of the language. It means that Groovy must necessarily avoid the traps of becoming too "beautiful" of a language forcing people into certain forms steepening its learning curve too sharply.

That's my opinion anyway. I happen to be one those kinds of guys who likes what I can do with a language. I tend to not get hung up on whether it is pretty, or if it is pure. It's all groovy man.

2011-02-02

A late New Year's post.

tl;dr I am a consultant now.

It's a quite late, but I did make some new year's resolutions. One was a personal fitness resolution to run a mile every workday. The other was a professional resolution to "get out there" more and contribute more to the Groovy/Grails community. For most of 2010 I felt as if I were under a rock and not able to contribute to the community more and so I've made a couple of drastic moves.

My first drastic move was to step-up my fitness routine. I have been working out 3 times a week now for a few years. This year I have stepped it up to 5 times a week. Yes. 5 times a week. My warm up is a 1 mile run.

So far this year I've managed to run one mile every weekday (I give myself Saturday and Sunday off from running). So far, I haven't missed a day. I was inspired by my son's devotion to his Cross Country training and I have set myself some small goals for my running to try and achieve over the next few years. My big goal is to eventually run a Marathon. This seems utterly absurd to say, I have so very far to go before I can do something like that. Barring any medical reasons I fully intend to achieve that goal.

My results this last month are encouraging. I started the year with a mile time of 15:44 (fifteen minutes and forty-four seconds) and I've managed to bring this down to 11:24 or so on my best day. I typically complete the mile now between 11:30 and 12:30 now. My goal is to make a 12 minute mile an easy run for me. If I can do that then I will begin increasing my mileage over time.

The other one of those drastic moves was quitting my job at a company I dearly loved working at and really respected. It was a very hard decision to make but I decided that I wanted to invest more directly in the Open Source community and open source efforts. I believe strongly in the cause of Open Software and if I believe in it I should put my whole being behind what I say. So I've joined forces with Open Software Integrators which is a young Open Software consultancy based here in the Research Triangle area of North Carolina. We have a strong match for vision and attitude toward software development and I look forward to working with the team here to help companies reap benefits from Open Source software and toward making solid contributions back to the Open Source community.

There have been a lot of preparations going on in making these transitions so I've not been as active here in this blog as I intended. I have made a resolution to also post more regularly here. It was this blog that enabled me to get published in GroovyMag, create the plugins that have taught me so much about living with open source software projects, and introduced me to so many of you.

I hope that I can find a way in my new role to make a real positive impact on the open source community and fill a need that is currently under served. As always I'm open to your feedback and I find your comments valuable. I am currently looking for conferences that would be open to me speaking so your pointers will be welcome. Obviously, I can't attend them all but I will make a real effort this year.

Thank you for reading and I hope I get meet some of you in person this year too!

2010-10-14

On the topic of Grails Audit Logging Plugin version 0.5.4

Last night, I released a new version of my Audit Logging Plugin. Release notes are here. There had been an outstanding compatibility issue with Grails 1.3.x based on JUnit 4's Integration tests. The bug documented here has been open for several months as I haven't had time to come back to the project to work on it.

Normally I don't blog about tickets but I figure this one requires some attention because I've run into a few plugins that I need in my day job that are "broken" in 1.3.x and I'm not sure who else is having these troubles. In the interest of helping the community as a whole I want to cover my experience.

It turns out that GRAILSPLUGINS-2243 (titled "Integration tests with auditable domain class do not observe test transaction boundary") is actually a more accurate description of the actual bug. The symptom is during integration testing you can't delete entities that are audited. If you take the same code and run it in development or production mode you can delete the objects.

The issue with my code is in this block... (extraneous logging and debugging code removed)

Session session = sessionFactory.openSession()
def trans = session.beginTransaction()
def saved = session.merge(auditLogObject)
session.flush()
trans.commit()
session.close()


Keep in mind this block functions exactly as expected in Grails 1.2 under all environments I know of. The one environment this code is horribly wrong is Grails 1.3.x in Integration testing. Only at that time does this code cause a problem.

So let me ask you... what's wrong with this code?

Before addressing the real issue, questions I anticipate:

  1. Why are you opening your own session?

    Because on a transactional database in some cases the audit log must fire after the database insert so that I can log the automatically assigned object Id. This means you can't use the open session without invalidating it.


  2. Why are you using merge and not save?

    Because there are edge cases where the AuditLog object will be saved twice and I don't want to dictate the logic for that in this block to keep it simple


  3. Why are you flushing the session?

    Because we want to make sure the audit log is being written outside the regular transaction cycle and this particular session is going to perform no other job we want to ensure the log is written out to the database



So ... what is wrong with this code again?


def trans = session.beginTransaction()


Apparently, under integration testing in Grails 1.3.x if you start a transaction in the way I have you will cause a problem with the other independent transactions in the rest of the application. This is simply not the behavior I see in my production systems under Grails 1.2 or in my staging systems running Grails 1.3 for that matter.

My solution is a bit of a work around. In the application context initialization for the Audit Logging plugin (the bit that runs just as you start up your grails application I have a block that does this...


if( Environment.getCurrent() != Environment.PRODUCTION && ConfigurationHolder.config.auditLog?.transactional == null ) {
transactional = false
}


... which simply says in environments that are not production (Notice I'm using the Grails 1.1 API to find that breaking compatibility with Grails 1.0) the boolean flag "transactional" is set to false. I then wrapped the begin and commit calls to the transaction around a check on this boolean. For good measure, I gave the end developer the ability to override this behavior using the setting "auditLog.transactional" in their Config.groovy file. (It would figure that I would release this as a feature and someone needs to use those transactions in their integration testing because they run their testing environment against Oracle or something so here's an out for you to get the old behaviors)

What took so much time to find this bug? It's not clear cut basically. I stumbled on this answer by blindly trying different things until I found a combination that worked. Then I tried to build a theory around this result that fit the facts that I had on hand.

My theory is the JUnit 4 integration environment does something to the session factory so it does not really produce new sessions such that the session that I get in my plugin's listener code is not really a separate session or transaction. I call commit on this transaction and when the session is returned to the normal GORM code it is already committed so the actual entity delete call can't happen and is swallowed.

What is disturbing about this is I didn't invent this technique for Audit Logging I'm implementing here. I created this code after being educated by the Hibernate wiki. This means if my theory holds it's not just a Grails application that will observe this strange-ness ... pretty much any Hibernate application with this kind of Audit Logging will be affected when integration tested under JUnit 4.

Beyond just this anyone developing applications that open their own sessions independent of the GORM session may potentially see bugs during integration testing that do not manifest in other environments. That can be a very difficult situation to deal with. So I've over documented things here for the benefit of the community at large.

In other news...

In other places I've noticed a change in Groovy 1.6 and 1.7's builder API. In particular I use RichUI in one project which makes calls like...

builder.yield(" var ${attrs.yuiVariableName}DataSource = new YAHOO.util.XHRDataSource(\"${attrs?.action}\");\n", false)

... under Groovy 1.6 yeild was a builder method.



But, under Groovy 1.7 this method is not present. That means the HTML rendered by code that used the yield and yieldUnescaped calls now create tags <yield> and <yieldUnescaped> which breaks some pages (but not all).

So far these are the only surprising issues I've run into that has kept Grails 1.3.x off of my production servers. I haven't yet seen and great benefit to 1.3 so I can't say I'm deeply compelled to move to the new version.

I am looking to rewrite the plugin in light of GRAILS-5725 but this will be a breaking change. Frankly, it's such a large change I'm surprised it was not pushed to Grails 1.4 ... however, it does not appear to interfere with the operation of plugins using the listener injection technique I am also using so no harm no foul.

I see I've lost a whole star in my plugin ratings so, my apologies to my end users who have not had a plugin that works with your Grails 1.3 integration tests. I sincerely hope I can earn back that extra star from you. Thanks for your support and help. I am reviewing code submissions for another version of the plugin coming up and I greatly appreciate your support.

2010-09-30

TriDroid: QRCode, Linkulator & other "move the data" ideas

At tonight's TriDroid we discussed QRCodes and other techniques for moving data between the environment and our Android phones. Here are hastily-hand-drawn my slides for anyone interested in them.



Other things we talked about:


EDIT:

As George points out (and many have pointed this out repeatedly) the Google Chart API has had QRCodes incorporated in it for some time. Once again, being lazy would have paid off much more than working hard. A lesson the universe seems to be trying to teach me repeatedly.