Thursday, December 04, 2008

SCJP Certified

After months of studying, I have finally taken the SCJP certification and passed. My learning in the immediate future will be more for fun than for a certification.

Thursday, November 13, 2008

PRG pattern alternative

I'm working on a websphere portal application and in it I have a lot of operations. Sometimes I post, and sometimes I use servlets. But I don't do any gets.

A while ago I introduced a problem to the application. Instead of just performing a normal search, I added a queue, and a get next feature. In order to keep code to a minimum I used the same portlet and just changed the action to let my portlet know which action it was supposed to handle. The end result is that both methods give me an account to show on the screen, the only difference was in how they retrieved that account.

Things have been working great, until the page only have reloaded and a user hit F5. Then instead of just forcing the page to reload with the information that it should have already loaded, it is doing another Get Next and the user is losing the current account.

Some research on this problem led me to the PRG (Post/Redirect/Get) pattern. Redirect after Post is a great article on this solution. However, it's not what I wanted to implement. I didn't want to modify my process that much. I like how my portlets are working without trying to get the redirect working (which I have read may be a problem).

Instead I needed a way to know if the page was performing a new action, or if it was resubmitting the old one.

I opted for telling my page what ID it should tell me when performing an action. Initially this value is set to 0. The first action runs and tells the page that it should next call with a 1. If the page does not call with a 1 then instead of performing a real action the page will instead refresh the information on the screen without performing an action. When F5 is pressed it resubmits all of the information that was submitted in the previous post.

There are 2 keys to this.
1. I have a hidden field in my form that holds the ID to send with the rest of the information for the post.

2. I use the session to keep that same ID active in the session.

Trying to think about all aspects of this, I also tried to think of problems with this solution.
1. If the session times out the user will need to log back in, but the portal already enforces that behavior.
2. If someone were to manually massage that value would there be a problem? Since I actually do nothing if the value is not what I'm expecting, then changing the data with a tool like firebug will only prevent the page from doing things, instead of allow it to do things. Since there is no way to massage the data that is submitted by pressing F5, there is nothing that should be a problem.

Tuesday, November 04, 2008

Performance Reviews should be banished.

There's an interesting article at InfoQ stating that Performance Reviews should be banished. I just finished my own self-review last week, which is even more painful than a standard review. Rather than just having my boss tell me how he thinks I'm doing, which is a monthly conversation anyway, I get to hear the summation of the year in review. It shouldn't take as long as it does. I also get to rate myself in all of the categories and defend why I think I rated myself awesome.

I mean really, what person will rate themselves and not say I did awesome. Even if I know there are bad things the result will still be "awesome, considering the situations". I will always work hard, and put in hours at home learning new things and trying out new ideas. I will always put in time trying to better myself, I will always do my best to get all of my work done as well as stop to help everyone that I can as often as I can. That's awesome.

Maybe my biased opinion needs some perspective. Maybe this review offers the opportunity to hear an opinion that may not be just "awesome", but if it is, that would be awesome.

Monday, November 03, 2008

Turning Agile to 11

There's some very interesting topics covered in this 31 minute presentation on Turning Agile up to 11. It was a presentation that got me thinking about some of the things that we are not doing on our projects currently, and how some of these additional techniques could be helpful.

I am guessing that most Agile groups are not even working at 10, I know mine is not. However, you should always strive for these kinds of improvements in your process.

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 net.company.webservice.business
Then %c will write out
net.company.webservice.business.CustomerBusiness

%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 log.info 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

Expectations

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 log4j.properties 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.
log4j.logger.net.sr.project.customerData=INFO,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 net.sr.project.customerData.datahelper, that too would get the Info level of logging.

In order to configure the console appender in your log4j.properties file.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
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=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ContextPrinting=enabled
log4j.appender.ROLLING_FILE.File=/opt/logs/myProjectt_log4j.log
log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d{ISO8601} %-5p %c - %m%n
log4j.appender.ROLLING_FILE.DatePattern='.'yyyy-MM-dd

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 CodeBetter.com. 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


always


--> 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.

Wednesday, September 24, 2008

Investigating Remember the Milk

I'm not a big fan of constantly changing how I keep track of my to-do list. I definitely prefer to keep track of it in a software application instead of paper.

I'm not tied to the web over a desktop application, however, I do keep different lists of what I'm working on at home and work, that makes the web a more acceptable solution for me anymore.

In the past I have done paper, which I was constantly rewriting. I love the look and feel of it, as well as the constant reminder of what I have to do while rewriting the list, however, with a decent size list rewriting it just took too much time. And I like order to my list enough that I could not just keep the list in a more disorganized state with items crossed off. It always felt too cluttered for me.

I've used Swift-To-Do List Lite. I like the interface, ease of changing views, scheduling items, creating repeat items and checking things off as done. I like that it's free. I don't mind that it's a desktop application, I've even blogged about how I liked using it in the past, and I still have it on my computer. However, I long ago hit the limit of 25 tasks. I like it a lot, but not enough to buy it and go over that 25 item limit. As of right now I still use this as my offline solution to quickly track something that I need to do. If I'm not at an Internet connection but have my computer, I will add it here and transfer it to my online list later.

I've been using Toodledo for about a year. There are a lot of things I like here as well. I like that I can make my list public. There is a great Google Gadget for Toodledo, that allows my home page in the browser to show me my tasks as well as the news. I'll save for later the argument about whether or not that's a good idea. One of my favorite features of Toodledo is that it is printable into a booklet. That allows quite a few tasks to be printed and easily carried in my pocket. There are times that I'm away from a computer but have time to do something that's on the list. When I knew these situations would occur I would print out the list. It is rare that I needed to have my list handy when I away from my computer. I still loved the feature. It also integrates with Google Calendar (of which I am a huge fan) and I can export the data into different formats to use wherever I want. I haven't gone through and used all of the additional integrations that exist, but the list is large and it's a very useful to-do list.

For some reason Toodledo has been getting annoying. I'm not sure why, maybe because I haven't been able to make public the list, or make public just a portion of the list. I want more visibility from what's on my list available to my co-workers, but only my work list, and I want my wife to be able to see my home list. And I have a list of things to learn, that I may want to share with specific friends. I don't want to have to have multiple accounts set up to create a list for each thing and then share them. I want to keep track of them all in one place, but share different lists.

Now I'm investigating Remember the Milk. When I started looking at Toodledo previously I had also looked at Remember the Milk. I still have some of the same complaints. The site looks like it was made for kids; maybe it's just the picture of the cow. I like the tabs on the site. The additional information that can be tied to each task as well as a note for tasks. I like that there are a lot of keyboard shortcuts. I don't like that there was no input feature, so I had to copy and paste my to-do items into here. I don't like that there is no export feature, so I cannot easily take my list and switch to a different system. There are less additional features than Toodledo has, but there does appear to be the ability to share publicly individual lists. I am still investigating and will post more if I find that it does support the features that I'm looking for.

Wednesday, September 10, 2008

We suck less is not enough.

There's a great presentation about Agile and it's implementation not being intense enough. This got me thinking about some things.

Why are companies implementing Agile?
What I can gather from reading is that companies implement agile in order to make the developers faster. However, the implementation of agile doesn't make developer's faster, only more focused. Since Unit Tests are used with Agile development it makes sure that changes are written in a way that doesn't break other parts of the application.

