Archive for the ‘Personal’ Category

I’m a Rogue

Saturday, June 7th, 2008

I’m delighted to announce that I’ve been hired as Rogue Amoeba Employee 008. (Employee 007 is Longwell, Justin Longwell.) I’ll be working on Rogue Amoeba’s apps as a software engineer, as well as providing comic relief. Thanks to Alex, Paul, and Quentin for this once-in-a-lifetime opportunity. My coworkers at Rogue Amoeba Software, LLC include fellow bloggers Mike Ash and Guy English. Together we form perhaps the most talented group of Mac programmers outside of Apple. (Yes, I’m talking to you, Adobe and Microsoft.) Indeed, I haven’t seen such an array of stars in one place since the Ghostbusters music video.

I’ve joined Rogue Amoeba just in time to miss WWDC ’08. In an earlier post, I mentioned that I left Marko Karppinen & Co. LLC just in time to miss WWDC ’07. (I’ll make it there someday! :-( ) The question is, what have I been doing in the meantime? Backpacking through Europe? Rotting in Gitmo? Running for President? No, I’ve been working on super-secret projects for Francis Technical Services, LLC. Although FTS is a little-known company, its software is well-known, at least inside Apple. For example, FTS is responsible for Radar, the Apple-internal Cocoa app that opens when employees click on the funny-looking rdar://problem/ URLs you often see. The number at the end of the URL corresponds to the problem ID of the bugs you file on the web with Apple Bug Reporter (also known as RadarWeb). It’s useful to have one of these URLs available when communicating with Apple engineers, because their managers forbid them from lifting a finger without a Radar problem number.

While at FTS, I did some bug analysis for Radar: that is, analysis of bugs in Radar’s source code, not analysis of bugs in Radar’s database, to which as a contractor I had extremely limited access. However, I mostly worked on other projects, such as Radar’s sibling app Sonar. Apple’s DTS uses Sonar to communicate with ADC members (such as me!). If you’ve ever seen sonr://request/ URLs — the Mighty Quinn provides one in an Apple Mailing List post — those open in Sonar. (By the way, I’ve read all of your emails to DTS. No, you haven’t been accepted to the iPhone Developer Program. Stop whining.) Another project that I worked on was Merlin, an app for Apple’s Human Resources department. I think that Steve Jobs is doing an outstanding job at Apple, so before I left I used Merlin to double his annual salary.

I’d like to thank Dave Francis, the owner and founder of Francis Tech, for the opportunity to work there. Despite appearances, I’m not really the type to hop from job to job. I’ve just been looking for Mr. Right, LLC, a company to fall in love with, marry, and have baby apps with. (As for any other support claims, sorry Billie Jean.) I can see myself growing old with Rogue Amoeba. (Easy to see when you’re already old?) Besides, someone has to stick around and keep an eye on mikeash, stop him from taking over the world.

Now without further ado, please take out your credit card and buy some of our fine software. As a special bonus for our Leopard customers, your purchase will be (code-)signed by your favorite Rogue Amoeba star.

Cocoa Blogs free, as in beer

Sunday, March 30th, 2008

Wait, beer is not free! Or so my bartender yelled last night as I ran out the door. (I also had one bourbon and one scotch.) The front page of Cocoa Blogs was already free, but the syndicated feed has only been free to contributors — kind of like Congress. Now Scott has decided (he is the decider) to make the feed available for free too. Indeed, new items are appearing in the feed. Remember, folks, you heard it here first. This is your Number 1 source for news, rumors, and outright lies.

My own long list of Cocoa blogs, including the Cocoa Blogs feed, can be downloaded for free from the “Favorite Feeds” link in the sidebar of my blog. The list is in convenient .opml format for import into your favorite free feed reader. There seem to be many choices nowadays. (Too bad that they all suck. Mine sucks the least, though.) The contents of my web site have been and always shall be free, as in loader. If I asked for contributions, that would just embolden the terrorists. Last call!

News Flash: Vienna brings down the mighty NewsGator

Wednesday, January 9th, 2008

In an obvious gesture of defeat, NewsGator has announced that they — is a company a collective or an individual? — are no longer attempting to charge money for NetNewsWire. Their cover story is some mumbo-jumbo about “enterprise”. Sure, and Leopard was delayed by the iPhone. ;) What they would never admit publicly is that they realized it was pointless to compete against the best Mac RSS utility on the planet. Who would pay for NetNewsWire when Vienna is free? Not to mention open source! (Oops, I just mentioned it. I take it back.)

