Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

2009-12-04

Surprized by how little I use multithreading...

Back in 2000 I was working on multithreaded applications. Since I was working in Posix environments in C I used the Pthreads library. I learned to use Pthreads from both C/C++ and Perl contexts but I had trouble with managing Pthreads and in 2000 I perceived that Java's threading would be easier to use.

For an honest and unbiased comparison of Pthreads and Java threads based on the state of things (at that time) you can look at this paper by Wim H. Hesselink which manages to cover in 8 pages most of the differences. It was these differences between C/C++ and Java that made me interested in shifting from Posix to Java development.

As it turns out, now that I work primarily in Java (something that took me the better part of a decade to orchestrate), I rarely make practical use of multithreading in Java. For the most part you don't need it when you work in an application server. In the cases I typically encounter if you structure your Java application properly it doesn't need explicit multithreading.

Notice, I said explicit. In Java Application Server environments we have tools like messaging queues and timers. Using these Application Server tools properly implicitly produces the same effects as you would get by setting up your own threads and these techniques tend to create fewer bugs since you aren't forced to write thread management code that is easy to make mistakes with.

So, what I'm looking for now are examples of problems that using JMS, asynchronous request processing, or Quartz timers won't provide a clean solution. Why do I need to use multithreading explicitly in today's managed Application Server world? What am I missing?

And once I'm developing multithreaded code... how do I test it?

I've gotten responses from some prominent developers out there already and I hope that we can collaborate and share from the experience. I am excited at the chance to learn from some of the people that I consider to be great thinkers in our community. Either way I know I'll learn something. In the end that's what I'm really after.

2009-11-02

Apache Ivy: Componentization? What's hot and what's not?

I'm working with Apache Ivy over the next few weeks. The problems I'm trying to solve are around the testability of a J2EE application and its functional decomposition. I have chosen Ivy after an evaluation period due to its simplicity and how easy it is to port Ivy into existing Ant build systems.

In the case of the Grails applications I'm working with this problem domain is all rather straight forward. The Grails applications can be functionally decomposed easily along plugins and modules. They were all developed with a Test Driven Design (TDD) mentality and so have a large suite of test automations around the application. NOTE: I have not yet picked a code-coverage tool for this environment, however, so don't ask about code coverage for now okay... suggestions are welcome.

The problem still lies with the J2EE application. I have several components I can identify that have not changed in years since the original system designers bequeathed the code to their heirs. The original system had no automated testing but had ample "test scripts" which were human driven. In some respects I'm shocked at this approach to testing but I can't say it surprises me.

I've been in work environments that literally employed armies of testers. (No really, it was literally the Army... literally armies of testers.) And while there is a place for this if you can afford it ... doesn't it make sense to focus those human-level testers on testing human-level problems? I'm not talking about getting rid of those armies of testers just focusing them on the most interesting problems, saving their collective power for the big issues.

So, here's my hypothesis about how you should decompose an application already long in development, with no automated test harness so it can be better managed. It's a work in progress so please help me knock off the rough edges or if you think I'm daft... let me know.

I'm operating under the theory that the human testing in fact exercises all relevant existing code as it is compiled and bundled up as a part of the whole system. Any components we identify were in that tested whole. Any components we create will be tested under the unified whole. Therefore any movement of components creates no net change in the whole. This initially appears pointless but positions us to begin creating automated unit and integration tests around the identified components. The outcome creates no user-visible results initially but is incredibly important since it makes adding features much more certain.

The end goal of the introduction of Ivy is to identify stable framework components and put those components under tests that mimic the current human-based test scripts. The end result will be the ability to identify the volatile system components and isolate them for focused testing and design work. This is desirable because you isolate the system's accidental complexity and help keep it away from its intrinsic complexity. You should in the process be able to identify layers of abstraction in the system.

NOTE: An interesting side-effect is that classes designed for use with RMI may not change frequently right now but we have observed that they will "break" backwards compatibility at seemingly random intervals. Since our system is distributed this poses a problem. Decomposing these RMI interfaces and classes into their own Jar (compiling them separately and only on the event that they are changed) means actions that change them thus breaking compatibility between nodes will become very apparent since it will be harder to make the change accidentally.

Working theory: Componentization of large existing systems

I'm thinking that (in the large existing system) you want to only decouple packages of classes from the grand unified build that have little change between revisions. You should be able to identify these "stable components" by creating a "heat map" of the repository and watching the rate-of-change in the change control system. The more frequent the changes the "hotter" the class. The "hotter" the class the closer to the other frequently changing components it should be... ostensibly going under a new round of full tests with them. I would only select the coldest classes to be moved into components for control by Ivy.

I will take these carefully selected classes and move them to a separate module to be built and packaged as a single Jar file. These will be placed in the Enterprise Ivy repository for management by Ivy. At build time the project will download these Jar files, just like other Ivy dependencies, from the Enterprise's Ivy repository.

When the unified whole goes under test part of that whole will be the independent Ivy managed Jars. These Jars can be instrumented during our human-driven tests to see how they are exercised by those armies of humans. With that documentation I can then devise unit and integration tests to reenact those human-level tests on the isolated Jars. That means, the next round of the application's life cycle will have a set of automated tests that document how the system operates.

Once we know what the colder classes do we can begin to formulate a framework based on them. And that begins the first steps to identifying and targeting changes to the system to add to what it can do... or designing a replacement... or designing a new feature. Each time behavior changes in the future it will be more explainable and thus more controllable.

And you start getting there by identifying what's hot and what's not.

Have I gone wrong? Commentary?

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.

2008-12-11

Groovy related random links

Here's some links in no particular order and for no particular reason...

Groovy + Ant = GANT - Guillec treats us to a Venkat inspired tour of Gant.

