Rainy days and Java always get me down

I've Moved My Blog

It's currently located at http://www.urlinone.com/blog

I should say "I'm moving my blog." It's a pretty painful process.

Pebble has blown up on me, and it's been many months since I've been able to blog reliably. I've lost posts. And now I've got to figure out how to migrate my past blog posts from Pebble to my new destination without all the URLs changing, lest external links become 404 Not Founds.

Why does everything in the 21st century have to be a three-day project???

My idea of documenting AppFuse line by line (well, at least the juicy parts) has taken on a life of its own. I'm going to release the tool as its own open source project. In preparation for releasing the first beta version, I went to register at both java.net and SourceForge. So, that's my first question: Which one should I use? Or does it makes sense to do both?

Next, the question comes up during registration at both sites: Under which license will you be releasing this open source project? Unfortunately, I had left my lawyer in my other pants. (I'm not even sure what that means.)

This was one of those seemingly innocent questions that almost made me abandon the whole process. There are literally 54 different licenses to choose from! Don't believe me? See for yourself!

I went into this thinking I was just going to give it away and be done with it. But when you're presented with fifty-four different ways to give something away, it really makes you pause and wonder what you're getting yourself into and if this is such a good idea after all. I mean, if a bunch of lawyers put this much effort into the legalities around giving some away, you've got to figure there's something in it for them on the other side.

Those of you who have released open source software, can you tell me how and why you chose the license that you did? Are they all pretty much the same thing, or are there significant differences to be aware of?

And please don't tell me to read the licenses. I tried reading one of them and fell asleep for three hours. I can't imagine trying to compare the merits of fifty-four of these things.

When you try to run a program that does logging from within Eclipse, have you ever seen this:

log4j:WARN No appenders could be found for logger (com.greymatter.MyClass).
log4j:WARN Please initialize the log4j system properly.
This happens because Log4j can't find its .properties file, so it can't configure its appenders, so you don't get any logging information. Here's how to fix this...

  1. In Eclipse, in one of the several places where you can find this, select either Run... or Debug... (Your change will apply to both types of program execution.)
  2. In the tree view on the left, select the Configuration you'd like to run with logging enabled.
  3. Click on the Classpath tab along the top.
  4. Click on the User Entries item in the tree view to select it.
  5. Click the Advanced... button.
  6. Select the Add Classpath Variables radio button, and click OK.
  7. If you see LOG4J_PROPS in the list of variables, select it and click OK. If it is not in the list, click the Configure Variables button. Add a Classpath Variable named LOG4J_PROPS with a value of the absolute path to the folder that contains the log4j.properties file. Once you've completed this process of adding the new variable, you will of course need to select it as you would have done if it had already existed.
  8. Click Apply to save your changes.

That's it! You should now be able to run or debug your app in Eclipse and have log4j configure properly. Ain't life grand?!

Revised January 17, 2005

A couple of weeks ago, I installed Mozilla Firefox, and I've got to say it's an environment in which I became very comfortable very quickly. I've had a few problems with printing, and there are still some kinks to be worked out, but it is overall a very usable browser.

One of the really nice features is the inherent extensibility of the platform. I've installed a couple of very powerful Extensions that make life so much easier. My favorite is Mouse Gestures by Optimoz. If you've ever used a Palm to write in Graffiti, mouse gestures are a very natural way to interface with a computer. Even if you've never used Graffiti, this is not a hard thing to pick up. It's so cool to be able to open links, move from tab to tab, close tabs and windows, and do pretty much everything I want to do with simple mouse movements anywhere in the browser window. It sure beats having to travel across the screen and aim and click on a small area to execute a command. Considering that I probably execute <swag>10,000</swag> little commands a day, reducing the effort in each one adds up to a lot of savings.

Incidentally, if you've been through the extensive search I have to learn how to create Mozilla Extensions, it's almost spooky how hard it is to find the information. I think it's a better kept secret than Area 51. Here is the one and only tutorial I found on all the web! Thanks, RoachFiend! (With a handle like that, you'd better be careful about exposing such carefully guarded government secrets. :)

The interesting thing about Extensions, from what I read in Eric's excellent tutorial, is how simple they are to write. Admittedly, I'm brand new to the whole process, but it looks like the folks at Mozilla really did a nice job of making an already powerful platform easily extensible.

