Verse Of The Day

Thursday, December 14, 2006

Ant Visualization Tool - yWorks Ant Explorer

Found this free tool last night that shows a visual graph of an Ant build.xml and shows the hierarchy of task dependencies. Can be stand-alone installed or Webstart, or IDE plugin for Eclipse or Netbeans.

Wednesday, December 13, 2006

DAO Gen Update 12/13

Between other tasks and our Christmas party, I got some work done on the DAO generator tool.

Completed Tasks
  • ResourceManager - getConnection() for when Connection is not supplied: Currently it's guts are commented out. Should put a JNDI lookup for a data source in there. That's how we do it, most likely anyone doing server-side code also does this. They could always customize for using DBCP or some other mechanism.
  • DB query tab. Lets you enter queries and run them. Results come out to output tab as tab-separated text, along with number of rows retrieved and how long it took to run.
  • simple Batch file launcher for Windows.
  • Fixed an elusive NPE on describe that only happened once in a blue moon.
  • Usability stuff: there are validations now for required fields being blank, and clicking on describe button will take you to output tab to show what is going on. When done, it goes to DB explorer tab. If a field is blank when validation runs, the config tab is selected so user can fill in,and some other things that make it all more usable.
Screenshot of simple query runner tab:

Outstanding Tasks
  • DaoFactory - generated factory class is missing factory methods for stored procedure DAO's (easy fix, but have been busy with GUI)
  • Stored Proc DAO's - need a lot of work
  • CLOBS/BLOBS/BFILES - haven't accounted for those at all. they are a pain to write by hand so they should be done right in the generated code.
  • Generated DAO's and all classes need to be fully tested to make sure the templates are right.
  • Dist - need to come up with a distribution package mechanism, with shell and batch files to launch, special directory for templates, etc.
  • Custom Queries - not implemented in generator or GUI yet.
  • Saving new project file - app should put .prj extension on filename automatically if it isn't there.
  • Help screen needs content
  • Code cleanup w/ respect to comments, package names, etc.
  • Pick a better name for application and update the package names
  • Documentation would be helpful
  • Pick an open source license and OS project hosting

Tuesday, December 12, 2006

DAO Gen Update 12/12

I got lots of cosmetic and functional work done on the GUI side of my persistence generator. Still need to work on the Velocity templates, implement custom query generation, clean up code/comments, pick a better name, open source it somewhere, and some more GUI features to add.

Progress this week:
  • Added a Browse button for the template directory to make it more consistant with the generated code destination field. Also improved the layout a little bit on the screen.
  • Switched to a tabbed interface. The main screen from last week is now the configuration tab. There will be a tab for writing the custom query methods, running queries against the current DB, the output window has been nixed in favor of an output tab, and a tab that visually shows the DB objects to some extent.
  • Add mnemonics to menu and toolbar controls.
  • Open and Save/Save As now fully work, and described database meta data gets saved with project.
  • Help "about" and "contents" actually launch screens, even if there is no real content yet.
Screenshots: Config Tab (default Java "Metal" look and feel)Output tab (used to be separate window)

DB Explorer tab:
Look And Feel is controlled by View menu, below are the Windows (native) and the crappy "Motif" look-a-like that comes with Java:

Outstanding task list:
  • ResourceManager - getConnection() for when Connection is not supplied: Currently it's guts are commented out. Should put a JNDI lookup for a data source in there. That's how we do it, most likely anyone doing server-side code also does this. They could always customize for using DBCP or some other mechanism.
  • DaoFactory - generated factory class is missing factory methods for stored procedure DAO's (easy fix, but have been busy with GUI)
  • Stored Proc DAO's - need a lot of work
  • CLOBS/BLOBS/BFILES - haven't accounted for those at all. they are a pain to write by hand so they should be done right in the generated code.
  • Generated DAO's and all classes need to be fully tested to make sure the templates are right.
  • Dist - need to come up with a distribution package mechanism, with shell and batch files to launch, special directory for templates, etc.
  • DB query tab - not implemented yet
  • Custom Queries - not implemented in generator or GUI yet.

Tuesday, December 05, 2006

A Few Unix Shell Tricks