However, according to the presentation when used correctly Agile is meant to improve the efficiency of the entire system more than 5 times. That means a lot. To me that says that we aren't getting enough out of Agile. We aren't using it to it's fullest potential. And if we're not, why not? Do we not have the right type of personalities in place to make this happen? Do we not have enough people, maybe we are too small? Do we include too many people in some meetings in order to just get people in the room?

I don't know the answers. I think that at my company our agile process has some places that are heavy. I think we do put too many people in some early design meetings. I wonder if training on agile itself could help improve us. Could I be a better part of the overall process if I understood something differently?


The most important thing I got from the presentation though, is that too many people are looking at agile as a way to suck less. Sucking less is not enough. We must strive to excel. To reach far above and beyond what we had prior to Agile. It's not okay to be good, good is the enemy of great because we can get stuck there.

Monday, September 08, 2008

The beauty of Unit Tests

I love unit tests. I've become a TDD guy and prefer to do my development that way. I've learned to do that on the back end of projects where it's been easier.

What I haven't gotten into yet is Front End Unit Testing. It's something that I've started with. I've started working with Watir and would like to use JSUnit to unit test more JavaScript, however at this point I'm just working with JUnit on the back end.

The beauty of these unit tests though is that they make it easy to ensure that the entire system still works as expected. At work we are upgrading the OS on our database server and we needed to verify that it would not cause any problems. After the test server was set up it took only 10 minutes to test all of the database functionality. There are many other applications that also use this server, most of which were written before we started using unit tests, and those applications will take a lot more time to test. If we had unit tests in place for all of those applications, they could be fully tested in half of a day.

Patches, OS system upgrades, and even new versions of software can all have unexpected effects on software. Automated desktop testing (even of web applications) can be used to test upgrades of desktop software.

Tuesday, September 02, 2008

Annoying power saving mode on computer

I have a simple cheap Dell desktop. I bought it from Walmart. A $500 PC more than serves the needs that I have for my home computing, even with the application development that I do.

One extremely annoying behavior that it has is the LED on the front. When the computer is on, it is a cool, calming blue light. However, to save power, I have the computer go into hibernate mode after 30 minutes. If I'm not using it for that long then I want to save as much power as I can. However, in sleep mode the blue LED become an annoying blink.

The blinking is especially annoying at night while I'm trying to sleep and laying in bed in the dark. Half my room is lit by this blue blinking. Why is it that there's not a more subtle LED in there that uses even less power to be lit, but more dimly when it's sleeping. Why does a sleeping computer have to be more annoying than an awake computer?

In case anyone is wondering, I leave my computer on instead of turning it off at night time, because I will have thoughts or dreams that come to me and I want to capture them quickly. A little jiggle of the mouse and I'm on my way typing. Also I will try to get on the computer before I head out the door for work in the morning. When I can, I only have a few minutes and can't spend them waiting for the computer to boot up. I am very mindful of the energy I use in my house, but I also love the availability of the computer always being on.

Wednesday, August 27, 2008

User defined tables as a parameter

Finally SQL Server 2008 offers user defined tables as a parameter. I've been using Microsoft SQL server since version 6.5 and this has probably been the biggest annoyance. There are so many times that I want to send a batch of records to be acted on, and I can't, I've come up with many different solutions, but none of them have ever let me do what I really wanted.

Now with SQL Server 2008 I will finally be able to. If I can just get us to upgrade to it at work.

There's more information at InfoQ

Tuesday, July 29, 2008

Where have I been?

It's been a busy time lately. At work I've been consumed with updating RAD 7. It seems that JSF applications did not work correctly after the upgrade from RAD6 to RAD7. All I have to do is install these few fix packs. Unfortunately, they didn't install correctly and I had to re-install RAD. That has taken 4 days of installing, without being able to work on the code that's most important to this project.

I've also been busy making changes to the Custom IE toolbar. This is a fun task that lets me use C#.Net to make things happen. I have to integrate with some COM components and with the web page that is being viewed. The code is fun and challenging. Since it's not solving the same problem as normal there has been a lot more outside the box type of thinking that I have had to do. I started with the code from "Extending Explorer with Band Objects using .NET and Windows Forms" at Code Project.

My home life has been busy and keeping me from playing online as much as I'd like. I've made July a month of exercise that I have really enjoyed. I'll be switching it up in August to focus more on tech endeavors. It's time for me to start taking my practice tests and earn my Java Certification.

Tuesday, July 15, 2008

Ode to RAD 6

RAD 6, RAD 6. I never liked you.
RAD 6 RAD 6 You were slow and clunky,
RAD 6 RAD 6 Your short cut keys were as hideous as emacs.
RAD 6 RAD 6 Where have you gone, I miss you so.


I installed RAD 7 last week. In general I like it. It's got a few new features that I know of that are nice, but it has some HUGE annoyances.

1. The folder layout changed in the package view. It used to list one package at the deepest level that was common and then expand a tree view for the subpackages. For example. com.mytest.business would be the folder, then under it would be "utilities", "test"

Now, I see com.mytest.business and com.mytest.business.utilities and com.mytest.business.test