It occurred to me a couple of weeks ago that it would be very helpful to have a directory-by-directory, file-by-file, line-by-line description of what's happening within AppFuse. A wise man once advised me "if you can't find what you seek, become it." (I don't recall seeking an overworked, underpaid Java programmer, but I became one anyway.) I thought I might be able to give something back by taking on this project myself. I knew I'd learn a whole lot in the process, too. And future AppFuse users would certainly benefit from the effort. (Assuming my information is accurate, so... ;)

I documented a couple of files using a prose description, but I was not happy with the result. I'm not sure how clear or useful my ramblings really are. Through my dissatisfaction, though, I started to formulate a vision of how I would like to present this information in a useful and accessible way. The vision of what this is is still taking shape, but I've got a half-baked prototype done.

What I started to write yesterday is a semi-automated system to assist in documenting a software project so that visitors get the layout, the moving parts, and the details. I copied the basic Javadoc paradigm, but have repurposed it to be oriented around directory, file, and line documentation.

If you're wondering what's wrong with comments in files, I guess you could think of this as Aspect-Oriented Documentation. I'm trying to document down a different axis or dimension, so that you can see how the source files interact as a whole application, rather than at the standard programmer's comment level. You wouldn't put the kinds of comments into your code that I'm talking about putting in here. But for someone coming onto a project, this is the kind of information that they would want in a form that is highly available. It goes from a high-level description of what each directory holds, down to what the purpose of each file is, all the way down to what each stanza of code is for. While you may include pieces of this information within your files (and Javadoc), this entire presentation is intended to illustrate the big picture. If regular comments tell "how," these are more about "why."

This is very, very, very, very early stuff. I spent a day on it, and I'm still unsure where I'm heading exactly. The scope and intent changes every time I revisit it. I'm trying to decide on the UI for both the developer/documenter, as well as the viewer. I'm also unsure how to manage the information, especially on a growing, changing project. There is no choice but to externalize the commentary from the source, but keeping it associated with the right directory, file, and line(s) could prove challenging as the project progresses.

Could this evolve into a worthwhile general-purpose project? I'm not sure. I'm going to document AppFuse while I expand "AOD" and see where it leads. It would have been really poetic to be able to use AppFuse to document itself, but it just wasn't a fit. Maybe in the rewrite.

Here's a peek at the output from Line-by-Line. There's no documentation included at the time of this writing, but I already like it as a quick way to flip through the sources. I only wish it had the pretty print capabilities of java2html (and xml2html, properties2html, jsp2html, etc.).

