A Pattern for Development: ORM Reverse DTO Pattern

NEOS, LLC. (my employer,) specializes in modernizing business processes and technology. The following issues and solutions are fairly common in that kind of effort, especially when porting from an older system where complex queries already exist and no one wants to change them or tune for other scenarios. While this may not apply to your software effort, it does ease a lot of pain when solving certain niche problems. Also, see Java Hair, the technical blog of a few folks at NEOS. 

Let’s start with a disclaimer – there are few perfect things and I don’t claim this is one of them, I just know that this works really well and I hope it helps someone else. I also don’t know if anyone’s named this pattern already. If so, let me know. Also, if there are any suggestions for better names, like “Lightning Bolt,” I’m all ears.

The Problems this Pattern Solves

Typically in a J2EE project involving Hibernate, the developers will encounter a situation where there are two or three conflicting needs. If they’re not specifically in conflict, these needs at least make the job a little difficult.

On one hand, there is a need to tune the Hibernate settings of an Entity bean to perform well in queries and take up minimal memory while executing the least number of sub-queries. On the other hand, there is a need for the Hibernate object to be editable and serializable in its original form, meaning that in some cases all data must be available and non-lazy. A third possible need is that somewhere out there is an Oracle/SQL Server/MySQL etc. DBA who is going crazy trying to tune for all the different ways Hibernate is generating queries. While each of these problems is reasonable on their own, solving all of them simultaneously (while doable,) takes up more effort than it should.

In other words, the following pattern allows the developer to solve all three problems with minimal effort on his or her part and minimal effort on the part of the DBA. Everybody’s happy, though I have heard complaints from Java purists. My response to purism is usually the same, whether it’s over-normalizing a database or writing software: “Purism and strict adherence to design doctrines are a means to an end, they are NOT the end. The end result should be cost effective deployment of a working application that can be maintained.” Sometimes I don’t actually say all of that, I may just mutter under my breath and go to refill my coffee.

How this Pattern Came to Be

Having been the software architect on several efforts where the above problems manifested (including one where Hibernate staff were involved and liked the approach,) this really didn’t become a standard until I was exposed to Oracle ADF. I like ADF quite a bit, it is a very short path to delivery and to a developer or business owner that means some good things. What caught my eye was that the ADF framework separated Entity objects from View objects. In ADF, an Entity object represents a table just like a Hibernate POJO usually represents a table. However, Entity objects proper are hardly ever shown in Lists of Values, Search results and so on. Instead, ADF abstracts the Entity objects with View objects. An ADF View object allows a layer of complexity or simplicity to built on top of one or many Entity objects, or it can be built using only a query as its source.

I decided that if it were a good idea for a core product and I’d made a similar concept work in my past projects, then maybe it was time it became a well defined solution to the aforementioned problems. The solution below isn’t exactly like ADF’s pattern. With ADF, View objects make reference to the underlying Entity objects. In the following pattern, we make an effort NOT to.

What it Is

The concept is very simple in practice. Hibernate mappings and beans are created as usual. However, when it comes time to run queries or search for data, a separate object is used. This second object is a Hibernate object that is not mapped to a table. Rather, it’s an object that includes one or more native SQL queries which alias columns. This has several benefits.

  1. A DBA can easily tune queries that return more than one result
  2. The Hibernate persistence context doesn’t need to track changes to the objects
  3. The objects are immediately detachable without ever needing to worry about lazy loading.
  4. The original entity can be tuned for any kind of eager or lazy fetching. This is especially useful if one isn’t using (or doesn’t want to deal with,) an  OSIV pattern.

To get these benefits, a few simple rules must apply to the View/DTO object.

  1. Don’t map the object to a table
  2. Don’t create more than one hibernate object to represent query results -in other words, NO relationship objects. No many to ones, no one to many… you get the idea.

There may be obvious exceptions to these rules and these are just the broad strokes. Usually when I implement this pattern I create a common abstract method in the View object that will allow a developer to get back a valid Serializable key for use in opening up a real Entity object for editing. In my implementations I usually call that method “getEntityPrimaryKey()” which returns a Serializable. Then I just pass that result to a simple Hibernate get or load operation and work with the Entity.

To reiterate: the purpose here is allow for peaceful coexistence between DBA approved queries, possibly massive search result tuning for various displays and individual tuning for editable objects.

