Friday, October 31, 2008

Ultra Edit Extras

Ultra Edit has put a lot of work into making Extras for their product available. I've been a huge UE fan for a long time now, sorry emacs people I like UE.

Finally they have word files for different languages available to download. I was a little disappointed in March when I was looking for a word file for Ruby which would allow me to continue to use my favorite editor to start working with Ruby. That is no longer an issue, they now have word files for additional languages that were not included in the original install. There are also additional dictionaries, tag files, macro tutorials, and basic scripts that can be used to teach you how to use Ultra Edit even more efficiently.

I have spent the past 2 years really getting familiar with all of the options of Ultra Edit. As David Hunt says in The Pragmatic Programmer, you need to be intimately familiar with all of the capabilities of your text editor, no matter which one it is, in order to be an efficient developer.

Thursday, October 30, 2008

Log4J tips.

An additonal log4j tip that I found today. %c is the class that is used to create the log4j class. It can be useful, if it is the actual class that is creating it. However, you probably do not need the entire class hierarchy. %c{1} will only show the classname itself without the heirarchy.

For example:
When you create your logger with
static Logger logger = Logger.getLogger(CustomerBusiness.class);

And CustomerBusiness is in package
Then %c will write out

%c{1} will write out CustomerBusiness

This may be considered small but the duplicated characters can add up to a lot.

The problem is even more pronounced if you have a separate log for a single purpose. We log all of our performance log information into a separate log file.
We do this by having a separate RollingFileAppender for performance logging and creating a 2nd Logger in the class with
private static Logger performancepaLogger=Logger.getLogger("net.comny.webservice.performancelogger");

As for the performance logger, I also think it's useful to format those in a standard way. That way slow operations can be tracked easily.

[DateTime] {ClassName}: {Function}: {Unique path} Call Time: {milliseconds}

One shortcoming of this is that in order to make the logging call itself faster you have to code each call to to pass through the values that are in {}.

The bonus of {Unique path} which in most of my applications would be an account number, is that I could see calls that look something like this.
AccountDAO: saveAccount: 223 Call Time: 20
AccountDAO: saveEmail: 223 Call Time: 25
CallDAO: saveCallInfo: 223 Call Time: 120
AccountBusiness: saveAccount: 223 Call Time: 200
WebService: saveAccount: 223 Call Time: 500

I can look at that and even with other records mixed in, I can see at the DAO level which calls are higher and causing the webservice call for a single record to be high. If the same database level access class has high call times for all of the accounts then it will show where optimization needs to take place.

Wednesday, October 29, 2008


What do you expect of yourself, of your co-workers, of your boss?

I have come up with a list that has worked well for me for the past several years.

Things I expect of myself and my co-workers:
  1. Work hard to get the job completed in a timely manner.
  2. Self improvement. Continue learning and educating myself on things I am using and those that I will need to use.
  3. Offer ideas to improve anything I can think of for either in the team or outside the team.
  4. Learn from past mistakes
  5. Communicate status, issues, and successes in a timely manner.

Things I expect of my boss:
  1. Honest feedback and open communication.
  2. Career development and guidance.
  3. Balanced assignments. I should always have work to do, but not be overloaded.
  4. Support me. Stick up for me.
  5. Offer opportunities for me to grow.
  6. Be prepared.
You cannot control the things that you expect of your boss. You can communicate those thoughts and let her know what you expect.

Friday, October 24, 2008

Mr. Fix It.

I feel like Mr. Fix It.

Instead of spending the time focused on what my goals were at the beginning of the day, I have spent much of the day hopping back and forth from one task to another in order to answer questions or solve problems. These are things that need to be answered and taken care of, but on days like this I never feel as productive. For me, oftentimes the opposite is true. Instead of getting the one or two things done that I plan to do, I end up finishing 5 or 10 smaller things and making more people happy. That's good customer service right?

I am really good at making these switches and looking into disconnected things all day long when I start my day with that kind of mindset, but when I actually plan to finish those one or two big things that I have been working for several days on, I can leave work feeling like nothing at all was accomplished. It's amazing how much different I feel about the same results based on my own mindset.

Thursday, October 23, 2008

Logging tips

I have found more and more that I rely on logging data, and capabilities to help me diagnose a problem. I'd rather have a ton of information to sift through and find the problem than just an an error message. Here are some tips to help you with what to log and when in order to find problems.

Logging needs to be configurable.
You must have the ability to change the level of logging being used easily in order to produce a lot of output when necessary, and minimal output the rest of the time. You don't want your servers or desktops to run out of space because of your logs.

Logs need to be disposable.
Logs are good for a specific problem that is occurring now. You do not need to keep logs from 3 weeks ago to find information. Even if you do need to keep some logs for a longer period of time for reference, it is easier to manage them when they are in daily files.

Logging needs to exist in Code.
Logging needs to be everywhere in code. The more important a piece of code is, the more logging that it needs to have. Log entry and exit points to functions, with some unique identifier, account or user, or account/user. With the exit include the time that the function took to complete. Log all errors.

