Tuesday, December 23, 2008

Container-managed transactions with JBoss/MySQL

Now that I find myself out of a job, I’ve got lots of time to get caught up on all of the technologies and stuff that I really should know.

I know how to build applications using Java/JavaEE. I know how to develop EJBs (particularly session beans and MDBs). I know how to use JSP and servlets. I know how to use JMS. I know how to use RMI. Most of this stuff is pretty automatic after having worked with these technologies over the past few years. Throw in some helper technologies, such as XDoclet (no more manual updating of deployment descriptors for me, thanks!), and things become even easier. While I can’t rattle off different parts of the J2EE 1.4 specifications, I like to think that I’m competent in my ability to use the technologies.

At least, that’s what I like to tell myself.

I had a bit of a disastrous interview last week. I got asked all kinds of questions about how different parts of J2EE work and, while I was able to come up with good answers for most of it, there were certain questions that I totally botched.

One topic that I really hosed was container-managed transactions (CMT). This is something that I should know something about, but in reality I never actually used them in the applications that were being built at my last job. We pretty much just assigned the “Required” transaction attribute to every EJB method and, as far as I was concerned, everything else just sort of worked. For the CWMP RPC method test system I built, transactions weren’t important at all, so I never really bothered researching about how they worked.

Using that botched interview to try to actually learn something, I set about experimenting with CMT. JBoss is the application server with which I am the most familiar, and MySQL is a free RDBMS that I am also familiar with, so I installed these two products for my testing.

Once everything was set up, I set about creating a simple EJB with a few public methods that my RMI-based test client would call. One method would successfully make changes to the database. A second method would make failed changes to the database. A third method would call the first two methods, allowing me to test multi-level transactions.

Based on what I had read about using transactions (and my own previously limited experience), it should be just a matter of setting up the XDoclet @ejb.transaction attribute on the appropriate methods and the container will take care of the rest.

Here’s an example of my “successful” method:
 /*  
  * @ejb.interface-method  
  * @ejb.transaction  
  *   type="Required"  
  */  
 public boolean updateMovie(MovieDTO movie) {  
   boolean success = false;  
   Connection conn = null;  
   
   try {  
     conn = _ds.getConnection();  
     PreparedStatement stmt =  
       conn.prepareStatement("UPDATE movie SET title = ?, year = ? WHERE id = ?");  
     stmt.setString(1, movie.getTitle());  
     stmt.setInt(2, movie.getYear());  
     stmt.setInt(3, movie.getId());  
     success = stmt.execute();  
   } catch (SQLException e) {  
     e.printStackTrace();  
     throw new EJBException(e.getMessage());  
   } finally {  
     closeConnection(conn);  
   }  
   
   return success;  
 }  
It’s a simple method that takes the contents of a DTO and updates the appropriate record in the database. Nothing fancy.

Here’s the code for the method that always fails:
 /*  
  * @ejb.interface-method  
  * @ejb.transaction  
  *   type="Required"  
  */  
 public boolean updateBroken(MovieDTO movie) {  
   boolean success = false;  
   Connection conn = null;  
   
   try {  
     conn = _ds.getConnection();  
     PreparedStatement stmt = conn.prepareStatement("UPDATE movies SET title = ?, year = ? WHERE id = ?");  
     stmt.setString(1, movie.getTitle());  
     stmt.setInt(2, movie.getYear());  
     stmt.setInt(3, movie.getId());  
     success = stmt.execute();  
   } catch (SQLException e) {  
     e.printStackTrace();  
     throw new EJBException(e.getMessage());  
   } finally {  
     closeConnection(conn);  
   }  
   
   return success;  
 }  
The difference here is that the query will fail because the “movies” table does not exist (it’s called ‘movie’).

When I installed the app and ran my test client, both methods behaved as they should. When I called the working method, the update occurred. When I called the non-working method, the update did not occur.

Then I added the following method:
 /**  
 * @ejb.interface-method  
 * @ejb.transaction  
 *   type="Required"  
 */  
 public void doStuff() {  
   ArrayList movieList = getMovies();  
   
   for (MovieDTO movie : movieList)  
     System.out.println(movie.getId() + ": " + movie.getTitle() + " (" + movie.getYear() + ")");  
   
   MovieDTO movieChange = movieList.get(0);  
   movieChange.setYear(movieChange.getYear() + 1);  
   updateMovie(movieChange);  
   
   movieList = getMovies();  
   
   for (MovieDTO movie : movieList)  
     System.out.println(movie.getId() + ": " + movie.getTitle() + " (" + movie.getYear() + ")");  
   
   updateBroken(movieChange);  
 }  
Again, pretty simple. It does the following:
  • Get the list of all movies and output them to the console
  • Change the year for one of the movies and update it via the “successful” method
  • Get the list of movies again and output them to the console (the idea to show that the update actually occurred)
  • Try updating the movie record again via the “unsuccessful” method
What should happen here is that the record in question will be updated to reflect the new year value (confirmed by the new fetch and display) and then that update should be completely undone because the second update will fail. That means that if I check the database after running the test method the original year value should be there.

This was not what happened. Every time I ran the doStuff() method, the year value continued to increment, despite the fact that the second update always failed. I was very confused.

And so began my 2 day odyssey to figure out what the heck was wrong.

I asked some former colleagues about our use of transactions with Oracle and MS SQL server. They claimed that everything was working as expected.

I read up on how to specify transactions in the deployment descriptors and verified that XDoclet was doing the right thing.

I started searching the web to see if anyone else was having problems getting transactions to work with MySQL and JBoss. It turned out that lots of people had problems getting them to work, and while people were eventually successful, I couldn’t see what they were doing to get it to work.

At one point, I stumbled across something that talked about needing to use XA drivers in order to get the transactions to work. While this should certainly do the trick, it seems to me that the XA stuff is really meant for establishing transactions across different types of systems (say the EJB container and some remote OSS or billing system). Still, I decided to try using the MySQL XA driver. I tried and tried to get things working properly, but the problem remained. Whenever I ran that test method, the year value was incremented.