How you choose to implement the pattern is up to you, but if I receive a few requests for examples, I’ll gladly post them here.


Javaspaces Redux

UPDATED – I’ve restored this code that was previously missing. The project is open sourced and available at http://code.google.com/p/splitframe-jar-server. I welcome improvements and commentary, and I will try and respond to requests or problems with the code.

You can download the zip file with everything you need at http://splitframe-jar-server.googlecode.com/files/SplitFrameJarServer.zip

Anyone who has used Javaspaces has probably achieved a measure of success on one or two machines, then started to think more about how to deploy their solution. They might ask…

“How do the other computers get the libraries needed to execute work without my altering their classpath?”

This is where the “codebase” comes in. Javaspaces/JINI (and other Java/RMI technologies for that matter,) have the ability to query a url for a particular class or jar file, and receive bytes from that request. That downloaded bytecode can then be added to the ClassLoader of the running JVM. For further explanation, see this excellent article.

In short, an Http server can easily serve classes OR jar files. However, configuring the client computers to take advantage of the available code still exists as a task. The scenario can increase in complexity based on added jars and new tasks to execute. One day, three jars served up may be enough. A month from then, perhaps fifteen jars are needed.

If you didn’t read the article mentioned above – Note the following… If the codebase url ends in a slash – “/” then the url points to the root of a classpath. However, if the url is a list of jars, separated by spaces, then that specific jar is served by the Http server instead. It is possible to do both:

-Djava.rmi.server.codebase=”http://poobah:8080/MyClasses.jar http://poobah:8080/ http://poobah:8080/log4j1-X.jar”

So if we serve multiple jars to the network, then obviously this configuration path can become long. When mutliple machines start participating, maintaining the proper list can be a problem. Also, one hard coded Http server address is hardly fault tolerant. Some failover ability is needed and lord yes, some simplicity.

I ran into this problem myself while working with a couple Grid Computing frameworks and decided to make my life more simple. The code for my solution can be downloaded http://splitframe-jar-server.googlecode.com/files/SplitFrameJarServer.zip, free to anyone who’d like to use it. (See the link at the bottom of this post.) The code is simple in concept and involves three components:

1. A small Http Server to handle requests.

2. A multicast listener (my own grid client processes extend a multicast base class that finds the url automatically on a LAN)

3. A jar indexer. The indexer should be pointed to a directory, and will recursively index every jar found in its path (including subdirectories.) One url is then needed to serve any class file found in any of the jars.

What this gives me, is the ability to always treat my jar serving http address as if it’s pointing to the root of an unzipped classpath, even though I may be actually serving classes from fifty jar files. Further, my grid clients can automatically find new jar servers if one of the jar servers goes down, since the servers themselves listen for requests and answer with their own url. This means that none of my grid computing remote computers require any rmi codebase configuration parameter at all. All I have to do to serve a new jar is drop the jar file into the path my jar server is indexing and it will be picked up and its classes will be available.

I am currently working on a more robust solution with a visual administration interface coupled with the ability to manage participating grid client tasks.

(repeat…) http://splitframe-jar-server.googlecode.com/files/SplitFrameJarServer.zip


									

What do you do when it feels like everyone is sabotaging your project to fail? How am I supposed to handle it?

The following assumes that the project is in its late stages. First, to every bad situation at work there is usually a way to excel.

In this situation, the upside is that you can demonstrate your ability to evaluate risk. Whereas developers and team leads generally think in terms of technical goals and purism, a manager is usually looking at the project in terms of:

  1. Visibility – if this succeeds/fails how does it affect me?
  2. Money – does the project achieve enough bang for the buck and on time?
  3. Risks – what causes or could cause the project to fail completely or be delivered late
  4. Dependencies – similar to #3, dependencies gets more specific in detailing the external factors that create the risks.
