Friday, March 28, 2008

Did you mean "rails"?

I really like dice.com but this is just wrong:







Ok, so there are 417 Rails jobs on dice and only 12 Grails jobs, but that's no excuse. I'm going to keep an eye on this and I'll report back when it changes.

Wednesday, March 26, 2008

Integrating Grails with EJB 2 applications

When attempting to convince an organization to adopt Grails you may have to demonstrate more than the superior developer productivity it provides. Integrating with legacy systems or even new systems that may continue to be developed in other tools will probably become an important topic. One way to integrate is to use the Grails ORM DSL to hook legacy database tables into a Grails application. Another way is to connect to existing EJB based applications. As you would expect Grails makes this so easy it seems like cheating.

In this example we have an EJB 2 server running in WebLogic. There is a CMP entity bean called Employee, a stateless session bean called EmpSession and a data transfer object called vEmployee. The EJB components and the DTO are in a jar called EmpEjb.jar. The session bean contains methods for retrieving and saving Employee entities via the vEmployee DTOs. We will focus on on how to get access to the EmpSession instance from our Grails application.

First we'll add a couple of beans to our grails-app/conf/spring/resources.groovy file using the SpringBuilder DSL.

beans = {
ejbJndi(org.springframework.jndi.JndiTemplate){
environment = [
"java.naming.factory.initial" : "weblogic.jndi.WLInitialContextFactory",
"java.naming.provider.url" : "t3://some.enterprise.server:7001",
"java.naming.security.principal" : "dave",
"java.naming.security.credentials" : "1234"
]
}
empSession(org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean){
jndiName = "EmpSession"
businessInterface = "com.enterprise.some.ejb.session.EmpSession"
jndiTemplate = ref("ejbJndi")
}
}

Let's look at what this code is doing. We have what looks like a method: ejbJndi. It is really a Spring bean id and its argument is the bean class. The block that follows includes one or more property assignments in the form of properyName = propertyValue. for the ejbJndi bean we only have one property, environment, which in turn contains several entries. The entries take the form of a map of propKey:propBody pairs. This sets up our JNDI Template which Spring will use to lookup our session bean.

Next we declare our remote session bean using Spring's SimpleRemoteStatelessSessionProxyFactoryBean (they said "Simple" not "Short"). We declare this the same way as the ejbJndi bean. This one has three properties, the session bean's jndi name, its remote interface class and a reference to the JNDI Template. For this last property we use the form property = ref("referencedBeanId").

Now we need to copy some jars to our application/lib directory. Since we are using WebLogic all of the EJB and JNDI classes we will need are in weblogic.jar. You may have one or more jars depending on your application server. Our EJB components and our DTO classes are in a single jar, EmpEjb.jar. These may often be in different jars, in which case both would need to be placed in the lib directory.

Beans defined in resources.groovy can be auto-wired by name so we can just place def empSession in any Service or Controller class and start calling session methods.

With this ability to integrate so easily with legacy applications there is just one less reason not to start using Grails in the enterprise.

Thursday, March 20, 2008

Sven and Glen are at it again!

The Groovy Posse, er, I mean the Grails Podcast is back with episode 50. In this episode they've got some big news about some big sites built with Grails. If you've heard the question "are any real sites using Grails?" as many times as I have then you'll want to check this out.

There's more but you'll just have to tune in for yourself. I have to say that I really appreciate the conversational style they have now with Sven and Glen; now if they could only find a Ben ...

Wednesday, March 19, 2008

You learn something new every day... on the Grails Mailing List

The Grails mailing lists are tremendous resources. Not only are they great for getting your questions answered by the helpful experts that never seem to sleep, but you can often learn something from someone else's question/answer.

For example, just the other day, I came across this very helpful post by Chris Chen that describes a simple way to deal with get methods in your domain class that don't have a corresponding set method (ie. calculated properties). If you try to do this without some extra code, you will get a PropertyNotFoundException. In the past I've usually handled this by renaming the method so it doesn't start with get, even though get might make the most sense. The alternative is to use a transients list, but that just doesn't seem right to me for this situation.

What Chris suggested was to dynamically type your get method. So, for example, if you have a Parent class which has a collection of Child and you want to find the oldestChild, you can do this:


class Parent {
...
static hasMany = [children: Child]

def getOldestChild(){
//logic here to get oldest child
}
}

That's all there is to it. Just use def instead of a static type. Now, as far as Grails is concerned you will have a property called oldestChild. It will even show up in the scaffolding. Hibernate, however will remain blissfully ignorant. Now that I've seen this it seems painfully obvious, but if I hadn't read Chris' answer in that post, I would have never thought of it on my own.

This is just one example, there are many others, so if you aren't signed up for the mailing list or at least perusing the archives, I would encourage you to get started today.

Monday, March 17, 2008

Use .each, Save A Puppy.