At one point I really mucked with the XA driver configuration and things stopped working altogether. At that point, I figured I needed to move into a different direction. This was confirmed when I asked a colleague about XA drivers and he mentioned that the product never used them.

Ok, back to the web and more endless digging.

After a few more hours, I just happened to stumble across this article, which talks about how to get CMT working with Hibernate in a JBoss environment. The key section is “Configuring MySQL”.

I didn’t really pay much attention to the table definitions (which may have actually saved me a lot of time, since I may have come across similar definitions before). Instead, I saw this little gem:

As you can see, we are creating tables of the InnoDB type. That’s important. MySQL’s default type is MyISAM. MyISAM is an improved replacement for ISAM, but it’s a non-transactional storage engine and it follows a different paradigm for data integrity, which MySQL calls “atomicoperations.” Again, it’s non-transactional, meaning that it does not support transactions. Obviously, we need a transactional table type, and in MySQL that means InnoDB.

Well, well, well.

When I created the tables initially, I didn’t specify any sort of engine, thus they defaulted to MyISAM. Since this engine does not support transactions, there was no way for the container to undo the first successful update.

Giddy with excitement, I fired up the excellent MySQL Query Browser tool and modified the table definition for the ‘movie’ table to use the InnoDB engine instead of MyISAM. I then ran my test client against the doStuff() EJB method and…

Success! The console output showed the list of movie data, the data with the updated value, and the failure exception. When I queried the database afterward for the current values, the original values were all still in place. The transaction had been completely rolled back. Hurray!

So that’s it. In order to get container-managed transactions to work with a MySQL database, the tables must be configured to use the InnoDB engine. A full table definition script would look something like this:

CREATE TABLE movie (
    id         int(11) NOT NULL auto_increment,
    title      varchar(255) default NULL,
    year       int(4) default NULL,
    PRIMARY KEY (id)
) TYPE=InnoDB;
I hope that this information helps someone avoid all of the headaches I experienced in trying to find out what turned out to be a very simple solution.

Tuesday, December 02, 2008

Uh, what the hell just happened?

December 1st, 2008. An ordinary day, I suppose. “Official” start to the holiday season, at which time I “allow” Andrea to start playing Christmas music and start my annual argument about when the decorations will be put up, the tree purchased and set up, and so forth. Apart from that, a normal day, with our normal routines.

I checked my Blackberry and noticed a handful of e-mail messages from E-Trade, sent around 12:30am. Each message said that my corporate stock options were scheduled to expire on March 1st, 2009. Given that my first set of options weren’t due to expire until some time in 2013 or 2014, I found that a little odd.

As I rounded up Olivia and wrangled her into the car to head to school, I continued thinking about the e-mail. March 1st was certainly an odd date – doubly odd that all of my option allotments were going to expire at the same time. Must have just been some sort of clerical error.

By the time I got to the office, the significance of March 1st finally dawned on me – it was exactly 3 months from today. At that moment, I recalled something in our employee guide that mentioned that employees had 3 months after the termination of employment to exercise any vested stock options. Uh-oh.

As I made my way to my office, everyone was sort of milling about and gabbing. There was certainly a bit of nervousness in the air.

“Anyone get any e-mail from E-Trade recently?” I inquired.

“No, why.”

“I just got a bunch of messages saying that all of my option grants are about to expire.”

“Dude, shut the hell up. People are nervous enough as it is.”

Allow me to step back into time for a moment. Back in October it was suggested/implied that layoffs might be coming before year-end. Near the end of last week, we got an e-mail mentioning that a senior VP was dropping into the office on Monday (December 1st) and that lunch would be provided.

So I’m sitting at my desk, dig out my laptop and set about getting started for the day. The e-mails continue to worry me, especially since I was the only one to get them. However, I had just received a glowing yearly review and a raise, and I was working on a project a little more closely aligned with head office.

My boss arrived and I went to see him.

“So, is there something that I should know?”

“Uh, no, why?”

“Well, I just got these e-mails from E-Trade about my options expiring on March 1st, which is 3 months from today.”

He shrugged. “I don’t know. I haven’t heard anything. I don’t even know why is here. Just continue doing what you’d normally be doing.”

Word finally starts circulating that the VP has arrived, but still no one knows what’s going on. Apparently my boss is in to see him.

Some time later, a colleague pokes his head into my office to tell me that our boss was just let go. Well, I guess we know why the VP was here and my boss had no idea what was going on.

A few minutes later, the e-mail prophecy comes true as I get called in to see the VP. The usual customary “you’ve done great work, bad economy, blah blah blah” stuff. I’m handed a couple of boxes so that I can take stuff of immediate importance, but told that I’ll have to make an appointment to come in and get everything else.

Even though I pretty much figured this was coming, it was still a bit of a surprise. I headed back to my desk, packed up a few essentials, and quietly headed out the door and to home.

And, for the first time in 15 years, I’m unemployed.

During the rest of the morning and afternoon, I was in communication with my now former colleagues, who kept me up to date on the carnage. In total, 6 people were let go.

Happy holidays indeed.

Sunday, November 30, 2008

Sightseeing in Stockholm

This has been in my queue for a couple of months now and I’m just now finally getting around to finishing it up and posting. The article refers to a trip I took to Stockholm for the Broadband Forum during the week of September 8, 2008.
--------------------------------
I was in Stockholm for the week attending a broadband specifications conference. The conference was scheduled to start Monday afternoon and run through until Thursday afternoon. Scandinavia was at the top of my list of places I really wanted to get to, so I was really looking forward to attending.

I scheduled my flights to arrive in Stockholm Sunday afternoon and depart Friday morning. Ideally, I should have scheduled my flights to either arrive the day before or to leave a day later so that I could do some touring, but I sort of dropped the ball on that one. However, with a late afternoon arrival and things not starting until Monday afternoon, there was some opportunity to catch some of the sights. I also knew that I’d at least get to the downtown area and see some nice architecture and experience some fine local cuisine most evenings, so I wasn’t too worried about having so little time.