The only thing you can do at this point is document the risks and shortcomings so far in a positive way. As an example of what to avoid, without naming names. Never name someone in a document like that… write it up, objectively, stating the missed points and dependencies without saying who is personally responsible.
Make sure that if you point out something that’s wrong, it must be followed up with a mitigation. Risk/Mitigation always go together. Whatever you do, do not expose anyone in a document because in doing so, it will seem likely that given the right situation you could expose that manager next time.
If done right, it will appear as if you have the potential to manage projects or be an effective team lead.
On the other hand, you could just look for another job. It all depends on how much confidence you have in individuals as managers… whether they have vision and integrity or not and what your personal job satisfaction is when factoring out certain problems or problem individuals. If you’re ready to leave but would rather not, do the following:
  1. Get job interest elsewhere, never negotiate without a fallback (anonymous resumes only, dice is good these days)
  2. State in your conversation that you do not want to leave, but there are some issues causing some serious lack of job enjoyment that you believe can be worked around or resolved. See what they think
  3. Stay with an internal move or leave.
As long as you’ve covered your bases, you will eventually come out on top. It will just come down to a choice of which position you like more.

Flex 3: Overlay Custom Plot Points on a Bar Chart (Custom Actionscript Rendering Class)

Coming soon :)


Open Source Project for Meebo Room Management

Project: http://code.google.com/p/mrbrooksmarshall/

Download bot at: http://mrbrooksmarshall.googlecode.com/files/marshallBot.zip

Marshall is a bot that joins your room as a mod and takes care of lots of dirty work. (See the features list.) It tracks all room events per user, and the room as a whole. Certain events are flagged as violations. For example, a user may send a very long message composed of many line breaks, something that users do in an attempt to blank out the message window. The bot recognizes a configurable number of line breaks and marks the activity as a violation for that user. The severity of this depends on the number of line breaks exceeding the limit in the configuration. The user will be warned privately by the bot, and repeat offenses will add to that user’s severity ranking. When the user has violated the terms enough times, they are kicked (with an explanation as to why, and that further violations may result in banning,) and are allowed to return to the room.

If many users are violating the terms, the room severity as a whole can reach a critical level, at which point the bot may password protect the entire room so that users already in the room can continue talking without interruption. This is temporary and the bot un-protects the room after a time. I’m still working on the time limits being configurable. It’s only a few minutes at the moment.

The bot accepts commands in the room from moderators.

  • b^nickname – bans a user. (Meebo’s in room ban option only kicks,)
  • k^nickname – kicks a user
  • m^nickname – mutes a user
  • um^nickname – unmutes a user
  • k^guests – kicks all guest accounts (non-signed in users)
  • b^guests – bans guests… good for some emergencies.
  • m^guests – mutes all guests
  • pause^ – prevents the bot from taking any action
  • unpause^ – resumes bot activity
  • set^propertyName – sets a property to a new value while the bot is running

This bot needs to be set up as an admin in the room. I recommend creating an account specifically for the bot. This helps keep things organized, avoid sign on collisions, and avoids any fear that somewhere the code is sending out your password. See the source, yourself… that’s another recommendation.

It will be super fast or super… “slow,” depending on your internet connection.

Running the bot and configuring the bot. http://code.google.com/p/mrbrooksmarshall/wiki/Example

Get the bot! http://code.google.com/p/mrbrooksmarshall/downloads/list

Features (configurable) via properties file.

  • Private messages users of its activity on their accounts
  • Auto-muting guest accounts or account with very long names
  • Allows moderator control of the bot via simple chat room messages
  • Prevents guest flooding
  • Prevents people repeating themselves, fast or slow, to spam or advertise in a room
  • Prevents people from sending messages very fast, to flood the room without repeats
  • Automatically detects and fixes backwards room hacks.
  • Detects too many line breaks in a message, usually meant to flood the room with white space.
  • Some of the room commands are very useful – muting all guests at once, kicking all guests, banning via nickname, etc.
  • More features will be added over time.

Getting Mac OSX 10.5.7 Working in VMWare 6.5

One thing I can’t stress enough is – it’s very stable to run with the ServerVersion.plist file out there with an unhacked darwin.iso. I recommend that over the other way. I use Linux so I had to figure out a workaround to being able to install applications. It was pretty easy. You just move the plist file out while you install, then move it back.

The other thing is, upgrading to 10.5.5 first helps a lot. Upgrading straight from 10.5.2 to 10.5.7 seemed to always hose me.

Now, about updating 10.5.2 to 10.5.7

Use a preallocated disk.
Upgrade from 10.5.2 to 10.5.5 THEN to 10.5.7. It’s more stable this way.
Use snapshots!!!! They are a lifesaver. Not the candy.
Don’t hack darwin.iso.
Use ServerVersion.plist to use darwin-64 as your guestOS. You can still install applications to your heart’s content. (See above and instructions below.)