Practically Groovy: Of MOPs and mini-languages - an Andrew Glover classic on MOP and a good read. I dusted it off in recently to refresh my memory.

Getting Groovy with with - Jeff Brown drops some Groovy moves on us. Always one for the slick trick that Jeff Brown.

How to write a Spelling Corrector - Rael Cunha shows us a reimplementation of the Norvig spelling corrector. Rael's post is really on Java but still shows some Groovy. Is there a Groovier version?

Some JavaFX, Java, Groovy Examples - Andres Almiray blows minds with his meta-hot JavaFX/Groovy cross over code. Along with his follow up it's a fantastic example of JVM polyglot programming.

... and now for something completely different.

2008-11-12

Fighting Annotation buildup

It was called XML hell. More precisely XML configuration hell. You would spend hours and days fighting with XML configurations that grew in size and complexity until they became a nightmare.

They call it Annotation hell. It is what happens when you get a the same problems as you had in XML hell manifesting in Annotations. The earliest mention of Annotation hell I can find is from 2004 in James Strachan's old weblog where he uses the term "annotation overkill" but is wrongly quoted in other blogs as saying "annotation hell".

There is an Annotation hell. And I've seen it. A good example is here in Eric Redmond's blog Annotation Hell where he posts a method with 10 annotations on one method operating in at least four contexts.

I've seen this before... although admittedly not nearly as bad... and I have called the same thing "Annotation Buildup" it's the cruft you get on a class that you are annotating for too many simultaneous execution contexts. It is a symptom of a design philosophy flaw.

The annotation centric design directly reverses the problem of XML hell by merging everything back into the class. This is good. It centralizes information related to the class into one place. The flaw is that all the configuration piles up in the same places and it isn't clear how the annotations make sense.

Grails solves this problem using Convention over Configuration (CoC) and a GORM Mapping DSL the effect is a much cleaner looking class. GORM can use the JPA if configured properly. And this isn't a bad combination to work in but the real advantage is being able to both centralize configurations for a class and also group them by context.

Convention keeps configuration hell at bay whether it is created by XML or annotations. Allowing a configuration DSL allows you to keep the flexibility of configurations without the XML and by placing the DSL inside the class definition you can keep everything related to a class together. The DSL also have the advantage of keeping related configurations grouped together so that you don't have to stare at a pile of annotations that don't relate to each other.

CoC in combination with in class DSL for configuration can keep annotation buildup at bay and keep away XML and annotation hell.

2008-11-07

More fun with Groovy and Reflection API

This time in a TagLib I need to see all the properties of a domain class but I don't want to look at anything that isn't sent to hibernate.

import java.lang.reflect.Modifier
static getFields(obj) {
def names = []
def fields = obj.getClass().declaredFields
fields.each({ field ->
if(!field.synthetic)
if(!Modifier.isStatic(field.modifiers))
if(!Modifier.isTransient(field.modifiers)) {
names.add(field.name.toString())
}
})
return names
}

... in another method I'll filter out the Closures by checking against Closure.class and the property's class.

2008-08-18

Frameworks, delicious frameworks...

This blog has been on "auto pilot" for the last few weeks while I've been on vacation. As my reserve of scheduled articles has dried up I guess it's back to work. I'll be at the trijug meeting tonight. We'll be hearing from Hadrian Zbarcea about Apache Camel which is yet another framework on top of Spring.

As I've noted previously in this blog, the J2EE space is being very effectively invaded by Spring. So effectively so that even J2EE Application Server provider JBoss provides Embeddable EJB3 which is a sub-set (as of this writing) of the full EJB3 environment that can deploy on "light weight" containers such as tomcat.

If that last paragraph made no sense, try thinking of it this way... JBoss, WebSphere, and other Application Servers provide a host of services that are considered part of an "Enterprise" stack. These services sit underneath specific applications. These are things that are conceptually low level like messaging between processes/beans, facilities for looking up shared resources, data persistence and storage, and security. Things like HTTP, HTTPS, and such are considered additional services and are provided by applications. A typical J2EE application looks up the additional resources it needs as it runs. So when your bean initializes it has to do a lot of leg-work looking things up and initializing resources.

The EJB3 application standard is in part an Inversion of Control framework. In some situations using Java 5 annotations EJB3 beans specify what resources they need and the framework wires up those resources so that they are available. Most notably the Entity Manager is usually wired up using annotations and not using JNDI lookups. It's so radically different that we call the new paradigm JEE 5 in some circles... not only skipping the numbers 3 and 4 (which are ugly looking anyhow) and jumping right to (the sexy looking) number 5... but also moving the number to the end of the acronym so we can spot the noobs.

Spring works on this Inversion of Control (IoC) design principle and this is a key feature of Spring that Grails makes heavy use of. The design inverts the J2EE sensibility of having a bean init and then look up everything it needs. It puts the control of a bean's initialization in the hands of the framework. Working this way actually means that the majority of logic for how a application server works moves out of the application server itself and out of the application and into the framework and its configuration files.

That means you can run complex applications in simpler "containers" like tomcat and jetty. That makes server administration simpler for shops running smaller and simpler applications. Shops with larger and more complex applications can migrate their Spring applications to heavier more robust clustering Application Servers. So you have simple to scalable in these lighter frameworks.

But, without the conventions found in Grails, IoC and Spring applications become "XML-er-ific" and choc-full of XML-ly goodness. You end up having to specify nearly all the same lookups and wirings you were having to do under J2EE anyhow. You just move the work from compiled Java to light-weight XML. It's better but you don't really escape the work.