The flight got into Stockholm pretty much on time, but by the time I got through customs, got my bag, and got to the hotel, it was a little after 7pm and I still hadn’t even checked in yet or figured out what was around. I ran into an acquaintance in the lobby and given the lateness and my level of fatigue, I decided to eat at the hotel and try to make it an early night. No big deal, I still had Monday morning to catch a couple of things.

The alarm went off at a reasonable hour Monday morning and I went about getting ready to head out. I was going to need some cash and a 7-day metro pass, so that was to be the first order of business. I was staying at the Quality Hotel Globen, which is part of the much larger Globen City complex that includes an arena and a shopping mall. The mall was only a couple hundred metres from the hotel, so that was to be my first stop.

The mall was just opening when I arrived. There were lots of people, but it wasn’t particularly busy. I wandered around the mall, looking for a bank machine and having a look at what the stores were offering, especially since I needed to pick up some sort of souvenir for Olivia.

I eventually found a bank machine, but I still needed the metro pass. I got to a set of escalators and headed down, which took me to the bottom floor of the mall. There were only a few stores on this level and so there was not a lot of traffic. I walked a couple dozen metres past another bank machine and stopped to look around for a moment.

To my right was an ICA store (which I believe is a grocery chain). To my left was what appeared to be some sort of lotto booth. I looked at the lotto booth store for a moment, trying to determine if there was some sort of sign that said I could buy a metro pass there.

I heard what sounded like a semi-hollow aluminium can hitting the floor and I turned around to see the can roll past my feet. The can started belching out thick orange smoke.

I was watching the can, wondering why in the world it was there, when a very loud noise started up. It was coming from back where the escalators were, so I spun around to see what was going on. There was a corner wall blocking my view, so I started walking towards the sound. After a few steps, I was able to see past the wall and found the source of the noise.

Two men wearing very fluorescent lime green jackets with blue stripes were standing in front of a door. One was wielding a very large gas-powered circular saw, like you would use for cutting concrete or rebar or some other tough metal, and trying to cut into the door.

“That’s odd,” I thought to myself. “I suppose maybe they’re doing some sort of maintenance work.”

The smoking can re-entered my thoughts and again I wondered about the relevance. It was smoking quite a lot at this point and the lotto booth was completely filled.

I continued looking at the two men. The one not operating the saw was looking around and turned in my direction. That’s when I noticed the reflective ski goggles.

The man made eye contact with me and waved me away. I was about 10 metres away and there were a lot of sparks flying, so I figured he just wanted to make sure I didn’t get too close.

Having had enough of that, I decided it was time to head out. There was a door leading outside a few metres away, so I headed towards it. A man with a panicked look on his face was kicking the smoke can out of lotto store and talking on his cell phone.

It occured to me just then that these guys weren’t trying to cut opening just any door. It was the door to the room containing the bank machine I had just passed.

That’s when it finally all came together.

These guys were robbing the bank machine.

My first thought at this point was, “Well, I really don’t need to be here, so I need an exit RIGHT NOW.” I very quickly walked to the (what appeared to be) automatic door. Nothing happened. I tried pushing the door open. Nothing. I tried pulling the door open. Still nothing.

Ok, great. A couple of guys are robbing a bank and I can’t get out of the mall. “Ok, ok, no problem. They’re busy with the door and probably don’t want things to get any more complicated than they already are,” I told myself. That’s when I had the brilliant idea.

“I know. The escalator is just over there, so I’ll very quickly walk along the wall past the would-be robbers and make my way up the escalator.” I started walking back towards the escalator.

I got around the corner again and stopped to see what the two where up to. One was still busy with the door. The other was nervously glancing around in the area of the escalator, his arm raised up into the air.

That’s when I noticed the gun.

I really don’t know anything about guns, rifles, pistols, and the like. I do know the difference between a revolver and something like a Glock/9mm/etc. This particular gun was black and looked like the latter.

“Oh, this is just fucking great,” I murmured to myself. “I can’t go out the automated doors because they won’t open. I can’t go up the escalator because these guys are armed. The mall is filling up with orange smoke. What the fuck am I supposed to do now?”

I turned back towards the door that I couldn’t open and saw the man still on the phone. This time, however, he was frantically slapping a black pad next to the door. He slapped a couple more times and the door that I couldn’t open finally opened. So it was an automatic door after all. Seeing my opportunity, I ran out.

Once outside, I took a few seconds to catch my breath and figure out what to do next. I turned right and started walking down the sidewalk. All I really knew at that point was that I wanted to be as far from the situation as possible.

I walked a couple hundred metres and came across a set of stairs to the right that went up to the plaza between the hotel and the mall. I had initially climbed a set of stairs right outside of the hotel and walked across the plaza to get to the mall. Wanting to get back to the hotel as soon as I could, I decided to climb up the stairs.

Once I got to the top, I could hear sirens. I figured that it must be the police, so I decided that instead of heading straight to the hotel, I’d hang around the plaza to see how long it took them to arrive and to see what happened once they got there. There was a steady stream of people exiting the mall, that orange smoke trailing behind them. It was really starting to fill up the entire building.

I wanted to see what was going on, but also be out of the way. Off to the left was a park bench. I decided to have a seat there and watch the event unfold.

Not 30 seconds later, a “side” door to the mall opened and two men dressed in fluorescent green jackets stepped out. I glanced at them and then quickly looked down along the plaza. Further away, I saw a few more people dressed in similar jackets. At first I just figured that the coats must be pretty popular. I glanced back to the two men. One of them looked right at me and that’s when I noticed the ski goggles and the big black bags they were carrying.

“Oh my god, you have GOT to be fucking kidding me!” I said aloud (not that they could hear me). “Why can’t I get away from you two?!”

Although it looked like they were looking right at me, they were really quite occupied with what they were doing and paid no attention to me. They very quickly opened a door to a stairwell and disappeared. Over the next few seconds, I could hear some banging, like something large and metallic was being dropped (something like a crowbar). A few seconds after that, two men wearing regular street clothes emerged. They very calmly walked over to their waiting motorcycles (well, one was a motorcycle and the other a scooter), donned their helmets, placed the black bags over the fuel tanks, and drove down along the plaza and out of sight.