RAD 6 had a test server environment that ran locally, it was fast. I loved it. A restart took 4 minutes, and changes to JSPs, Javascript, and CSS were done instantly with just a refresh to the browser. RAD 7 no longer has this test environment, instead I have to use a full server running locally. This manages to somehow take up less hard drive space than RAD 6, but changes are much slower. The server must republish everytime I make a change to those files, which takes 3 and 1/2 to 4 minutes (I've timed it). I accidentally restarted the server today instead of publishing and it took nearly 13 minutes. Developing in RAD 7 for the Portal, or any web page changes has become very tedious. I hope IBM has remedies most of this with RAD 7.1.

Tuesday, July 08, 2008

A bad design with a webservice call.

We noticed at work the other day that a web service seemed to have a strangely high number of hits to it. I started looking into it the logs and found that the same user would hit the web service over and over. I could easily see that it was more than 40 times within the same second. This was curious. The developer who worked on this is not here any longer and nobody was sure why it would need so many hits.

I was off, searching through code trying to find the place where the web service was being pounded and the reason for it.

I found it.


public static string GetInfo()
{
   ArrayList u = new ArrayList();
   for(int x=1; x<100; x++)
   {
      u = WebServiceCall();
      if(u ==null)
      {
         z=1;
      }
   }
   return u;
}


If you are like me you looked at this code and went "Huh?"

Sadly though, there is no notation anywhere that states what the original problem was. I doubt that this crazy loop was only put here for the heck of it, something strange was probably happening and this was only part of the debugging method used to find the issue, but it was never removed and it was not documented. I am left with an application that hits the same web service 100 times and ignores the results of the first 99 attempts. This causes tens of thousands of unnecessary hits to the web service daily.

I have two suggestions for you. First, if you ever put something crazy like this into your code, add a comment explaining the craziness. Second, if you are really ignoring the first 99 results, then most likely this is some kind of business decision, you are trying to wait a certain amount of time for something. Put that business logic into the back end where it belongs.

Monday, June 30, 2008

My favorite benefit of Unit Testing

Test Driven Development has lots of benefits: Better quality code, good code coverage, good design, and refactoring.

Refactoring is my favorite. I try to write my tests before I write my code, but sometimes, I get a little ahead of myself and jump right into code. I know what it needs to do after all, and my mind just attacks the problem and puts all the code and if statements in place to handle it. And then I realize, that I need to test my code, so I write my unit tests. As soon as the unit test starts to be cumbersome to write, I know I have a problem. I've written my code to be too complex. The Unit test should be a simple thing to set up. Now I get to refactor the code.

Test Driven development makes you think. It makes you think about what a function or object should do, and what it should not do. And I take a lot of pride in refactoring. Not just other programmers' code, but mine too. Refactoring should always improve the code. Make it more self documenting, more loosely coupled, more testable. I love taking my own code, code that would have worked, and making it better. Test Driven Development is the tool that helps me reach my goal of good code that's easy to understand.

Tuesday, June 24, 2008

Thoughts on laptops in school

I've got a lot of thoughts around laptops in school. I've not read of any school that's actually succeeded in making laptops in school work, however, I also think that laptops are a great way to introduce students to computers, the internet and many things that they need in the corporate world. Not every job will need computers like that, but the computers could help them get into a more advanced position.

The New York Times and The Pittsburgh Post Gazette both have stories posted about schools that are canceling their laptop programs. Apparently the students already know so much more about computers than the teachers that they spend the entire time chatting and doing things that they should not be doing.

However, I think that there are a lot more possibilities with computers. Topics that are not normally covered can be covered. Less books need to be printed. Students can and should participate in writing about school programs that are then made visible on the school website. All of the sports can be fully covered, but so can other activities that never get anything more than a single picture in the yearbook. Students should keep blogs about the things that they have learned.

If you know of any successful laptop programs, let me know, I'm interested. I want to see this succeed.

Saturday, June 14, 2008

Don't use BeginTransactiion within a transaction.

Running Java code the other day I ran into a strange issue. My mock unit tests all worked, so I deployed a change to test, but when I ran test, it didn't work. The real thing acted differently than my mock did.

It took me nearly two hours to track the problem down, and it was strange enough that I had to resort to stepping through Java code. I prefer to find where things fail with the logging statements.

My error was with this (psuedo-code):


UpdateRecord(Record record, boolean updateRelated ) {

beginTransaction;
updateRecordInDB(record);
if( updateRelated ) {
Collection related = getRelated();
foreach(relatedRecord in related) {
UpdateRecord(relatedRecord, false); // recursive call
}
}
endTransaction;
}


When the beginTransaction was called within the recursive call, the Connection threw an error.

The solution was to remove the recursion.

UpdateRecord(Record record, boolean updateRelated ) {

beginTransaction;

insertRecordIntoDB(record);
if( updateRelated ) {
Collection related = getRelated();
foreach(relatedRecord in related) {
insertRecordIntoDB(record);
}
}
endTransaction;
}

insertRecordIntoDB(record) {
// do some important stuff.
updateRecordInDB(record);
}


That refactor allowed me to not duplicate code, and let me only call beginTransaction once, so all related records were updated within the same transaction.

Friday, June 13, 2008

Why I hate 3rd party closed source applications

I didn't always feel this way. For years I have loved 3rd party tools, some kind of black box that I just plug into and trust. I tell it what it needs and it does what it's supposed to. When there's a problem I complain to support and they update their product.

I liked this method. For many years. It's a simple method. I put my trust in someone, and they provide service. It's a proven method that works, kind of.

The problem arises when the responsiveness of the third party is slow. I find a bug that affects a major piece of functionality in my application, only in odd circumstances, but still, it happens. There is no log, and no way for me to prove that the black box is where the problem is. Unless I had source code. Something that I could step into, modify to log, or even fix the problem. It may not be a change that the provider decides to ever implement, but it could at least handle my environment the way I expect it to.

I'm not sure if the change in my philosophy is because I've grown to be more advanced as a developer, or if the market and open source has changed the expectations. I may not understand all of the source code for an application, but if I can step through it, I can usually figure out what the problem is and being able to fix something now instead of waiting weeks for a response from the vendor can be huge.

Think about the software you use in your enterprise. If you don't build it yourself, seriously consider open source, or at least contracts that let you view the source code. Having the ability to fix those problems or find the actual problem sooner, even if you can't rebuild it, can help you work with the vendor to get a fix in place sooner.

Tuesday, June 03, 2008

Four benefits of Pair programming

Over the past year I have been able to practice pair programming as well as work on my own. Between the two methods, I definitely prefer pair programming. It has several benefits that I've been able to take advantage of, and that I think other developers will get a lot out of. The hardest part about pair programming is having a good teamwork mindset.

The four benefits are:

1. Stay focused more. I tend to get sidetracked when working, not just chasing down rabbit holes looking at pieces of code that I don't need to, but sometimes with things that are not even related to the current project. When I'm pairing, the other person won't let me get sidetracked in those situations.

2. Better design. Pair programming is the same as constant code review. Even when I know the right thing to do, I don't always see that what I'm programming would benefit from approaching it a different way. Having a second person sitting there giving opinions and even just asking questions, can cause me to think about the design of the code more and implement it better.

3. Better Quality. I won't say that there are no bugs. Runtime logic bugs still get through. However, combined with Unit testing there are fewer. But the more important aspect for quality is that words are sometimes a poor way to convey a message. The two of us may look at what needs to be done and understand it differently. This difference causes more conversation and better understanding with the client. It's not a chest beating for who was right, or more right, but an effort on the part of the team to make sure that the solution is right.

4. Better/Faster Learning. A huge benefit of pair programming is that a less experienced developer can pick up a lot of really good information. A competent developer can pick up new techniques and new languages in less than half the time if he is paired with someone who is good. This was a huge benefit for me. I practically learned Java in a month pairing with a good programmer.

Wednesday, May 28, 2008

Unit testing exceptions

When unit testing exceptions, be sure to test for the exceptions that you expect.

I spent nearly an hour rewriting tests to test for what they said they tested.

Here's an example of a bad test.

Exception ex;
// configure mocks
try {
// call test
fail();
} catch(Exception e) {
ex = e;
}
assertNotNull(ex);


Any and all errors that are thrown, including "the mocks are not configured properly" is considered a successful test pass, instead use.



Exception ex;
// configure mocks
try {
// call test
fail();
} catch(Exception e) {
ex = e;
}
assertEquals("the error message I expect.", ex.getMessage() );

Tuesday, May 27, 2008

JRuby pains

I was dickering with JRuby for three days trying to get it to run, I kept getting all kinds of strange errors.

I found out that calling JRuby is actually calling a batch file that deals with compiling things to run as java, so I turned echo on in it and the batch files that it calls. I started tracing the route through looking for the problem.

My environment variables Path, jruby_home, and Java_home were all 3 correct. From a command prompt I could type "java-version" and get 1.6.0_05 and yet, it was giving me a strange error. The only thing I found online for that error was that it was using the wrong version of the runtime, but the runtime and java were fine. Or so I believed.

I went to a different machine and tried installing the Bin version of JRuby1.1.1. It worked. I knew that nothing could be wrong, even inadvertently with the bin code on the web since it worked perfectly on the first attempt on another computer.

Back to the first computer I went. I don't know what brought it on, but for some reason I decided to check that the version of java in java_home matched the version in my path. It didn't. Java_home was using 1.4.2. I updated the environment variable to point to the correct version and everything worked.

If you are having strange errors and your computer has multiple versions of Java installed, you may want to verify that you have the right versions in your environment variables.

Monday, May 26, 2008

What programming languages should you learn?

"a language that doesn't affect the way you think about programming is not worth knowing".
-- Alan Perlis

Saturday, May 24, 2008

Trying the Uniball pen.

I'm trying out a new pen. I've never been real specific about what I write with. I'm using the one with .7mm thickness. Generally I prefer thinner lines, but this one seems to have very concise lines even at this thickness.

The uniball pen is very light and has a similar feel to a pencil. This may be a turn off for others, but for me, I love and prefer writing with pencil. I like the feel of the pencil and the friction it has on the paper, generally I find a pen too smooth.

There are a few downsides to the pencil. It smudges and will continue to smudge even after weeks. It's hard to read it in some lighting conditions, especially flourescent lighting. Since I'm switching to CFLs even at home, it's becoming harder to read pencil. That's why I'm looking for a pen that I am comfortable writing with.

The Uniball pen is very light. It's lighter than just about any other pen I've used, and lighter than most of the pencils I've used, even the mechanical ones.

Friday, May 23, 2008

How to use new technology at work

Don't ask.

That appears to be the answer that's most common. Find technology that's free, so it doesn't cost the company money, bring it in house, set it up without the real powers that be knowing about it, and use it. After it's proven useful, then present it. I've been listening to the Ruby on Rails podcasts from 2006 (I'm just getting into them), and every one of them says that they got Ruby into the office by just doing it and not asking. If they couldn't have flown under the radar they wouldn't have made it.