This configuration issue is where Grails shines. Grails removes the need for most configuration work by introducing conventions. Because Spring is still under Grails you can over-ride or change the conventions if you want or you can abide by them and get the full benefit of Grails. So once again Groovy and Grails provide you with the choice of staying as shallow or diving as deep as you need. A great benefit that is missing in most development frameworks which either force you to become an expert of force you to keep the training wheels on forever.

I'm curious to learn about Apache Camel to see how they solved these issues. I'm also curious to see if JBoss will bring along their embeddable EJB3 to compete in this space. Obviously Groovy/Grails is my personal favorite but I'm always up for learning from others.

2008-04-28

Changing the face of UI

I have talked previously about how I felt about many of the UI building environments out there today. My UI experience comes from a nearly decade old C/C++ experience in CaveGL, OpenGL, and GLUT... so I can't speak much to Java UI. Fact is I've never had to build a full Java UI for a commerical project before. I've only had toy Java UI projects.

Recently, when an opportunity to do real Java UI work landed in my lap, I jumped on it a little too eagerly. In my time working with Java UI I've found that unlike my days with OpenGL and other open source GUI rendering tool kits the ones for Java are comparatively opaque.

Part of what worked well in those "primitive" environments was how easy it was to stumble upon or discover the API and design a system with trial-and-error. My feeling is you can't do this in Eclipse because the system has too many moving parts to just tinker with and discover. I feel strongly that software on any level should encourage play and discovery and be tolerant of screw-ups by the user.

I've also mentioned that UI should perhaps be a descriptive exercise. That is to say that the look of UI should be described and computed. The function should be meticulously programmed but the look and feel should be easily changed and readily played with.

Today I found this project, Java Builder. The idea behind Java Builder is exactly what I've been trying to express in words. Java builder provides a YAML based DSL to describe Java UI. The YAML is turned into straight Java.

This is brilliant work that is moving in the right direction.

2008-04-16

Audit Logging in Grails

EDIT: Audit Logging is now available via the grails command line tool
$ grails install-plugin audit-logging


Here's the story of how I ended up writing an AuditLogging plugin for Grails. I've posted the Grails Audit Logging plugin here. And I'll do a more formal write-up later. A demo project is here if you want to see it in action.

So, my story.

I have a project that I needs audit logging for certain objects in my domain. As usual (in the last six months) I started the project using Grails because of it's powerful and full featured GORM tool. GORM in case you didn't already know is built on top of Hibernate. So that means deep down we have the powerful hibernate events model to hook into.

A couple of years ago on the LAMP stack I would have written triggers in my database to handle the changes to certain tables. This would have the distinct disadvantage of not having any knowledge of the actual domain model that the table was supporting.

Today I can hook into Hibernate and get the same results keeping my domain class and triggers nice and close to each other.

Honestly, I would have probably went with the in database triggers and felt bad about it. Thank goodness I stumbled on this blog entry by Kevin Burke I would have had a much less interesting and satisfying project. Instead Kevin's influence caused me to create the AuditLogging plugin for Grails.

Kevin had the need to hook into the Hibernate Events model, and had already written the Grails Hibernate Events Plugin. I was still a few weeks off from needing this plugin but I was glad to see it existed. Frankly, I'd be utterly lost without Kevin's plugin to show me how to work with Grails and Hibernate Events.

In true groovy fashion Kevin's work leans heavily on closures. He's added ten new conventions to GORM domain classes for use in the events plugin. I won't list them all there but the ones I was interested in were the afterInsert, afterUpdate, and afterDelete events and their matching closures.

When fired the event handler will call each closure from the matching org.hibernate.event.*Listener class. Kevin's project doesn't need to see the old values and compare them to the new values. So he doesn't pass these back down to the handlers defined in the class. Unfortunately for me. That's not going to work. I need audit logging and I need to be able to do custom things for some domain classes when certain values change. Pretty tall order actually.

I spent some time reading up on events in Chapter 12 of the Hibernate 3 documentation. And taking a look at the Hibernate documentation I can see that any of the event objects nicely expose the Hibernate internals. In specific using the event object I can snag the EntityPersister that fired the event. That's interesting since I need to be able to see specifically what changed and throw one of 35 different event objects (that's a specific detail of my current project) out into GORM when it happens.

In particular I want to have a very groovy plugin that can be turned on and off for a given domain class using a convention like searchable does... I want it to be able to specify an "onChange" handler that can see old values and new values and do different things depending on what changed and how it changed... yeah... a pretty tall order.

That's why I'm so surprised at how easy this was to write. I was lucky to have the work of Rob Monie and even Kevin's Hibernate Events plugin to reference. The result is a plugin that you can use pretty simply.

To install my plugin just:

$ grails install-plugin http://shawn.hartsock.googlepages.com/grails-audit-logging-0.1.zip


Then in your favorite domain class do this:

class MyClass {

static auditable = true
Long id
Long version


String someValue

def onChange = { newMap, oldMap ->
oldMap.each({ key, oldVal ->
if(oldVal != newMap[key]) {
println " * $key changed from $oldVal to " + newMap[key]
}
})
}


}


Now when the class is acted on a new AuditLogEvent record will be inserted. The record will record when the event happened and what changed. If it's an insert or a delete then it will only record that the event happened.

What if you don't want every detail logged but only wanted that onChange handler? Then you can specify

static auditable = [handlersOnly:true]


Now only the handlers you specify will be called. My plugin handles onSave, onUpdate, onDelete, and two types of onChange. The first type of onChange takes two parameters. The second kind takes none. In practice the no parameter onChange is identical to the onUpdate.

I'm putting this plugin to use in my project now. Hopefully someone else will find this useful. This work is still very rough but I will be torture testing the plugin in my own project which will have thousands of events per second. Any input is appreciated.