If you haven’t been listening to the Grails podcast you’re missing out. Sven Haiges has done a great job of bringing interesting news, tips and interviews related to Groovy and Grails. Now Glen Smith (creator of groovyblogs.org) has joined Sven and a good thing has gotten even better. Could we be seeing the beginnings of the Groovy Posse? Any ideas for the theme song?

My favorite line from the last episode was when they were discussing the old Java for loop and Glen was talking about how he couldn’t imagine using a for loop to iterate over a collection and then said that “Every time you do that a puppy dies somewhere”. So next time you find yourself falling back into old habits, think of the puppies and use .each

Be sure to check out the podcast. It’s supposed to be out fortnightly (that’s every two weeks for us Yanks) so the next one should be here soon!

Sunday, March 16, 2008

I Survived SD West

This post is a bit late, since it's over a week since I got back from SD West in Santa Clara, CA. (March 3 - 7).

There was some great technical content and some very interesting people at this conference, but what made the week memorable for me and the family was that I was scheduled to speak at it. My session was during the last slot of the last day (they always save the best for last, right?). Still mulling over the ideas and inspiration gained from the Groovy/Grails Experience last month, I spent most of my spare time in my room working on my slides, which my kids proofed for me from home. (slides and code sample can be downloaded here)

This is the first of the Dr. Dobbs family of conferences to have any Groovy or Grails presentations: it had one of each. First on Monday Andy Glover gave a very interesting and entertaining half day tutorial on Groovy. You could feel the excitement in the room. In fact a guy sitting next to me leaned over at one point and said "This stuff is amazing!"

Later came my session on Agile Web Development with Grails .... I thought I had my nerves under control, and the audience was involved and had many good questions. It was obvious that these folks were thinking about how and if they could start using Grails. After it was over, it was great to have several people stay and offer nice comments, or ask additional questions. However, one kind lady made the comment that it was "very brave of you to get up there in front of all these people". Perhaps my nerves weren't quite as controlled as I thought.

While the Groovy and Grails aspects were a high point for me, there was some other good stuff at SD West. The Beautiful Code panel was a lot of fun and contained some good insights. The Developer Bowl was a hoot and a half and, James McLurkin of MIT gave a very interesting presentation on robotics and how to save the world by being a geek. Then there was Uncle Bob. Robert Martin has always been one of my favorite speakers and although I only caught one of his talks this time, Clean Code was terrific. We all know shorter methods are better but Uncle Bob gave some very practical suggestions and examples of how to do it.

It was all good, but I'm glad to be home.

PS: The kids didn't really have to carry me on a stretcher, but its good to know that if I ever need this type of assistance, they are up for it.

Saturday, March 15, 2008

Grails' ORM DSL Rules!

Probably my favorite feature in Grails is GORM, the Grails Object Relational Mapping. GORM gives you a host of time saving and powerful tools. Early on I was wowed by the GORM methods that were dynamically added to my domain classes: save(), delete(), list(), get(), findByProp1AndProp2, and the list goes on. I still appreciate these features, but a more recent addition to GORM has moved to the head of the class with me. The ORM DSL introduced in Grails 1.0 makes it trivially easy to map your domain classes onto legacy database schemas. It was already possible to do this in Grails and Jason Rudolph has given us some helpful tutorials, but the ORM DSL makes it so easy even I could do it. And that's important because it enabled me to get Grails into a production project with my current client. They were impressed with the productivity promise of Grails and were quite ready to look into something beyond the JSF/EJB stack they had been fighting with, but having anything or anyone besides the DBA creating the database schemas was out of the question.

Let's take a look at just how easy it is to use the Grails ORM DSL. For our example we will work with the tried and true Book and Publisher classes, but with legacy tables in an Oracle 10g database.

Here's our domain classes in Grails:

class Publisher {
String name
String city
static hasMany = [books : Book]
}

class Book {
String title
String author
Integer pages
Publisher publisher
static belongsTo = Publisher
}

And here's the legacy tables we have to work with:

TABLE PUB01
Column Name Data Type
ID_PUB_PK NUMBER
PUB_NM VARCHAR(100)
PUB_CTY VARCHAR(100)
SEQUENCE ID_PUB_PK_SEQ

TABLE BK01
Column Name Date Type
ID_BK_PK NUMBER
BK_TITLE VARCHAR2(100)
BK_AUTHOR VARCHAR2(100)
BK_PGS NUMBER
ID_PUB_FK NUMBER
SEQUENCE ID_BK_PK_SEQ

Now let's map our Publisher class to the PUB01 table:

class Publisher {
String name
String city
static hasMany = [books : Book]
static mapping = {
table 'PUB01'
columns{
id column: 'ID_PUB_PK'
name column: 'PUB_NM'
city column: 'PUB_CTY'
}
id generator:'sequence', params:[sequence:'ID_PUB_PK_SEQ']
}
}

Let's look at what we did here. We created a static block called 'mapping'. Inside the mapping block, we first define the table for this class (note that the table name and all column names are in quotes), and then we create a nested block called columns. In the columns block we list each property, a space, and then column: 'column name'. Using the word 'column' on each line might seem redundant, but there are other attributes of a property that can be set in the columns block, so when you are setting the column you have to be specific. After the columns block we have the id generation scheme, which we'll discuss in a bit.

