This entry is part 3 of 3 in the series Port Unification in GlassFish

With this third installment, we’re getting to the most interesting feature:  serving multiple protocols on one port.  The uses of this are fairly obvious:  simpler administration, easier on firewalls, etc.  Many of the elements we’ve already seen and so should be fairly familiar.  We’ll simply build on things we’ve seen and take them just one step further.  In this simple demo, we’ll be serving up HTTP traffic and a “dummy” protocol.  We’ll look at at the code needed to implement this protocol once we cover how to configure it.

The first step we need to is to copy the attached protocol zip file in to GlassFish so it’s ready for us to use.  Once you’ve downloaded the zip file, copy it to <glassfish>/domains/domain1/autodeploy/bundles/.  (You might need to create this directory first.)  If you’re watching the server logs, you’ll notice in a few seconds that GlassFish has detected the file and has deployed it.  With that done, we can configure the system to serve up that protocol.

This script is very similar to what we’ve already seen:

asadmin create-protocol pu-protocol
 
asadmin create-protocol-finder --protocol pu-protocol --target-protocol http-listener-1 --classname com.sun.grizzly.http.portunif.HttpProtocolFinder http-finder
 
asadmin create-protocol pu-dummy-protocol
asadmin create-protocol-finder --protocol pu-protocol --target-protocol pu-dummy-protocol --classname org.glassfish.devtests.web.portunif.DummyProtocolFinder dummy-finder
asadmin create-protocol-filter --protocol pu-dummy-protocol --classname org.glassfish.devtests.web.portunif.DummyProtocolFilter dummy-filter
 
asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-1.protocol=pu-protocol

As you can see the steps here are almost identical to what we’ve done in the past. In this case, we’re reusing the http-listener-1 <protocol> definition and pointing the HttpProtocolFinder there. This is the default protocol definition that ships with GlassFish. We’re creating a new protocol definition for the dummy protocol and creating the finder and filter for the protocol. As a last step, we update the http-listener-1 <network-listener> to use the new pu-protocol we defined. And with that we’re ready to test.

The HTTP test is simple enough: point your browser and http://localhost:8080. You should seen the standard GlassFish welcome (or an app if you’ve deployed one to that location). Testing the dummy protocol is a little more involved but not too bad. The protocol is simple enouugh. It looks for the text dummy-protocol and then responds with Dummy-Protocol-Response. If you have the nc command installed, you can simply do this:

echo dummy-protocol | nc localhost 8080

If not, you can you the telnet command. Simply telnet into localhost port 8080 and and the prompt enter dummy-protocol and hit the enter key. The server will respond with Dummy-Protocol-Response. Then you know you’re done. We’ve seen this kind of configuration several times before. Let’s look at the code that drives.

The first player in all this is the finder. This code detects the dummy protocol and responds accordingly. The finder looks like this:

public class DummyProtocolFinder implements ProtocolFinder {
    private final static String name = "dummy-protocol";
    private byte[] signature = name.getBytes();
 