EDIT see also Grails Audit Logging Plugin

2008-04-01

Dominant Groovy

Steven Devijver has an interesting post over at java.dzone.com titled Groovy will replace the Java language as dominant language

While I'd love to agree with Steven, I'm afraid I don't. Now... I think Groovy has the potential to be very very popular on the JVM and I think it is a wonderful way to work. Python didn't replace C. From Steven's own article:

Groovy is the dream child of James Strachan, extravagant open-source developer and visionary. While waiting for a delayed flight he was playing with Python and found it such a cool language that he decided the JVM needed to have a language like this too.


No matter what programming language popularity chart you like to stare at and hit reload on in the middle of the night the top two languages today are Java and C not C++ but good old C. That means that even when some programmers could choose from Python, Perl, PHP, Ruby, Haskel, or a whole bevy of languages the still choose C. So I think we'll see the same on the JVM. Many programmers will have the chance to adopt other tools other than Java but the majority will probably choose to stay with Java.

This is a bit of a warning to Sun. C hasn't had new features in a while. Maybe Java shouldn't get new features so fast either? Creating new languages to support new features seems like a really good move to me.

I really like Groovy a lot and I sincerely hope Groovy makes it into the top 10 programming languages in the world in the next few years but I don't think Groovy will supplant Java in the near term. I can see a time when nearly all Java testing is done in Groovy and much web development. But, even when Grails gets "serious" they use Java.

I also don't buy the analogy of "Java is assembly to Groovy" argument. I think Groovy is to Java as Python is to C. This is a big deal on the JVM since scripting on the JVM has been very hard to do. I remember a long time ago there was talk of porting Perl to the JVM and that never really materialized. There is serious work today on Ruby for the JVM and that work seems to have legs.

The idea for multi-language VM is a very good idea. I also think it's counter productive to speculate on who will trump who for popularity. So far I've only seen this cause problems for people and create unnecessary friction. Soon there will be a very big swelling of Groovy support in niches where performance is trumped by developer productivity but where performance still holds sway over productivity and code output Java still reigns.

2008-03-17

Working with Grails 1.0.1 inside Eclipse

I've started on a new project using Grails 1.0.1 and I've had to change a few things since working with Grails 1.0-RC4. Fortunately I did get an upgrade to Grails 1.0 into my application before deploy but 1.0.1 came too late to make it through our regression testing on that application. Today starts a new development project from scratch so I'm using 1.0.1 and when I went to use grails create-app it crashed on me... sorry I wish I had saved the trace... but I fixed this issue by deleting the ~/workspace/.metadata directory from my workspace.

Unfortunately, when you delete the .metadata directory Eclipse forgets many of your settings. In setting up my new eclipse project for Grails I set up the Eclipse Groovy plugin to output to bin and I set the build path of Java to output to project/bin which made both Groovy and Java compilers output to the same directory. This seems to work well with JPA classes too. After I get farther with this project I'll write up yet another Groovy, Grails, and the JPA tutorial using the new 1.0.1 conventions.

This next project will make heavy use of XML and XSD files as well so this should be a very informative project. Another problem to solve will be using SSL certificates and CAS. The CAS work has been very easy thanks to the CAS Client Plugin for Grails (it works great if you already have CAS set up). Now I need to add role management... but that's another story.

2008-03-15

... with the Eclipse RCP

I've been working with Eclipse RCP and the SWT on a project lately.

I started writing software in C/C++ about a decade ago. I remember working with C programs and UI back then as state machines. Essentially the UI would set states that a processing thread would later act upon. If you think about it this was an early form of Model View Controller separation.

I understood this type of separation well because the main process and the UI process essentially communicated through a set of state variables. If you were smart you nailed down these state variables and kept them in a central location and made them easy to understand.