A few minutes passed and I was still sitting on the bench in disbelief of everything that just happened. The police finally showed up and I walked over to the wall along the plaza to see what was going on. While I was standing there, someone next to me asked what was going on. I mentioned that a couple of guys were trying to rob a bank machine in the mall and that they came up onto the plaza and drove away on motorcycles.

My initial plan was just watching the police for a few minutes and then walking away, not wanting to get involved at all. However, after talking to the person next to me and watching the police begin interviewing people, I figured that I should probably head down the stairs and mention that I saw the guys originally show up and start cutting into the door and that I saw them leave.

It looked like there were plenty of witnesses, so I doubted that I’d be able to offer something that someone else hadn’t already provided, but I figured I’d wait anyway. As it turns out, it looked like it was a good thing that I told my story. There were plenty of people who witnessed the actions in the mall and lots of people saw a couple of guys riding away on motorcycles, but, as near as I could tell, I was the only person who actually saw both parts. I have no idea if my ability to link the two events together will have any effect on things, but at least I felt like I had contributed in a meaningful way.

After the interview, I headed back to the hotel and tried to clear my head. At this point, the morning was shot and it was time to get ready for the first working group session. So much for getting any sightseeing done.

The police called me about an hour after the initial interview. They wanted me to show them the doors that they had come out of and the stairwell I had mentioned, and where they went on the bikes. After that, I never heard from them again.

I spent a few hours trying to find news articles about the incident on the internet. It was quite a while before I found anything and, of course, just about everything was in Swedish. Interestingly enough, Google Translate doesn’t really do a good job translating Swedish to English. Despite that, I was able to discern some information about the incident. One thing I found particularly interesting was the report that the thieves had escaped in a car. That certainly wasn’t what I saw. I suppose they could have ridden the bikes just a few hundred metres to a car and then driven off. *shrug*

And that was my first full day in Stockholm.

Saturday, November 29, 2008

HD Update

Quite a long time ago I spent some time talking about the not-so-good HD signal provided by Eastlink. Some days were good, some days were bad. Some channels were consistently good, some were consistently bad. I had called into Eastlink to inquire about the signal issues and they had mentioned at that time that my location had known issues, and that they were eventually going to solve the problems. I don’t really watch a lot of TV so, for some reason, I seemed to be ok with that.

Fast forward a whole big pile of time…

It has literally been months since I last had the HD TV on for actual viewing of HD television. If the TV is on at all these days, it’s because I’m playing a video game (I love Rock Band and Olivia loves Mario Kart) or, very rarely, I’m watching a movie.

Olivia fell asleep in our bed tonight (she had a very busy day). I wanted to see a bit of the hockey game, so I figured this was as good a time as any to turn on the big TV. I noticed all kinds of new HD channels. I haven’t really had any time to check them out, but it looks like there may be a couple of cool science/nature channels (Equator, Oasis, etc). I suspect it’s some sort of free-view happening and will be ending shortly.

The other thing I noticed, especially once I flipped over to CBC to watch the game, was that the signal quality was very good. CBC tends to be good, but their hockey broadcasts always seem to suffer from blocking problems on Eastlink. That really was not the case at all tonight. Yes, there was some very minor problems, but, for the most part, the signal quality was bordering on excellent.

I don’t know if I just caught everything on a good night or if Eastlink is finally starting to get its act together, but I look forward to testing out the signal quality again over the next few days, just to see.

Not that I’m likely to actually watch it or anything. Someone remind me why I’m paying for this? :)

Saturday, April 19, 2008

iPod Chronicles - Part 8: Nike+ Accelerometer Calibration

I never bothered calibrating the accelerometer when I first got it. In the manual, it suggested calibrating the unit, but it also said that the default settings were likely fine for most users. I had measured out a variety of distances from my house in half-mile increments, so I figured I'd compare the default calibration with my already known distances and see how they compare. If the accelerometer wasn't too far off, I wouldn't bother.

