04 January 2012

How To Add An Existing Git Project to Eclipse



Here's another quick set of notes for myself for posterity. I always clone and build a project on the command line before I import it into the IDE to begin hacking code. Right now I have to handle a hairy merge so I need a visual tool to make things a bit easier. For this purpose, I want to make Eclipse git aware so that I can use the visual diff in the IDE. Hopefully these notes will help out someone else, too.

For this situation I'm dealing with a Java project that uses git. First some quick items to set the stage:

  • IDE:For Java development, my IDE of choice is the SpringSource Tool Suite (STS). If you develop Spring-based Java apps and you like Eclipse, you should really be using STS.
  • SCM: The majority of projects I have worked with over the last few years use git for SCM. It is vastly superior to any other SCM tools I've used and documentation abounds for it, but it is a bit like a razor blade.
  • IDE+SCM: The standard git tool for Eclipse is EGit


To make the Eclipse project git aware, follow these steps:

  1. Go to Window->Show View->Other
  2. In the filter field, enter the word git
  3. Select Git Repositories and click OK
  4. Click on the icon whose tooltip reads 'Add an existing local Git Repository to this view'
  5. Click on the browse button and navigate to the directory that contains the project source code
  6. Click the Search button
  7. Click OK
  8. Right-click on the project in the Package Explorer
  9. Go to Team->Share Project
  10. Select Git and click Next
  11. Check the box for 'Use or create Repository in parent folder of project - this should automatically find the .git directories
  12. Click Finish and let EGit complete the integration


After following these steps, the projects should be connected to their git repository. This allows you to handle the vast majority of git commands right from inside the IDE.

For more info about EGit, check out the EGit User Guide.

02 January 2012

Developing Apps for Mac OS X With Objective-C and Cocoa



Even though I've used Macs for over 20 years now, I have never developed a native app for the Mac OS. So over the holiday break, I finally spent some time getting ramped up on Objective-C to develop apps for Mac OS X and IOS. This meant reading a lot about Objective-C, XCode and Cocoa.