I welcome your feedback on the idea, the implementation, the AppFuse content (once I've added some), etc.

I recently went on a quest to find the best tools and frameworks on which to build a new Java web application. AppFuse by Matt Raible is one of about 4,873 different pieces of open source software I've tried out in the last eleven days.

Okay, I'm exaggerating a little. But only a little.

SourceForge and Jakarta are amazing treasure troves of mouth-wateringly enticing software tools. (Some of them even work.) And that's just the beginning. There's OpenSymphony, codehaus, java.net, and countless other sources of open source tools and libraries. You can make a career out of exploring them all. And you can do it all without ever accomplishing anything. It's a wonderful, horrible thing.

The nice thing is that there are people who have been down the road before you and have discovered what's really good and what's not so hot. The beauty of AppFuse is that Matt has gathered a whole bunch of the "best-selling" open source tools into a cohesive package -- not to mention the fact that AppFuse does some of the fundamental things that practically every web app needs, such as user registration, login, security, and administration. Best of all, AppFuse let's you be productive before you truly understand all the tools and concepts you're using.

I'll say that again:

AppFuse makes it possible for you to be productive, to take advantage of some of the most powerful and widely used open source development tools, before you really understand what you're doing. As a beautiful side-effect of this, you become familiar with Ant, Hibernate, Spring, Struts, Tiles, XDoclet, JUnit, Cactus, Canoo, DBUnit, and on and on -- all in the process of developing your application!

It's a headstart on your application

It's an education in web application development.

It's a dessert topping.

Wait, you're both right. Well, two out of three, anyway.

Matt continues to add new frameworks and features to AppFuse. Want to develop a web app, but you don't know where to start? Want to keep up with the latest, hottest Java development tools and frameworks? Want to learn about web app development and still be productive? Try AppFuse.

Floating down through the clouds
Memories come rushing up to meet me now.
In the space between the heavens
and in the corner of some foreigh field
I had a dream.
I had a dream.
Goodbye Max.
Goodbye Ma.
After the service as you're walking slowly to the car
And the silver in her hair shines in the cold Vovember air
You hear the tolling bell
And touch the silk in your lapel
And as the tear drops rise to meet the comfort of the band
You take her frail hand
And hold on to the dream.

A place to stay
"Oi! A real one ..."
Enough to eat
Somewhere old heroes shuffle safely down the street
Where you can speak out loud
About your doubts and fears
And what's more no one ever disappears
You never hear their standard issue kicking in your door.
You can relax on both sides of the tracks
And maniacs don't blow holes in bandsmen by remote control
And everyone has recourse to the law
And no one kills the children anymore.
No one kills the children anymore.

Night after night
Going round and round my brain
His dream is driving me insane.
In the corner of some foreign field
The gunner sleeps tonight.
What's done is done.
We cannot just write off his final scene.
Take heed of the dream.
Take heed.

This tile is included in baseLayout.jsp within web/WEB-INF/tiles-config.xml. Matt Raible included a comment that indicates that the way header is used here demonstrates the use of a Tiles Controller.

Within the <definition> of baseLayout, Matt has the following line:

<put name="header" value=".header.userCount">

Thus, header is refering to yet another tiles definition.

Down below, at line 72, we see where .header.userCount is resolved:

<!-- Header definition - shows user Count using a Controller -->
<definition name=".header.userCount" path="/common/header.jsp"
controllerClass="com.greymatter.webapp.action.UserCounterController" />

Thus, header.jsp displays the number of active users in the top right portion of the page.

The next block of logic in header.jsp checks to see if the logged in user's role is tomcat or admin. If so, the link to the Main Menu is inserted at the top of the page, so it will be available for any page based on baseLayout.jsp.

by Bob Dylan

May G-d bless and keep you always,
May your wishes all come true,
May you always do for others
And let others do for you.
May you build a ladder to the stars
And climb on every rung,
May you stay forever young,
Forever young, forever young,
May you stay forever young.

May you grow up to be righteous,
May you grow up to be true,
May you always know the truth
And see the lights surrounding you.
May you always be courageous,
Stand upright and be strong,
May you stay forever young,
Forever young, forever young,
May you stay forever young.

May your hands always be busy,
May your feet always be swift,
May you have a strong foundation
When the winds of changes shift.
May your heart always be joyful,
May your song always be sung,
May you stay forever young,
Forever young, forever young,
May you stay forever young.

by Rod Stewart

May the good Lord be with you
Down every road you roam
And may sunshine and happiness
surround you when you're far from home
And may you grow to be proud
Dignified and true
And do unto others
As you'd have done to you
Be courageous and be brave
And in my heart you'll always stay
Forever Young, Forever Young
Forever Young, Forever Young

May good fortune be with you
May your guiding light be strong
Build a stairway to heaven
with a prince or a vagabond

And may you never love in vain
and in my heart you will remain
Forever Young, Forever Young
Forever Young, Forever Young
Forever Young
Forever Young

And when you finally fly away
I'll be hoping that I served you well
For all the wisdom of a lifetime
No one can ever tell

But whatever road you choose
I'm right behind you, win or lose
Forever Young, Forever Young
Forever Young ,Forever Young
Forever Young, Forever Young
For, Forever Young, Forever Young

Who knew there were so many songs called Forever Young??? If you Google for it, you'll find that every artist is contractually obligated to write and publish a song with this title. And they apparently all have to have similar lyrics, in which the phrase "forever young" is repeated multiple times. There's so much I don't understand about contracts.

This is a very sweet, simple song. It reminds me of the blessing that Jewish parents give to their children each Friday night:

May G-d bless you and safeguard you.
May G-d illuminate His countenance for you and be gracious to you.
May G-d turn His countenance to you and establish peace for you.

Whether this song is directed from parent to child, from spouse to spouse, or from friend to friend, the generosity and love in the blessing is moving. Is there anything more we could hope for ourselves in our brief time in this world than what is wished for in this song? Is there anything more we could hope for our loved ones?

May you stay forever young.

WARNING: The song Forever Young does not appear on the Garrison Keillor album. I've heard him do it on his radio show on National Public Radio, but I am not aware of it being on an album. I include him here because he's so talented, and it was hearing him do Forever Young on his radio show that made me rediscover and fall in love with the song. Thank you, Garrison.

I awoke to over 1300 spam messages this morning.

It's just amazing to me how many people think only of themselves and not of the greater good. It's true of the Saddam Husseins and Yassir Arafats of the world. It's true of spammers. It's even true of the morons who proposed and promoted the CAN-SPAM Act. Gee, what a difference that has made.

Everybody's got their agenda, their axe to grind, their own self-interests to look out for.

Next time you do something, try to consider the Greater Good. Is what you are doing going to be positive for you but negatively impact someone else? If so, don't do it. Stop and think of another way to do something good for yourself that also does something good for others. It takes a little more effort, but it's well worth it.

This concept is what makes capitalism work. To do well for myself, I have to create a product or service that is positive and desirable for others. It's so simple, but it's a paradigm that brings about the best in most of us. Nay-sayers will gleefully throw the Enrons and their ilk in my face, but I would say they are an anomaly, not a natural result of capitalism. Besides, they got caught and are going to jail. The United States is a nation of checks and balances, from the three branches of government to the battle between corporate greed and journalistic integrity.

Just do your job with honor and a little thought to how it impacts others. This is all that's required to live in a peaceful world. Is that so much to ask?

baseLayout.jsp is the file upon which all other AppFuse JSPs are based. It contains the overall structure of each page, where the contents of the page are inserted via Tiles.

A peek into web/WEB-INF/tiles-config.xml will reveal that baseLayout is a name in a <definition> tag that points to the actual file baseLayout.jsp in a path attribute. Within the definition, certain variables are "put" into the "definition" with <put>, <putList>, and <add> tags.

Taking it in sections, the beginning on the file includes /common/taglibs.jsp, so each JSP that is rendered will have available to it all the tag libraries that are mentioned in taglibs.jsp.

Similarly, after that, /common/meta.jsp is included. This contains all the meta tags your pages might need, so you can maintain them in one place.

Following that, there are a number of sections that import javascript and stylesheets. These are defined in lists at the beginning of web/WEB-INF/tiles-config.xml. You will see <putList> entries for scripts, styles, and printStyles. These lists are then converted into appropriate <HTML> tags within baseLayout.jsp.

Finally, on line 55, we come to the <body> tag. Here, you can see that the bodyId string that may have been defined in tiles-config.xml is included as the id of the body, if present.

Next, the errors.browser.warning string is retrieved from ApplicationResources for the current Locale.

Following that, within the div named screen, the div named header is displayed. This section checks to see if the current URL contains the string login.jsp, because this header text is only output if NOT on the login page. This header section is where you find the logged in user's name, as well as the link that says "Logout."

Following this, the menu is output, with a deceptively simple <tiles:insert> tag.

Equally minimalistic, the next div is called "content" and prints out the heading as an H1 header, followed by the /common/messages.jsp, which will contains whatever messages have been placed in there by prior processing, and finally, the actual contents of the page is inserted with line 84's <tiles:insert attribute="content"/>.

At the bottom of the page, the footer defined in tiles-config.xml is inserted.

"What we've got here is failure to communicate.
Some men you just can't reach...
So, you get what we had here last week,
which is the way he wants it!
Well, he gets it!
N' I don't like it any more than you men."

Look at your young men fighting
Look at your women crying
Look at your young men dying
The way they've always done before

Look at the hate we're breeding
Look at the fear we're feeding
Look at the lives we're leading
The way we've always done before

My hands are tied
The billions shift from side to side
And the wars go on with brainwashed pride
For the love of God and our human rights
And all these things are swept aside
By bloody hands time can't deny
And are washed away by your genocide
And history hides the lies of our civil wars

D'you wear a black armband
When they shot the man
Who said "Peace could last forever"
And in my first memories
They shot Kennedy
I went numb when I learned to see
So I never fell for Vietnam
We got the wall of D.C. to remind us all
That you can't trust freedom
When it's not in your hands
When everybody's fightin'
For their promised land

And I don't need your civil war
It feeds the rich while it buries the poor
Your power hungry sellin' soldiers
In a human grocery store
Ain't that fresh
I don't need your civil war

Look at the shoes your filling
Look at the blood we're spilling
Look at the world we're killing
The way we've always done before
Look in the doubt we've wallowed
Look at the leaders we've followed
Look at the lies we've swallowed
And I don't want to hear no more

My hands are tied
For all I've seen has changed my mind
But still the wars go on as the years go by
With no love of God or human rights
'Cause all these dreams are swept aside
By bloody hands of the hypnotized
Who carry the cross of homicide
And history bears the scars of our civil wars


I don't need your civil war
It feeds the rich while it buries the poor
Your power hungry sellin' soldiers
In a human grocery store
Ain't that fresh
And I don't need your civil war
I don't need your civil war
I don't need your civil war
Your power hungry sellin' soldiers
In a human grocery store
Ain't that fresh
I don't need your civil war
I don't need one more war

I don't need one more war
Whaz so civil 'bout war anyway

Phew. What a powerful song. You don't have to be a liberal (I ain't!) to find something to like here. Conservatives don't love war; we're just willing to face the fact that it is sometimes necessary.