Use Different levels of logging.
Logging needs to be able to be turned on when it's needed, but turned down to almost nothing when it's not needed. Use debug level for deep details of objects. Use Info level for certain details at key points. Use Warning for situations that may be indicative of a problem or boundary condition that could cause problems. Use Error when errors occur that you do not handle. Do not log as an error things that you handle and do not consider a true error. You only want something showing up at the level of ERROR if it's really an ERROR that you need to possibly fix your code to handle.

Logging tips.
With objects you can override the toString method and simplify your logging statements to get data. Since multiple threads may be writing to the log at the same time, you want to write some unique piece of information to the log for each entry, so you can easily track what a single path is doing. Even though I completely embrace logging, I know that too much of a good thing, can be bad. Too much logging can slow a process down dramatically while it waits for file locks to release. Take advantage of different logging levels, and possibly checking the logging level with if statements prior to using the log statement. Using more efficient methods of logging, such as a message queue can insulate your code from some of the locking issues.

Tuesday, October 21, 2008

Log4J tips.

I've been in the Java world for just over a year now. I've been mostly busy trying to learn all of the different technologies that are needed to get my job done. Some of them have well documented places online to go and find information, others are harder to understand and require much more digging. To make it easier on some other people, I'm trying to pass on some of the things that I've had to learn to get started.

We use Log4J (log4j-1.2.8.jar) as the tool for our logging. I don't know why we don't use built in java logging, I can't say if it's better or not, but all of the projects already were using Log4J. I was going to have to learn it in order to maintain existing applications, I may as well use it as well.

Log4J is the logging tool written by the Apache group. The Log4J manual is pretty good, unfortunately I didn't find it until after I had stumbled my way through some problems.

In our projects everything was using a static logger. With my C background I had to get used to the fact that this actually meant only one logger per Class, rather than one per instance.
static Logger logger = Logger.getLogger(CustomerBusiness.class);

Next, the file is used to control everything. It can be done via code, but it's better to keep it separate.

Logging is inherited and all of the classes inherit from rootLogger.
log4j.rootLogger=DEBUG, CONSOLE

The above setting sets the default level of logging to be for all messages of DEBUG and higher,
with output going to the CONSOLE object. The console configuration will be shown below.

There were some times that I had one of my classes spitting out more logging than I needed at the time. In order to limit one class's logging the level for that class can be changed with an additional line in the configuration.,CONSOLE

This will increase the level of logging for my customerData object to be Info and higher, which will ignore all of the logger.debug statements. Also if there is a class under the path customerData, maybe there is a helper clas that is, that too would get the Info level of logging.

In order to configure the console appender in your file.
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-5p %c - %m%n

This is a console appender because it user org.apache.log4j.ConsoleAppender. The name CONSOLE, both here and in the above configuration is arbitrary, it could just as easily be name FRED. This CONSOLE object also configured the output and what it will look like. You can read more about the Pattern Layout if you want. I pretty much just keep the same one.

Another good appender is the Rolling File. This has the ability to limit the size of a file, and will create a new file daily. Having a new file daily is a huge benefit, because old data can more easily be searched, zipped, archived, or deleted. If you are going to write data to a file I definitely suggest using the rolling file. Here is the rolling file configuration.

log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d{ISO8601} %-5p %c - %m%n

One note of warning. Errors will be thrown from logging if there is an error. Logging an object that is null with throw a null pointer exception, even if the logging level is set to higher.

For example.
Interger age = null;
logger.debug(age); // this will throw a null pointer exception.

Friday, October 17, 2008

Yahoo UI 3.x

I watched the video on Yahoo UI 3.x It's amazing how much improvement they are able to keep making with these libraries. They somehow find a way to offer more functionality and make the code smaller and faster.

I love that these great tools are being provided, but I wish more that some of the javascript lessons learned were being passed on, that way if I have any of my own code to implement I can follow the same good design and implementation that they have done.

Wednesday, October 08, 2008

JMS Training: Day 3

The final day of training was very anti-climactic. Originally scheduled until 5PM, class was over at 10:30 AM. I asked a few questions of the teacher after the class was over and he uses Websphere MQ, but not Websphere Application Server.

The topics covered were MQ specific security and functions. Eventually we may use MQ where I'm working, but at the moment we are planning to use JMS and the Message Queue provided by WAS.

I headed back to the hotel with the hopes of changing my flight home from Thursday to Wednesday, but the additional costs of changing the ticket was too great.

I spent the entire afternoon taking a practice exam for the SCJP 5 test that I have been studying for months for.

Tuesday, October 07, 2008

Book Review: Foundations of Programming

Foundations of Programming is a free eBook that discusses many best practices. These are some of the same things that are talked about while building software developers into Craftsmen. The book is for C#, and covers great topics including Unit Testing, Dependency Injection, Object Relational Mappers, and How and When to use Exceptions.

I definitely recommend taking the time to read the 79 page eBook. There's only 72 pages of content (not counting the table of contents and the acknowledgments). And any developer new or experienced will probably learn something new from reading through this book.

I also recommend following the blog posts that are on This book is written by Karl Seguin who is one of the bloggers there. There's always good tips being posted on that site.

JMS Training: Day 2