I actually worked this way for most of my career... except for a few years back around 2000 when I joined the Internet hordes... and except for the last 4 years when I started working on Ajax applications (well, we didn't call them Ajax applications until recently).

I was pretty well familiar with Ajax by the time an opportunity to work with SWT came around. I had one project in Swing in the fall of 2001 but since then Java UIs weren't in the picture for me. I'll tell you EJB3 was a welcome change from the J2EE work I had done back in 2001 but that's another post entirely. Let me focus on the SWT in this post.

When I was given the chance to take apart and enhance an Eclipse RCP project I saw it as a golden opportunity to gain familiarity again with Java desktop applications. That's not an area that I personally get to work with much. Most of my time is spent working with server-side and database projects... ironically my university emphasis was on 3D graphics in OpenGL... so a chance to work with graphics again was really welcome.

The SWT and Eclipse are not kind to new comers though. In particular you need to be careful of "kitchen sinking" your Eclipse IDE when you go to develop on it. The rule for how to keep Eclipse from getting "kitchen sunk" seems to be to keep the plugin base as minimal as possible. A bit of a pain especially since the Eclipse plugin manager will let you break Eclipse out-right by letting you get into a configuration that "does not contain the platform" (whatever that means) so that you have a nicely dead eclipse.

I hadn't realized that I had been lucky with eclipse up to this point. Most of my projects being server side didn't need advanced Eclipse features such as the GEF. Apparently if you try to use VE, GEF, jface, and eclipse.ui in the same project you're going to be doing some juggling.

Soon after I launched into this project I decided I needed training material since I wasn't intuitively picking up on SWT. The Visual Editor (VE) works with both SWT and Swing components but that's no consolation if you don't know either very well. It still isn't easy to make progress.

And this is where I think I'm starting to change my mind about a few things. I'm sure you've seen the GWT (that's the Google Web Toolkit if you didn't know) and it's basically a Swing/SWT type of web programming UI library. This is great if you like that kind of UI work... but really... I don't think I do.

I think I actually like Ajax and that mess of HTML and I think I like it because it's so easy to see what a UI element is going to look like. I think the HTML forces such a clean break between the controller and the view that it's actually beneficial. It's a disconcerting view for me to entertain because I actually come from a C/C++ background and I would probably prefer a more rigorous UI development environment.

In my utopia VRML would actually have lead somewhere instead of dying out. The concept behind a VRML interface and a web page is that presentation should be scripted. The idea of a mark up language hinting at a layout for a render engine is some what radical by itself but once you accept the idea ... you have to wonder why not use it everywhere?

I've actually had to write postscript drivers and code generators for postscript code. Postscript is actually a remarkable display oriented language. It is also far from a mark up language looking more like a custom graphics DSL than anything. So it's no shock to me that it may have taken two decades for the industry to accept the idea of markup for describing how to display things.

Consider that HTML and VRML are concerned with general descriptions of elements and leave the particulars of display up to the render engine. And this is the liberating feature of the markup language you get to care about only the particulars you want to. That frees the designer to paint with a broad brush and can separate the design and implementation functions very nicely.

Certainly the same discipline can be applied to work done with SWT, GWT, and Swing but that requires the effort and attention of the programmer. The web interface and its restrictions actually force the issue of the separation of design and function.

*sigh* but, design and function aren't actually separate are they... design dictates what a function must do and a function is only comprehended through the design of the interface to the function. A chair must have the shape of a chair... a cup must be a cup. Handles and legs and decoration can be added without too much troubling the core purpose of the artifact but ... really the design and function are one and the same.

So what am I saying about the SWT, GWT, Swing, or any other UI design API for that matter? I guess I'm trying to get at this idea that you need to be able to describe the UI in graphical terms. Component UI toolkits procedurally describe how a UI is built up in steps... and it's still procedural even if the procedures are encapsulated in objects.

Consider in all the UI toolkits I know (other than the Ajax ones) you build a menu object, build a menu item object, give the menu item object a code, enum, or pointer to a method to call, and then inject it into the menu object at menu initialization. This is very procedural and has virtually nothing to do with what a menu is graphically.

Now consider an Ajax design: You mark up a set of blocks to hold the menu items and apply style guides to them and then hook the onclick event to the appropriate action or link. The trick here is we are describing visual elements and the only thing that makes anything a menu is how it is used. That's a subtle but important paradigm shift.

It's subtle because a menu element and a menu object aren't conceptually that different. It's important because a menu element is really just a display block primitive with some style guides and a menu object is a much heavier complex and rich thing. But in the end they both do the same thing. It's just that one way is describing a thing that happens to get shown in a particular way graphically and the other is describing a graphical thing that happens to get used in a particular way programmatically.

The markups are interested in describing visual elements given a handful of visual primitives but the toolkits are focused on the aggregation of visual elements in a prescribed taxonomic hierarchy. That means that the toolkits are actually in danger of creating an impedance mismatch akin to the famous object-relational impedance mismatch that we've fought in OOP and RDBMS circles for the last decade or so.

I wonder if we won't see talk of a UI-Object impedence mismatch or other metaphorical terminology for the mismatch between UI and UX expressions and the creation of component based taxonomic object hierarchies that pervade the practice of OOP. This is an especially ironic argument to make since OOP was created to better match a graphical environment. It's actually almost silly to make the argument against using OOP for GUI work... but here I am entertaining the notion.

I am looking to technologies like ZUML in the Zk Framework to start showing us if markup-componentized hybrid frameworks are actually feasible in a non-proprietary system. For now it's simply not practical for a "main stream" application to entertain the use of a Zk based design. Unless you and your users are ready to surf the cutting edge you will have to ride along with the rest of us and our component based frameworks.

Or you could go with Ajax.

For now I've decided to continue slogging through my work with SWT and Eclipse but it's really because I've got too much into this particular direction to back out now. I will say I have high hopes for the GroovySWT project and I've already sampled the Groovy Swing project. These are very nifty projects that promise the creation of a builder or markup-like way to express GUIs in both Swing and SWT. Hopefully both projects can find ways to "macro" or simplify UI building in the process of providing a new way to rapidly build up UI. The SWT builder already provides a very intuitive container syntax that eliminates some of that counter-intuitive procedural buildup code you find in Eclipse RCP Perspective and Activator objects.

I for one welcome our new groovy-builder overlords.

2008-01-27

Paradox/Parabox of Choice

A late night post due to a late night. Some things are bothering me and I decided to put them in words.

Consider this post on slashdot this is problem is real and a real burden to many shops. If you were a LAMP shop and that 'P' was Perl and then you add PHP because marketing wants something... and then you add RoR because somebody thought it was cool. Then you add Java to the mix. How many platforms are you supporting? How many different server configurations... and what is that costing you?

Even if you are a Java shop which kind of Java shop are you?

Both Neal Ford and Scott Davis talk about this idea called "The Paradox of Choice." The problem is that in Java land there are far too many choices between frameworks for anyone to comprehend and deal with. The paradox is that when given too many choices people can't make any choice.

Java has so many frameworks for so many different environments that it has become a joke amongst techies: "How many Java frameworks are there? Dunno, a new one comes out every second so what time is it?"

In typical tongue-in-cheek fashion I will instead refer to The Farnsworth Parabox of choice. This is a technique that I think will help. See the Parabox is a box that Professor Farnsworth put the universe inside... or is it a box with a universe inside it? Anyway at the end of the episode the Professor had created a box that contained our universe. Grails is your box. Grails contains the universe of Java but it fits neatly into a box.

Think inside the box. Check to see what works well with Grails. No seriously. If you use the Grails "defaults" you can effectively eliminate the need for making dozens of choices. Which framework to use? Well, what is the Grails default? Spring it is. Which application server to use? Which one comes with Grails? Jetty it is.

When you reach the edge of the box or can't fit a need you have into that Groovy/Grails box that's okay because the whole universe of Java is inside that box too. All you have to do is reach down deeper beneath the Groovy skin and dig into Hibernate, Spring, or EJB3 and that whole cosmos is ready and waiting for you. Conversely, if you are comfortable floating around in the gigantic universe of Java then you can reach down into the box and take out what you need.

Grails is the Java universe in a box.

2008-01-18

Deploying Grails on JBoss 4.2.1

I'm deploying Grails applications into a shared JBoss environment. Now if you've read the Grails FAQ there's a nice bit in there about deployment isolation in JBoss. Specifically you'll use jboss-web.xml and isolate the deployment. If that works for you kudos. Didn't work for me.

When I isolate my deployment I see this error:

17:02:08,115 INFO [STDOUT] [5] digester.Digester Digester.getParser:
java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl
at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:107)
at org.apache.tomcat.util.digester.Digester.getFactory(Digester.java:487)
at org.apache.tomcat.util.digester.Digester.getParser(Digester.java:692)
at org.apache.tomcat.util.digester.Digester.getXMLReader(Digester.java:900)
at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1562)
at org.apache.catalina.startup.TldConfig.tldScanStream(TldConfig.java:507)
at org.apache.catalina.startup.TldConfig.tldScanTld(TldConfig.java:544)
at org.apache.catalina.startup.TldConfig.execute(TldConfig.java:294)
at org.apache.catalina.core.StandardContext.processTlds(StandardContext.java:4450)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4257)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:761)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:741)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:553)
at sun.reflect.GeneratedMethodAccessor233.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297)
at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.apache.catalina.core.StandardContext.init(StandardContext.java:5310)
at sun.reflect.GeneratedMethodAccessor229.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297)
at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.web.tomcat.service.TomcatDeployer.performDeployInternal(TomcatDeployer.java:301)
at org.jboss.web.tomcat.service.TomcatDeployer.performDeploy(TomcatDeployer.java:104)
at org.jboss.web.AbstractWebDeployer.start(AbstractWebDeployer.java:375)
at org.jboss.web.WebModule.startModule(WebModule.java:83)
at org.jboss.web.WebModule.startService(WebModule.java:61)
at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
at $Proxy0.start(Unknown Source)
at org.jboss.system.ServiceController.start(ServiceController.java:417)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy182.start(Unknown Source)
at org.jboss.web.AbstractWebContainer.start(AbstractWebContainer.java:466)
at sun.reflect.GeneratedMethodAccessor212.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:97)
at org.jboss.system.InterceptorServiceMBeanSupport.invokeNext(InterceptorServiceMBeanSupport.java:238)
at org.jboss.ws.integration.jboss42.DeployerInterceptor.start(DeployerInterceptor.java:93)
at org.jboss.deployment.SubDeployerInterceptorSupport$XMBeanInterceptor.start(SubDeployerInterceptorSupport.java:188)
at org.jboss.deployment.SubDeployerInterceptor.invoke(SubDeployerInterceptor.java:95)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy183.start(Unknown Source)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1025)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:819)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:782)
at sun.reflect.GeneratedMethodAccessor25.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
at $Proxy9.deploy(Unknown Source)
at org.jboss.deployment.scanner.URLDeploymentScanner.deploy(URLDeploymentScanner.java:421)
at org.jboss.deployment.scanner.URLDeploymentScanner.scan(URLDeploymentScanner.java:634)
at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.doScan(AbstractDeploymentScanner.java:263)
at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.loop(AbstractDeploymentScanner.java:274)
at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.run(AbstractDeploymentScanner.java:225)
My first guess is this has something to do with a conflicting version of the Xerces libraries between JBoss and Grails. But I'd rather not resolve this issue...