I've heard it said that it's better to ask forgiveness than it is permission.

What all of this really says though, is that generally corporations are against helping themselves. They go out of their way to prevent new technology and solutions that could help them advance. Look around at your company, is it stuck in the status quo? Does it still do what it did 3, 4, 5 years ago? Even using the same technology to solve those problems? You may be at a company that's in it's own way. Think about that when you start looking for things to do to fill your free time, you may need to start looking at the next language. Figure out what will work best for you, but don't let your skills get stale, just because you are at a company that still does what it used to do.

And as you learn these new technologies, bring them in to work. It's easier to ask forgiveness than permission, and your company probably needs a good internal push anyway.

Thursday, May 22, 2008

Log4j tip

A few log4j tips from mistakes I've made, or things I've struggled with recently.

  1. When using logging to send emails, send to an email group, that way if members that receive the email change, the group can be updated without having to touch the program.
  2. Be sure logging changes for live from test, you probably don't want to log debugging in live. Do it manually, use Ant scripts, whatever, but be sure that logging is set for live when deploying to live.
  3. When writing files to your local box (windows) where the server is running, have the log file path be c:\ Any more complicated of a path may not exist on another developers machine when they pull code out of CVS (or Subversion)
  4. Name our log files with [ProjectName]_log4j.log This should ensure that the file is unique.
Not sure if it's a must, but when I was making changes to log4j, they did not appear until I restarted the server.

Wednesday, May 21, 2008

Method naming conventions

This is just another rehash of what you've probably read many other places.

Start the method with a verb and end it with a noun. You want to make the method name be like what it does.

Bad method names.
verify
get

Good method names
verifyPhoneNumber
getAccount

I ran across a method today that threw me. An object was declared off of my screen and set to
employee = getEmployee()

I was looking for a property of the employee object so I went digging for it, however, the object appeared to be a string. I went looking and yep, it was.

String employee; was declared off the screen above and the method returned the EmployeeName. Inside the getEmployee method it actually retrieved an employee object then returned just the name.

A few refactors later and everything was all better.

Monday, May 19, 2008

Funny Typo

I was typing an email today and typed "toolbra". Ha, Toolbra.

Are Team Agreements Useful?

Jim Brosseau has an article at InformIT titled "Testing That Team Agreement" It goes into the difficulties of setting up a team agreement.

I've read about team agreements:
Each team is required to write up a team agreement form. The purpose of this agreement is to identify, agree upon, and formalize each team member’s individual responsibilities and accountabilities. The minimum length for this agreement is two pages.


I don't like team agreements, because I've never seen one that was anything other than, be nice to each other. How long does the meeting have to be and how many ways do we have to say it before everyone is on the same page with "Be nice to each other". Everyone gets a say, I won't interrupt, I won't personally attack someone, I won't call someone's idea stupid unless it is, I'll be happy, smile, and participate, I'll dance and laugh and sing, oh, and I'll do this all for half price during these meetings because we have a Team Agreement.

Unless you are on a team that has some specific rules that need to be followed in order to further the project, where the rules are not so much team rules, but project management rules, then everything will continue to come down to Be Nice to each other.

I have no use for an agreement that tells me what common sense already tells me, it just makes me want to call the organizer of such an agreement stupid, which would be against the agreement, if they weren't actually being stupid and wasting time.

Here's my proposal. A team has expectations. This is put on the team by the business, it's not negotiable. "You are expected to work as a team, communicate with each other, help each other, stand up for each other, and get along amicably at work. You will communicate your status and let management know when things are behind and why." If you cannot do these things, then you will not be a part of this team. Your agreement is your acceptance of your paycheck. The point at which you no longer agree, you are free to stop accepting your paycheck.

The team agreement now does not ever need to be modified, there is no need for a meeting about what it is, it's be nice to each other. Now please, don't waste any time on the agreement, and get down to accomplishing the goals before you.

Friday, May 16, 2008

SCJP Day 5 Training

The last day of training. A day of goodbyes, and heading home. I've been spoiled by making such good friends from other training classes, it's strange that this one will probably turn into just a class that I attended with some people.

We continued with the Swing application. However, since it's not supposed to be on the exam, I think we spent too much time on it. We spent most of the morning finishing the front end of a chat application so we could learn networking and threading. The networking discussion was very rudimentary. We basically just typed what we needed to open the specific socket. We had decent coverage of threads with how to work with shared data and synchronizing, but I think we could have done gotten more information about wait and yield.

I would have preferred that the last day have started us with a project to load that had the GUI finished and we could have focused more on the threads and networking. These were probably the worst examples of the weak.

I learned more about Swing than I thought I probably ever would, and I find myself asking, what they were thinking with the different layout managers. I've built many VB6 and C# applications that look really good without having any of those layout managers, or their problems.

The most informative thing we learned on the last day is the state pattern. I'm glad Martin also teaches the patterns class, he was able to incorporate a few patterns into the class. Since a few of my classmates were novices I don't know that they got a lot from the design patterns, but it was useful to see them incorporated into the class.

Thursday, May 15, 2008

SCJP Training Day 4

Another day another day.

Day 4 of training was new for me. We covered additional File IO and Stream IO, we covered the Scanner class. The Scanner class was interesting, but probably not something I will use. It does seem to have a good use as a quick tool for a delimited file when you need to deal with every field, however if you have a file with a lot of fields and you only need a few of them, reading the data as a row and parsing it will probably be easier.

Next we went over some Swing. GUIs are not on the certification any more, but we're writing a quick and dirty IM Client to set ourselves up for the networking code that we'll learn tomorrow. Having come from VB and C# for my GUIs I'm surprised at the number of different layout managers that there are. None of those are available in .Net and I haven't really seen the need for them yet. So far, it just looks like creating a Swing application is more of a pain, and a lot more hassle than using .Net, other than the fact that it's more portable.

We're ahead of schedule in class, so we've covered a little bit with patterns as well. Today we talked about the Singleton Patter and the Observer pattern.

Knowig the agenda for tomorrow and what I've learned this week, I'm disappointed. If I had known better what the class was going to cover, I would have saved the money and just bought the book. If you are good at picking up your information from books, then read the SCJP book instead of paying for the SUN certification, it covers everything in at least as much detail as the class will.