Vista (Satan.) This tip from zxed may solve some of your Vista-as-host headaches. Thanks zxed! Persistence and investigation are key to getting this far.

If you are on Vista, and first boot works for you, but if you shutdown, close VMware., reopen VMWARE, launch VM and it does not work then this is how you get it to work..

VMX file.-> open in NOTEPAD..
1. make sure its .encoding = “UTF-8″
also.. click on File-Save As, and change ANSI to UTF-8..

not done yet..
also look for
sharedFolder0.expiration = “never”
this line seems like its also contributing to the grey screen hang..

also, when you close the vmmachine.. VMWARE re-writes the VMX file… it seems as if its changing the encoding back to ANSI.. sometimes it doesnt., sometimes it does.. to test this out., if it doesnt book., close the vmachine (not vmware) taking u back to home screen., open the VMX file., save as… with UTF-8, open vm, click play and see it boot up… strangeness.

ive run thru this sequqnce about 100 or so times… to the point that i have notepad open with the VMX., saved it as UTF-8., loaded the VM, ran the VM., once i see it booting (activity on grey screen). ill stop., and rerun the VM. and it hangs.. Stop VM., resave the open notepad., RUN VM., and it boots..”

CREATING A SCSI DISK, PREALLOCATED, IMAGING THE 10.5.2 DISK TO THAT, THEN MAKING IT BOOTABLE

1. Take the time to make a SCSI disk, with all space allocated. You either need to have another disk for the Development folder (this takes up the most space of the SDK installs,) or you need a big enough SCSI disk. My image has a preallocated 25Gb disk. It tarred down to 3.8 Gb though for the torrent. >> http://files.getdropbox.com/u/1115348/osx1057.torrent

UPDATE – A good tip from zxed (in Comments)

BTW a tip…. earlier when i was messing with other installers… i was able to force my IDE into SCSI by changing the vmx, so i did the same for this., and instead of taking 1.5 hours to clone, it took 20 minutes…”

2. Once you have allocated space to a SCSI disk, attach it to your vmware image. The OS will take longer to boot the first time. When it does, you’ll get a prompt from OSX saying that you need to initialize the disk. Go ahead and click the Initialize button and you’ll be presented with the disk utility screen.

3. In the disk utility screen you have almost everything you need to migrate the image from a dynamic expanding drive to a preallocated drive. Click on the new SCSI drive and partition it with one partition, name it something snazzy like “Spoon.” Well… pick your own name.

4. Notice the mount point… in my example, the disk will be mounted as /Volumes/Spoon

5. Click on restore… when you do, you will see two fields. You can drag the original volume, your boot volume, to the first field. You drag the new volume, spoon, to the second field. Then just click Restore! Don’t mix these up. You SHOULD be prompted to enter in the admin password. If you aren’t, or you miss that prompt somehow, you’ll get a security error. If that happens, no big deal, just do it again.

6. The process should take up to 1.5 hours to complete, but may take much less time depending on how much data you’ve put onto your disk already. When it’s done, you have a cloned disk that you CANNOT boot from yet. To make that disk bootable, issue the following commands:

sudo -s
bless -folder /Volumes/Spoon/System/Library/CoreServices

7. Your new drive is now bootable. Shut down the image, disconnect the old drive and boot up to your new one. Should be faster, although the first boot with a new disk image is always slower with OSX. It’s all good, just be patient.

UPGRADING THE OS. UPGRADE TO 10.5.5 FIRST!

Now – about making upgrades to the OS.

Things to know:

The upgrades DO try to hack you on restart. You’ll need to edit the /System/InstallAtStartup/scripts/1 file to fix that.

The upgrades mess with your power management during the install. You need a loop running to make sure that doesn’t happen.

The upgrades may hose your OS. Therefore, take a snapshot before each try. Snapshots rock, use them.

Your OS will boot wonderfully without hacking the darwin iso, as darwin-64. Just create the ServerVersion.plist file and be done with it. That whole problem of not being able to install software with that plist file is bogus – it’s easily gotten around.

So step by step, here’s how to upgrade.

1. Issue the following commands if you haven’t done so