Day 2 of training started bright and early at 8 AM. Everyone was in the class by 10 till, so we got started. Our instructor is a member of some magic group based in Hollywood, and he starts the morning off with a magic trick.

At 10:30 we are most of the way through what is on the Agenda for us. We have one lecture and one exercise left for the day.

I have created a sender and receiver and run two separate programs to send and receive messages. These messages are very much like RPC calls with COM+ and C#, you know where it's going to, but you don't know what's on the other side answering the message and responding. Unlike COM+ you have to have a separate listener to hear the responses. For what we are considering, we will be using a fire and forget methodology. A web service call with send a message and immediately return success trusting that the message processor will pick up the message and successfully save it to the database. Because there is no way to wait for a response Any business validation that will catch known errors should occur before sending the message to the queue, this is the only way to be able to inform the user that there is an error immediately.

WebPage ---> Ajax Call to Servlet ---> WebService Call --> Business Layer validate()

if successful --> Send Message


--> return success --> Webservice return success --> Ajax refresh the screen.

Then the listener will pick up the message

If the DB is available, write to the DB. Here's where the dangerous part is. Any failure to write to the DB will not be sent back to the user for a retry. It must retry itself or fail completely. We could write this information to an alternate queue, and write our own front end to listen to this error queue and allow modification to the data that is passed in for another attempt. This becomes ugly because we only want the data that was saved by the original user to be saved as it is with no modification. Thus a failure to save must only occur from the database being unavailable, and not from bad data, that is why the validation must be complete and pass before sending to the queue.

We ended today's agenda and started on started on tomorrow's. With only 3 sections left, the instructor expects us to be finished by lunch. I look forward to being out of the classroom. The content is good and the instructor is somewhat entertaining, but the chairs are terrible and my back is killing me. With as much as training classes cost I would expect training facilities to have better chairs than most other places.

Monday, October 06, 2008

JMS Training: Day 1

I was the first to arrive this morning, despite not being able to find the building. The facilities are in a strip mall, and off the street, but there is no sign facing the street.

I noticed right away that there were 6 packets for students. When the instructor Robin, an Australian gentleman showed up he handed out the sign in sheet, which only had 4 names on it.

Bored and sitting in front of a log in screen I started guessing passwords, 3rd try I was in. I'm sitting at a Windows XP computer with a 3 GHz processor and 1 GB RAM, it's a VMWare session. I see that Websphere MQ Explorer and Rational Application Developer are both installed.

A quick perusal of the Agenda shows that today will be an introduction and mostly talk. We have one exercise to perform and it's configuring the Message Queue. The next two days will be much more in the way of JMS exercises.

All three of the other students in here are Websphere MQ Administrators and not programmers, they are just looking for an overview of it in order to be able to understand what the developers are trying to do against their system.

Apparently there is a bug in the GUI version of the software that comes with Websphere MQ 6.0, so we did all of our configuration from a command line tool. There is no documentation on this tool included, so the instructor just told me what to type. I have it running in class, but could not reproduce the steps if I needed to. That's a bit of a drawback. At least MQ 7.0 sounds like there are a lot of new features and bug fixes. The biggest new feature is the native support of JMS which makes it 5+ times faster than MQ 6.0 with JMS clients.

One of the other students said he wanted to be able to leave between 2 and 3 on Wednesday to catch his flight. My flight is not until Thursday because the schedule stated that class would go until 5 on Wednesday. We finished the agenda for today at about 2PM. The instructor added 2 sections that he does when he's at other conferences talking about Websphere MQ. It was good detailed information. We finished the day by covering tomorrow's first section.

We also decided to start at 8 AM the next two days instead of 9 AM. If we go until 5 tomorrow I think we'll be done really early on Wednesday.

How to encourage your company to build Software Craftsmen

I was watching this video about creating Craftsman developers, and it only briefly touches on how to get management buy in.

It basically says that you have to convince them by showing them case studies and showing them the successes you are having. However, it doesn't go into detail on what those are.

I think that one good way is to try and show some skills that are lacking. Start with a survey to find out what skills the developers have. The goal needs to be getting more people with more of those skills. If there is any skill that only one or two people have, this is a potential huge problem. Having additional cross training and teaching meetings to teach more people these skills is a huge benefit for a company.

Another good way to do it is to try and show some testing metrics. Some companies may have automated UI test tools and have a way to show how many are passing, however many do not. Many also do not have or use unit tests. The lack of code based testing also means that there is a potential hole in applications. If this is the case then the craftsman skill of unit testing and mocks is probably not prevalent and needs to be passed on, as well as measured in it's practice. Measure the number of unit tests and code coverage.

You can buy a good plant and put it in your garden, but if you don't continue to put time and resources into that garden, then it will become overrun with weeds and your strong expensive plants will die. Programmers are like that, only they will become stagnant, or move on to another place where they have the opportunity to continue to grow.

Sunday, October 05, 2008

Google Search Results could be better.

Google has spoiled me with GMail and Google Reader. I'm used to using short-cut keys on the Google sites.

I miss these shortcuts on the search results. I want to easily move to the next page or previous page of the results. I want to be able to quickly go to one of the results, all without using my mouse. Give me more of the keyboard shortcuts I love, please.