If I turn off deployment isolation and then hit a JSP page in a non-Grails application (carefully selecting a JSP that has never been hit before) I get this error:

Caused by: java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:903)
17:11:58,316 INFO [STDOUT] [2008-01-18 17:11:58,314] DEBUG core.ApplicationDispatcher.:185 servletPath=/Login.jsp, pathInfo=null, queryString=null, name=null
17:11:58,317 INFO [STDOUT] [2008-01-18 17:11:58,316] DEBUG core.ApplicationDispatcher.doForward:375 Path Based Forward
17:11:58,319 INFO [STDOUT] [2008-01-18 17:11:58,318] DEBUG servlet.JspServlet.service:249 JspEngine --> /Login.jsp
17:11:58,321 INFO [STDOUT] [2008-01-18 17:11:58,320] DEBUG servlet.JspServlet.service:250 ServletPath: /Login.jsp
17:11:58,323 INFO [STDOUT] [2008-01-18 17:11:58,321] DEBUG servlet.JspServlet.service:251 PathInfo: null
17:11:58,325 INFO [STDOUT] [2008-01-18 17:11:58,324] DEBUG servlet.JspServlet.service:252 RealPath: /home/shawn/jboss/jboss-opengate/server/default/./deploy/VIF.war/Login.jsp
17:11:58,327 INFO [STDOUT] [2008-01-18 17:11:58,326] DEBUG servlet.JspServlet.service:253 RequestURI: /VIF/Login.jsp
17:11:58,329 INFO [STDOUT] [2008-01-18 17:11:58,328] DEBUG servlet.JspServlet.service:254 QueryString: null
17:11:58,331 INFO [STDOUT] [2008-01-18 17:11:58,330] DEBUG servlet.JspServlet.service:255 Request Params:
17:11:58,335 ERROR [STDERR] [2008-01-18 17:11:58,333] ERROR [/VIF].[jsp].invoke:719 Servlet.service() for servlet jsp threw exception
java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jsp.Login_jsp._jspInit(Login_jsp.java:25)
at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:323)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:687)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at org.apache.catalina.authenticator.FormAuthenticator.forwardToLoginPage(FormAuthenticator.java:316)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:244)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:437)
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:381)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:595)
17:11:58,336 WARN [FormAuthenticator] Unexpected error forwarding to login page
javax.servlet.ServletException: java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:274)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:687)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at org.apache.catalina.authenticator.FormAuthenticator.forwardToLoginPage(FormAuthenticator.java:316)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:244)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:437)
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:381)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jsp.Login_jsp._jspInit(Login_jsp.java:25)
at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:323)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
... 20 more
Which I know thanks to this post has something to do with the Jasper compiler. So I turn off isolation remove the jasper, xalan, and xerces libs and viola it all works.