If you want to set a value in a shell script, but only if it isn't already set (e.g. set a default value but let it be overridden), try this. The following command will set PROJECT to be mqbridge, unless PROJECT is already set. In that case, the current value overrides. I have used this trick in ksh and bash. Not sure what other shells it works in.

export PROJECT=${PROJECT:-"mqbridge"}

Redirecting stderr to stdout: If you are trying to capture output of a command into a file, you will notice the regular output goes into the file, but errors go directly to the screen instead. If you want to capture both, use shell redirection like this (2>&1) after your command.

For example, to have all output go to the screen and to a file, you can do something like this: 2>&1 | tee output.log

Wednesday, November 29, 2006

Crontab Format

Every time I need to put something in cron, I forget the format or layout of each job. I stripped this decent explanation from this site:

The format of the crontab file is as follows:

Minute (0-59) Hour (0-23) Day of Month (1-31) Month (1-12 or Jan-Dec) Day of Week (0-6 or Sun-Sat) Command

0 2 12 * 0,6 /usr/bin/find

This line executes the "find" command at 2AM on the 12th of every month that a Sunday or Saturday falls on.

Wednesday, November 08, 2006

In Loving Memory...

(AKC "Good Grief Charlie Brown")
April 27, 1998 - November 7, 2006
Airedale Terrier

Charlie was our first dog, our first baby. He was diagnosed with Lymphoma (cancer of the lymph node system) about 2 weeks ago, and we had to put him down last night. It was not an easy decision, but it was what was right for him so he wouldn't suffer and be in pain any longer.

The Lymphoma was a horrible disease, because early detection doesn't really buy you anything. We took him to the vet because his throat was swollen and his eyes were red. We thought he had an allergic reaction or infection. We weren't prepared to hear the doctor say the "C" word, especially since Charlie was acting completely normal, looked normal, was still playing and happy, wagging his tail, eating and drinking, and just being himself.

Charlie was a great dog. Even when we had children, he took to them very well and welcomed them to the family. He soon became very protective of them, like they were his own. He would sleep in the hallway outside their doors at night. If someone he didn't know came to the house, he made sure to be between the girls and the stranger at all times. When they cried in their crib, he would go investigate and come barking at us so we knew something was up.

(Left: Charlie and Morgan taking a break from playing)

He was of course every bit a terrier though, we can't forget that. He was smart, but stubborn. When training him, he would reach a point where he would get bored and just wouldn't cooperate. He was big enough to do his share of "counter surfing" -- getting up on the counters to steal any food that wasn't bolted down. He had no use for other animals, especially strange dogs. Sure he played with the dogs he knew, like Morgan, Pongo, Sage, Wolf, etc. But any other dog he would go nuts barking and lunging at them. As a very small puppy, he actually started barking and "picking a fight" with a full grown rottweiler. That's terrier attitude for you.