For the first few weeks, the calibration seemed to mostly match my measurements, with the accelerometer being short about .1 miles after 3-5 miles (ie, I had to run 5.1-5.2 miles in order for the accelerometer to register 5 miles.

In the first week of February, I finally had to get a new pair of shoes - the cushioning in my old shoes was totally shot and my knees were suffering. I bought the same shoes, only in the newer version. Again, I cut a small slit in the underside of the tongue and inserted the transmitter, making sure to place it under where the laces cross, just as I had with my old shoes (I still hadn't figured out the thing was an accelerometer yet).

From the very first run (3 miles, if I remember correctly), the accelerometer seemed a little more off than before. Noticeably. It wasn't until I put in about 7 miles and hit the 7.5 mile mark that I finally decided that I needed to do a calibration.

The calibration process was very simple. A basic calibration can be done with a run or a walk of some distance no less than .25 miles (400 metres). A more accurate calibration is achieved by doing the distance as a walk and as a run. Wanting to be as accurate as possible, I decided to do both.

I measured out .5 miles (I should have done 1 mile, which would likely give a more accurate calibration, but the walk would have taken a while and I was pressed for time) and ran it out. I set it up again and walked the distance back to my original starting point. Good thing I did - it turns out that the calibration was off by about .07 miles PER MILE. That's not a whole lot at a short distance, but when you run 10 miles, it's going to matter.

I've done plenty of runs since the calibration, and the accelerometer seems to pretty much match my measured distances bang on. I read somewhere (website, manual? I forget now) that frequent calibration is encouraged. Now that I see how easy it is for the calibration to be off, I'll likely perform one every month.

Friday, April 18, 2008

iPod Chronicles - Part 7: Nike+ Data and Website

The Nike+ website itself is nice enough, with an interesting Flash-based interface, but it is a bit limiting. It does a lot of basic stuff, such as graphing each run, keeping track of distances on a per run, week, and month basis, and comparing a particular distance with the best similar distance in the history, but there's a lot more I think I'd like to be able to see.

At a minimum, I'd like to be able to easily see a total history summation, like the iPod interface shows - total miles, total hours, total calories, etc. It would also be nice to be able to select and graph multiple runs at the same time, rather than just one particular run against a "best" run.

I have just recently discovered that people have figured out the API the Flash app uses to access the run data, so I may start to experiment with it in the near future. The data is XML-based, so I could use the API to grab the data, import it into my own database, and then do whatever I want with it. A simple set of web pages that offers a bit more functionality (such as the items listed above) would be interesting to experiment with.

Thursday, April 17, 2008

iPod Chronicles - Part 6: Nike+ Running Kit

As I said before, one of the reasons why I got the Nano was because of the Nike+ running kit. A few friends have the kit and raved about how well it works. I'd always run without music in the past, but the idea of being able to determine my pace, distance, and time without having to figure it all out in my head from the time on a regular watch was appealing. I also liked the idea of having a running history (which I tried to keep via an Excel spreadsheet in the past) and being able to graph my runs.

The kit consists of two pieces - an accelerometer/transmitter, which inserted or otherwise attached to one of the shoes, and a sensor that plugs into the sync port of the Nano itself.

Of course, I don't have a pair of Nike shoes with the pocket under the insole for the transmitter, so I needed to come up with some other way to attach it to my shoe.

When I was first fiddling with the accelerometer, I didn't realize that that's what it was. One side of it squishes in a little bit, so I figured the thing worked on pressure, kind of like a pedometer. I was always a little suspect of that, though, since how would it be able to determine distance? In any case, in order to make sure the thing would work, I thought I had to make sure that the squishy part was in contact with my foot somehow.

The accelerometer is pretty small, but I decided to try sticking it under the laces of my shoe, on top of the tongue. With the laces over top, I figured that that would engage the action. After some initial walking around the house, the sensor picked up the transmitter and every thing seemed to be fine. Time for a test run...

It turns out that simply sticking the transmitter under the laces isn't such a good idea. I didn't even get half a mile into my test run before the thing went flying out of my shoe, tumbling down the street ahead of me. I was going to need to find a better way.

I starting thinking that maybe I needed to sew a little bag or something ot tuck under the laces. I'm pretty certain that that would have worked, but while I was lamenting the issue with some friends, one of them mentioned reading that some people cut a little slit in the tongue and put the transmitter in there. My shoes were nearing their end of life, so I figured I'd give it a try.

I cut a small slit on the underside of the tongue, off to the side, and slid the transmitter in. Again, thinking it worked by pressure, I made sure that the laces were crossing over the top of the transmitter. I walked around for a bit and the thing was still registering, so I went for another test run. Success!

At first, I didn't like running while the music was playing. I have a small (512mb) iRiver MP3 player that I was going to use for running (as well as travel), but I just couldn't deal with the music in the background. Each song had a different tempo, which I subconsciously tried to match, making running difficult. When I started with the iPod, it was just the same as before - the changing tempos kept throwing my running off. I really liked the stats aspect, though, so I kept at it. I figured that if I couldn't deal with the music, I might get away with listening to podcasts.

Music with lyrics really threw me off, but instrumental songs seemed to cause me fewer problems. I started experimenting with different instrumental stuff, eventually settling on Jesse Cook. I ran almost exclusively to Jesse Cook songs for several weeks.

Eventually, I got used to the idea of having music in the background. I've even managed to deal with lyrical songs as well. Sometimes a song will come on and it starts to mess me up if I start to actually listen to it (which happens if it's a song that I think I might be able to easily learn on the guitar). When that happens now, I just skip to the next song. And now the iPod has become a very valuable part of my running program.

Tuesday, April 15, 2008

iPod Chronicles - Part 5: iPod Docking Station

I used to have a pretty decent stereo in my living room, but I've had a couple of amp/receivers fail that I haven't replaced. With the completion of the home theatre, all of the working equipment was moved downstairs, leaving a void in the living room. This wasn't such a big deal because we don't really listen to music all that often upstairs. If we really want to listen to something, there's an under-the-counter radio/CD player in the kitchen or we could turn on the TV to one of the digital music channels.

Despite all of that, one of the reasons for getting an iPod was that we could get a speaker docking station and set it up in the living room, giving us access to a larger library.

I wasn't in any particular hurry to get the dock, but Andrea really wanted one, so, as I always do, I started doing some basic research.

I didn't want anything ridiculously expensive (somewhere around the $150 range would be fine), too hideous, and something that projected decent sound. without actually hooking the iPod into a real stereo I knew that the quality would never be spectacular, but if I was worried about that I wouldn't be using any compressed audio files in the first place.

I did some rudimentary searching online to see what was available from my local stores and then did some basic research into several models that interested me. With that knowledge, I then headed into Future Shop for some sound demos.

Buying stuff at Future Shop is always hit-or-miss, unfortunately. You really do need to know exactly what it is you want, since the staff tend to be non-helpful. Add in the fact that it's sometimes very hard to demo anything and you've got a recipe for frustration. Still, I usually know what I want, which is why I keep going there.

Once I got to the store, I headed to where the docking stations were. As luck would have it, most of them had a power connection, making it easy to give each unit a test. I reached into my pocket, pulled out my iPod, plugged it into the first dock, and ...

A sales droid ran over. "Can I help you?"

"Not really," I replied. "I'm just testing."

With that, the guy starts trying to move me to particular units. I brush him off.

I give the first station a whirl and I'm immediately unimpressed. I move to the next unit and start it up.

Now there are two sales droids. I'm not sure why this always happens, but whenever I'm trying to demo something, I'm immediately surrounded by people who think they know more than I do.

I continue to try units and the sales droids continue to try to interact with me.

"Well, what did you think of that one?"

"Don't like it. Too tinny." I try to be curt, with the hopes that they'll get the message. They don't.

"Yeah, that one's not very good. You should try this one instead." Grrr.

Despite all of the annoyances of the sales droids, I manage to narrow my selection down to two particular units: the Altec Lansing M602 and the Mirage OmniVibe.

I've got a set of Altec Lansing speakers for my desktop and I think the sound they produce is quite nice. The M602 had a similar sound quality (although not as nice without a dedicated subwoofer), configurable bass and treble settings, a remote, and the price was decent ($150).

The OmniVibe had fantastic sound (as you would expect from any Mirage kit). It also comes with a remote, but does not have bass and treble settings. The price was also pretty steep (I believe it was about double).

The decision came down to two things. First was the price. $150 was reasonable and $300 was not. The Mirage had much better sound, but I didn't feel the cost was justified. Second, the OmniVibe has a top-mounted speaker set-up, which would be better if installed in a semi-central location. The M602 has the speakers front-mounted, like a ghettoblaster. Since I was likely to set the unit up on top of the entertainment unit, I figured the front mounts would be a better choice.

So I walked out the with M602.

I eagerly set the unit up when I got home and I must say that I was pretty amazed at how the system manages to fill the living room with sound. Andrea was also impressed with the sound.

Deep down, I know the OmniVibe would have been a better selection, from a sound perspective, but given our listening habits, the M602 has been perfectly adequate.

Monday, April 14, 2008

iPod Chronicles - Part 4: Cover Art

Hello, my name is Mike Digdon, and I'm addicted to cover art.

There, I said it. Now I can take the next step towards recovery, although I'm not all that certain I want to recover, since cover art is fun!

Let's take a few steps back, to give this some context.

One of the nifty things about the Nano is that it has a covert art mode, just like the iPhone/iPod Touch. I don't particularly use the cover art mode to choose an album to play all that often, but it is nice to flip through the collection every once in a while.

The big thing for me is that I absolutely can't stand seeing that yucky grey default cover picture that the iPod uses when there's no cover art for a particular album/song, so I absolutely insist that every song loaded onto my iPod have the cover art from the album that I ripped it from.

When you rip a CD into iTunes, iTunes has an option to go fetch the album art for you. I find that this only works some of the time. There are typically two reasons why it doesn't seem to work all that well for me.

The first is that iTunes seems to sometimes grab the wrong cover art for a particular album. Unfortunately, it grabs the first entry it finds and that's what you're stuck with. This is something that Window Media Player has in it's favour - if it detects multiple entries for a particular album, you are presented with the list of possibilities and then you can select the one that is appropriate for you.

The second is that I seem to have a bunch of albums that aren't available on iTunes. If an album isn't available, there's no cover art for it. Bummer.

All is not lost, however, since iTunes has a mechanism to load cover art images from disk. The only question was "where would I get the images?"

Of course, I knew that Windows Media Player keeps track of cover art images, so I figured that if I could find out where they were stored on my computer, I could just use WMP to find all of the missing images. So, I went through the effort of trying to find those images.

After much searching the internet, I discovered that the images are kept in the album folder in a file called Folder.jpg. Of course, these are hidden files, so I first had to modify the folder view options in order to be able to see them.

Somewhere along the line, it occured to me that going to Amazon, looking up the album, and saving the cover art image to a local file would be a lot easier. It also wasn't too much later that I discovered that I can simply paste a cover art image into iTunes, rather than loading one from disk.

I still use iTunes to find the cover art first. If the correct image cannot be found, I then go to Amazon and get the correct image.

One day, I happened to look at the Nano while it was playing a song and noticed the evil default cover art image. I was a little confused about that, since I knew that I had installed the correct cover art image. And thus another little idiosyncrasy with iTunes was revealed.

When you have iTunes download cover art or your opt to add it in yourself via the "Get Info" option, the image is only attached to whatever songs you currently have selected. Ultimately, this makes perfect sense, but what confused me is that I would click on the first song and use iTunes to fetch the image, which would eventually be revealed. However, sometimes only portions of the album art would be revealed. By clicking on the other songs in the album, additional portions would be revealed. I have no idea why iTunes does this, but it led me to believe that the album art was attached to all songs in the album. Apparently not.

Once I had figured out that I need to select all songs in the album first, everything has been fine, and I'm able to collect my cover art with ruthless efficiency.

Sunday, April 13, 2008

iPod Chronicles - Part 3: Using the iPod

Once I got some songs copied over to the iPod, it was time to demo the unit and see if I had thrown away my money or not.

The interface on the iPod itself is pretty intuitive, as you would expect from a finely-honed Apple device these days. The screen is sharp, the colours are nice, the font is readable.

I really like the click-wheel, although I must say that sometimes it misbehaves a little bit on me. Sometimes I'll scroll through to a particular item, yet when I remove my finger, the selection changes to either the item before or the item after.

I'd heard some horror stories about Cover Flow not working all that well on the Nano, but I have to say that it seems to work pretty well for me. There are times when you scroll through the albums really fast and the Nano hasn't had a chance to load in the cover art in time - maybe that's what they were referring to. I haven't seen Cover Flow on an iPhone, so I have no previous reference for correct behaviour.

Of course, the most important aspect of the Nano is the sound quality. I'm no audiophile (if I was, would I be using MP3s in the first place?), but the sound quality on the Nano seems pretty good to me. Definitely better than the iRiver. Earbuds/headphones make a lot of difference, so it could just be that the earbuds that come with the Nano are better than the ones that came with the iRiver. In any case, I'm very happy with the audio quality.

One thing that the iPod can do is normalize the volume from the various tracks. Depending on how you have iTunes set up (or how your MP3s were originally created), the volume levels from all of the tracks may be different. With the flick of a virtual switch, the Nano will supposedly adjust the volume levels from track to track to keep them consistent. I've tried this briefly, but I have to say that I wasn't all that thrilled with the results. I'll definitely do some additional testing, but I have a feeling that I'll get better results by configuring iTunes to do the normalization at rip time.

A totally useless feature that I like anyway - when you select a source category (music, podcasts, movies, etc), the Nano will start up a slideshow using the various cover art that you've supplied (or opening frame to a movie or whatever).

I showed nervousness about iTunes in the previous posting, but now I see why it wants to be the keeper of all things. iTunes takes all of that song data and uploads it to the iPod, allowing you to see all of that information, as well as search for songs based on title, artist, album, and composer. I tend to just do album searches, but it's still nice to have the option.

Video playback was not really much of a factor in my choosing the Nano - the idea of watching a movie on a 2-inch screen wasn't appealing in the least. However, since it had the functionality, I figured I've at least test it out.

You can't just put any video onto the Nano - it first needs to be in the correct format. iTunes supposedly will convert a video automatically when you import it, but so far I haven't been able to get that to work. Unable to get a video onto the Nano, I did some googling to see what I could do. It turns out that there are all kinds of video convertors for the Nano.

I found a free one called Videora, installed it, and gave it a whirl. I didn't want to wait around all day for the conversion to finish, so I selected the Robot Chicken Star Wars double-episode for the test source. I used all of the default settings in Videora and let 'er rip.

It took a while, but eventually it finished. I loaded up iTunes and the newly-converted video appeared in the video library (which is how I knew the auto import stuff wasn't working, because it never showed up on the library). I synced up the Nano and there it was in the Movies menu. Not expecting much, I started up the video.

I was amazed.

Yes, it's still a rinky-dink 2-inch screen, but I was amazed at how watchable the video really was. I don't think I could watch a lot of stuff on it, but I could probably sit through a movie on a flight.

Of course, the converted videos only look good on the Nano screen. If you use iTunes to view the video, the quality is quite awful.

Unfortunately, the iPod seems a little unstable at times. For the first little while, I never had any problems with it at all. I think I had to "reboot" the thing only once. However, once I got the Nike+ kit (see parts 6, 7 and 8), I found that I had to "reboot" at least a couple of times a week.

Sometimes the iPod seems a little slow, too, like the CPU has been maxed out or something. I'll turn it on and try to use the click-wheel, but the scrolling is delayed. I'm not sure why this happens, but it's only sometimes.

Hopefully future versions of the firmware will address some of these issues.

iPod Chronicles - Part 2: iTunes

One of the things that sort of bothered me about getting an iPod is that I knew I would have to use iTunes to manage my files. Although I had to use proprietary apps to get songs onto a media player in the past, they tended to merely be conduits and let me do pretty much whatever I wanted. I'd heard lots of horror stories about iTunes over the years, but lots of friends with iPods told me that the latest iterations of the app are pretty decent. So I bought the iPod, with some mild trepidation about signing my life away to an Apple application.

Having said all that, iTunes is a decent piece of software, but it can be pretty infuriating at the same time.

When I first started it up, it asked me where my music files were kept so that it could import them into the iTunes library. That was cool, since I was going to have to do that anyway.

What's not so cool was that as soon as I plugged the iPod into the USB port, iTunes immediately tried to copy my entire music library onto the iPod. On the surface, that's probably not all that bad, but automatically trying to copy about 15 gigs of music over to the iPod without once asking if I really wanted to do that is probably bad form.

There are some things about iTunes that I find a little aggravating.

The first is that it grabs the very first cover art image that Apple offers up (based on the CDDB listing for an album). I wish there was a way to be able to search for the correct image (as it turns out, I found a better way - see part 4).

Second, iTunes seems to be limited in the length of a filename, resulting in filenames (which are made up of track number, artist, and song title) being chopped off. It doesn't affect the MP3 track info within iTunes, but it's annoying.

Third, the idea that a compilation album is somehow different from regular albums. If an album is tagged as being a compilation, it gets put into the "Compilations" sub-folder. Again, this doesn't really affect anything, but why??

Of course, there's lot about iTunes that I really like.

I really like how iTunes will automatically ask to import and convert a CD as soon as you put one into the CD drive. What's even nicer is that it asks first if that's what you really want to do. It's too bad this behaviour isn't a little more consistent throughout the interface.

I'm completely impressed at the speed at which iTunes will rip a CD. In the past, I've always used a program called CDEX, which I've always found to be excellent, although a little on the slow side. It wouldn't be unusual for a CD to take about 20 minutes to rip. iTunes, however, can rip a CD in 4-6 minutes.

I love the whole podcast system. I love being able to subscribe to a podcast and have iTunes automatically check for, download, and sync new programs. I also like how it detects that you haven't listened to a particular podcast in a while and stops downloading new episodes until you start listening again.

Finally, there's also lots of stuff that I haven't really messed with yet, such as playlists. On-the-go playlists are interesting, although I find using the iPod itself to generate the playlist is a little time-consuming. I typically just find a genre or band that interests me and turn on shuffling.

All in all, iTunes is an interesting app and I hope it only improves going forward.

Saturday, April 05, 2008

iPod Chronicles - Part 1: Selecting the iPod

I've always had a portable music player of some sort since about Christmas of 1983 when I got my first Walkman. I've gone through times when I was a heavy user and times when I hardly ever used it at all, but I've always had one available.

When I started training for the marathon back in 2005, I started thinking that it might be nice to have listen to music while I was running. Everything I have is on CD now and I don't think I actually have a functional tape deck, so I figured that I'd take the plunge and get myself an MP3 player.

iPods were all the rage at the time, but they were prohibitively expensive, so they were off the list right away. There were all kinds of other models available at the time, but I didn't really know a whole lot about them.

Long story short, I opted for an 512mb iRiver 700 series, mostly because a couple of friends had iRivers and were reasonably happy with them. It was interesting because you could very easily drag-and-drop MP3s to and from the player, even though you had to use the iRiver manager program. The sound quality was lacking, but it was good enough. And it came with an armband.

I never really used it for running because I found it difficult to listen to music and run at the same time, but I did use it a lot for all of the air travel that I was doing at the time.

As you can well imagine, 512mb doesn't really hold a whole lot of music. It wasn't much of a chore to copy music back and forth from the player, but it did mean that I had to think about what I might want to listen to on a flight.

* fast forward to mid-2007 *

I was doing a LOT of travelling at this point and figured that I could use a player with a little more room on it, so I started some research.

Basically, I was looking for something with around 16gb that had decent audio quality. Lots of players now can do video as well, but I didn't really care about that. The idea of watching a movie or whatever on a 2-inch screen didn't really appeal to me. I also needed to be able to find some sort of strap or armband for it, since I was hoping to try using it for running (again, even though that didn't work in the past).

iPods had some down in price considerably since I last looked at players, but they were still at a premium compared to other units. I researched some other players, but the only other one that made any sort of impression was the SanDisk Sansa e200, which has all of the same functionality as an iPod, but is considerably cheaper.

I hummed and hawed for quite a while, trying to decide what to do. During this time, I decided that I wanted a player that did not use some sort of hard drive for storage. An hdd-based player probably doesn't have any skipping problems, but I didn't want to have to deal with that in a high-impact environment (such that running would provide). That eliminated all of the video iPods, leaving only the Nano and Shuffle. The shuffle doesn't have enough storage, so it was off the list. That left the Nano and Sansa.

Also during this time, a couple of friends who have iPods also started talking about the Nike+ kit they were using for their running. This obviously intrigued me and definitely had me leaning towards the Nano.

It was around this time that Apple was going crazy with the new iPhone. I have no interest in the iPhone whatsoever, but what is important is that shortly after the introduction of the iPhone, Apple announced that some new iPods were coming, including a new Nano. The new Nano looked very interesting to me, but without being able to actually see the thing, I still couldn't make up my mind. The smaller size was appealing, as was the better display. Sure, it was supposed to be able to play video, but I didn't care about that.

Eventually the new iPods were available for purchase and I headed over to Future Shop to take a look. There they had the new Classic, Nano, and Shuffle. Not only that, but they actually had power (a rarity), allowing me to play with the menu.

I immediately grabbed the Nano and the first thing that I really liked about it was the size and shape. It fit in my hand perfectly. I worked through the menu and I was pleasantly surprised with the interface and how good everything looked. I played with the cover flow stuff (there were a handful of albums on it) and was surprised by the performance of it (I had previously read that the cover flow stuff was pretty sluggish).

All in all, I was pretty happy with what I saw.

I continued to do some research into the Nike+ kit, and the more people told me, the more I liked it. The scales were finally tipped in favour of the Nano and I decided that that's what I would have.

Andrea and I had discussed getting a new MP3 player and we decided that it would be a Christmas gift for me, so I was going to have quite a wait. I tend to be pretty patient about that kind of stuff, so it wasn't going to be that big of a deal.

However, something about having it now totally resonated with me. I had been saving up some money anyway, so I went out and bought it, telling Andrea that it would be an early Christmas present and that she was not to get me anything substantial (to which she abided!). I also bought the official Apple Nano armband at the same time (which turned out to be perfect, since it has two "settings" - one for the plain Nano and one for the Nano and Nike+ sensor).

I ripped open the (minimal) packaging, hooked it up to my laptop, copied over some songs (sort of - iTunes started copying over my entire MP3 collection), and had a listen.

I've been happy ever since.

iPod Chronicles

I bought an iPod Nano back in October 2007 (well, whenever the 3G Nanos came out) and I am absolutely delighted with it. Sure, there have been a few hiccups, but overall it's been a fabulous device for me.

From the time I got it, I've been making notes about my various experiences with it, both good and bad. I've always intended to post those thoughts and experiences here, but as you can see, I'm pretty lazy and I'm only just getting to finally formalizing those notes.

Over the next couple of days, I will be posting an 8-part series on my experiences with the iPod, including iTunes and the Nike+ running kit.

I hope you find the information interesting.

Thursday, January 24, 2008

Nike+ test

This is just a test post to see if people can access my Nike+ running profile. This is subject to disappear at any time.

Tuesday, January 01, 2008

Another year, another post

Merry New Year!

No, wait, that's not it.

Ho-hum New Year!

No, no. Uh... gee...

Oh, wait, I've got it!

Happy New Year!!

Or something like that.

Ok, so it's a new year, which means that it's time to come up with some new year's resolutions. As I've said in the past, I tend to think that resolutions are mostly silly because it is usually only a matter of (a short) time before those resolutions are broken/forgotten/ignored. I'm not particularly interested in self-improvement, but I do have a small set of goals for the year.

Number 1: More guitar practice. As I suspected, getting the Godin really encouraged me to play more. Of course, it also highlighted the fact that, despite hacking away at it for seven years, I still can't play the damned thing. I'm going to try to find a way to get in at least 1 hour of practice in a day. This is one that Andrea probably won't be too happy about, but I'll try to find some way to do this without impacting her time too much. :)

Number 2: Another marathon. I ran the Bluenose marathon back in 2005 (as I talked about lots here) and I've been trying desperately to run another one, but something always gets in the way. In 2006, I was sick for about 4 months, making training impossible. In 2007, I was sick for almost 6 months and ended up off the continent for race weekend. I'll be starting up my training tomorrow (Jan 2nd) and hopefully I'll stay healthy this time through. If not, I'll try for one of the summer or fall marathons. My knees aren't too happy these days, so this may be my last kick at the can.

Number 3: Finish the damned DVD inventory system. I've been working on this thing off and on (mostly off) for the last 4(?) years now. I've been using this as a tool for learning/using new technologies. The problem is that it is taking so long that technologies change before I finish. It started out just going to be some sort of Perl-based app. Then it was going to be JSP. Then I decided to use Struts for the GUI. Then Struts 2 came out. I'm hoping a Struts 2 book becomes available soon, since it's been hard to find the documentation I'm looking for online. At this rate, even Duke Nukem Forever will be released before I finish.

Number 4: This one is a bit of a stretch goal - more writing. In particular, more blog updates. I come up with things I want to write about all the time, but writing is a slow process for me. I'm also still wrestling with the scope of this blog. My life isn't interesting enough to be any sort of diary. I like technology and various "toys", so I'd like to focus on those topics whenever I can. Certainly, I'm hoping to do better than one post every 4 or 5 months. :)

See? That's a pretty short list, and there's nothing too outrageous there. Let's see how I do.