There are 3 benefits of the class.
1. It's training, getting away from work for a while every now and then is good, especially when you make new connections.
2. Paying for the class comes with additional online courses that have more material in them, covers the cost of taking the exam, and has a practice exam.
3. It's given me something to blog about.

Wednesday, May 14, 2008

SCJP Training Day 3

Another day of training. By the end of the day we finally have gotten to topics that I do not do all the time already, so I am now starting to learn new things. I wish I could get the past two days back from training, but without them I would not have made the new connections that I have.

It's interesting talking history with the teacher. Being from England originally, he seems to be more of a history buff than many Americans. I missed how the conversation started, but he was talking about Issac Newton Brown who was in charge of the USS Arkansas and faced insane odds in the Civil war, but won. There was a quote. The USS Arkansas was the only Rebel ship in the battle so he said, "Any where I shot I wasn't worried about hitting a friendly ship". It's probably paraphrased, but it's a good outlook on overwhelming odds.

I have stayed ahead on the labs, even now that I'm learning new things I'm a full lab ahead of the class. It gives me time to work on more detailed things with the lab and play with things that are not specifically being mentioned.

Today we covered Interfaces, Abstract Classes, Creating and throwing our own exceptions, handling exceptions, the difference in Checked and unchecked exceptions, Collections, Maps, sets, the new Generics for collections, Serializable. And some File IO coverage.

While discussing the Generics, there was a small communication issue with the terminology, you have to type
List myList = new List();

This is generally spoken as "List Angle brackets String angle Bracket myList ..." At least in all situations that I've been in previously.

Professor Littler though said "List chevron..." and nobody else in class got it. I knew what the Chevron was and it is the right term for the <, thank you StarGate. It was interesting enough that several other students went out and looked it up. It's cool that this class is teaching more than the Java language. US History, English, what's next?

Lunch and dinner were both spent in some deep conversations with one of my classmates, not all of the conversation was code based, but it was all very interesting.

Tuesday, May 13, 2008

SCJP Training day 2

Today was more of the same. The class speed has started picking up. We are going through things faster and covering more interesting topics. Yesterday it felt like everyone was asleep compared to today. The class was involved in a lot more side discussions, which add a lot to classes.

Some of today's discussions were about the John Adams series on HBO. Rugby. Soccer. How hard it is for a common man to succeed in England because of their aristocratic history. Australia and Georgia as penal colonies. How some very famous people are not actually from the countries they are associated with such as Hitler, Churchill, Stalin, and Ben Franklin.

The labs haven't been too hard, I've been able to fly through them. I've been able to play on the internet during that time. I finished the Hands on Ruby tutorial. It's been odd the number of things that don't work in Mozilla on the computer in the lab.

I've made good use of my breaks and taken walks through the building and up and down the stairs instead of using the elevator.

In class today we covered Arrays, Classes, inheritance (interfaces are tomorrow), static, final, imports, Static imports, abstract classes.

I seem to be the only one in the room that's done anything in the way of Object Oriented programming, none of the others have used interfaces or inheritance at all. It's been fun though because I've gotten the chance to explain the benefits of it.

Clint, one of the other guys in the class was a roommate with a guy I work with. He's a newbie to Java, but he's really curious, so he and I talk a lot during breaks and lab time.

Monday, May 12, 2008

iTunes killed my internet connection

Tonight I had plans to be online, listen to podcasts, read a bunch of blog posts and web articles that I had been holding off from because of their size. Everything was going well until about 8:30 when the network connection dropped.

After 30 minutes of looking into all local settings and rebooting my laptop, I called the tech support for the hotel. Apparently I had been blocked for "Excessive Bandwidth" usage. The very strongly accented gentlemen told me I was watching a movie, I was not, I was writing a blog post.

During the 20+ minute tech support call I realized that iTunes downloads podcasts automatically. The Learning Rails podcasts have changed to video casts, which are much larger. Lo and behold, they have a new screen cast that has not been downloaded.

Before the connection came back online I changed my setting to not automatically download these, but it bothers me that I cannot download these even at some kind of throttled speed. If I'm OK with downloading a large amount of data, can't they just let me? I don't want to take down anyone else, I just want to be able to listen to the podcasts that are out there.

SCJP Training day 1

I was a little disappointed today in training. Day 1 We started with Introductions and what everyone knows. It appears that I'm the most experienced Java developer in the room. Unfortunately that means the class will go slower than I expected. I will learn some good features of Java and the agenda for Thursday and Friday look very promising, however I think I'll have to suffer through Tuesday and Wednesday to get there.

Here's a few notes from my day of class.

The teacher started the day with: "Code Monkeys is what this course is aimed at. There's no analyses, no UML, and it's not for a beginner programmer." I loved that he brought up code monkeys. Of course listening to his talk on the process and who this class is for, it sounded like the class was designed for a very large organization that had code monkeys. I'm not one of them. I fill the role of every layer that he talked about.

The teacher is SCJP certified, but not up to date. He worked for Sun for years. He's from England, but is now a US citizen. He still has the English accent. I haven't had any trouble understanding him, but he has some turns of the phrase that are very English. Instead of long underwear he called them wooly drawers (while discussing the use of &&) he talked about getting a 99 from an ice cream truck (apparently some kind of ice cream cone with a candy bar in it).

I ended up with 7 pages of notes from class today, but almost none of the notes were about the things being taught they were random thoughts and observations about the other people in the room.

The slow start to the class was at least interrupted by window cleaners dangling from ropes and pounding away on the windows. But by 10 AM they were gone.

The class is taught completely on Sun hardware. It's a Sun desktop with a Sun branded keyboard, mouse, and 17" CRT monitor. I miss my LCD monitor. I don't like the keyboard. The control key is only on the left, and I use my right hand more often than my left when pressing control, even if I'm not supposed to.

We are using NetBeans to write the Java code. And using the Common Desktop Environment (CDE). I have never seen either of these before so I had to play around with both of them for a bit to get started this morning. I like the 4 desktops in the CDE, it reminds me of what I played with on Linux machines in the past. Although finding applications seems to be impossible. To run NetBeans I expected to find an icon in some place for it, but the teacher had us type NetBeans at a command prompt to open it. Closing the command prompt also killed NetBeans, so I'm forced to leave open a terminal window that I'm not using for anything else.

The labs are ok. They have each had 3 levels, Level 1 is for the advanced developer and gives a description of what you need to do to accomplish the lab, level 3 is every character you need to type, Level 2 is in the middle. I have been successful accomplishing all the labs with level 1 so far.

I'm constantly amazed at the number of programing examples that use the number 42. Does everyone who writes a programming book or training think that they have some kind of inside joke with this? Hasn't everyone already read "The Hithchiker's Guide to the Galaxy"? If you haven't you should, at least the first book, I have never laughed out loud more when reading a book.

Not that I need a moleskin, but with the amount of notes that I took today, and the fact that the wire binding in the center of the book is annoying me, I'm considering looking into it. I have to find a Barnes & Noble or a Borders so I can check them out. The hardest part about getting it will be bringing it to work and defending having it after having given my boss such a hard time about carrying his diary (moleskin) with him constantly. At least my boss knows we were just kidding with him and giving him a hard time, I never thought he was carrying a diary.