I'm primarily a Java developer these days but I'm familiar with writing C code (though I haven't written it in many years) so this knowledge helped me quite a bit. The syntax for Objective-C was a bit strange at first but I got the hang of it after a bit and I'm continuing to learn. I managed to develop a command line app and a GUI app using XCode. Building the command line app was much more understandable for me because you are writing all the code by hand. Constructing the GUI app was a rather nebulous task mainly because you rely upon the IDE to handle many things for you. XCode is the IDE for building Objective-C apps for Mac OS X and IOS. When developing a GUI app, XCode provides a visual tool called Interface Builder that is amazing. It provides a standard set of widgets for your apps and allows you to do visually design the UI. Interface Builder simplifies the creation of connections from the code to the GUI widgets via dialogs and selections in those dialogs. Because the actual code to handle these things is hidden behind the IDE, the experience was rather cloudy in my mind. At some point, I plan to dig down into what is actually happening behind the curtain here to solidify it in my mind. I also used the XCode debugger and profiler which were both very nice tools and were both included in the IDE.

I forgot to mention that I am using Objective-C 2.0 and XCode 4.2. This is not only a new release of Objective-C but it's also a new release of XCode with a dramatically improved set of functionality. My prior experience was with XCode 3.x, it was minimal and I was not writing Objective-C, so I didn't really get to experience the power of XCode. Now that I've been through a couple of tutorials with XCode 4.2 and Objective-C, I must say that I'm duly impressed. In fact, Eclipse could stand to learn a few things from XCode. Objective-C 2.0 is a big improvement over the previous version. There's now automatic reference counting to help you with memory management (the big thing I hated about C/C++) and much more.

The apps I created run on Mac OS X. They are both very minimal and not very useful overall, but it is invigorating to delve into new territory for a platform that I have known and loved for over 20 years already. I plan to keep at it as time allows and build some useful apps. Perhaps I will even develop some IOS apps.

For those who are interested, here are the two tutorials that I followed:

I've also been reading many blogs from Objective-C and Cocoa developers. I also found some items for Java developers who want to learn Objective-C:

I will try to keep adding info about resources here as I think about them. Not only is this a record for myself, but hopefully it will help other folks as well.

19 September 2011

Installing PostgreSQL 9.0 on Mac OS X 10.6.8 via MacPorts



While installing PostgreSQL 9.0 on Mac OS X again, I had to figure out all these steps yet again. So I'm documenting this process for my own sake because I have been through this now twice on two computers recently, having to hunt down all of these commands each time. I'm hopeful that this will help others as well.

Use the MacPorts command port to install PostgreSQL 9.0, then create and own a data directory and a logs directory:

$ sudo port install postgresql90-server
$ sudo mkdir -p /opt/local/var/db/postgresql90/defaultdb
$ sudo chown -R postgres:postgres /opt/local/var/db/postgresql90
$ sudo mkdir -p /opt/local/var/log/postgresql90
$ sudo chown -R postgres:postgres /opt/local/var/log/postgresql90

Now you need to initialize the database using the data directory that was created above:

$ sudo -u postgres /opt/local/lib/postgresql90/bin/initdb -D /opt/local/var/db/postgresql90/defaultdb

I prefer to change the postgres user's shell to bash:

$ sudo dscl . -create /Users/postgres UserShell /bin/bash

View the postgres user account just to make sure it all looks OK:

$ dscl . -read /Users/postgres
AppleMetaNodeLocation: /Local/Default
GeneratedUID: 5B38F583-CBBF-4082-A32D-C17947394A27
NFSHomeDirectory: /opt/local/var/db/postgresql90
Password: *
PrimaryGroupID: 501
RealName:
PostgreSQL-90 Server
RecordName: postgres
RecordType: dsRecTypeStandard:Users
UniqueID: 502
UserShell: /bin/bash

Also check the postgres group:

$ dscl . -read /Groups/postgres
AppleMetaNodeLocation: /Local/Default
GeneratedUID: 715FEB22-D0F1-443F-BC93-55896210DB44
Password: *
PrimaryGroupID: 501
RealName: postgres
RecordName: postgres
RecordType: dsRecTypeStandard:Groups

Now edit the pg_hba.conf file to add the appropriate permissions:

# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust

This should allow you to connect easily using the psql utility.

I prefer to use the pg_ctl command to start and stop PostgreSQL. This is simply because I learned PostgreSQL on Linux and that's all there was. To prevent having to retype the full command every time I want to start or stop the database, create a start script and a stop script in the postgres user's home directory named pg_start and pg_stop. Below are the contents of the pg_start file. Make sure to create these files as the postgres user in the home directory:

$ sudo su - postgres
$ vim ./pg_start
#!/bin/sh
/opt/local/lib/postgresql90/bin/pg_ctl -D /opt/local/var/db/postgresql90/defaultdb -l /opt/local/var/log/postgresql90/postgres.log start &

Below are the contents of the pg_stop file:

$ vim ./pg_stop
#!/bin/sh
/opt/local/lib/postgresql90/bin/pg_ctl -D /opt/local/var/db/postgresql90/defaultdb -l /opt/local/var/log/postgresql90/postgres.log stop

Don't forget to make them executable:

$ chmod +x ./pg_start
$ chmod +x ./pg_stop

(There is a Mac OS X way of starting PostgreSQL using launchctl but I don't tend to use that because I'm used to the standard pg_ctl command.)

Now use the pg_start script to start up PostgreSQL. Execute it as the postgres user (sudo su - postgres) I tend to cat the log file just to make sure it's running correctly:

$ ./pg_start
$ server starting

$ cat ../../log/postgresql90/postgres.log
LOG: database system is ready to accept connections
LOG: autovacuum launcher started

Looks good so we'll create my user:

$ /opt/local/lib/postgresql90/bin/createuser bsnyder
Shall the new role be a superuser? (y/n) y

Because I made my user a superuser, I can create my own db schema, so log out of the postgres user account and back to my own account first:

$ exit
$ /opt/local/lib/postgresql90/bin/createdb
CREATE DATABASE

The createdb command automatically uses my username as the schema name.

The only thing left to do before starting up the database is edit your ~/.profile or ~/.bash_profile to put the path to the PosgreSQL bin directory into the PATH:

export PATH=/opt/local/lib/postgresql90/bin:$PATH

Now just log into the PostgreSQL server using psql to make sure we're ready to roll:

$ psql
-bash: psql: command not found
bsnyder@skunk [darwin](DARWIN-1527) $ /opt/local/lib/postgresql90/bin/psql
psql (9.0.4)
Type "help" for help.

bsnyder=# select version();
version
------------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 9.0.4 on x86_64-apple-darwin10.8.0, compiled by GCC i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664), 64-bit
(1 row)