Now we'll modify our Book class and discuss one interesting thing there:

class Book {
String title
String author
Integer pages
Publisher publisher
static belongsTo = Publisher
static mapping = {
table 'BK01'
columns{
id column: 'ID_BK_PK'
title column: 'BK_TITLE'
author column: 'BK_AUTHOR'
pages column: 'BK_PGS'
publisher column: 'ID_PUB_FK'
}
id generator: 'sequence', params:[sequence:'ID_BK_PK_SEQ']
}
}

You'll notice that this was pretty much the same thing we did with Publisher. The one difference is the way that we mapped the relationship. The publisher property, which is of type Publisher, is mapped using the foreign key for the Publisher table, 'ID_PUB_FK'

Now let's talk about id generators. In Grails you can use any id generation scheme supported by Hibernate. To do this with the ORM DSL, you basically call an id method and pass it a Map. The first key in the Map is the word generator, and the first value is the name of the generator class, such as 'hilo', 'seqhilo', 'identity' or 'sequence'. The Hibernate docs list the possible classes and their params. The next key is the word params and the value is another Map. The keys for this Map are name attributes of each of the param tags taken by this generator class. The values are the bodies of the param tags. In the case of the sequence generator we only have one param tag, with a name attribute of sequence, and the body would be the name of the sequence in the database, in our example 'ID_PUB_PK_SEQ' or 'ID_BK_PK_SEQ'.

One more note: We were able to talk our DBA into adding a number field called version to each of our legacy tables, so we left versioning on. If you cannot add a version field to your tables (and don't already have one), then you can turn off versioning by adding the line version false after the line where you declare your table. If you do this you will lose the optimistic concurrency that Grails / Hibernate give you and will have to provide some other method of handling concurrency.

There is a great deal more that you can do with the Grails ORM DSL, but I only wanted to discuss features that I've actually worked with. As I dig into this more I may add more details, but in the meantime you can read all about it in the Grails online docs.

Monday, March 3, 2008

Good Stuff In Milwaukee

This past weekend I attended the Greater Wisconsin Software Symposium in Milwaukee. This might seem strange considering I just went to the Groovy / Grails Experience (2GX) last weekend, but it's all part of my master plan. You see, at the 2GX there were 5 concurrent tracks and it was quite difficult to decide which sessions to miss. However, six of the 2GX speakers were also scheduled to speak at the GWSS, I knew that I could safely skip the sessions that would be repeated there. Most notable among those were Scott Davis' pair of talks entitled "Groovy: The Blue Pill" and "Groovy The Red Pill" which I caught on Friday afternoon. These sessions were worth the wait! In the first one Scott focuses on the smooth integration between Groovy and Java; using examples such as creating an interface in Groovy and then creating a Java class that implements that interface. Since, once it's compiled, a Groovy class is a Java class, there's really no limit to the ways you can intermingle Java and Groovy classes. One of my favorite lines in this talk was when asked the question 'will Groovy replace Java?' Scott answers 'No more than icing will replace cake.' That's classic!

The Red Pill talk dug into some the really cool stuff you can do with Groovy once you're ready to take it to the next level. He covered things like method pointers, closures, named arg/var arg constructors and operator overloading. Then he got into meta-programming and,well I don't want to give too much away. You'll just have to catch an NFJS event near you and see for yourself.

Next up was Scott Davis again with “Grails for (recovering) Struts Developers”. This was basically an introductory Grails talk (and a good one), but targeted at developers who were used to the Struts way of doing things.

The next day I can't report on because I went, with my family to the Milwaukee zoo. Well I guess I could report on it but it probably wouldn't be very interesting for someone reading a Groovy/Grails blog. Except that they did have some very groovy apes there.

Sunday morning Venkat Subramaniam gave a presentation on TDD/BDD that was very motivating. He showcased FIT, FitNesse and easyb, by the oh so hip, Andy Glover.

Then on to more testing stuff, Jeff Brown gave a talk on TDD in Groovy and Grails. Testing is another great showcase for the power of Groovy and Jeff did an excellent job of highlighting that.

Then came a hearty lunch, visits with a bunch of fellow Madisonians and the speaker panel. The speaker panel is always a high point of a NFJS event and this one was no exception. Brian Sletten continues to improve his ability to turn almost any question into a discussion of the Semantic Web. (go Brian!). There were two more sessions in the afternoon but I had to catch a flight out to California for SD West, where I will be presenting on “Agile Web Development with Grails” this Friday. Speaking of which, I better get back to work on my slides. But firs I want to mention how great it was to see so many members of the Capital Java User Group at the Milwaukee conference. We could have held a meeting there and it might have been one of our best turnouts. Also I have to give a big Thank You to the good folks at Smart Solutions who offered to send all of their Java developers to this conference. Now that's a forward thinking consulting firm. As well as a great company to work for.