While Axl and company may have been railing against the "military-industrial complex," I see something deeper in this song. This is about the sadness of man's inhumanity to man, in all its forms, throughout history. For the most part, the masses are merely pawns in the ridiculous struggles for power fought by a handful of men at any given moment in history. The fact that today's struggle is a necessary one doesn't lessen the tragedy of war, nor does it minimize the suffering and loss that war brings upon people who neither asked for it nor have a choice in it.


I've always been a patriot, even when I was a kid. My pride in the United States used to give me a lump in my throat, even when I was too young to really understand what I was feeling. Corny? Yeah, probably.

In these post-9/11 days, it is that much more important to me that I live in a country where peace and freedom are a reality. I can't imagine what it is like to live in a country where your perception of reality is so skewed that bombs and destroying the lives of others are your only forms of self-expression. To a certain extent, we are all victims of the circumstances around us, but we also create our own reality. Not every Palestinian thinks teaching their own children to blow up innocent children and old people makes sense. Not every Muslim thinks that there are 72 virgins awaiting them in heaven if they will only blow up non-Muslims. But there are far too many of each.

One of the things that makes the United States unique is the fact that it is, in a very tangible sense, The New World. Physically separated from most of the population of the world, North America took a heroic effort to reach. When you were living in the world that you knew and understood in Europe, it took a very significant decision and a great commitment to get yourself here. In a very real sense, then, we inhabitants of this great country were naturally selected for a desire for a better life. We are the decendents of people who dared to venture into the unknown on a quest for freedom, wealth, opportunity, and happiness. While other people stayed where they were comfortable, our ancestors left their warm beds and crossed an ocean to reach the land of opportunity.