bsnyder=#

And we're good to go!

03 August 2011

Courage Classic Charity Ride 2011, Even Better Than 2007



Every year I ride in a three-day cycling event in the Colorado Rocky Mountains named the Courage Classic. I participate in this ride every summer because it benefits the Children's Hospital Foundation, a wonderful cause that directly benefits many kids with life-saving care. To find out more, check out the website.

In 2007, I wrote about riding the Courage Classic with my oldest daughter. That was a wonderfully proud moment for me as a parent. But this year was even better.

For months now, my youngest daughter has been talking about riding the Courage Classic family day this year. We were never sure if she would actually do it or not, but we worked up to it by practicing and kept encouraging her. Not only did she ride the same little single-geared bike that her older sister rode over the 33 mile course from Copper Mountain to Breckenridge and back, she did it a year earlier -- and she's only eight years old!!! What really drove her, I found, is that she is one year younger than her older sister when she rode it for the first time. Ah, sibling rivalry has its positive moments. All along the entire course, people cheered her on and she got the biggest thrill from it.

Not only did my eight-year-old ride for the first time, so did my wife and she did great. She's typically a runner and only likes casual bike riding, so I wasn't sure how it would go. A few days beforehand, I took her around Turquoise Lake near Leadville, CO (which is about 10,000 feet of elevation) as a training ride. She was not too excited by this choice as the last training ride for her, but she did admit that it helped her prepare and she really surprised me.

So I got to ride with both my daughters and my wife on the second day of the ride this year. A memorable day indeed!

02 August 2011

The iPhone is Not a Submarine But Apple Made My Day



This morning I got up at 5am to ride up Flagstaff Mountain with a friend. Soon after I got up I dropped my iPhone in water, totally submerging it. Great. What a wonderful start to my day. Obviously this rendered the phone completely dead. Excellent. So I rode this morning with my old iPod Shuffle, so that wasn't a big deal. But I didn't have a clock so I took my wristwatch and put it in my jersey pocket.

In my second hour of riding I pulled the watch out of my jersey pocket (pockets are on the back of a bike jersey) and I dropped it on the rode. When I circled back and picked it up, I realized that one of the pins had bent and needed to be replaced. Not a big deal really as I've had this happen many times over the years. And there's a jewelry place right near the Apple Store I typically use. Still, that's strike number two for the day. I rode the third hour just waiting for the third bad thing to happen, but it never did.

I just returned from the Apple Store and I'm glad to say that I was quite happily surprised. This phone was covered under AppleCare but it doesn't cover dropping your phone in water. Matteo at the Flatirons Crossing Apple Store informed me that Apple has a policy of leniency when it comes to your first major accident with your iPhone so he was able to basically give me a get out of jail free card and save me $200 (the cost of replacing an iPhone 3GS). What a surprise!!! I was prepared to pay the cost of replacement and be on my way. So I was very pleasantly surprised.