sudo -s
touch /System/Library/CoreServices/ServerVersion.plist

(this creates a file, nothing more.)

2. Use a non hacked darwin.iso. If you need the non hacked version, download it straight from me – http://files.getdropbox.com/u/1115348/darwin.iso

3. Change your VM OS to darwin-64 instead of freebsd-64. Load the darwin iso but DO NOT attempt to boot with it. Just leave it there, attached.

4. When it comes time to install any kind of software, issue the following command BEFORE installing the software:

sudo -s
mv /System/Library/CoreServices/ServerVersion.plist ~/

5. When that software is done installing, like SDKs for example, move the file back. DONT FORGET TO MOVE IT BACK!!!!

sudo -s
mv ~/ServerVersion.plist /System/Library/CoreServices/

See? easy.

6. Go pee. It’s for your health.

7. Install 10.5.5 combo update FIRST. I don’t know why this freaking makes the 10.5.7 upgrade work later on, but it does.

Here are the steps to running that, or any OS upgrade.

8. Open a terminal, and do this:

sudo -s (you saw that one coming didn’t you…)
mv /System/Library/CoreServices/ServerVersion.plist
while sleep 1;
do rm -rf /System/Library/Extensions/AppleIntelCPUPowerManagement.kext; done

At this point, the terminal should be running a loop. Minimize it.

NOTE: IF YOU HAVEN’T TAKEN A SNAPSHOT, DO THAT. (and go back to step 8.)

NOTE #2: IF YOU STILL HAVEN’T TAKEN A SNAPSHOT, SMACK YOURSELF IN THE FACE, THEN TAKE A SNAPSHOT.

9. Mount the 10.5.5 combo update and install it.

10. do NOT restart. Instead, go back to the terminal and Ctrl-C to end the loop.

11. Edit /System/InstallAtStartup/scripts/1 and look for the line that loads a “DontStealMacOS.kext” file. (Not sure if I have the exact file name right, but it’s hard to miss if you look for “Dont”) Change the filename but not the path, to load dsmos.kext instead.

12. In a terminal with sudo priveleges, mv ~/ServerVersion.plist /System/Library/CoreServices/

13. Unmount the update image and reboot.

A note about 10.5.5 vs. 10.5.6/7. 10.5.5 does NOT appear to try and load the DontStealMac file. Check anyway. But be aware that 10.5.6 and 10.5.7 DO try to hack you when you reboot. Don’t miss that step in subsequent updates just because it’s missing in 10.5.5 ;-)

REPEAT, IT’S IMPORTANT.
One thing I can’t stress enough is – it’s very stable to run with the ServerVersion.plist file out there with an unhacked darwin.iso. I recommend that over the other way. I use Linux so I had to figure out a workaround to being able to install applications. It was pretty easy. You just move the plist file out while you install, then move it back.

The other thing is, upgrading to 10.5.5 first helps a lot. Upgrading straight from 10.5.2 to 10.5.7 seemed to always hose me.


What Hibernate Likes to Do With Your Lovely SQL

Hibernate sometimes doesn’t like you at all.

You, the seasoned JDBC/Oracle developer. Some of you have learned that to query using HQL, you must use the hibernate equivalent object names, but still you persist (forgive me the pun, there,) in writing HQL that looks like SQL!! This is bad.

This is bad because your application is suffering. It’s suffering from verbosity, and from poor performance. Here is why – and here’s what to do about it.

Let’s take the following example HQL query:

select o from ManyToOneObject1 mo1,
ManyToOneObject2 mo2,
ObjectWeReallyWant o
where mo2.number = ?
and o.manyToOneObject2 = mo2
and o.
manyToOneObject1 = mo1
and mo1.idOfSomeKind in
(select distinct mo3.idOfSomeKind
from [some subquery to do with filtering records])
order by mo1.descriptionField

This is an actual query from “the field.” The first thing that struck me as odd about the query was that it forcibly joined many to one objects instead of just asking for the object they wanted. Like this:

from ObjectWeReallyWant as o
where o.manyToOneObject1.number = ?
And o.
manyToOneObject1.idFieldOfSomeKind in (select idFieldOfSomeKind from [subquery stuff here])
Order by
o.manyToOneObject1.descriptionField