Even the Mexicans who illegally cross into this country have the gumption to risk it all in pursuit of a more promising future. This land attracts the best of the best. People strive to get here. They let go of what they know in the hope of something better.

As much as the rest of the world resents us and loves to point out our many flaws, they, too, recognize that we are a nation of achievers, decended from their own departed pioneers and risk-takers. We, not they, carry in our genes the vision of a hopeful future and the chutzpah to actually go for it.

Flawed and imperfect as we are, We the people are imbued with a spirit and determination that the rest of the world can only dream about. We live it.

I've been a little unfair to Java in my previous posts. I don't really have anything against the language or the environment. Overall, it's a really cool, productive language. I've gotten pretty spoiled about not having to clean up after myself. I don't think I could go back to C++ without leaving awful memory leaks all over the place.

The real problem, as I see it, is with writing web apps. It's a really tedious process of shuffling parameters from layer to layer, and there's very little really interesting code. It's really a shame that the richest, most accessible business opportunities involve the most boring kind of software. Databases are dull. HTML is laborious. The only really hope for good stuff is a little interesting business logic, a few compelling classes, and some snazzy Javascript. It sure ain't the fun of embedded systems.

On the other hand, the end result is very cool. The possibilities presented by web apps are quite exciting. You can do some really amazing stuff, just by creatively assembling these few boring bits of software. It's an interesting trade-off.