Thursday, December 3, 2009

Rsync with central Maven repository

For reference here is the rsync command to copy files from the central Maven repository.

rsync -v -t -l -r /local/path

Sunday, November 22, 2009

XUbuntu 9.10

I have an old Fujitsu laptop (pentium 3, 256 MB RAM, 20 GB disk) that has gone through a few iterations of various linux distributions. I used XUbuntu 7.04 for a while and it was ok, but it was just too slow. The tricky part is that it has an old Cisco Aironet 360 wireless adapter which only works with a 2.4 kernel (or at least I thought this was the case). I tried out Damn Small Linux, and it's great for what it does, but for my laptop I couldn't get the wireless card or the touchpad working. I tried out various combinations of older versions of Fedora and Ubuntu, but they were always either painfully slow or unable to handle the old wireless card. Fedora 12 was unbearably slow.

I didn't think a recent version of XUbuntu would work, because in the past I was only able to get the wireless working when using a 2.4 kernel. But I'm really glad I gave it a try anyway, because it works! XUbuntu 9.10 was able to find and configure everything on the laptop right away, including my old wireless card. The install process is improved since previous versions, the boot time is faster, and the gnome interface seems more responsive all around.

Big thanks to the XUbuntu guys for all their work on this. Now I have an extra working laptop again!

Friday, July 24, 2009

Ant refid resolution 1.5, 1.6, 1.7

I noticed some behaviour changes in Ant related to refids. In Ant 1.5.x a fileset refid has to be defined before being used. So for example if I define a fileset in target "a" and then call target "b" which uses the refid, the build will fail because target "a" was never run and never set up the refid.

This behaviour changed in Ant 1.6.x, so that Ant tries to be more intelligent and automatically searches for refids that are defined in the build, but not necessarily run. So in the above example, Ant silently succeeds and the refid is found in target "a" even though that target was never actually called. This seems like strange behaviour to me, because it's not well documented and seems like it could produce some tricky bugs. I guess the Ant developers also thought this behaviour was not ideal because in Ant 1.7 the same automatic refid resolution works but now produces a warning. I briefly tried to track down some discussion related to this in the ant developer mailing list archives, but I was unsuccessful in finding anything.

Tuesday, July 14, 2009

Recursive Grepping

I recently had some need to search for certain text within files in a directory. This works with eclipse, but sometimes it can be slow and a bit limited in options. So I turned to good old grep. I wanted to exclude certain directory patterns from the search, but the problem I ran into was that the version of grep packaged with Fedora 10 and available in the yum repository is an older version (2.5.1) and does not include the "--exclude-dir" option. So I had to grab a recent copy of the source. I then did a ./configure, make, make install and I was good to go with version 2.5.4. The last tricky part for me was how to match multiple filename patterns using GLOB. Here is an example of the final command:

grep -R "apache.commons." . --include={*.xml,*.ent} --exclude-dir="output"

Monday, June 29, 2009

Making a Sasuke (Ninja Warrior) Cliff Hanger

After watching the show Ninja Warrior on G4 for a couple years, I finally decided to build my own Ninja obstacle. I thought about what obstacle might be reasonable in effort and cost to build by myself (and with a little help from my friends) and eventually decided on a Cliff Hanger. This is one of the most well known obstacles from the show and probably one of the easiest to build.

Here is a video of my friend practicing on the (almost) finished cliffhanger. Sorry for the low quality:

At this point, I hadn't put the higher ledges on yet, and keep in mind that I purposely built this to be low enough for my 5 year old son to use.

I'm not at all experienced building stuff like this, and there are probably other people out there like me who might want to build there own Sasuke training equipment but aren't sure how difficult it is. So I'll try to give as detailed instructions as possible for anyone that wants to build something like this themselves. The total cost of the project was about $100, and in general I'm pretty happy with the way it came out although there are a few minor things I would change if I could do it again.

Equipment and Materials

  • Drill - Power drill with 1/4 inch wood drill bit.
  • Power Saw - It's possible to have all the cuts done at Home depot or wherever you buy the wood, but it requires some extra up front planning.
  • Power Sander - This is not absolutely necessary, but it comes in handy for sanding rough spots and fitting some of the pieces together.
  • 2 clamps - I didn't use any clamps but they would have been useful when drilling holes for some of the parts.
  • A sawhorse or other item to temporarily bear weight - This is another area where I improvised and just used whatever I had within reach to temporarily prop up the structure while building.
  • A step ladder.
  • 4x8 foot 1/2 inch thick plywood - 1 @ $15 each
  • 8 foot long 2x4 standard studs - 10 @ $2 each
  • 1/4" thick 3-1/2" long galvanized bolts with washer and nut - 8 @ .50$ each
  • 1/4" thick 2-1/2" long galvanized bolts with washer and nut - 10 @ .50$ each
  • Size 12 wood screws 2-1/2" long - 1 box @ $10
  • 4 Small metal L-shaped brackets for attaching two 2x4 wood studs at a 90 degree angle. And 4 nails or screws for each bracket.
  • Outdoor paint (optional) - 1 gallon buck @ 25$
  • 4' long 2x2 (optional) - 2 @ $2