Let it not be said, however, that we are without pity for the downtrodden. On behalf of the Vienna developers, I apologize for destroying the commercial feed reader market. What else can I say? Ya gotta do what ya gotta do. Give the fans what they want. The battle has certainly made great entertainment, the classic David vs. Goliath tale. Once again, David (actually Jeff) has overcome insurmountable obstacles, beat overwhelming odds, leapt over tall buildings in a single bound, to emerge victorious. It’s always a thrill to see the underdog win … except the Miami Dolphins.

Yet I shall only allow myself a moment to rest on my laurels, to savor the sweet smell of success. (It smells a little like tequila, actually.) For I’ve already chosen my next target: outliners. Look out, OmniGroup!

WordPress Bug Fix: more props for me

Saturday, December 15th, 2007

Although I abhor self-promotion — much as Roger Federer abhors winning tournaments — someone must take on this thankless task. (I had to fire my publicist, because he had never heard of me.) Thus it is with great regret and sorrow that I announce my latest contribution to the WordPress open source project. It was just one minuscule twitch for mankind, yet one ginormous vault for a man, viz., yours truly.

Now some critics might claim that the security issue was trivial. In my defense, I would argue that critics are doo-doo heads. Except the ones in New York: they all love me.

What ever happened to Cocoa Blogs?

Thursday, November 29th, 2007

It seems dead, though the clock is still ticking. (Countdown to extinction?) Anyway, I’ve just updated my own extensive list of cocoa blogs and other favorite feeds, which you can download from the Downloads section of my sidebar. FileMerge will reveal the changes in my all-important favor. Remember bloggers, X-Mas is coming soon, not to mention Y-Mas and Z-Mas. I’m keeping track of who’s naughty and nice — mostly by intercepting your wireless packets. If you’re nice, you’ll get a hot dog and a shake.

WordPress Bug Fix Near Saturday: props lapcat

Saturday, September 22nd, 2007

The network has decided to renew my series for at least one episode. WordPress 2.3 is approaching release, and I’m pleased with the progress that it has made in supporting syndicated feeds. The patch I submitted to fix the Atom feed modification date bug has been committed to the trunk. RSS 2.0 feeds still don’t give modification dates, but that could be considered a personal preference. (As can RSS 2.0 itself. Of course, no one would prefer the worse to the better, as Socrates would say, if he were 2500 years old and spoke English.)

Other syndication bugs that have been fixed in the trunk include checking the last modified date of posts rather than comments for comments feeds, an obsolete Atom feed template, and checking the last modified date of unapproved comments for comments feeds. WordPress 2.3 should be a good update for feed readers such as you and feed readers such as Vienna.

Time to go. Joan Cusack is calling again.

Fewer feeds, more favorites on average

Sunday, August 19th, 2007

Despite what I said in my comment, I did end up taking Daniel Jalkut’s message to heart.

To an extent. A tad.

Basically, I cleared out some dead and abandoned feeds. I added a few new ones too. Sorry Daniel, I’m incorrigible! I’m also an enabler: for all you news junkies out there, get your fix by downloading the updated opml of my Favorite Feeds, available in the sidebar of my blog. Go ahead, just browse a bit. Once you develop a taste for syndication — by a taste for I mean an addiction to — you’ll need a powerful feed reader. And then … well, that’s about it.

Embedding frameworks in loadable bundles

Saturday, August 11th, 2007

While I worked for Marko Karrpinen & Co. I only made one commit to BaseTen, but as Sappho would say, that one was a doozie! BaseTen is an open source Cocoa framework for PostgreSQL. It has an API resembling Apple’s Core Data framework, which uses SQLite. You can check out the source and build BaseTen.framework as well as the optional BaseTenAppKit.framework and an Interface Builder palette, BaseTenPalette.palette. (By the way, I abhor Interface Builder. Or at least Interface Builder 2. I’ll reserve judgment on Interface Builder 3 until I learn more about it, and only then will I abhor it.) The frameworks are designed to be embedded within your application’s bundle, in the standard location for embedded frameworks: the directory Contents/Frameworks.

