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.

2010-07-14

App Inventor

If you haven't heard about it App Inventor is available to educators wanting to teach students about programming. It allows novice programmers to create Android applications using a graphical programming environment similar to Scratch.

The educational perspective that motivates App Inventor holds that programming can be a vehicle for engaging powerful ideas through active learning. As such, it is part of an ongoing movement in computers and education that began with the work of Seymour Papert and the MIT Logo Group in the 1960s.


This is probably one of the more interesting and exciting ways to engage lay-programmers in software creation. It is possible to view the graphical programming language blocks as a Domain Specific Language but I'm not clear on whether this is actually the case or not. In particular:


  1. the types of statements are limited to available blocks

  2. these statement blocks are limited to guided classifications specific to phone app development

  3. user and device interactions are limited to the palette



In these ways the "developer" is "on-rails" (in the video game sense) limited to a certain type of application. This kind of limitation is beneficial in some cases guiding the developer toward a "good" application. In this case the limitation keeps the developers from heading down paths that require knowledge about the halting problem or multi-threading. For this class of application... that's a good thing.

The OpenBlock abstract certainly sounds like a description of a Domain Specific Language (emphasis added):
Graphical programming systems have been built to lower the threshold to programming for beginners. However, because these systems were designed to make programming more accessible to novices, they were developed with narrower intentions for their users and applications. For example, in StarLogo TNG, a graphical block programming environment, users may create games and simulations, but they cannot use this same system to create programs that can automate their computer processes, like the text-based scripting system AppleScript. Application developers can create their own programming systems, but doing so can take a significant amount of time to design and implement. This thesis describes an extendable framework called OpenBlocks that enables application developers to build and iterate their own graphical block programming systems by specifying a single XML file. Application developers can focus more on the design of their systems instead of oil the details of implementation. The design and implementation of OpenBlocks are described, along with a user study conducted to test its usability and extendability.


On the other hand it could be argued that the graphical programming environment is just an immature environment and is only limited because of how new the tool set is. There is no intrinsic reason a graphic block based programming language couldn't eventually become as rich as a traditional text based language. The real differentiator between a (DSL) Domain Specific Language and a GPL (General Purpose Language) is that the scope of the programming done.

You evolve a DSL either by creating a very rich API that "begins to talk" or you create a deliberately limited subset of your GPL that can be exposed and interpreted using limited API.

So is App Inventor using a new(-ish) Domain Specific Language or a new way to wrap a General Purpose Language?

2010-07-09

Three Small Ideas

I was glad to be interviewed by DZone a while ago. The second interview was on my current Open Source work and I gave what is probably a non-traditional answer on why Open Source contribution is important for a developer. The google appengine project I'm talking about is the qrcode linkulator. And, for the record, I've got a better hair-cut now.



My statistics are from this article on Functional Fixedness at wikipedia. The over-lapping concept I'm trying to tease out is that there are problem solving exercises that are not served by tightly focused environments like business. As a developer you need to be able to work in spaces that allow for creative freedom and the lessons you learn there (for better or worse) translate back into your "high pressure" environment. The result is a better developer that is able to think outside the parameters of the problem.

A nice animation covering the idea popularized by Daniel Pink (who is an infinitely better speaker) is on youtube:


My contribution is: not only is open source a product of intrinsic motivation... it creates intrinsic motivation to improve yourself as a developer. These improvements translate back to your "day job" ... so for purely selfish reasons you *should* create open source code. You will be forced to learn. You'll get interaction with other developers. You'll learn much more than if you stay locked in your office and never get challenged by people who never would think like you do and have no reason to pretend they do.

Even if the project is a failure and your contributions are insignificant... you'll learn something.