Before you rush out to Home Depot, you may want to think about how large (tall and wide) you want to structure to be. The cliffhanger that I built is a little low for most adults, but the lowest level is just right for my 5 year old. He is about 1-2 feet off the ground when hanging on it, so if/when he falls, he doesn't drop too far. The higher levels are out of my reach (I'm 5'11") when standing on the ground, but when hanging from them, the lower parts of the structure block your body from swinging forward. So it doesn't feel exactly like the real thing, but I don't mind because I don't plan on going to Mount Midoriyama any time soon.

So an alternate construction plan for adults only use would be to buy 10' long 2x4s instead of 8' long. This would make the whole thing a bit taller without any need to change the design. Another option would be to use a plywood that is 10' by 4'. This will give a little more lateral distance and probably feel a little closer to the real thing.

Getting the materials

I bought most of the stuff at Home Depot over several trips as I figured out what I needed. If you have a pickup truck or a friend with a pickup, then you shouldn't have any problem bringing the stuff home. I had to tie the plywood to the top of my minivan which was a pain but it worked.

The plywood is pretty heavy and you should have someone help you when bringing it home. You may want to cut a 6" strip of wood off the bottom of the plywood. This will make the bottom of the plywood a little higher (for more swinging room) and this piece can be used across the bottom for extra support.

When you buy the wood you can have them make some cuts for you to save time. There are 4 upright posts and two base pieces as you can see from the picture. These don't need to be cut.

The diagonal pieces that prevent it from tipping forward or back are just 2x4s that were cut in half. So these can easily be cut before bringing them home.

The stopper pieces that are attached to the upright posts and the base are just 6" long pieces of 2x4. Home Depot wouldn't cut shorter than 1 foot, so I had 4 1' pieces cut, and then I cut each one in half at home to make 8 6" pieces.

The ledges used to hang on are just random lengths and can be configured however you like (different lengths, angles, etc). You should probably wait until the end of construction to make all the cuts for the ledges because you have a lot of options here.

I used 6 1/4" galvinized (prevents corrosion) bolts 3-1/2" long to attach the upright posts to the plywood backboard. Three on each side basically evenly spaced. These seem to hold very well so I wouldn't really change anything here. When you buy the bolts, just put a 1/4" inch washer and nut on each bolt and then you know you will have the right amount of each.

I used size 12 2-1/2" wood screws in various places. For example to hold the stoppers to the upright posts and the base posts.

To attach the ledges to the plywood, I used 2" long 1/4" thick bolts. How many you will need really depends on how you configure the ledges. In the material list I put 10 because this should be enough to get you started.

I spent some time sanding and painting before actually putting everything together in the hopes that my cliffhanger would last against the weather a bit longer. I've seen a couple of rains so far, and it's easy to see how the non-painted parts soak in the water. I recommend buying some outdoor paint if you are not on a strict time/cost budget. Painting was one of the more time consuming parts of the project but if you want your cliffhanger to last for more than 1 year, it's probably necessary.

One last thing to note about the materials, my measurements were not exact. So don't worry if your cuts are not perfect, especially if you have an electric sander.


Step 1 - Sanding, Painting, Cutting.

The first thing I did was sanded and painted the pieces I had. Looking back, I probably didn't need to sand everything, but just removing the really rough spots is probably a good idea. I painted many of the pieces before assembling. Another option would be to just paint the whole thing after it's constructed. Painting at the beginning probably makes it a little better sealed against the elements, but it's more time consuming this way.

As I mentioned in the materials section, you will need 8 6" pieces of 2x4 that can be used as stoppers to hold the diagonal support pieces in place. If you couldn't get these cut when you bough the wood, you will want to cut them now.

Step 2 - Assemble the upright posts.

Lay the plywood onto two 2x4s. Line up the outside edges of the plywood with the 2x4s and then you can drill 1/4" holes for the 3-1/2" bolts. I made three evenly spaced holes for the bolts to go through two 2x4s and the plywood. This photo shows one of the bolts that holds the plywood and upright supports together.

For extra support and to better hold things in place I recommend taking a small piece of the plywood or another 1/2" wide shim and put it between the two upright 2x4s at the bottom. Then bolt them together with the remaining two 3-1/2" bolts. This will help hold the 2x4s in place because they tend to warp.

Next, attach the small 6" 2x4s to the base pieces. I used 2 2-1/2" screws and that seems to work ok.

Step 3 - Attach base to the upright posts.

You will probably need help from a friend for this part, because the cliffhanger is already getting heavy at this point. Prop the lower part of the upright posts at about a 30 degree angle. If you have a couple of sawhorses that would be good, or find a small table stepladder or something else you can use. Line up the base 2x4 so that the center is leaning against the bottom of the upright posts. Drill a thin hole and screw in the base pieces from the bottom so that they are attached to the upright posts.