An app needs to know how to locate linked frameworks at runtime, so at compile time the app’s executable gets a record of each linked framework’s install name. An install name is, as you should expect by now, not a name. It’s a path, namely, the location of the dynamic library containing the framework’s code. To be exact, the install name is where the library should be at runtime, for a library wouldn’t even need an install name if it just indicated where the library actually is at compile time. Install names enable you to target Panther, for example, while still compiling with Tiger. You can use the command-line otool -D to see that the install name of

/Developer/SDKs/MacOSX10.3.9.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

is

/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

Using absolute paths for install names is fine when your app links against system frameworks, which reside in pre-determined locations, but absolute paths won’t suffice when your app links against embedded frameworks, because the app could be installed almost anywhere in the file hierarchy, e.g., ~/Desktop or /Volumes/MyDistributionDmg. That’s why an embedded framework needs a relative path install name. The BaseTen and BaseTenAppKit projects achieve this by setting the build setting INSTALL_PATH (what else would you do with a build setting but set it?) to @executable_path/../Frameworks. The relative @executable_path is the path to the Contents/MacOS directory in your application’s bundle. When BaseTen is built with that build setting (to answer my last question, you would build with it), the install name of the framework becomes

@executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen

as you can verify with otool -D. Thus, when your app links against BaseTen.framework and records the install name, it can find the framework in its own bundle at runtime.

BaseTen’s IB palette needs to use the BaseTen frameworks too. The problem, however, is that if the frameworks are built to be embedded in an application, they aren’t configured correctly to be embedded in the palette. When Interface Builder launches it will fail to load the palette, logging an error:

Interface Builder[29996] *** -[NSBundle load]: Error loading code /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette for bundle /Users/jeff/Library/Palettes/BaseTenPalette.palette, error code 4 (link edit error code 4, error number 0 (Library not loaded: @executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen
  Referenced from: /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette
  Reason: image not found))

The reason that the image is not found — the reason behind the reason — is that the executable in this case in not actually BaseTenPalette but rather Interface Builder itself, which is trying to load the palette. The @executable_path leads to

/Developer/Applications/Interface Builder.app/Contents/MacOS

but BaseTen is embedded in

~/Library/Palettes/BaseTenPalette.palette/Contents/Frameworks

so the install name doesn’t locate the framework at runtime.

In Tiger, the relative @loader_path was introduced to supplement @executable_path. The @loader_path is relative to the image loading the dynamic library, wherever that image may be. Thus, if we change the install name of BaseTen to

@loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen

and the install name of BaseTenAppKit to

@loader_path/../Frameworks/BaseTenAppKit.framework/Versions/A/BaseTenAppKit

then BaseTenPalette should be able to locate the frameworks when Interface Builder launches. Problem solved, right?

If you’ve already skipped ahead to the end of this post, you’ll know that the problem is not solved. (Spoiler alert: Harry drops out of school to follow Trey Anastasio.) We’ve eliminated one error only to find another:

Interface Builder[2599] *** -[NSBundle load]: Error loading code /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette for bundle /Users/jeff/Library/Palettes/BaseTenPalette.palette, error code 4 (link edit error code 4, error number 0 (Library not loaded: @loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen
  Referenced from: /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/../Frameworks/BaseTenAppKit.framework/Versions/A/BaseTenAppKit
  Reason: image not found))

Whereas BaseTenPalette can now find BaseTen at runtime, BaseTenAppKit cannot. They both have a record of BaseTen’s install name as

@loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen

but they don’t have the same @loader_path.

At this point, you may throw up your hands and throw in the towel, exclaiming Alas, BaseTen cannot have two install names! — or some such exclamation perhaps not suitable for children. (Oh rat farts!). Yet your exclamation would be in vain, because the install name of the dynamic library doesn’t matter after linking. All that matters is the install name recorded in the linked executable, and that can be forged.

Apple provides the nefarious command-line install_name_tool to forge install names for dylibs and give them fake id’s. This is how frameworks get into bars, since there are very few that are twenty-one years old. You can examine the details of my fix in the BaseTen Trac, but basically what I did to allow BaseTenAppKit to find BaseTen was to run the following command in a build phase script for BaseTenPalette:


install_name_tool -change \
	"@executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen" \
	"@loader_path/../../../../Frameworks/BaseTen.framework/Versions/A/BaseTen" \
	"$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH/BaseTenAppKit.framework/Versions/A/BaseTenAppKit"
	