Martin (the teacher) said that we will be writing tests for the code that we are working on. So far the tests have just been the "main" function running and writing output to the console. The correct output is in the lab book and I have to visually compare. I would expect that we get into using asserts, which are built into Java now, or we would include JUnit and start using it as our test framework, but for now, it's a very poor test system and nothing at all like XP.

Thursday, May 08, 2008

One record on two lines.

A real-life work problem cropped up the other day. One that needed a quick hack solution to fix the problem. We had a fixed length file, but all the records were broken between two lines.

The file load was going to be done with an SSIS package in SQL Server, but it doesn't nicely handle two line records. We had to combine the two rows into one.

One of the developers did this quickly in VB.Net 2005 because that's what he knows, but it got me thinking. How else could I solve this? What other language do I already know that I could use to fix this problem?

Ruby, Perl, Java, VB6, Can I do it with a macro in Ultra Edit?

Here's several solutions to the same problem. Read 2 lines, write 1, you can also think about it as, remove every other newline character.

VB.Net 2005
Imports System.IO

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim rdr As New StreamReader("C:\readfile.txt")
Dim wtr As New StreamWriter("C:\writefile.txt")
Dim IStr2 As String
Dim Istr3 As String

IStr1 = rdr.ReadLine

Do While Not IStr1 Is Nothing
IStr2 = rdr.ReadLine
Istr3 = String.Concat(IStr1, IStr2)
Istr3.Replace(Chr(10), "")
Istr3.Replace(Chr(13), "")
wtr.Write(Istr3)
IStr1 = rdr.ReadLine
Loop

rdr.Close()
wtr.Close()
End Sub
End Class


This works, other than the initial trouble of having to tell .NET that I actually wanted the program to have access to the file. That was a problem that it took me about 30 minutes to overcome.

Ruby
counter = 1
outfile = File.open('c:\writefile.txt', 'w')
open('c:\readfile.txt') do |readfile|
readfile.each do |line|
outfile.write line.chomp
# only add the newline for every other line, Don't add it on the last line in the file.
outfile.write "\n" if( counter % 2 == 0 && line != line.chomp)
counter += 1
end
end

outfile.close

I spent about 15 minutes writing the Ruby code for this, mostly because I felt like there should be a cleaner way to solve the problem. I had been using a fairly ugly check to either write the entire line or write the line chomped (without the newline). I decided to always write the line chomped and add my own newline when it was needed. It's the same number of lines with less checks and it looks cleaner.


Perl Version 5.0
open(INPUTFILE, "c:\\readfile.txt") || die "system can't open file for reading";
open(OUPUTFILE, ">c:\\outfile.txt") || die "system can't open file for writing";

my $count = 1;
while() { # reads a line into the default variable $_
if( $count % 2 ==1 ) {
chomp $_; # only chomp the odd number lines
}
print OUPUTFILE; # Writes the value from $_ to the OUTPUTFILE
$count++;
}
close(INPUTFILE);
close(OUPUTFILE);


I don't need enough hard core Perl functionality to stay up to date on the most recent version. However, I like to tweak files occasionally in Perl, just to try and keep it fresh enough in my mind that I could use it for something if I had to.


Ultra Edit.
Open the file.
Put the cursor in the first row.
Start Recording a macro. Perform the actions.
{end} {del} {down arrow}
Stop recording the macro

Play the macro repeating until end of file.

I can perform this operation with the macro faster in Ultra Edit than I could write even the simple programs that were written above. It's not always the best solution, but it helps to know your tools. Sometimes, knowing the strengths of your own tools can save you the hassle of writing something. For a one time operation this is acceptable, it's the things that need repeated that this doesn't work well for.

Java

import java.io.*;

public class converter {

public static void main(String[] args) {
try
{
PrintStream p = new PrintStream( new FileOutputStream("myfile.txt") );

FileInputStream fstream = new FileInputStream("c:\\readfile.txt");
BufferedReader d = new BufferedReader(new InputStreamReader(fstream));

String s = null;
long l = 1;
while ( (s = d.readLine()) != null ) {
if( l % 2 == 1 && l!= 1)
p.print("\n");
p.print( s.replace('\n', ' ') );
l++;
}

d.close();
p.close();
}
catch (Exception e)
{
System.err.println ("Error writing to file");
}
}
}


The Java method is a little longer, but works just as well.

This was a fun exercise. I love solving a problem and actually thinking about the problem. Different languages have different strengths that they bring to the table. In this instance Perl and Ruby are the easiest to write the code for. Java was probably the most difficult code to write because files are buried under more classes than in the other languages.

Slick Run Wins out over Launchy

I've read about Launchy several times in the past. Eveyrtime I've seen it I've thought, "why would I change, it doesn't do anything that slickrun does already". I had the "If it ain't broke, don't fix it" attitude.

However, as I have been setting up my tools on a new computer, I decided to give Launchy a try. Why? Because SlickRun only works when configured. It will run any and all of the programs that I want it to, when I configure a MagicWord for that program.

After the install the visual footprint of Launchy is a lot bigger than slick run, however, when typing a word, it gives me hints for what it thinks. I like that. It also hides completely, not even taking up space in my taskbar. I have more than enough things that take up task bar space and having one less is nice.


I've now been using it for a few days, and trying to stress both slickrun at work and launchy at home. Here's my thoughts on each.

SlickRun:
  • The floating command in the bottom corner of my window all the time is nice. It doesn't take up any space on my taskbar.
  • The date-time is visible whenever it does not have focus, which lets me remove the windows clock from the taskbar and keep a time visible always.
  • I can have multiple shortcuts for the same thing. I use edit and ue both to open Ultra Edit. Depending on which one I was thinking of at the time, they both work.
  • Commands that would work at a command prompt work in Slick run for example "javac c:\test\test.java" will compile the test.java file that folder.
  • Typing a folder name opens the folder "c:\rubycode" opens my rubycode folder.
  • A magic word can be for a program, a folder, or a website.
  • A magic word can chain other magic words together. I use one called morning, that I run first thing each morning, it opens outlook, instant messenger, a few things that I need to monitor daily at work and firefox. All that opens with me only having to type mor, because at that point the word is unique.
  • Typing 'hide' will minimize the floating command to the taskbar. I would prefer hiding it completely in those instances.
Launchy:
  • alt+enter shortcut to show application is great, I love that it's completely hidden and doesn't take up any space in the taskbar.
  • I would rather create a keyword in the application than have to create a shortcut with the keyword that I want. I don't want extra shortcuts running around anywhere on my computer, that's just more files I don't want to deal with.
  • I can potentially use batch files, but I like the chaining effect in SlickRun
  • The visual appeal of Launchy is great.
  • Web bookmarks are automatically indexed so whatever you have named them you can use to open those web pages. This is only useful to a limited number of bookmarks because I use Del.icio.us for my bookmarks.
  • A calculator plugin is included by default. sometimes I need to do a quick number check when figuring out payments or balancing something, I can type the numbers directly into Launchy and see the total. This is not an issue for me though because I have the calculator in the Google sidebar and calculator is a MagicWord in launchy so it is only a few more characters to get the same functionality.
I will leave Launchy at home for a while longer, and at home it may not be an issue, but on my work computer, where I need more exact control of things and I'm more of a power user of the tool, I will keep Slick Run, it serves my needs better, faster, and easier.

Monday, May 05, 2008

A stack - a visual representation

As I rolled up the unrolled toilet paper roll in the bathroom, thanks to my 2 year old, I thought, this is a lot like a stack; the first piece of toilet paper on in the center is the last piece off.