That's because JBoss has this Unified Class Loader... or something. Once a class is seen it's loaded and available to all the non-isolated archives on the system. That's what is solving that first exception when we tried to deploy the WAR while it was isolated. Instead of having our copy of the class and JBoss's copy of the class we have one and only one copy of any given class.

It turns out that the deployment needs to hand back a copy of a org.apache.xerces.jaxp.SAXParserFactoryImpl to the JBoss environment. The classes don't match and boom! your deploy blows up. Remove isolation and you get the Jasper problem. Which doesn't manifest until after you try and use a JSP outside Grails that has never been used before.

The second stack trace is caused by the Jasper libraries embedded in your Grails WAR bleeding out into JBoss land and generally mucking up the JSP compilers in the JBoss container. To stop this remove all the jasper Jars from your application.

This doesn't strike me as best practice but it's the best I've got on short notice.

So the short answer? Remove these JAR files from your Grails WAR when deploying into JBoss 4.2.1GA if you don't use jboss-web.xml:
  • jasper-compiler-5.5.15.jar
  • jasper-compiler-jdt-5.5.15.jar
  • jasper-runtime-5.5.15.jar
  • xalan.jar
  • xerces-2.8.1.jar
  • xercesImpl-2.6.2.jar
  • xercesImpl.jar

Without deployment isolation on a newer JBoss you don't need any of the hibernate JARs either and it's tempting to remove even more JARs to trim the deploy. I haven't done this yet but it seems that because Grails doesn't know what your deployment environment already has in it you can't expect grails to find this combination of classes for you.

If you do use jboss-web.xml to isolate your deployments then you need to make certain your xercesImpl.jar, xalan.jar, and other XML jars are the same version or at least compatible with the JBoss libs.

EDIT
I don't have to do any of this when using Grails 1.0 so this only applies to older Grails versions.

2007-12-18

Single Sign On with JBoss Portal and Active Directory

No one has asked for it but I've begun work on a SSO project when I'm between official projects. I discovered the power of Acegi and CAS. I have an install of the JBoss portal as well and that requires its own set up too... however it is looking like we are going to use Joomla instead.

I began with understanding how to talk to an ldap server (in my case Active Directory). Once I understood how to query LDAP I began searching around using my groovy scripts to find the object classes, and specific names I would need inside my CAS configuration.

I then followed this tutorial for CAS to authenticate the users:

Next I built in the CAS client into JBoss portal using this wiki page's instructions:

Finding the specific settings were hard. In particular I had to muck about with the ldap_identity-config.xml deep inside our jboss-portal.sar file... it turns out our AD setup is somewhat "special" and needed some extra care beyond what is in this page:

I have no idea how I would have figured out how to do that kind of configuration without that wiki page.

Once I managed to stitch together both sets of instructions I could have my users authenticate via CAS and then the portal would query roles on its own against Active Directory.

Next I'll investigate how to bring Groovy and Grails into this mix. I'll have a project for delivery in March that will need to hook into this SSO system... and likely subsequent projects to link into the CAS system using PHP and Perl.

2007-11-14

Groovy Grails and the JPA

If you are using Grails 0.6 or later chances are the tutorials you've found for making EJB3 persistence annotated POJOs work with Grails don't match up exactly. If you're like me, probably need to be made aware of a few differences in configuration. They aren't big... but the little differences could trip you up.

First note my version of myApp/grails-app/conf/DataSource.groovy

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
dataSource {
configClass = GrailsAnnotationConfiguration.class
pooled = true
dbCreate = "create-drop"
driverClassName = "com.mysql.jdbc.Driver"
dialect= org.hibernate.dialect.MySQLInnoDBDialect
url = "jdbc:mysql://localhost:3306/grails"
username = "grails"
password = "grails"
}

Is not the same. Just because configClass = GrailsAnnotationConfiguration.class is set and your IDE says the class is found in this context doesn't mean that it's working for you... that import above still has to happen...

Next, I have added a file under "grails-app/conf/hibernate/hibernate.cfg.xml" and this part goes pretty much like the tutorials from last year... you register each class here one at a time. I need to research this one but I think grails mixes in this hibernate.cfg.xml with another one at run time so just stick to registering your classes. I tried to get fancy here and it didn't work out too well. My working hibernate.cfg.xml looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping package="com.mycompany.shared.domain" />
<mapping class="com.mycompany.shared.domain.Subject" />
</session-factory>
</hibernate-configuration>

You'll need your Java files to be in "src/java" and annotated up. I will be trying to make a shared JAR file full of only the shared domain objects for the various projects that need them. I don't know how well this is going to work but my idea is to create one set of JPA annotated EJB3 Entity classes and put them in a JAR and share them between various Spring applications. I don't know if that's a good idea or not...