As Matteo was filling out the necessary forms for the replacement, we chatted a bit. He asked me if I upgraded to Mac OS X Lion yet. I explained that I had not because I was speaking a conference in Portland last week and I didn't want to chance any issues with my laptop until that was done. This led him to asking me more about speaking at conferences and what I do for a living. After explaining that I'm a software engineer at VMware, his response was, 'We all love VMware Fusion!" I agreed and explained that I use it often for testing and running other operating systems on Mac OS X. He said that folks inside Apple really prefer VMware because it's so reliable, which was nice to hear.

Before leaving, I asked Matteo to help me find the AC adapter that plugs into the end of a USB cable. I left one in my hotel room in Portland last week so I needed to replace it. Unfortunately you cannot buy just the AC adapter, you must buy a new USB cable as well. But Matteo said, 'Hold on a minute, I'll be right back.' A minute later he returned with the very AC adapter I needed and said, 'Here you go, free of charge. Because you work for a cool company that we love. And I can see that you need a change of luck today." Wow! Yet another pleasant surprise!!! I think this might be a good day after all. Thanks, Matteo!

12 July 2011

Triple Bypass 2011



On Saturday I rode the legendary Triple Bypass. Although this is the 23rd year of the event, this was my first year to participate and I completed it in 8h 10m riding time and I actually felt pretty good afterwards.

The weather forecast called for thunderstorms throughout the day along the entire route. But I had a good run of luck and it didn't rain for nearly the entire day save for some sprinkles here and there. This was my biggest worry because once you are soaked your core gets cold, it's very difficult to warm it up again (I've experienced this before and the only thing that can warm me back up again is a big, hot cup of tea in my water bottle).

The Triple Bypass begins in Evergreen, CO (elevation: 7,220ft) and goes over three mountain passes:
  1. Juniper Pass, elevation: 11,130ft
  2. Loveland Pass, elevation: 11,990 ft
  3. Vail Pass, elevation: 10,617 ft
These make for over 10,000 feet of elevation gain through the day. Although I had a riding jacket with me, on both Juniper and Loveland passes, I could see my breath and I was shivering, so I stayed only long enough for a bio break, bananas and water, then I took off again (except for Loveland Pass where there was no aid station). The ride ends in Avon, CO making the total mileage 120 miles (check out the route map).

By the time I made it to Copper Mountain and started the ascent up Vail Pass, I realized that my time was cutting short -- I had paid for a shuttle ride back to my car in Evergreen and it was scheduled to depart Avon at 5pm. So I didn't take it easy going up Vail Pass and I made it to the top at 3:55pm still with about 32 miles to go. After waiting in line for a bio break, and refueling as quickly as I could, I left the top of Vail Pass at 4:09pm. I pushed it all the way down the west side of Vail Pass and continued all the way through Vail, CO. I was lucky enough to hook up with another dude and we wound up taking turns drafting for one another, hammering the entire way. Just beyond Vail but before Beaver Creek, CO, my legs began to give out a bit, so I had to ease up some. At that point I tucked in with a group of four other riders and drafted again. But to keep up with them I had to muster the last ounces of power I had left in my legs to raise my cadence a bit to keep up. As we sailed through Beaver Creek, I was counting down the miles, just hoping that I was going to make it (I hadn't checked the time since I departed Vail Pass). We pounded on to Avon, around the corner to the finish and I stood up to drive it home.

I immediately saw the transportation tent and headed there. Upon checking in, to my surprise, I found that I had actually made it - the bus had not yet departed back to Evergreen! As I checked in I looked at the time and it was 5:11pm. I had covered just over 30 miles in 1 hour! Although it was mostly downhill, it was still a tremendous amount of work after a long day, but I made it! I only had time to grab my bag from the luggage truck, no time for a bio break or even to grab water or food and the bus was off, headed back to Evergreen.

As we crested Vail Pass, all of us on the bus were noting the number of riders that were still coming down the west side of Vail Pass and still climbing up the east side. Just then, the clouds suddenly opened up and it was an utter downpour. One bus companion said, 'Better them than me, dude!' My comment was, 'Oh that sucks bad, I've been there before!' because I have been caught in the same spot in another event twice during a downpour, so I know from experience that that meant downright misery.