This next part is important. You should take some small metal L-shaped brackets and use them to hold together the base piece with the upright posts. I didn't do this and it caused me some problems/breakage when I tried to lift the structure upright.

This picture shows that I didn't have the 1/2" shim or the metal L-shaped brackets, and this was the one part of my design that I really made a mistake. Because it didn't hold together well during contruction, and we had to do some fixing afterwards.

Step 4 - Fit the diagonal support pieces.

After you attach the metal brackets, next you'll want to attach two 6" stoppers to the upright posts, and then fit the diagonal support pieces into them. Measure approximately where they will line up, and then make it a little shorter so that you can sand the diagonal pieces until they fit.

You only need to attach the diagonal supports on one side of the cliffhanger, just the part that is currently on the bottom. These are necessary, so that the base doesn't break off of the main posts when you lift the structure upright.

After attaching the diagonal posts on one side, you will need a friend to help push the structure upright, and then hold it up until you attach the second set of diagonal support pieces. With an electric sander you can sand the corners of the diagonal 2x4 to a point so that it fits nicely into the corner made by the stopper.

Step 5 - Attach ledges and decorate.

The last step is to attach the ledge pieces using the 2" bolts. This step is pretty straight forward. Just get on a step ladder and drill a hole through the 2x4 or 2x2 and bolt it on.

And of course you can add a little decoration to the back just for fun.

Please let me know if you have any question about this project. If you build your own cliffhanger I would love to hear about it the comments section and provide some pictures!

Friday, May 29, 2009

JPackage Nonsense

I've never understood the purpose of the JPackage project. As a Java developer one would think I would be in their target audience, but it really doesn't solve any problems for me, and causes many inconveniences. The goal of the project is to package java projects up into nice little upgradable rpms, but I think the java and rpm worlds are really just incompatible. I use Fedora (currently version 10) for my main development environment and I've tried using the prepackaged version of things like eclipse, but it never seems to work as well as the downloadable version.

Just today I was having problems with an Ant build using ant version 1.6.5 (I currently have 3 different versions of Ant installed for testing). I'm getting errors with 1.6.5 that I haven't seen before about missing task definitions. So I run "ant -version" to make sure I'm pointing to the right installation and it returns version 1.7.1. That's weird! So I double check my path "which ant" and check "$ANT_HOME", both are pointing to ant 1.6.5. I end up tracking down that the ant startup script is looking for a file called "/etc/ant.conf" to use as a global configuration file. I don't remember editing this file, but I do remember past experiences with jpackage rpms that do weird stuff to my java applications. Sure enough this configuration came from an rpm and is now breaking my default ant installation.

So the only way to fix this is to either remove the file from "/etc/ant.conf" but the next yum update will probably just put it back and break things again. Or I can hand modify my ant 1.6.5 startup script to not check for this file (very ugly).

I decided to remove the ant rpm "yum remove ant". This fixed my ant installation, but I'll have to watch out for this in the future in case the ant rpm accidentally gets installed again.

Thursday, March 26, 2009

Jar Manifest Attribute Names

I probably should have known this before, but I discovered today that a "." character is invalid for a jar manifest attribute name. The attribute name is limited to:

{A-Z} | {a-z} | {0-9} | - | _

I tried using an attribute name of "java.version" in my jar manifest and the jar was created by the Maven build without any problem, but when the jar was used as a dependency of another project, then I got a warning about an invalid name.

The maven jar plugin and maybe assembly plugin should probably do some regex validation while creating the jar to at least give a warning. Otherwise maven will happily create a jar with invalid manifest and you may not discover this error until it starts causing some problems in other projects. I created a Jira Issue about this.

Wednesday, January 28, 2009

Restore a deleted file from subversion.

If you want to restore a deleted file from svn there are a few ways to do it, and some work better than others.

The subversion book gives the basic info for restoring a file using either merge or copy. However, the method used in the example for copy didn't work for me. So let's say you delete a file "" in revision 100. Then you would want to restore the file, using the previous revision, into the current working directory like this.

svn copy -r 99

My svn server didn't seem to handle the revision option correctly, and kept telling me that the file didn't exist. So an alternative syntax looks like this:

svn copy

This second syntax, which I didn't see mentioned in the svn book, worked like a charm for me.

If you don't know in which revision the file was deleted, you can use svn log in the directory to see a history of file changes.

After you copy the deleted file, you are not quite finished. You'll still have to commit your changes. So something like svn commit -m "Restore file" will finish the job.

Monday, January 12, 2009

RPM for Pidgin msn pecan

Apparently Microsoft changed something on the MSN Messenger servers today, and this was causing problems for many people using Pidgin. One workaround is to use the modified msn plugin from google. But I couldn't find any Fedora rpms for this. So I decided to make one.

The rpm for Fedora 10 is here.
And the source rpm is here.