Monday, April 28, 2008

Ruby, don't take your love to town.

I'm on the road to learning the ruby language. I've been reading several different resources on the basics, and I'm starting to get a grasp on how the syntax is working. There are a lot of things that make this a bit difficult for me to learn, but I like the way it looks. Once I have a good grasp on it, I think I'll really like it a lot, I just have to keep looking for places where Ruby is the answer, instead of making Ruby the answer even when it's not.

I've been readying Why's (Poignant) Guide to Ruby, which could be called Why's acid trip to understanding ruby. It's the best metaphors and explanations about the syntax that I've found, but it's also got crazy bizarre things in there that I think, what was he smoking?

I've also started looking at Programming Ruby, which is known as the pickaxe book. I've been looking at this one, because it's installed with the one-click installer for Ruby, so it's already on my computer, but you can also read it online.

There's also a neat interactive ruby tutorial that makes you type the code and read about why at the same time, there is some of the same bizarre things in this as the Poignant guide above because it is also written by Why the Lucky stiff.

So far I'm just learning to do the basics, and I haven't created anything new or solved any fun problems, but I'm enjoying learning the new language.

Monday, April 14, 2008

It's good to have someone you can trust

Sometimes as developers we lose sight of what is right in front of us. A quick change to a piece of code and WHAM, something breaks.

It's times like this that it's good to have someone we trust. We can ask that person to look at our change and help us find the fix, which is often just something extremely stupid that we did.

Too often when we've done something stupid, we look right at the mistake and see it for what it was supposed to do, not what it is doing. A 2nd person can usually find this bug within a few seconds.

This is one of the biggest benefits for paired programming. In those cases there is a lot less chasing your own tail around, because the feedback is immediate. That's why paired programming teams have higher quality and stay focused better.

Thursday, April 03, 2008

The practice of boring

Software Development is boring. I'm a software engineer, Software development is my tool. Software development is the practice of boring.

The practice of boring is doing the same things over and over and over. That's what software development is. I am constantly connecting to a data store, pulling back data, displaying it in an application. Something can then happen to the data and it will be saved back to the database. I have just described practically every piece of software ever. Essentially Blogger is the same thing.

Blogs are saved somewhere, they are then displayed for editing by the author or viewing by anyone else.

Amazon is that way. A list of things for sale, their reviews, their price are all saved somewhere and displayed when you log in. Even your preferences based on a history of your purchases from Amazon are stored and pulled to display suggestions.


Online newspapers display their stories into their web page layout.

Software developers write the software to get data and display it, sometimes with editing. Software development is the practice of boring.

It's a good thing I'm not a software developer. I would go completely bonkers with a redundant mundane job like that. I'm a problem solver. My job is not to just write software, I need to be able to understand a specific problem, decide if there is an existing solution that can be re-used or if a new one has to be developed. I need to understand what needs to be tracked to make the project a success and to make the work done on it legal. I need to understand laws and how they relate to the potential solution I develop. I need to stay aware of different development methodologies because one of the new ones may be a faster way to provide my solution.

I need to be great at the practice of boring, in order to really focus my ability and skills into problem solving. The better I am at the boring task of writing software, the more prepared I am to write the software needed to solve that next problem. I embrace the repetitive task of getting data from somewhere and displaying it, because all of the in-between steps where the process and business rules lie are what makes each application unique.

There is a lot of tools, tutorials, books, and training available to improve your software development skills, the only way to get better at solving problems is to solve more of them. Experience is the key. Be the best developer you can be, learn to code the highest quality code the fastest, in order to get on to that next problem. Keep your job interesting, with the practice of boring.

Thursday, March 27, 2008

Would you follow me on twitter?

The past month I've started asking myself if anyone would follow me on twitter, and who would I follow on twitter. Not surprisingly I began asking, why anyone would ever use twitter.

I know of a few people that use twitter, and I hear about it a lot in the podcasts that I listen to
however, I don't understand the true purpose of it.

Twitter's site asks, "What are you doing?" So from that I take it to mean that the purpose is to tell the world constantly what I'm doing.

Since the majority of my daily activities are boring enough that I wouldn't want to make someone follow me around, I don't think that most things are worth mentioning. Heck, my job is sitting at a computer. From the outside looking in, I'm pretty boring. I even find it hard sometimes when my kids ask what I did today, and my answer is, "I read 200 pages of documentation trying to find how to do something that we haven't done before". Or, "I made a change to the program that I'm working on to allow someone to edit the phone number in the middle without the cursor being reset to the end after every keystroke". To which they seem to always look at me dumbfounded. So instead I try to say things like, "I made some else's job easier today".

Even my home activities are not the most exciting. Things like "Doing dishes", "Eating a great dinner my wife cooked", "Playing catch with the kids". These aren't things that I do that would be interesting to people.

I've heard of, and seen some people use twitter solely as a marketing tool for their blog. I guess this is possible, but most likely, if I'm going to care enough to follow someone on twitter, I'm also following their blog in an RSS Reader, so I don't want them to post that they have a new blog to read, and I don't want to do that myself.

I have seen a great use for something like twitter within a company or team, in order to keep everyone informed on the current status of what each member in the group is doing. However these statuses are not useful to the world at large, and are possibly proprietary enough in nature that they need to be housed completely in house at the company.

Since I began my twittering experiment a few days ago, I now have a good reason for the service. There are some people out there that I admire. I am amazed at the way they think, and the things they think about. These are people that I look up to and aspire to be more like. It's possible that through twitter I can get a little more of a glimpse into the things that these people do. Maybe the reason they think a certain way is influenced by things that they read, and something like that could be shared on twitter. That extra glimpse into what helps to open their mind to creativity, could provide me a way to become more open to creativity too.

So why would I post anything about myself on twitter? I've already explained that I see myself as boring. But that doesn't really mean I am boring. And it doesn't mean that others see me as boring. Maybe instead, by my posting on twitter, someone will be inspired or influenced by something that I do or say. The only way to know for sure is to keep tweeting and see how it goes.

That begs the question, would you follow me on twitter?

Thursday, March 13, 2008

Using Ultra Edit for Ruby

Configure Ultra Edit for Ruby Syntax highlighting.
First open Ultra Edit. Open the View Menu. Open the View As (Highlighting File Type) and see what the next empty language number is.

Then Open C:\Program Files\IDM Computer Solutions\UltraEdit-32\wordfile.txt.

Move to the bottom of this file and paste the following code. Change the L12 to L## to the next Language number in your Ultra Edit menu.