(Left: classic example of Charlie being in the middle of the action during Taryn's birthday party)

When we first went to get Charlie as a puppy, we were "just going to look". I liked Airedales from what I knew about them, but had no real intention of actually getting one right then. I was still in an apartment that didn't allow dogs, but I was closing on my first house in a few weeks. Plus I was going to ask my girlfriend to marry me. I wanted it to be a surprise, so I kept telling her I didn't have the money for the ring. Well in her mind, I had no money for a ring but I just dropped $500+ for a puppy. I just couldn't resist once I saw them. There were about 4 puppies left when we got to the breeder's house, and Charlie was running around with a little purple ribbon tied around his neck like a collar. For some reason we gravitated right to him, but he kept running under their porch. The breeder spent a good 15 minutes or so trying to get him to come out so we could take him home. We're glad he finally came out. And my wife has since forgiven me for the ring incident once she found out I had already purchased the ring.

(Right: Upside-down Bear)

If Charlie was laying down, and any of us walked near him, he would roll over on his back with all 4 paws up in the air. We would say "Charlie's upside-down" and then rub his belly. After getting used to this behavior, he would sometimes "go upside-down" even if you weren't near him, knowing you would go over and rub his belly anyways. We even taught our daughters that any time he was upside-down, they had to rub his belly.

He was never much for the game of Fetch in the traditional sense. Throw a ball or frisbee and he would run over, grab it, and then lay down to chew on it. So we turned it into a game of "I'm Gonna Get You". We would run after him, and he would grab the toy and run away, purposely getting himeself into situations where we could corner him and grab the toy, but then running past us in the other direction.

Sometimes Charlie would kind of sigh in his sleep, so it sounded like he was "leaking" air. Another strange thing he did was he would lick my head when I got down on the floor to play with him. It was funny when he would get done eating or drinking, then walk the length of our bed rubbing one side of his face on the comforter, then back the other way rubbing the other side of his face, like our bed was a giant napkin just for him. Speaking of napkins, he would go on one his marathon water drinking sessions, then come up to you with his terrier beard dripping wet and put his head on your lap (usually when you're wearing shorts!).

We will miss Charlie a lot. I didn't really feel ready to say goodbye, but I wouldn't have been any more ready next week, next month, or even 8 years from now when he would have been "old". We did the right thing for him instead of being selfish and keeping him around in misery. We'll always remember him and love him. He was our first baby.
(Left: "You lookin' at me?")

(Below: Just hangin' out)

Monday, September 18, 2006

Outer Joins: Sybase versus Oracle

I've never had the 'pleasure' of dealing with Sybase. I've created databases in Sybase and MS SQL Server (based on Sybase code at one point), but never had to interact with them directly (they were just meta databases for Silverstream servers).

So on a current project I have to convert a bunch of queries in Java code from Sybase to Oracle, as the database has been migrated.

To oversimplify, a right outer join in Sybase might look like this....

FROM table1, table2
WHERE table1.col3 =* table2.col3

And in Oracle it would look more like this...

FROM table1, table2
WHERE table1.col3(+) = table2.col3

For a left outer join, Sybase...

FROM table1, table2
WHERE table1.col3 *= table2.col3

And Oracle...

FROM table1, table2
WHERE table1.col3 = table2.col3(+)

As a side note, when you see something like "SELECT getDate(), ...", the getDate() function is basically the Sybase equivalent of SYSDATE.

Thursday, September 14, 2006

Rednecks on Parade

From a car show in my home town of Scottdale , PA last summer. Just came across these pictures on my hard drive. Some guy spent a lot of time and money building this replica of the General Lee, complete with the musical horn. Except for some minor details, he did a pretty good job. I loved that show as a kid (still do), so my wife got a few pictures for me.

Tuesday, August 29, 2006

Robb's Southwest Chicken Tortilla Soup

I ordered chicken tortilla soup at Red Robin one day and liked it. But I thought I could at least match it, if not make it better at home. After we had a roasted whole chicken for dinner one night, with lots of broth and leftover meat, I came up with this recipe. I've altered it a little bit each time, so there is really no "wrong" way to make this -- it's hard to screw up. Great to have cooking in the fall on football Sundays!


  • A Left over roasted chicken, deboned & cubed
  • Chicken broth or stock, bullion/water as needed
  • Frank’s Red Hot (cayenne pepper sauce) I don't measure so it might be about 1/4 cup or so?
  • Spicy V8 Juice (maybe about 1 cup or so, this is optional as sometimes we don't have any)
  • 1 can black beans, drained/rinsed of the “sludge”
  • 1 can sweet yellow corn
  • Finely chopped fresh cilantro (1 bunch)
  • 3-4 slices bacon, chopped and cooked (optional, I always forget this and it always tastes great anyways)
  • Garlic cloves, minced (a few spoonfools, depending on how much you like garlic)
  • 1 large onion, finely chopped
  • 1 Jalapeno pepper, finely chopped
  • Little bit ground cumin to taste
  • Dinosaur BBQ “Foreplay” and/or Chili powder to taste
  • Black Pepper to taste
  • The chicken and broth are probably plenty salty but you can add more if desired

Cut the chicken into small cubes or pull apart with a fork, depending on how you like chicken in soup. Put all the ingredients above into a crock pot and cook it on low all day. When you're ready to eat, scoop it into a bowl and crumble some tortilla chips on top, sprinkle some cheddar or "taco" cheese on top, and add a dollop of sour cream. Enjoy!

Thursday, August 24, 2006

JavaOne 2006

I should say something about JavaOne too, while in a Blog Editing frenzy. I can sum up JavaOne 2006 in three workds: Annotations, AJAX, and SOA. Well, AJAX and SOA aren't words so much as acronyms. Well, okay, AJAX kind of is a word if you are talking about the cleaning product, and it's funny how some of the folks have turned SOA into a word, as some talking heads kept referring to "sew ah".

Overall, Sun does one heck of a job producing this thing. The whole even is just overwhelming. It is like controlled chaos, so many people doing so many things and yet it is well organized for the most part. You had to sign up for your presentations ahead of time and your smart card was read at the door which would let them know if you were signed up or not. Big screens everywhere with the Sun/Java propganda blaring, all the signage was Sun or Java or Duke, you would think you were in a Sun building instead of Moscone center. There were bean bags, video games, movies, foosball, etc in the open areas for people to relax and hang out between sessions. Of couse Wifi everywhere, and it was funny to see people huddled around the few outlets charging their laptops (I was one of them, so it wasn't so funny when all the outlets were being used).

Anyways, all the complexity of J2EE programming (sorry it's now Java EE, not J2EE) is now gone! Instead of writing butt loads of XML descriptors for the J2EE containers, you just slap some annoations in your class and PRESTO! Write a simple POJO and spew @Session in there and now it's a session EJB. Expose it as a webservice, you say? @WebService. It's all magic. It's all...Xdoclet. Really, how writes all those EJB interfaces anymore anyways? Not that annotations aren't a welcome convenience, but it's not a revolutionary new idea that Sun just ame up with. Other things annoations are used for are dependency injections. So not just XDoclet, but Spring. Oh well, how can anyone say open source community is irrelevant when so many of the ideas are making into the new "standards-based" Java world?

SOA, everyone demo'd some sort of SOA tools it seemed. Sun kept pimping the latest NetBeans and Glassfish, which lets you do all kinds of drag and drop poop-flinging or WSDL files and services and whatever to create brilliant SOA based applications. Oracle, not to be outsold by rival crack dealers, had to push their own version of the drag-n-drop SOA tools on their own server. Eek, it's freakin' flowcharts all over again to look at these tools. And it's all so easy, you have perfect like web services already wel defined and sitting there, with one method call on each one that sends back simple strings, and we string them together with a little bit of drag-n-drop data mapping and a few conditionals, and BAM! A useless application!

Those were all in the keynote sessions in the morning. So I figured the SOA sessions would be even more detailed and in depth, but it was basically the same smoke and mirrors. At one point, a presenter was making a change and went to the browser to show us how it would just magically show the extra service or whatever, and ...crickets... it didn't work. It's all freaking magic point-n-click until something doesn't work -- then what? You have no idea what's really going on under the hood of all that graphical diarrhea and annotation soup.

I went to the Jboss party and the Eclipse party. Both were cool in their own ways. It was hard to find just a regular old neighborhood bar to go and grab a beer in San Francisco. Everthing was pretentious and/or artsy crap -- like wine bars, or places with cloth tablecloth and $50 a plate meals. I want a place where you walk in and they have beer, lot of beer, that's not $8.00 a pint, and burgers and chicken fingers and crap like that. A bar for regular Joes like me. Couldn't find it.

So the first time I really got my drink on that week was at the Jboss party. That was weird. I walked to the end of the street and didn't see the place where the party was supposed to be. Finally I saw the address on the building across the street, and it matched. It looked like an abandoned warehouse though. I walked up and a couple guys in black with headsets said "this way" and pointed to a chainlink gate. We walked down that "alley" to a side door, where another dude in black with a headset welcomed us in. I made the comment to the guy next to me that I felt like we were in a bad mobster movie, and we were about to be gunned down. Inside was a big empty room with a DJ pumpin out beats and open bars. OPEN BARS! Jack Daniels and Cokes for me please, and lots of them. Free food too, but OPEN BARS. It got weird when Fleury got up to speak, as I couldn't understand a word he said, but between his red beret and maniacal screaming it seemed like he was a third world revolutionary getting ready to overthrow some corrupt regime. Then some lady came out and did some sort of weird trapeze dance thing up in the air. Odd indeed.

Thouroughly beyond soberness, I left with a couple of dudes from Sherwin Williams, and tried to get into the SDN party. I of couse didn't have my invite, and they did. We tried, but I got turned away. As if this weren't enough of an omen to go back to the hotel, I instead stumbled over to the Eclipse party. Free microbrew beer. Sweet! I'm already stumbling and they are givingme 20 ounce glasses of really dark and strong beer. I talked to some dudes from I think Finland or Norway or something like that until the place shutdown, then made my way back to the hotel.

It was a good night. The party put on by Sun was OK, but it was 2 drinks and you had to wait in line forever since it was pretty much all of the JavaOne attendees instead of, say, just the Jboss or Eclipse users. It was cool to meet the guys from MythBusters though.

It was a good time overall, got my loot bag filled up, learned some new stuff, got some pointers, talked to some smart folks, and just plain absorbed all that is Java for a week. I would definitely go back if my company offered again.

As a new Christian trying to read and understand the Bible for the first time, I've found this website to be invaluable to my study. I just found it a few hours ago, but in that time it has been incredible. You can search any passages, in just about any language and any translation of the Bible. You can even show different translations and different languages side by side, for example comparing the King James Version, the New Internation Version, and the New American Standard Version side by side. This not only helps compare and contrast the various Bibles to see which one you might like to buy, but also provides better understanding and insight into the passage as you read the different translations. I never even knew so many versions existed, or what the reasoning or goal of the translations are/were. It's all explained on this site.

I've entered a search form over in the margin for you to try out a simple search, as well as an updating verse of the day at the top of this page. There is even a Firefox toolbar that lets you search this site.

Useful Windows Tips And Tricks

Here are some useful little tricks and tips I've found in Windows over the years.

Keyboard shortcuts (The Win key is the one with the Windows logo)

  • Win-E launches new Windows Explorer window
  • Win-R opens the "Run" dialog box
  • Win-M minimize all windows (show desktop)
  • Win-Shift-M restore all windows back
  • Win-D seems to do same as Win-M and Win-Shift-M, more of a toggle back and forth (no shifting necessary)
  • Win-U launch Utility Manager (for accessibility options)
  • Win-F launch Find or Search window
  • Print Screen Takes snapshot of entire desktop and puts into memory. Open Paint and then Edit -> Paste (control-v) to save as a bitmap file. Or you can paste it directly into a Word file, a new email, etc.
  • Alt-Print Screen Takes snapshot of only the active window. Very useful -- you don't know how many people I see taking snapshots of the entire screen and then carefully trying to cut out only the current screen.
  • Alt-<underlined letter on desired menu option> Accessing menus by keyboard
  • Alt-space Accessing the "Window" menu (the one with the application icon, and options for minimize, restore, close, etc.)

Backup Registry

  • Before installing anything potentially "dangerous" backup your Registry file. Good idea to back this up every month or so anyways. Win-R, type "regedit" and hit enter. Select Registry -> Export Registry File. Save it off to a safe place with the current date in the filename so you can restore if necessary.

NetMeeting on Windows XP

  • NetMeeting doesn't seem to be exist in XP anymore, but it does. Win-R then "conf" runs the installer/setup and creates the Start menu options.

Writely Word Processor

Using Writely word processor (
Sweet. Would be cool to do resume here so I have an editable version anywhere that can be saved as PDF, Word, HTML, etc. and emailed or blogged or whatever.
Work on that later (when not at work, obviously).

Thursday, February 23, 2006

Some CSS Resources

Today, instead of just using CSS (cascading style sheet) elements that others in the group have already built, I had to make my own for a cruddy little user-requested feature of our flagship app.

There was one little feature I needed help with so I did a Google search, and came up with two resources that were helpful and cool.

One is a 2-page PDF file that when printed is a tri-fold quick reference card for CSS. The link to that puppy is:

The other tidbit of info is cool because it is setup to be readable on your iPod. Most iPod since the 3rd gen and iPod mini have had the ability to store text notes and contacts. You unzip this directory and drop it in your iPod’s “notes” directory. Then you can scroll through the menus and pick the elements you need more info on. You never know when you might have to whip up some CSS style sheets and you don’t have your handy reference card. You can rock out to Killswitch Engage while building the next great web portal. Link is:

As a side note about CSS, it’s a lot more powerful and useful than just fonts and colors, as I have found out. As a programmer it is nice to see presentation and information separated as much as possible, which is why I kind of like XML and XSLT (as much of a pain as it is).

Friday, February 17, 2006

OpenLaslo And Java RPC

Continuing on my evaluation of the OpenLaszlo 3.1.1 web application development environment ( ), I’ve got the Java RPC stuff working. You can build POJO Java classes and put them in the Laszlo’s WEB-INF classes or lib directory, and then call them from your LZX code.

Last night I built a simple class with a method that returns an XML snippet. Easy enough, it took maybe a half hour to get it all perfect. Today, I got a little more complex and made a class that talks to a WebSphere MQ server, getting queue depths, and putting and getting messages from queues.

I tied that into my little sample LZX app, and have buttons that get queue depths and put messages on a queue. Still simple, but I’m starting to see how this can be very powerful. I still need to get better with the front-end LZX language and events handling to make the GUI more robust, but for now I am happy to be able to talk to server-side classes that tie into existing business logic and applications.

To let your LZX code know about a class and allow it to be called, you drop it in the WEB-INF/classes or WEB-INF/lib for JAR files, and then add this snippet of code to the LZX. This explicitly allows the class to be run from LZX via RPC, all others are implicitly denied:


The pattern can be a regular expression, for example to allow everything with a certain package. You could also specify each class individually by putting in multiple <pattern> elements.

To create an instance (or really client side stubs), a chunk of code would look something like this:

<javarpc name="rpcadapter" scope="none" classname="BaseRpcAdapter">

<remotecall funcname="getMqQueueDepth">
<param value="'RAN.TEST.QUEUE'" />

<remotecall funcname="putMqMsg">
<param value="'RAN.TEST.QUEUE'" />
<param value="'blah blah'" />


And then to call the methods, you could do something like this to create a button and tie it to the method:

<button onclick="rpcadapter.getMqQueueDepth.invoke()">
Get Queue Depth

So far it’s impressive, even with the lack of direct DB support. To make this viable in the enterprise, I also have to figure out the security models, and how to lock everything down better.

Side note from yesterday’s post: Still no direct database access. The options right now as I see them are to front-end your persistence and business logic layers with either an RPC adapter like I’ve done here, or expose them via Servlets, JSP, or web services (Session EJB & Apache AXIS is what we generally use).

Thursday, February 16, 2006

OpenLaszlow And Persistence

I’ve been evaluating the OpenLaszlow rich web application framework, and it seems really cool at first glance. It is very easy to build a very rich and interactive GUI using their LZX language (XML based). Your LZX code gets compiled into SWF shockwave code that runs in the browser window, and the whole thing is served out of a Tomcat servlet container.

But is it ready for enterprise applications? I wanted to say yes, but I’m not so sure yet. Yes, it has the ability to talk SOAP and XML via HTTP. It also has the ability to run POJO Java classes using RPC (I haven’t tested this yet, but the docs say it’s so, and the demos seemed to work OK).

But what about databases? Persistence? The data-binding demos look impressive, how you point it at a datasource and it can list out the data, or put the data in an Excel-like grid, etc. If your data is XML. Let me repeat, If your data is XML. I have been looking and searching for the database API’s, and the reason I haven’t found them is they are not there. They assume your datasource is XML, either from a static XML file or from a JSP or web service that serves XML-based content. Then it used XPath to do searches and binding. Nice for XML, but what about databases?

Almost all of my development involves talking to a database. Basic CRUD functionality is assumed in most enterprise applications. It’s not here. No ODBC, no JDBC, no “Laszlow-QL”, etc.

So the front end is now easy and pretty, but your back end application ends up being a bunch of servlets or POJO classes that serve up XML. It’s possible, but the expected tie-in just isn’t there – you must now build servlets, JSP’s, or web services that front-end a database, and then with the source code of the LZX being visible to the end user, you have potential security concerns as they can see how to manually call your services.

Maybe I’m just missing something, and need to read more of the docs and dig deeper into the language.

I guess my next step is to build a serious prototype of an application to see how my concerns can be addressed in the “real world”.  I’ll post my progress and any tips or pitfalls I encounter.

Monday, February 13, 2006

Software Development Tools

Here's a quick list of some of the tools I use for various aspects of software development and debugging. Some of these I use all the time (daily), and others fill a niche need that arises once in a while.
  • Notepad++ - Free Source code editor, with a lot of nice features, but a lot smaller and faster than a full-blown IDE. Link

  • NetBean - Open Source Java IDE (and development framework)Link

  • Eclipse  - Open Source IDE (and development framework) Link

  • MyEclipse Enterprise Workbench - Set of commercial plugins to add a lot of J2EE functionality to Eclipse Link

  • Vim (gvim) - Nice GUI version of of an "improved" vi editor clone Link

  • Ethereal - Network Protocol analyzer Link

  • MQJExplorer - Websphere MQ management tool. Simple but powerful Link

  • TortoiseCVS - Open Source CVS client that features integration with Windows Explorer. Link

  • MC4J - GUI tool for remote JMX administration Link

  • JProbe Profiler - Java Profiler tool from Quest Link

  • DJ Java Decompiler - Java Decompiler. Used to be free, now it seems to be shareware. Link

  • Jboss - Open Source J2EE Application Server and more Link

  • TOAD - Tool For Oracle Application Developers. Also versions for SQL Server, MySQL. There's a free version and commercial version. A lot nicer than the SQL Plus command line. Link

  • PuTTY - A Free SSH and Telnet client for Windows Link

  • Cygwin - Unix-like environment for Windows, complete with all the command line favorites and XFree86 support. Link

  • SysInternals Utilities - This site has a lot of useful utilities for Windows, like TCPView, Process Explorer, etc Link

  • ArgoUML - Free open source UML editor that can be downloaded or run via Java Web Start Link

  • Cooktop XML - Free XML editor for Windows Link

  • Butterfly XML - Another free XML editor, very simple and stripped down. Link

  • MarrowSoft Xselerator - A very nice commercial tool for working with XML and especialy XSL stylesheets and transformations, and FOP.Link

TAO of Regular Expressions

Another quick software development link for y’all. I found this link to the “TAO of Regular Expressions”, and have found it to be extremely handy, and definitely worth sharing.  It’s a good reference, concise and informative, without a bunch of crap.

Quick vi Editor Reference

Looking for a quick no-nonsense reference for the vi editor? Look no further than It’s concise and to the point, without a bunch of crappy pop-ups or annoying graphics.

Friday, February 03, 2006

Re-Synching Oracle Sequence With PL/SQL

Sometimes an Oracle Sequence can get out of sync. For instance, if a sequence gets dropped or wraps around to zero while there is data in the table, or if data is loaded while the sequence is disabled. Here is a quick PL/SQL block to reset the sequence to 1 more than the max id in the data.

Replace column_name, table_name, sequence_name below and then run it.

max_id number;
tmp number;
max_id := 0;
select max(column_name) into max_id from table_name;
if max_id > 0 then
for i in 1..max_id loop
select sequence_name.nextval into tmp from dual;
exit when tmp > max_id;
end loop;
end if;

Basic Linux Troubleshooting Commands

The following commands are useful when trying to troubleshoot issues on our J2EE servers. This is for Red Hat Linux, but some of these commands are generally applicable to other versions of Linux and Unix as well. This is by no means a full tutorial on Linux administration, just some quick stuff for a guy doing basic troubleshooting.

top - memory and CPU utilization of various processes.
lsof - List open file descriptors
file – shows what type a file is
ps – shows processes and their id’s, children and parent id’s
netstat – shows ports and connections status, e.g. netstat –a to show all connections.
ipcs – show shared memory info
nice, renice – change the run priority for a process
sudo – run a process as the root or other privileged user
who –r – shows current run-level of machine
kill - everyone knows the basics of kill, interupts a process with a signal you specify. kill -l to list the signals, kill –3 for instance is stack trace, kill –9 really kills the process dead.

ran488>kill -l
1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
5) SIGTRAP      6) SIGABRT      7) SIGEMT       8) SIGFPE
9) SIGKILL     10) SIGBUS      11) SIGSEGV     12) SIGSYS
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGURG
17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU
29) SIGLOST     30) SIGUSR1     31) SIGUSR2