I discovered the correct install name through a stroke a genius, or to put it another way, trial and error. The @loader_path for BaseTenAppKit turns out to be

~/Library/Palettes/BaseTenPalette.palette/Contents/Frameworks/BaseTenAppKit.framework/Versions/A

which makes sense in retrospect, but if you could guess ../../../.. on your first try, you’re a superfreak. Anyway, you can check the install names before and after with otool -l, or succinctly with otool -L.

Caveat developtor: for install_name_tool to work, you may need to build your frameworks with the option -header-pad_max_install_names. BaseTen already does this. See the man pages for more information, man.

What I’ve been doing recently

Saturday, July 21st, 2007

I’ve been asked what I do for a living by a number of my loyal fans. For example, two of my parents. (The third doesn’t care.) Deplorably, I receive no residuals from “The Distinguished Gentleman”, so I guess that I’m a working man. I tried working for no pay, but as rewarding as that was, I couldn’t get my landlord to appreciate the value of my contributions to the open source community. Therefore, I had to sell out to The Man.

The man, in this case, was Marko Karppinen. Marko, you Da Man! Paul, you de Man. When I joined Marko Karppinen & Co., the hazing began immediately: my first assignment was to implement full disk encryption. I also had to purify myself in the waters of Lake Päijänne. I must have passed the initiation, though, because Knox 1.5 is here. It kicks ass! (It sure kicked my ass.) If you don’t believe me, you can download and try it yourself free for 30 days. Launch it from the distribution dmg for kicks. Knox makes encrypting your data effortless, disproving the proverb that you can’t put a price on security. In my opinion, Knox is under-priced, and I’m not saying that because I’m financially compensated by MK&C. Actually, I’m not financially compensated by MK&C.

No, Marko isn’t holding my cats hostage for code. I decided to leave the company recently to pursue another opportunity. Plus, the daily commute to Helsinki was kind of long. I left on good terms, hopefully, and I miss those Pyro-maniacs, my fellow MKCKittens (inside joke). They’re a great group of folks! The strangest aspect of my job was that I never met my coworkers, since I quit right before WWDC. D’oh! I like to imagine that the gang at MK&C is exactly like Dethklok. Did anyone see Toki at the Moscone Center? I guess that makes me Pickles, or maybe the rock & roll clown.

It should be noted that according to my careful tests — I checked my gut and Wikipedia — Knox 1.5 was entirely bug free when I finished. By that irrefutable logic, therefore, any problems that you think you may experience with Knox 1.5 are purely imaginary, and you should ask your doctor about Thorazine. I cannot say the same, however, about that whole Master Control Program I wrote, which got a little out of hand.

My other major project at MK&C was Pyro 1.6. If you use Campfire chat, then Pyro will blow your mind. Or anyway, it significantly enhances the experience. Among the new features Pyro 1.6 introduces is instantaneous switching between multiple chat rooms. (I’m partial toward automatic zip-archiving and uploading of folders and packages.) If you don’t use Campfire, you and your company should give it a try. We used Campfire extensively for internal communication and for customer support.

By the way, there are apparently some problems with Pyro under the deceptively-named Safari 3 beta. That’s not our fault, because Apple released it without any advanced notice to developers. The so-called Safari beta is actually an update to the WebKit system framework, affecting any application on your computer that uses WebKit, not just Safari. The Safari beta has caused problems for other apps too, including Vienna and Apple’s own Mail and iChat, so apparently it was a secret within Apple as well, or they didn’t test it enough. Brutal.

Ranting aside, I’d like to thank Marko for letting me hack on his public-facing apps. Not only would I like to thank him, but I shall. Thanks, Marko! I hope that he and everyone else enjoy the results. Now I must move on and take the next step in my goal of total world domination … by cats.

A nice pair of updates

Sunday, June 24th, 2007

I’ve updated my list of Favorite Feeds, which you can download from the sidebar of my blog. The list is in opml format, so you import it into feed readers such as Vienna. And speaking of Vienna, a new beta version of Vienna 2.2 has just been released. If you’re an intrepid or foolhardy type, you can download it from SourceForge. Beware: this is a pre-release version we’ve released. That’s impossible and therefore pretty scary in itself. Moreover, Vienna 2.2 hasn’t been fully tested. It’s certain to have bugs, perhaps an STD or two. We take no responsibility if your computer decides to start playing Global Thermonuclear War; in that unfortunate event, set the controls for the heart of the sun.