    public String find(Context context, PUProtocolRequest protocolRequest)
            throws IOException {
        ByteBuffer buffer = protocolRequest.getByteBuffer();
        int position = buffer.position();
        int limit = buffer.limit();
        try {
            buffer.flip();
            if (buffer.remaining() &gt;= signature.length) {
                for(int i=0; i

This code simply scans the incoming bytes looking for “dummy-protocol.” if it can’t find it, it returns null telling the underlying grizzly code to keep looking. If it finds it, returns that string to the caller signifying it’s found the protocol. At that point, control gets handed off to the DummyProtocolFilter:

public class DummyProtocolFilter implements ProtocolFilter {
    public boolean execute(Context ctx) throws IOException {
        SelectableChannel channel = ctx.getSelectionKey().channel();
        OutputWriter.flushChannel(channel, ByteBuffer.wrap("Dummy-Protocol-Response".getBytes()));
        ctx.getSelectorHandler().closeChannel(channel);
        return false;
    }
 
    public boolean postExecute(Context ctx) throws IOException {
        return true;
    }
}

The filter is simple enough. It just prints back the text we’ve been expecting. When it’s done it returns false to show that execution is finished and the response can be closed out. Obviously a more complex protocol would require a more complex filter, but this is the basis of any such filter.

That’s all it takes. If you wanted to serve up more protocols, you’d simply add more filters and finders as needed.

Share and Enjoy:
  • Digg
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Technorati
  • email

Technorati Tags: ,

This entry is part 2 of 3 in the series Port Unification in GlassFish

It’s taken more time to get back to this topic but it’s time.  In part 1, I covered how to set up GlassFish to push all HTTP traffic to HTTPS.  In this post, I’ll show you how to set up the reverse.  In the next post, I’ll cover how to configure GlassFish to serve up multiple protocols from the same port.  The steps are basically the same so this will be a short one.  Similar to last time, we’ll issue a few simple commands:

asadmin create-protocol --securityenabled=true https-redirect
asadmin create-protocol-filter --protocol https-redirect --classname com.sun.grizzly.config.HttpRedirectFilter redirect-filter
asadmin create-ssl --certname s1as --type network-listener --ssl2enabled false --ssl3enabled false --clientauthenabled false https-redirect
 
asadmin create-protocol pu-protocol
asadmin create-protocol-finder --protocol pu-protocol --target-protocol http-listener-1 --classname com.sun.grizzly.config.HttpProtocolFinder http-finder
asadmin create-protocol-finder --protocol pu-protocol --target-protocol https-redirect --classname com.sun.grizzly.config.HttpProtocolFinder https-redirect
 
asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-2.protocol=pu-protocol
asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-2.enabled=true

This should familiar if you’ve read part 1. We do a little extra work to set up some ssl config elements primarily to preserve the standard settings in case you want to roll back these changes when you’re done. If you do, you simply need to delete those new protocol elements.

To see it in action, simply issue the following command:

wget -q -S --no-check-certificate https://localhost:8181/

You should see something like the following:

HTTP/1.1 302 Moved Temporarily
Location: http://localhost:8181/
Connection:close
Cache-control: private
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1-SNAPSHOT Java/Apple Inc./1.6)
Server: GlassFish Server Open Source Edition 3.1-SNAPSHOT
Accept-Ranges: bytes
ETag: W/"5212-1279828070000"
Last-Modified: Thu, 22 Jul 2010 19:47:50 GMT
Content-Type: text/html
Content-Length: 5212
Date: Fri, 23 Jul 2010 16:50:22 GMT
Connection: Keep-Alive

As you can see, the https request received an initial 302 response pushing off to the http url which then returns the 200 response we’d expect. To verify even further, use wget to fetch the http url and you’ll see something like this:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1-SNAPSHOT Java/Apple Inc./1.6)
Server: GlassFish Server Open Source Edition 3.1-SNAPSHOT
Accept-Ranges: bytes
ETag: W/"5212-1279828070000"
Last-Modified: Thu, 22 Jul 2010 19:47:50 GMT
Content-Type: text/html
Content-Length: 5212
Date: Fri, 23 Jul 2010 16:57:31 GMT
Connection: Keep-Alive

That’s it. As promised, short and sweet. Currently this approach does not allow you redirect to a different port number. We have added a new configuration element that simplifies this setup and allows for cross-port redirects. However since there isn’t asadmin support for it yet, I’ll defer discussion until we can get those commands written. That’s in the works so it should be in the next week or two.

With that, though, I’ll wrap this one up and start working on the more interesting Part 3.

Share and Enjoy:
  • Digg
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Technorati
  • email

Technorati Tags: ,

The Apache/Sun rift is well-known to most following the Java world. Apache has long demanded that the field of use restrictions be dropped.  There’s some consensus that the FOU clause actually violates the JCP’s charter.  I’m not a lawyer so I can’t really comment either way.  This has prevented Apache Harmony from certifying as a Java implementation and, at least in part, has led to the development of the Dalvik VM up on which Android based applications run.  A new article in The Register reports that talks between Apache and Oracle have started to break down and that should worry anyone who works with Java.

Java’s promise and value has long been platform portability.  Except for a few corner cases here and there, an application written in Java could run on any platform which had a JVM.  Even most of those cases can be mitigated if your application is written correctly.  With the rising popularity of “non-computer” computing devices (smart phones, tablets, etc.), Android has become an considerable presence in the industry.  Whether or not Google chooses to certify Dalvik as a JVM or not, it isn’t allowed to even try, really.  The Java JCK won’t allow it.  And that poses a real threat to Java.

The FOU restriction was added, in part, to protect Sun’s JavaME business.  This made business sense to a degree as that’s an enormous market.  Back when devices couldn’t support a full JVM, JME made a lot of sense.  That’s changing rapidly these days.  Personally, I think the days of JME are numbered.  I think Android is going to be a huge player in the years to come.  And it isn’t Java.  Already, dozens of times I’ve personally helped debug someone’s “Java” code only to find that the tried and true answer doesn’t apply because, surprise!, that code was actually running on an Android device.

The mobile market is already huge and it’s only getting bigger.  There’s little reason for Oracle to retain the FOU clause.  Oracle doesn’t need the JME market the way Sun did.  Opening that up will allow Dalvik, and others, to certify as a Java implementation and push Java into even more markets.  If Oracle fails to do this, it could ultimately end up ceding the mobile market to others.  I’ve long agreed with Apache that the FOU is unfair and violates the spirit (and probably the letter) of the JCP agreement.  Oracle should drop the clause as they’ve said in the past that Sun should.  Vendors who still need JME can still pay for it.  But, increasingly, JME is looking more and more anachronistic.  I see very little reason to protect it any longer and every reason to push Java in to more and more markets.

Update: Yes, in some ways I’m conflating Harmony and Dalvik.  They’re both emblematic of the larger issue.  The problem of the FOU and the viability of the JVM on an embedded device is the main point.  Please don’t get too caught up in the finer technical points.  I apologize for any confusion.

Disclaimer:  These opinions are my own.  I do not speak for any of the parties involved nor do I have any inside knowledge despite my employment at Oracle.  I am simply a passionate Java advocate expressing an opinion.

Share and Enjoy:
  • Digg
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Technorati
  • email
This entry is part 1 of 3 in the series Port Unification in GlassFish

There are two main cases I want to cover here:  port redirection and serving multiple protocols on one port.  I’m pretty sure that covering both in one post would egregiously long so I’m going to break things up into two posts.  In this first post, we’ll cover what will likely the be more common use case:  port redirection.  In this example scenario, you only want to serve requests via https rather than http.  In this case, you can configure GlassFish to return a 302 and push clients off to https transparently.  This type of configuration has been available in GlassFish since at least v2 and is still available in v3.  However, in v3 it wasn’t “officially” supported so you had to manually massage your domain.xml.

While documented in various blogs around net, it’s not officially supported in v3.  As of, well now I guess, that’s all changed.  I’ve added some asadmin commands to the 3.1 nightly builds that expose a more user friendly way to configure port unification.  In this blog, I’ll introduce these commands and show you how to set up a simple redirect to enforce https requests on a given listener.  As always, when experimenting with this sort of thing, you should back up your domain.xml so if you hose your configuration, you can easily roll back to a working configuration.

There are two main concepts involved:  <protocol-filter> and <protocol-finder>.  There are a handful of other elements involved but we’ve hidden them from you by default since very few people will need to manage those elements.  The first step is to create the <protocol-filter>:

asadmin create-protocol --securityenabled=false http-redirect
asadmin create-protocol-filter --protocol http-redirect --classname com.sun.grizzly.config.HttpRedirectFilter redirect-filter

We need to create a new <protocol> element to hold our new filter first.  You can’t simply reuse, say, http-listener-1 because port unification elements and <http>/<ssl> can’t coexist on the same protocol elements.  You could of course issue a number of commands to preserve the name of http-listener-1 but the work involved is likely not worth it.  It’s certainly overkill for this example so I’ll leave that as an exercise for you if you’re that interested in it.  The next asadmin command creates the actual protocol filter.  With these two commands we have now have a new entry in our domain.xml that looks like this:

<protocol name="http-redirect">
  <protocol-chain-instance-handler>
    <protocol-chain>
      <protocol-filter classname="com.sun.grizzly.config.HttpRedirectFilter" name="redirect-filter" />
    </protocol-chain>
  </protocol-chain-instance-handler>
</protocol>

Notice that there are new elements: <protocol-chain-instance-handler> and <protocol-chain>. These are some implementation details that should be mostly irrelevant to all but a handful of users. I only mention them so that you’ll be expecting to see them and that you know you can safely skip over them. With those pieces in place, we can now create our finders.

To create our finders, we need to create another <protocol> element to hold them and then create the finders themselves:

asadmin create-protocol --securityenabled=false pu-protocol
asadmin create-protocol-finder --protocol pu-protocol --target-protocol http-listener-2 --classname com.sun.grizzly.config.HttpProtocolFinder http-finder
asadmin create-protocol-finder --protocol pu-protocol --target-protocol http-redirect --classname com.sun.grizzly.config.HttpProtocolFinder http-redirect

Note that the first <protocol-finder> refers to the http-listener-2 <protocol>. We’ll be using that protocol definition to configure the https processing. The second finder refers to the <http-finder protocol> definition we just created and it is this piece that will be doing the redirect from http->https for us. The first finder will trap all https requests and hand them off, while the second will handle all cleartext http requests and redirect for us. The resulting domain.xml elements looks like this:

<protocol name="pu-protocol">
  <port-unification>
    <protocol-finder protocol="http-listener-2" classname="com.sun.grizzly.config.HttpProtocolFinder" name="http-finder" />
    <protocol-finder protocol="http-redirect" classname="com.sun.grizzly.config.HttpProtocolFinder" name="http-redirect" />
  </port-unification>
</protocol>

Again, we silently create the <port-unification> element for you so you needn’t worry about it. These elements that we silently create for you, we will also silently delete them for you when you delete the last elements contained in them. So those are our port unification elements. With those created, we just need to reconfigure listener to use these new elements:

asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-1.protocol=pu-protocol

With that, we can try hitting port 8080 and see things in action. The easiest way to see this, probably, is to use wget:

wget -q -S http://localhost:8080/

With this command, you should see the following output:

  HTTP/1.1 302 Moved Temporarily
  Location: https://localhost:8080/
  Connection:close
  Cache-control: private

As you can see there, the server returns a 302 back to the client with the new location of https://localhost:8080. That’s all it takes. Now every request will use https regardless of the original request. You could, of course, use a similar set up to push everyone from https back to http. This is especially useful for those without any need for https and are concerned about server load since https can be expensive to process.

In the next entry, I’ll tackle the use case of serving up multiple protocols from one listener. This will be especially useful for those behind firewalls wanting to open only a single port to the outside world. Hopefully this will get you started. If you have any questions, feel free to leave a comment or ask on the glassfish users mailing list.

For convenience, here are all the commands necessary to try this out at home in one downloadable file:

?Download pu.sh
wget -q -S http://localhost:8080/
 
asadmin create-protocol --securityenabled=false http-redirect
asadmin create-protocol-filter --protocol http-redirect --classname com.sun.grizzly.config.HttpRedirectFilter redirect-filter
 
asadmin create-protocol --securityenabled=false pu-protocol
asadmin create-protocol-finder --protocol pu-protocol --target-protocol http-listener-2 --classname com.sun.grizzly.config.HttpProtocolFinder http-finder
asadmin create-protocol-finder --protocol pu-protocol --target-protocol http-redirect --classname com.sun.grizzly.config.HttpProtocolFinder http-redirect
 
asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-1.protocol=pu-protocol
 
wget -q -S http://localhost:8080/
Share and Enjoy:
  • Digg
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Technorati
  • email

Technorati Tags: ,

I’d never been in the room when someone died.  Yet for the last week, we’d all been waiting for, and dreading that fateful moment.  With my father stretched out on the bed, tubes streaming from his withered form, we huddled together and waited for the end.  An end all the more bitter for its prematurity.  We’d all thought we’d have more time together.

My father was, by all accounts, in very good shape.  At 60 years of age, he exercised more than most people I knew:  running, sit-ups, push-ups, etc.  He worked on his cars himself.  Reroofed his house basically single-handedly.  Built his own garage.  He did it all himself with only slight grumbling about his knuckles hurting from when he’d tried to punch through a board in karate class some years prior.  The man was busy.  Then … he had trouble swallowing one day.

“It’s cancer,” the doctor told my mom and dad.  My dad’s response, as I am told, was to turn Mom and, “I’m sorry.”  That’s the kind of man he was:  so worried about being a burden that he apologized to his wife.  For having cancer.  I’m sure there was more to it.  He had to have known that this was essentially a death sentence.  More and more people fight and beat cancer these days.  But not as many as we would like.  Not even close.

With little else to do but get on with it, Dad started rounds of chemo.  Chemo, being chemo, was going “ok.”  Hair came out.  Weight came off.  Appetites disappeared.  But he remained in good spirits.  At least, as far as he showed us.  Knowing the course this cancer would probably take, we decided at the last minute to fly back to Oklahoma to spend his birthday with him.  We couldn’t be back there for Christmas (we had family coming to see us for a change) and knew that by then he might be too sick and weak to really enjoy his grandchildren.  So we went.  It was, all things considered, a great visit.  The kids enjoyed seeing Grandpa Lee and Grandma Lee.  My parents had fun with the girls.  We took lots of pictures.  It was one of the last times I heard his voice.  It was the last time I saw him on his feet.

We flew back to Brooklyn and continued on with our lives.  I tried to check in weekly with Mom and see how things were.  I talked to Dad occasionally but mostly talked to Mom.  Some weeks he was doing pretty well; others, he couldn’t eat too much.  Some weeks he seemed to improve and others … not so much.  Thanksgiving came and went.  He couldn’t eat too much.  Wasn’t terribly interested.  On December 10, he went in to the hospital for the last time.

He’d had trouble swallowing and had Mom call the doctor.  The doctors looked him over and found more cancer.  It was here,  It was there.  They needed to operate.  The doctors tried valiantly.  I can find neither fault nor blame with their efforts.  They were fighting a losing battle.  But they tried their damnedest.  All through this, I would check in with Mom.   “Should I come?”  “I’m not sure.  Do what you think is best.”  She was so gracious with me in all this.  I wanted to be with them but I had work and kids and such.  What I ultimately wanted was to be with Dad at the end and be with Mom.  But trying to time that long distance is as quixotic as trying to time the stock market.  We would just have to wait and see how things went.

Christmas came.  “Should I come now?”  “You have your family and your kids.  Stay with them.  Enjoy your Christmas.  We can see what happens in a few days.”  It was getting harder and harder to not be there.  I could hear him in the background grumbling and complaining.  He wasn’t entirely coherent all the time.  The pain medicine was taking most of that away.  But he had his moments.  He knew he had family around him.  Christmas, it turns out, would’ve been a horrible time to travel there.  My siblings, a mere 20 minutes away, couldn’t even make it to the hospital.  Snow and ice shut down much of the state.  So I stayed in NY.  I enjoyed Christmas with my wife and kids.  With my wife’s sister and her husband.  I had fun.  I kept thinking of Dad.

Every time my phone would ring, I would go in to near seizures trying to get to it.  Was this it?  Is this The Call?  Then it came.  “If you want to see him one last time, you probably should come now.  He’s … not doing so well.”  I booked a flight and that Tuesday I flew down.  Without being too dramatic about it, it felt like a storyline out of a movie:  Will I get there to find he passed away while I was in the air?  Every little delay was agonizing but there was nothing to do about it but ride it out.

When I finally arrived, the worst had almost happened.  After a reasonably routine procedure to remove a line, he (almost?) crashed.  They’d had to put him on life support or he *would* have died while I was in the air.  He was still with us.  But he couldn’t speak.  He couldn’t, for the most part, respond to any stimulus whatsoever.  Apart from groans he would utter over the next week, I would never his voice again.

The waiting game began.  He was getting food and oxygen from bags and tubes and machines.  He would from time to time roll his head when we went in to see him.  His eyes would roll around glassily only to snap into hard focus as if he had found some reserves deep inside for one brief moment.

For the next week, I lived in the hospital with my mom.  We stayed in the ICU waiting room and we, well, waited.  We talked about this and that:  what’s to come, the sadness we were feeling, whatever stupid show was on TV.  We made friends with another family who was there with their loved one.  We laughed together.  We shared stories, jokes, and sorrow.  At times we felt guilty having such a good time with my father dying just through those doors.  But we never would’ve made it without that family.  Life isn’t all jokes and laughter but neither is death all sorrow and pain.  We gave and received a measure comfort in our unexpectedly shared time of sorrow and worry.  It was probably the sweetest, most heartbreaking week of my life.  And it shared with strangers turned new friends.

We spent the nights at the hospital.  Mom had been there for three weeks already.  I’d missed enough already that I had no desire to leave.  I could’ve slept on a real bed only 20 minutes away but I couldn’t bear the thought of being away anymore.  It was my turn.  Mom wasn’t leaving.  Neither was I.  Oh, I left once or twice for food.  I walked down the hall to grab coffee sometimes with, sometime without, company.  But we were there.  We weren’t going anywhere.  Mostly we ate in the cafeteria there.  Sometimes it was most or all of us siblings and Mom.  Sometimes it was just me and Mom.  We talked about more about the next steps.  We knew it couldn’t be too much longer.

Finally, we all came to the question we’d been putting off:  What to do about life support?  We all knew there’s no way Dad would want to be kept alive by mechanical means.  Truth be told, there wasn’t really anything left for him to hold on for.  He was on life support for various reasons unrelated to his cancer.  But that cancer had done far more damage than we’d thought.  He had weeks at most left.  There was no hope of recovery.  He would never leave that hospital again.

With the dawn of realization washing over of what we were talking about, we decided to remove his feeding tube and let nature take its course.  We signed the papers.  We talked to the doctors.  We went in to say goodbye.  We held his hands.  Told him we loved him.  Kissed his forehead.  Then we all stepped back and let the tech do his job.  In minutes it was done.  The feeding tubes and the oxygen tubes were out.  And despite all expectation, he held on.  We moved him to a hospital room and began the wait once again.

He lasted only handful days more.  He’d moan and grunt as who knows what was going on for him.  He was all but unresponsive to us.  But we were there.  Holding his hand.  He’d gasp for air as hard as he could and then suddenly he’d stop.  Desperately watching his pulse throb in his throat, we’d hold our breaths.  Seconds would pass and finally one of us would call out, “Dad?”  A slight pause and suddenly he’d draw another ragged breath and settle back down.

Days like this passed.  Until finally on January 4, he drew his last breath.  I watched as his throat ceased to throb and no amount of calling his name would bring that next breath.  Mercifully, painfully, his suffering was over.  The nurses and and doctors came in to do their jobs as unobtrusively and respectfully as they could.  But it was worrying and the wondering were over.  It was time to grive.  After some time, we all started making phone calls:  me to my family still here in Brooklyn, others to various friends, loved ones, or church members.

We buried my dad a few days later on a frigid Oklahoma winter’s day.  The little country church my family has attended since I was a child was packed with more people than I can ever remember seeing in it.  My father was a Marine Corps veteran of the Viet Nam War.  He didn’t talk much about it preferring to try to forget it as much as possible.  He’d talk about it from time to time but there were too many painful memories for him.  So much so that he’d leave a graveside service where Taps was played;  the grief was just too much.  So we didn’t have Taps played at his funeral as much as I would have loved to have honored him that way.  But the Marines did send out two soldiers whose sole duty that day was to deliver some of the saddest, most reverent words I know:

On behalf of the President of the United States, the Commandant of the Marine Corps, and a grateful nation, please accept this flag as a symbol of our appreciation for your loved one’s service to Country and Corps.

Five months it’s been now. I feel fine most days.  But occasionally something will trigger an especially poignant remembrance of him.  This weekend as the trailer for the new Tron movie started, I began to cry in the middle of the darkened movie theater.  My dad would have loved that movie.  There’s so much he would’ve loved to have seen.  But he’s gone now and I can only remember the man as best I can.  And what I remember is that he loved his family more than his own life.  And I remember that I love him.  And that loss hurts like hell.

Share and Enjoy:
  • Digg
  • Reddit
  • del.icio.us
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Technorati
  • email
Powered by WordPress Web Design by SRS Solutions © 2010 Antwerkz, Inc. Design by SRS Solutions