Wednesday, February 01, 2006

iTunes Library.xml, Meet XSLT

If you've looked at the iTunes Library.xml file, you were probably shocked at how cryptic XML can be. You have a list of songs and playlists, with attributes such as song name, album, band, etc. Seems simple, but that XML is UGLY.I found this XSL sniipet on the web somewhere and started to play with it. I'm not an XSL guru by any means, but I've hacked together a couple XSL transformations to make some sense of the Library. In this case, it is a two step process (I'm sure it could be boiled down to 1, but I'm not XSL guru, remember?). This creates a simple HTML table with song, album, band, genre, etc.

Step 1: Flatten out the relations a little to make it look more like you expected in the first place:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="plist/dict/dict/dict"/>

<xsl:template match="dict">
<xsl:apply-templates select="key"/>

<xsl:template match="key">
<xsl:element name="{translate(text(), ' ', '_')}">
<xsl:value-of select="following-sibling::node()[1]"/>

STEP 2: Render the output the way you want it, simple example shown below:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="">
<xsl:template match="/">
<body bgcolor="navy">
<table border="1" align="center" bgcolor="silver" width="90%">
<th bgcolor="#8b9ffe">Artist</th>
<th bgcolor="#8b9ffe">Album</th>
<th bgcolor="#8b9ffe">Year</th>
<th bgcolor="#8b9ffe">Track</th>
<th bgcolor="#8b9ffe">Song</th>
<th bgcolor="#8b9ffe">Genre</th>
<xsl:for-each select="/tracks/track">
<xsl:sort data-type="text" order="ascending" select="Artist"/>
<xsl:sort data-type="text" order="ascending" select="Year"/>
<xsl:sort data-type="text" order="ascending" select="Album"/>
<xsl:sort data-type="number" order="ascending" select="Disc_Number"/>
<xsl:sort data-type="number" order="ascending" select="Track_Number"/>
<td><xsl:value-of select="Artist"/></td>
<td> <xsl:value-of select="Album"/></td>
<td> <xsl:value-of select="Year"/></td>
<xsl:value-of select="Disc_Number"/>
<xsl:text> </xsl:text>
<xsl:value-of select="Track_Number"/>
<td> <xsl:value-of select="Name"/> </td>
<td> <xsl:value-of select="Genre"/> </td>