That’s a little easier to read. Either way we format the query, there is a big problem! When I looked at the SQL output in the logs of our application, I found one main query, followed by a very long list of select statements – one for each many to one record! But why? We can specify a “join” or a “select” for those mappings, and each setting will cause a different problem.

Join – we can have a cartesian product pulled back from Oracle. Hibernate eliminates the duplicates… but isn’t that what an INNER join is for?

Select – Hibernate will issue a separate select statement for each record.

Since neither of these options is what we want (an Oracle developer would look at our original HQL and think “inner join,”) we can tell Hibernate exactly how to fetch those relationships, as follows:

from ObjectWeReallyWant as o

inner join fetch o.manyToOneObject1

inner join fetch o.manyToOneObject2

where o.manyToOneObject1.number = ?
And o.
manyToOneObject1.idFieldOfSomeKind in (select idFieldOfSomeKind from [subquery stuff here])
Order by
o.manyToOneObject1.descriptionField

Using the “inner join fetch” HQL statement does what we expected the original statement to do – inner join. In our application this resulted in one statement, and no extra records.

To find this and other problems (Hibernate LOVES to left outer join, leading to cartesian product hell,) turn on your SQL output. (Use property: “hibernate.show_sql=true”)


Javaspaces: the Codebase Problem and a Solution

UPDATED – I’ve restored this code that was previously missing. The project is open sourced and available at http://code.google.com/p/splitframe-jar-server. I welcome improvements and commentary, and I will try and respond to requests or problems with the code.

You can download the zip file with everything you need at http://splitframe-jar-server.googlecode.com/files/SplitFrameJarServer.zip

Anyone who has used Javaspaces has probably achieved a measure of success on one or two machines, then started to think more about how to deploy their solution. They might ask…

“How do the other computers get the libraries needed to execute work without my altering their classpath?”

This is where the “codebase” comes in. Javaspaces/JINI (and other Java/RMI technologies for that matter,) have the ability to query a url for a particular class or jar file, and receive bytes from that request. That downloaded bytecode can then be added to the ClassLoader of the running JVM. For further explanation, see this excellent article.

In short, an Http server can easily serve classes OR jar files. However, configuring the client computers to take advantage of the available code still exists as a task. The scenario can increase in complexity based on added jars and new tasks to execute. One day, three jars served up may be enough. A month from then, perhaps fifteen jars are needed.

If you didn’t read the article mentioned above – Note the following… If the codebase url ends in a slash – “/” then the url points to the root of a classpath. However, if the url is a list of jars, separated by spaces, then that specific jar is served by the Http server instead. It is possible to do both:

-Djava.rmi.server.codebase=”http://poobah:8080/MyClasses.jar http://poobah:8080/ http://poobah:8080/log4j1-X.jar”

So if we serve multiple jars to the network, then obviously this configuration path can become long. When mutliple machines start participating, maintaining the proper list can be a problem. Also, one hard coded Http server address is hardly fault tolerant. Some failover ability is needed and lord yes, some simplicity.

I ran into this problem myself while working with a couple Grid Computing frameworks and decided to make my life more simple. The code for my solution can be downloaded here, free to anyone who’d like to use it. (See the link at the bottom of this post.) The code is simple in concept and involves three components:

1. A small Http Server to handle requests.

2. A multicast listener (my own grid client processes extend a multicast base class that finds the url automatically on a LAN)

3. A jar indexer. The indexer should be pointed to a directory, and will recursively index every jar found in its path (including subdirectories.) One url is then needed to serve any class file found in any of the jars.

What this gives me, is the ability to always treat my jar serving http address as if it’s pointing to the root of an unzipped classpath, even though I may be actually serving classes from fifty jar files. Further, my grid clients can automatically find new jar servers if one of the jar servers goes down, since the servers themselves listen for requests and answer with their own url. This means that none of my grid computing remote computers require any rmi codebase configuration parameter at all. All I have to do to serve a new jar is drop the jar file into the path my jar server is indexing and it will be picked up and its classes will be available.

I am currently working on a more robust solution with a visual administration interface coupled with the ability to manage participating grid client tasks.

(repeat…) http://splitframe-jar-server.googlecode.com/files/SplitFrameJarServer.zip


									

a Little bit About Choosing a Framework

Here’s a nice list of available frameworks…