/L12"Ruby" Line Comment Num = 2# Block Comment On = =begin Block Comment Off = =end Escape Char = \ File Extensions = RB RBW
/Indent Strings = "do" "begin" "{" "|"
/Unident Strings = "}" "end"
/Delimiters = []{}()<>="'.,+
/C1"Keywords"
__FILE__ __LINE__
BEGIN
END
alias and
begin break
case class
def defined? do
else elsif end ensure
false for
if in
module
next nil not
or
redo rescue retry return
self super
then true
undef unless until
when while
yield
/C2"Object, Module, Class, Kernel"
__id__ __send__
ancestors alias_method append_features attr attr_accessor attr_reader attr_writer abort at_exit autoload
binding block_given?
class_eval class_variables clone const_defined? const_get const_set constants callcc caller catch chomp chomp! chop chop!
display dup
extend_object eval exec exit exit! eql? equal? extend
fail fork format freeze frozen?
gets global_variables gsub gsub!
hash
included_modules instance_methods include iterator? id inspect instance_eval instance_of? instance_variables is_a? inherited
kind_of?
lambda load local_variables loop
method_defined? module_eval method_added module_function method method_missing methods
name nesting new nil?
open
private protected public private_class_method private_instance_methods protected_instance_methods public_class_method public_instance_methods p print printf proc putc puts private_methods protected_methods public_methods
remove_const remove_method raise rand readline readlines require respond_to?
scan select set_trace_func singleton_method_added sleep split sprintf srand sub sub! syscall system send singleton_methods superclass
test throw trace_var trap taint tainted? to_a to_s type
undef_method untrace_var untaint
/C3"Instance Variable"
** @a @b @c @d @e @f @g @h @i @j @k @l @m @n @o @p @q @r @s @t @u @v @w @x @y @z
/C4"Class Variable"
** @@a @@b @@c @@d @@e @@f @@g @@h @@i @@j @@k @@l @@m @@n @@o @@p @@q @@r @@s @@t @@u @@v @@w @@x @@y @@z
/C5"Globals"
** $
/C6 "Symbols"
** :
/C7"Constants"
** A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
/C8"Operators"
+ +=
- -=
% %=
/ /=
** **=
& &=
| |=
^ ^=
> >> >>=
< << <<= = == ===


This configuration was originally pulled from a website about supoort. But seeing how I couldn't actually find anywhere on their website that linked to the file, I decided to just include it here. I thank them greatly for a good layout to work with Ultra Edit.

I've been wanting to learn Ruby for some time, and finally found what looks like a good beginners guide to ruby. Here's a link to The Little Book of Ruby. I've only made it through chapter 1 so far, but it looks like a good place to start.

**** Updated 10/31/2008 ****
IDM now has word files for Ultra Edit on their site. Their version of the Ruby language is possibly more complete than the one I have included. You may want to check it out at http://www.ultraedit.com/downloads/extras.html#wordfiles

Sunday, March 09, 2008

A wiki for a knowledge base.

In my continuing series on tools and processes that we looked at and used to solve problems at work, I'll discuss the knowledge base next.

Part of the problem we had, was the ability to support an application, when the primary developer of that application was on vacation, or worse, had quit. Each application had only a few who knew it, but that knowledge had continually left with them.

We wanted a knowledge base, so when problems occurred we could capture:
  • What Happened (What is the symptom)
  • What is the underlying problem, can we fix this later.
  • How do we fix it now.

Without company support for this decision, we started investigating open source solutions to the problem. We installed and tested a few knowledge base systems, but they were cumbersome to use at best. We had just installed MediaWiki. It didn't really have a purpose or design in mind, it was just there. I took the opportunity to play with it and started documenting support options on the wiki.

It was apparent pretty quickly, that the ease of editing, searching, and cross linking made this a great place for a knowledge base. While some of the knowledge base systems seemed to support a better interface for finding a related problem, grouping pages logically, and using the search feature of a wiki made more sense.

Since then, we use the wiki to document all of our knowledge base items, more and more of our applications, and we're even using it to manage some of our projects. We aren't the first either, I've read that Thoughtworks uses wikis to manage their projects.

Wednesday, February 27, 2008

Training

Let me start with, I love my company, and am very happy where I'm at. I wasn't always that way. At one point in time there were major problems there. And many of those problems started with training.

Training was considered an "after you need it" item at the time. If we purchased a new technology, or already decided that we were going to do something different, then and only then would a few select individuals get to go to training. In the department of about 30 developers, there were maybe 5 that were getting to attend training or a conference every year. It was always same people, and everyone else was left out. Those few were then expected to return to work and pass on their newly acquired knowledge to the rest of us.

The list of things wrong here is long. The rest of us felt left out, mad, heck - flat out pissed off. We didn't understand why we were never allowed to go to training. We didn't understand why training was only after the fact. IT is a fast paced world, and you have to be ahead of the curve on training or you fall too far behind.

We built business cases for why training was good. Found studies on the internet to support our reasoning, and submitted it. Only to find out that no, we weren't getting more training.

Then there was a changing of the guard. A new boss came in. He walked into a company with a lot of people complaining about a lot of things. One thing he really supported though was training.

Since that time the training budget has gone up a lot, training is available to everyone now, and we get to choose what to go to, not go to something after the fact.

Training has been a huge moral booster the past 2 years, and it's helped improve skills. Being able to go away to training and learn something, then come back and apply it is exhilarating, and exciting.

Coming soon a series on tools and processes.

Several years ago a group of developers at work got together and came up with some ideas of things that could make the developers in our department more productive and the process better.

We had a list, which I can no longer find, but I remember several items.
  • A code library
  • A forum
  • A knowledge base
  • Business Analysts
  • Code Reviews
  • Cross Training
  • Training
Over time we implemented all of these, and have stopped some of them for one reason or another. Over the next several posts I will address the reason we wanted these, along with why they did, or didn't work.

Monday, February 18, 2008

Testing on an island

I read Derek Whittaker's post the Sound of One Man Testing, and it got me thinking to the first to adopt people. The ones that read incessantly and find the hints of good ideas and do what they can to introduce new concepts into their work. These people are the ones that figure things out, and solve the hardest problems, they go the extra mile all the time.

I got to thinking about unit testing at my own work. About 3 years ago I had just heard the concept of test driven development. The few paragraphs I read about it sounded interesting, but I couldn't quite get my head around it. I didn't understand why I'd write a test for every level of code, when an integration test would take care of all of it. This just didn't make sense to me. I like to pride myself on being one of those early adopters. I'm not on the bleeding edge, but I do what I can to read about things and stay up to date at least on the concepts for things. Test Driven Development is a huge concept, with great benefits and I couldn't quite get it. It took me a reading a couple of books and writing a project with test driven development before I started to get it. Yes, after a fully TDD project I only started to get it. Even at that point I had done things wrong. Mocks were still a mystery and I hadn't found any good tutorials. For the first time I felt like I needed my hand held as I walked through something new. It was scary.

When it comes to work I tend to be fearless and take on any challenge given to me. But this was different. So for those early adopters that are out there trying to be the person testing on an island and starting it in your company. Remember, even for some of those who tend to lead, it can be hard. If you work in a place where you do have some small 1 man projects I recommend using one or two of those as proof of concepts for TDD before even attempting to insert it into a larger project. Talk to your co-workers about TDD. Send them blogs, magazine articles, books, anything to make TDD a topic of conversation. And then, offer to hold their hand. Show them with in-house training, led by you. Teach them about mocks and dependency injection and why you have to use them with the design in order for the unit tests to be black box. Explain black box and talk about all of these concepts, which are very likely new concepts to a team that is not already doing Test Driven Development.

Finally, start adding tests to a large project that you are working on. Offer to help your co-workers build their tests.

I've been reading about TDD for 3 years now. Currently I'm working in Java and I'm comfortable from the bottom layer all the way through the web service layer in writing tests, but I still don't know how to test the GUI. Even after 3 years there is still a lot of room to grow in my Test Driven development. And if you are thinking of starting Test Driven Development, don't look at this and think that it's too hard. It's not, and the quality that you gain in the layers that are tested is great. The current project I'm working on is closing in on 1,000 unit tests. I love being able to run them and know that the refactoring that I had just done didn't break any code that someone else was relying on.