Finally, you'll need to get the compiled class files for these annotated POJOs into "web-app/WEB-INF/classes" that means you need to do a "grails run-app" or similar first so that the Java files get compiled into classes and dropped into the "web-app/WEB-INF/classes" directory.

Once that is done you can run the "grails generate-all" command on your Java classes.

If you're interested in working through the EJB3 examples I have posted ejb3_grails.zip which uses this tutorial by Jason Rudolph but also uses Grails version 1.0_RC1 and the Groovy Eclipse Plugin.

EDIT: in version 1.0 and higher recent experience shows that if you set the Eclipse Groovy plugin to output to bin and set the build path of the Java compiler to output to project/bin class resolution will work fine for the IDE. When Grails itself goes to run the application or build the WAR file, the right class files will make it into "WEB-INF/classes" since Grails uses a separate class cache anyhow. It seems the reason I advised to output Groovy and Java classes to "web-app/WEB-INF/classes" is no longer true.

2007-10-12

The new Alfresco

TriLUG last night had a special presentation from principal architect Jon Cox. Jon Cox had developed software for the Interwoven product suites and is now working for Alfresco which has released a new versioning engine based on Jon's work.

The new alfresco tool's new features include Native Office integration, multiple locking models, adaptive workflow engines based on jBPM, REST style API, a new Web 2.0 front end, web portal integration, and web content management features. The big win here is the long awaited Office integration. Unfortunately, this feature is apparently very new and doesn't have good documentation around it yet.

For a programmer the most common use of versioning is in source code version management with tools such as SVN. The difference between Alfresco and SVN was described by Cox using this analogy:

Imagine you have a window pane and you are looking at the Mona Lisa. You can draw on this pane, erase it, do what ever you want and no one but you can see it. Now imagine there are three of you... Alice, Bob, and Charlie. Charlie puts a mole on Mona Lisa, Bob puts a mustache, and Alice adds a goatee. If Charlie commits (permanently saves) his mole Alice and Bob will suddenly see the mole show up underneath their window panes.

This is very different from source code control in products like SVN and CVS. In source code the developers all have their copies that they work on. When they are done they commit their changes. In SVN if Charlie has committed that mole neither Alice nor Bob will see the mole until they go to commit. When they try to commit they get an error. Alice and Bob each have to update manually and then make changes to accommodate Charlie's mole addition.

This is inappropriate behavior for managing documents. And, that is why Alfresco can be set up with either pessimistic locking (source code type locking) or optimistic locking (everyone sees each other's changes immediately).

I took away these key concepts:

Alfresco versioning composed of three layers... The official copy, the working copy, and the preview.

The official copy is like the Mona Lisa under glass, the working copy you have is like a pane of glass that you can draw on and no one can see. The preview exists behind you as a preview that you can send "links" to other people who can then look "over your shoulder". This set of concepts allows people to play "what if" scenarios with their documents and web sites.

The working copy can pass through an approval process before it reaches the official copy. You may snapshot a working copy before you send a preview and only allow a preview of the snap shot. And all this can be used to version sets of documents or websites.

Toward the end of the talk Jon entertained the long term vision that the Alfresco object-version system could be used for source code control. It would allow for the implementation of different policies on how source code could be modified and worked with... and could be used to implement radically different software work patterns then what we use now.

2007-10-09

Watching ProjectZero

I just saw this ProjectZero Demo and given that this is IBM developing the tool I'll be watching the development of this project over time. It seems that Project Zero competes with Spring. Unlike Grails which builds on top of Spring, Zero appears to create a new set of conventions and competes with Spring.

SunSpot + Lego + LeJOS + Groovy

A few ideas have been rolling around in my head for the last few weeks. For one I really like the idea of the SunSpot kit and I really like the idea of LeJOS which is Java for the Lego Mind Storm robotics kits. I am slowly finding myself becoming a Groovy fanatic too.

So, I've got this crazy idea of doing a Lego + LeJOS + Groovy + Sun Spot project just to prove it can be done. I'm just entertaining the idea right now... but I think I'll need several hundred dollars in hardware to pull off a project. I hope to turn this particular idea into more than a pipe dream but once again I'm severely resource constrained.

Anyone think I can get a grant to do this stuff?

2007-10-02

Ruby on Rails: The Java web DSL

Technical evaluations aside, the longevity of a technology has more to do with the community behind it than it does with the suitability of the product. The "Sun surprise at railsconf Europe 2007" has shed some light on what the character of the Rails community may become. Justin seriously thinks this could lead to a hybrid Java/Ruby or JRuby coming of age in the near future.

That Ruby thunder is the Groovy rumbling we heard all summer. It looks like the "official" Sun Java camp may be backing the Ruby on Rails horse. In Open Source technology it isn't always the best, most feature rich, or advanced product that wins. This is probably the revelation that Sun is working from. Ruby on Rails is popular and Java can ride that train all the way into town.

The question is now, will JRuby ride its rails over Groovy or does Groovy still have a niche.

Moving from Java to Groovy is simple since most Java syntax works in Groovy. That means you only need to add on new language features and you're writing in Groovy. A very shallow and gradual learning curve for Java people. Is that enough? Is that everything?

JRuby's claim to fame will be the ability to work with EJBs and run in an "enterprise" environment. When that hype train comes into the station many things won't matter. When RoR is a full fledged member of the Java environment Ruby becomes one more Java DSL and Rails becomes one more Java web framework.

And that's a good thing. It means Ruby on Rails and Java are not mutually exclusive. It means both sides benefit. These are critical developments to watch right now because the fall out from these will greatly influence the political landscape of web development for years to come.

If Java can successfully bring Ruby into the fold we can reverse some industry killing fatal fragmentation.