Personally, when I look for a framework, I consider a few factors. One of the most important factors to consider is the time available married with the existing skills of the team. If time is tight, and your entire team knows Struts very well – maybe you use Struts!

Second, there are frameworks that approach very specific technical problems and there are frameworks that deal with all tiers of the architecture. Sometimes architecting an application is a mix and match situation. In Spring’s case this is very true. For example, Spring is multi-purpose and you don’t have to use all of its features. You can mix various combinations of the following frameworks – Spring, Struts, Hibernate, Stripes. Struts and Stripes are the only two that are mutually exclusive. This is just one example and I’ve left out Webwork as a valid framework – it’s a good one, too.

An architect may choose to implement an even more varied combination by implementing one tier in Java and the other tier in some other language. The possibilities are wide and varied.

In short, I look in two places from the get-go before I choose a framework or combination of them. My own experience and Google. Once I have a list of available frameworks I then consider the following factors.

1. Nature of the project – Mission Critical or more of an R&D effort? For more mission critical systems it’s good to make sure you have support and a mature framework that has a history of usability.

2. Skillset of the team vs. available time. (Need I mention apititude or lack thereof?)

3. How complex does the project NEED to be? The rule of thumb is – as simple as it can possibly be and no simpler.

If you’re looking for a list of frameworks, I suggest the link provided at the top of this post.


“It Just Works” Convention over Configuration

Well, you say… What does THAT mean? And why the hype over Ruby on Rails or Stripes?

Convention Over Configuration is a fancy way of saying “Sensible Defaults.” (er… in my opinion.) You see, a framework is like your mom. Helpful, useful and inserts itself whenever it can. Sometimes you wish you could tweak it a bit, but no one wants to really completely dismantle it and start over. Personally I have never wanted to dismantle my mother, but that’s another blog entirely.

Whether a developer is working with .NET, Perl, ColdFusion or Java; configuration can sometimes be a problem.

When someone chooses a technology or framework for their project, certain restrictions are immediately imposed upon them, their design and the long term outcome of the project itself. This is the caveat of not reinventing the wheel. It’s not a bad trade off at all, and the payoff can be wonderful. However, when anyone implements a “framework” they are agreeing to comply with the framework’s needs. If a person uses Hibernate (or NHibernate for you .NET folks,) they must configure it! The same is true for Spring, Struts, etc. These frameworks are all good at their jobs when used correctly but… one must tell them how to behave.

For the uninitiated, let’s clear something up. A framework is NOT a library. They are two vastly different things. What’s the difference? A framework inserts its behavior into your application and can provide external control with which you must cooperate. A library is simply used. They are on opposite sides of the coin of control. There are two basic kinds of application frameworks. There are blackbox frameworks and whitebox frameworks

So, that said – frameworks require configuration. This is sometimes a LOT of work, and it is also a lot of work to come behind a developer and try to figure out why a particular page navigates this way or that, and where the heck is that configured anyway??

That is the problem “convention” tries to solve. Put simply, when you’re adhering to a conventional means of doing something, you can make a LOT of assumptions and be right. Someone can then come behind you to do some maintenance work and make some assumptions and also be right. This saves time. With frameworks like Ruby on Rails or Stripes, a person simply has to name things the right way, and the application is magically wired together. However, there is a trade off.

Any convenience that a framework (or Operating System for that matter,) provides, usually comes at the price of the loss of control at a low level. The more any entity does for you, whether it be your mom, your government, your operating system or your framework of choice, you lose a little bit of control (or sometimes a lot.) However, managers and CIOs and developers too, are tired of the ability to easily make mistakes. They are also tired of having to train people to use a framework. A framework should save the company money, and be easy to work with.

To say a framework is easy to work with is a subjective statement. However we could make that statement more quantitative by saying that a framework takes a certain percentage of time to piece together components, and a certain percentage of time to implement those components. If that is our measure of ease, “convention over configuration” is easier. These frameworks may not suit every application’s needs, so avoid the knee jerk reaction of “this will make our lives easier, let’s use it!!” That’s simply wrong. However, if an Application Architect really understands the business needs of an application and can use such a framework, most people believe that much time and money would be saved. That is why convention over configuration is exciting. Not because it’s fun, not because it’s new. It’s exciting because it’s marketable to management, and can provide quick results – especially in an Agile environment.


Follow

Get every new post delivered to your Inbox.