Wednesday, January 18, 2006

Log Aggregation And Searching

Ever have one of your customers call you about a transaction that failed in some way, or a message that never reached it's destination, or some other problem? Of course you have. And that usually means tracking down the issue through log files, and lots of them. You have a cluster of application servers, sitting behind load balancers, talking to queue managers and legacy systems. Each of which has their own log files to pour over. Did this particular transaction hit node 1 of the cluster, or node 2, 3, 4, ..., X? Did it get to the cluster or fail on the load balancer?

The old way would be to login to each server and grep through logfiles. The new way is Splunk ( It's a log aggregation and indexing tool with a clever front end to search. Imagine having a Google-like search engine for ALL of your logs, all in one place.

I am playing with the free server version (1.1) right now, and it is slick. There is also a pay version that includes more features and support. The front end does a lot with AJAX principles, so you get full features like a popup-menu as you type with possible search terms and the number of occurrences of each, boolean searches for more complex queries, and search results where every term is clickable. For example, hover on a word or phrase in your search results, and every occurrence in the result set highlights. Clicking searches on that term, control-clicking AND's that term to the current search criteria, and control-alt-clicking NOT's that word from the criteria.

The backend is highly configurable. For example, you can set up directory monitors to watch a directory for new files, or set up tailing processors to index a live file in real-time. There are other options as well, but I'm still new at Splunking. I can see already that this can be an invaluable tool for troubleshooting complex systems, though. I definitely would recommend checking it out soon.

Tuesday, January 10, 2006

Resetting Google Desktop Search Index

Resetting Google Desktop Index

I ran into an issue where Google Desktop told me my index was at its max size. Crappers, I'm not done doing stuff on this PC, so I'm screwed from this point on. Of course, GDS docs tell you to uninstall and reinstall -- what a pain.

A quick Google search brings up Scott Hanselman's blog entry ( ) that tells you how to reset without uninstalling. Basically, just shutdown GDS, and then whack the files under your C:\Documents and Settings\ <username> \Local Settings\application data\Google\Google Desktop Search directory. He mentions "some long number" and files that begin with "sidebar_*.*", but my version of GDS didn't have any of that.

Once you restart GDS it will start from the beginning. This is great because I was getting search hits for stuff I deleted long ago.