Saturday, March 19, 2005

Use AOP to wrap objects
(and solve thorny dependency injection issues)

At first glance Java was supposed to have this garbage collection feature that would cure the common cold and world hunger.

It was soon realized, though, that there are kinds of resources other than memory that require deterministic cleanup. An example is a database which has a license that restricts maximum number of connections. Any Java code that uses db connections needs to deterministically release a db connection as soon as possible in order to maximize the utilization efficiency of this limited resource.

Because this is a reoccurring problem, Java classes that encapsulate such resources tend to provide a close() method, etc., which can be explicitly invoked to deterministically release the underlying resource. (The C# language introduced the IDispose interface and 'using' keyword as features in that language to effect this particular pattern - and works fine for the occasional case where the resource is only used for the lifetime of some local scope of activation.)

Well, relatively new concepts, such as dependency injection (where a framework is in charge of setting references to dependent collaborating objects on behalf of client code that it manages), introduce yet an additional strain on Java programming practice.

If a framework is in charge of providing and setting references to dependent resources, then it will need to be in charge of managing the continuity of these dependent objects. The client code that is managed by the framework should never have to worry with the lifetime availability of the collaborating objects it makes use of or else the whole notion of dependency injection breaks down. (The goal is for client code managed by the framework to solely concentrate on business logic and not unrelated concerns.)

Opinion: Injection in EJB going too far?

So the framework provider could provide a wrapper class for every such dependent object that it has responsibility for injecting. This wrapper code would intercept all method calls such that when invoked there will be an opportunity to reestablish the availability or viability of the wrapped resource (in the event it has gone away or gone bad), and then complete the call transparently to the caller. Effectively there is a proxy object that is intercepting all access to the underlying wrapped object. It is a reference to the proxy that the framework injects into the client code that it manages. The proxy is then responsible for managing its underlying wrapped object.

Implementing such wrappers for complex classes would get tedious very quickly, though. What is needed is a language feature that simplifies wrapping other classes with such pervasive interceptor mechanisms. Perhaps what is needed is something analogous to the C++ ability to create smart pointers via overloading the pointer access operator. Well, one could indeed add a new Java language feature - but in contemporary Java the thing to do would be to use AOP to byte code enhance the public methods and properties of the target class. One would have to specify the pointcut in xml AOP language instead of rely on an AOP annotation because most typically the target classes one wants to wrap are being provided from third parties in the form of .jar libraries (i.e., a database JDBC driver) where there is no access to source code.

The upshot is that this problem is quite solvable and with the advent of AOP it should be straightforward for framework providers to implement. Most frameworks which are providing the feature of dependency injection are now also general purpose AOP frameworks. Hence the tools are already present. Contrary to the linked discussion above, the is no inherent fatal shortcoming to the feature of framework provided dependency injection. The problem issues that were raised are entirely solvable with application of yet more AOP.

Wednesday, March 09, 2005

current state of Microsoft .NET

[my rebuttal]
One assessment I agree with Mr. Grimes on is what a total waste of time VB.NET was. He was a little harsh on the size of the .NET Framework - for enterprise intranet rich client development it's no big deal to install 25 MB on the client workstation. I know one thing for sure - I'd much rather develop our rich clients using C# .NET rather than C++ and MFC/ATL.

He's also correct that WinFS was another MS misstep - just like the Object File System a decade before it. Google local search coupled to conventional file systems will rule. Turning the file system into one big SQL server storage system was a bad idea - chiefly because of the burden it places on developers to devise storage format concepts that accommodate this approach (and where's the ORM solution that eases all the pain?). And just how normalized will that storage be (and secure in an isolated sense)? Where's the crisp distinction of data borders that we have today with files?

The real problem with LongHorn is that it's so far behind the curve. On Mac OS X I'll soon be enjoying the Tiger release. Given the Mac's already existing easy-to-use advanced UI (with cool 3D effects) and the new Tiger features, LongHorn will be long preempted elsewhere before it ever sees the light of day in a shipping version. The next couple of years will be a wonderful time to jump ship from Windows to Mac - can you say "Mac Mini". (Now I can relegate my Windows boxes to being headless servers - the same way I use my Linux boxes. That way they can't cause me near so much pain and sorrow.)

And then on the server-side - well ASP.NET is pretty much a one trick pony. Not a very rich server-side development environment to work with there, alas. The puke of .NET Remoting or Web Services over HTTP - pick your poison. Yeah Indigo might finally provide a managed messaging implementation (just like ORM this is another feature of .NET that was axed back in '99/00 timeframe when I was still there), but Microsoft's idea of heterogeneous messaging is “between different versions of Windows”. The prominent JMS implementations will be over a half decade old in maturity by the time Indigo is shipping code. The leading JMS vendors are already heterogeneous in both programming language and platform that are supported for messaging.

Indigo as described would indeed address some of what is retrograde about ASP.NET and Web Services combo as they exist today (except that there’s still the issue of addressing transparent clustering for scaling and high availability - as well as replicating transactional distributed caching that will enable capitalizing on 64-bit address space and multi-gigabyte RAM in current generation servers). It is just that with the years of maturity of the enterprise Java platform, where all these capabilities already exist in spades, the question any responsible IT staff will ask is why put all of one’s eggs in one “Microsoft basket” - and for a set of technologies that are a year or much longer from being shipping code? Microsoft historically has done well with the mid-tier and lower-tier IT crowd of VB developers, but for really serious enterprise IT development needs they've always been a day late and a dollar short.