After dozing on the bus ride back, I picked up my car, stopped to gobble down a burrito and headed home. My wife was sorry that she and my girls could not be along the route at various locations throughout the day for mental support as they usually are, but I understood and knew ahead of time that they couldn't be there. She asked me if I'd do it again and my response: 'Yes, definitely!' What a ride in the beautiful Colorado Rocky Mountains!

BTW, there were many riders I spoke to during the day who were doing the inaugural Double Triple Bypass. That is, on Saturday you ride 120miles from Evergreen to Avon and then on Sunday you turn around and go back. Maybe I will consider doing that next year, we'll see.

08 July 2011

Commercial Vendor Spreads FUD About ActiveMQ



It has come to my attention that a particular commercial integration and messaging vendor is actively spreading FUD about ActiveMQ.

In an official letter that was sent out yesterday, this vendor called out numerous aspects of ActiveMQ, claiming that each is a problem with ActiveMQ and their product 'resolves all of these issues'. Only one of the items mentioned in the list holds any merit. So let's first take a look at the letter and then I will address each item in turn:

Here is the official letter that was sent by the company's media relations:

============================================================
<quote>
From: Fiorano Software
Date: Thu, Jul 7, 2011 at 6:22 PM
Subject: Graduating from ActiveMQ for Enterprise Class Messaging

Dear Joe ,

If you are an ActiveMQ user, you may very likely be experiencing some or all of the following issues:

1. Poor Performance or limitation on speed - particularly for persistent queues and topics.

2. Stability issues or loss of messages, specially with clustering enabled.

2. Poor Documentation - difficult to quickly find what you're looking for or even with paid support you are unable to troubleshoot the problem.

3. Poor Reliability - when a broker goes down, do clients auto-reconnect when the broker comes up again?

4. Inadequate Technical Support - No clear directions/answers from Technical Support - for instance, if you wish to perform memory tuning, do you get clear instructions promptly?

5. Inability to handle "peak loads" - when there's a peak-load condition, does the broker tend to fail?

6. Scaling only with new hardware?

FioranoMQ resolves all of the above issues. With Fiorano, you have the best performance in the industry (for both queues and topics, persistent and non-persistent), responsive and accurate technical support, proven reliability, solid documentation and enterprise-class scalability — all of which adds up to dramatically reduced development and deployment times, with a maintenance cost lower than that of ActiveMQ and other open-source offerings.

To get started, download FioranoMQ now, at http://www.fiorano.com/downloads/login.php?prod=fmq
or contact us via email or phone to get more information.

Regards,
The Fiorano Team
info@fiorano.com
+1-408-354-3210

</quote>
============================================================

Just so you are clear, I did not write this letter. It is an official message sent out by the commercial integration and messaging vendor. Not only has this vendor posted the message on their website:

http://www.fiorano.com/newsletters/ActiveMQ_Issues_July_2011.html

They even tweeted about it:

http://twitter.com/#!/FioranoGlobal/status/89193558032134144

(Yes, I know those are not live URLs. I refuse to provide a live links to be picked up by the Google spider.)

So now let's walk through each point in this message, providing some discussion as we go.

Claim #1: Poor Performance or limitation on speed - This is rather broad statement and I'm sure that's on purpose. The idea when spreading FUD is to be as broad as possible. This way your statements can act as a catch-all for any problems that a user might be experiencing and loop them in based more on emotion rather than fact.

ActiveMQ can certainly provide poor performance if it is not configured correctly. You can do the same with any software that is not configured correctly. From time to time, I have dealt with performance related issues with ActiveMQ on consulting engagements. As I comb through configurations and code to take a look at a situation, many times I find that either the broker or the client are not configured correctly or there's something about the user's code or application design that plays into this scenario. Occasionally a user has asked about providing a better configuration out of the box for ActiveMQ to address a given problem. The answer is that we already do -- ActiveMQ distributions provide a configuration out of the box that should support middle of the road use cases. Problems arise with specific use cases or in a specific environment, etc. There are far, far too many use cases to provide a single configuration that will work with anything anyone might ever dream up.

Claim #2: Stability issues or loss of messages, specially with clustering enabled. - Loss of messages? Really?! Do you think if ActiveMQ actually lost messages that it would be as popular as it is? But blaming the clustering is ingenious for one single reason -- most users don't know enough about the ActiveMQ clustering that they are apt to believe that this claim is true. The only scenario where a user might perceive that messages have gone missing is one where messages get stuck on a particular broker in the cluster. Again, configuration plays a big role in getting clustering set up correctly as does proper application design.

Claim #3: Poor Documentation - This is the only claim that holds any truth, but it's only really half true. The ActiveMQ documentation is certainly lacking. However, the ActiveMQ website does hold a wealth of information. The real problem with it is finding what you need. Although some vendors who provide support for ActiveMQ have attempted to provide improved docs (e.g., notably the documentation for the Fuse Message Broker). This is exactly why Rob, Dejan and I wrote a book about ActiveMQ titled ActiveMQ in Action. We're quite proud of the book because it does provide markedly better documentation for ActiveMQ. If you need better info on ActiveMQ, pick up a copy.

Claim #4: Poor Reliability - when a broker goes down, do clients auto-reconnect when the broker comes up again? - This particular claim makes it clear that this vendor has little to no knowledge of ActiveMQ. This is exactly why the ActiveMQ failover transport was created. In short, the failover transport provides a JMS client automatic reconnection in the event that an ActiveMQ broker goes down or just becomes unreachable. The failover transport is extremely configurable in order to deal with many different scenarios including the ability to delay the initial reconnection, to set a max number of reconnect attempts, to exponentially increase the wait period between attempts and much more. In the ActiveMQ 5.4 release, the failover transport introduced a new feature to provide automatic cluster updates and broker rebalancing to JMS clients. The failover transport is highly powerful and strongly recommended, so I'm surprised that this was overlooked.

Claim #5: Inadequate Technical Support - Based on the vendors listed on the ActiveMQ support page, there are now at least five companies providing support for ActiveMQ. And I even know of a company that provides support which is not listed there, Savoir Technologies. If you are paying for ActiveMQ support and you are not happy, I encourage you to either speak to your vendor about it or find one that works better for you.

Claim #6: Inability to handle "peak loads" - This is a claim against ActiveMQ that I have never once heard from a user. They are essentially asking you if at the time where your business experiences a spike in the amount of messages it is handling, does ActiveMQ fail on you. Yet again, if you are truly experiencing this, then you need to take a serious look at your system design. I have helped many customers successfully address issues of scale through a number of means including some intelligent sharding of JMS client connections across a cluster of ActiveMQ brokers, use of a virtual IP address and even use of a load balancer. If ActiveMQ had a habit of failing for users during peak loads, I would have heard about it at least once.

Claim #7: Scaling only with new hardware? - This claim is similar to claim number 4 and really makes it clear to me that whoever compiled this list is not familiar with ActiveMQ. Did they bother to search the ActiveMQ site? Here is just one page on the site from the FAQ titled How do I configure 10s of 1000s of Queues in a single broker ?. Furthermore, Rob, Dejan and I clearly explain how to scale ActiveMQ both vertically and horizontally in our book. Again, this really depends on the situation and the environment, there is no single silver bullet solution.

Addressing each of these claims was actually quite easy for me to do. And I hope that each of the vendors providing professional consulting services and technical support for ActiveMQ are aware of the tactics being used by this commercial integration and messaging vendor. It sounds to me like ActiveMQ has become a real threat to this vendor's business.

I will leave you with a quote:

"First they ignore you, then they ridicule you, then they fight you, and then you win."
— Mahatma Gandhi