Welcome to Planet Eclipse

January 07, 2009

Antoine Toulme
Antoine Toulme

Eclipse just had a japanese smoothie

The huge contribution made by the Blanco project, sponsored by NEC, and watched over by Mori-San, was effectively added to the Babel database today.

Thanks to everyone for your hard work on making this happen.

Antoine Toulme
Antoine Toulme

The Union of The CheckBoxTreeViewer TreeItems : We shall be disabled together, or die in single combat!

Dear committer, prepare your jFace-foo !

We have a case where we have a CheckBoxTreeViewer that represents a list of elements.

The list in itself is informative. The user is going to be very interested into what is selected, and what isn’t.

It’s certain that at some point he will expand the tree to look at some nodes, come back, etc.

Right now, you cannot disable the checkboxes of a CheckBoxTreeViewer without disabling the whole tree.
So that means that your users cannot check checkboxes (that was the intent), but they also cannot expand the tree.

What if you’d like to disable some checkboxes only ? That’s unsupported too.

Unfortunately, there is no solution for this problem so far. I filed 259092 earlier today to investigate the issue, and it seems you can try to add a listener to revert the check event when the user clicks on checkboxes. Users would still see the items as enabled though, and given the complexity of the interface, adding a tooltip, a new decoration is just going to be confusing.

If you have a spare vote to cast for this bug, a comment, and idea, and ideally a patch, let’s talk about it on the bug!

January 06, 2009

BUG Community
BUG Community

R-OSGi, or how to call OSGi services remotely: Part I

When learning OSGi and discovering the power and simplicity of the service registry, a common thought is "Oh, I want to use this service remotely...how can I do that?"  And, well, currently the answer is you can't!   While there is active work going into remote services in R4.2, the existing OSGi specification only defines what happens inside of a single JVM instance.  But what if you really want to remote your OSGi? One sweet solution is R-OSGi

The BUG runs the Concierge OSGi framework, and happily it was written to support R-OSGi, but other frameworks should work as well.  The HOWTO will cover installing R-OSGi on the BUG and Virtual BUG, creating a service server and client.  A forthcoming post will detail service discovery and "seemless" distributed apps.  If you don't have or care about BUG, this HOWTO works great on regular Java on regular machines.  So, continue on to learn about R-OSGi!

1. SDK Setup

Make sure you have the latest version of the SDK.  Now download the "Remote OSGi" application from BUGnet into the SDK.  Your SDK should look something like this:

created on: 01/06/09

Now you'll notice that there are some compiler errors.  This is because R-OSGi requires the Event Admin, an OSGi service designed for pub/sub messaging.  Let's install the event admin application from BUGnet.  Search for and download Event Admin.  Your workspace should now look like this:

created on: 01/06/09

 

 

Now let's start the Virtual BUG and use the console to see if our new bundles are running.  Type 'bundles' at the Concierge prompt.  Here is what I got:

created on: 01/06/09

Great!  Now our Virtual BUG has R-OSGi!  Let's now install Remote and EventAdmin on the BUG.  Simply connect the BUG and download the apps.  Notice how the R-OSGi bundle does not show up in the applications folder on your BUG.  This is because it's not designated as a "BUG Application".  You can add the header "Bug-Bundle-Type: Application" to the manifest to make it show up.

2. A Remotable Service

Now R-OSGi is running both on the real BUG and the Virtual BUG.  Let's create a service, a bundle that exports the service, and a bundle that consumes the service.  We'll deploy the server to the BUG and consume it on the Virtual BUG.  To keep things simple, we'll create a service that has one method that returns a string.  Notice that we add one property to the service to let R-OSGi know that we want to make it accessible by remote clients.

Activator.java: package serviceproducer; import java.util.Dictionary; import java.util.Hashtable; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import serviceproducer.pub.RemoteServiceDefinition; public class Activator implements BundleActivator { private ServiceRegistration sr; public void start(BundleContext context) throws Exception { Dictionary d = new Hashtable(); d.put("service.remote.registration", Boolean.TRUE); sr = context.registerService(RemoteServiceDefinition.class.getName(), new RemoteService(), d); } public void stop(BundleContext context) throws Exception { sr.unregister(); } }

RemoteService.java: package serviceproducer; import serviceproducer.pub.RemoteServiceDefinition; public class RemoteService implements RemoteServiceDefinition { public String getMessage() { return System.getProperty("os.arch"); } }

RemoteServiceDefinition.java: package serviceproducer.pub; public interface RemoteServiceDefinition { String getMessage(); }

The app is here on BUGnet: http://buglabs.net/applications/ServiceProducer  Now let's install the app on the BUG via the SDK.  After installing, type "services" at the OSGi console on the BUG.  You should see your new service registered:

(: services ... 31 serviceproducer.pub.RemoteServiceDefinition service.ranking = 0, service.remote.registration = true,

 3. A client that consumes a remote service.

Now let's create our client bundle.  Create a new BUG application and call it ServiceConsumer.  Again to keep things simple, we will not get fancy with our consumer. 

Activator.java: package serviceconsumer; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import com.buglabs.application.IServiceProvider; import com.buglabs.application.RunnableWithServices; import com.buglabs.application.ServiceTrackerHelper; import serviceproducer.pub.RemoteServiceDefinition; public class Activator implements BundleActivator, RunnableWithServices { private ServiceTracker st; public void start(BundleContext context) throws Exception { st = ServiceTrackerHelper.createAndOpen(context, RemoteServiceDefinition.class.getName(), this); } public void stop(BundleContext context) throws Exception { st.close(); } public void allServicesAvailable(IServiceProvider serviceProvider) { RemoteServiceDefinition svc = (RemoteServiceDefinition) serviceProvider.getService(RemoteServiceDefinition.class); System.out.println("The Remote Message: " + svc.getMessage()); } public void serviceUnavailable(IServiceProvider serviceProvider, ServiceReference sr, Object service) { } }

Now you should be able to run a Virtual BUG and see this all working (locally).  In the log output you should see something like: "The Remote Message: i386"   Funny, I'm not using a 386.  Oh well.

This, as it is, will not work as remotable.  There are ways to add other things that will allow this bundle, as is now, to be able to consume a remote service.  This is the very powerful aspect of R-OSGi and will be covered in the next installment. 

For now we'll need to simply tell R-OSGi how to get our remote service.  Here is our new activator.  Notice we are tracking the Remote OSGi Service and a NetworkChannelFactory.

Activator.java: package serviceconsumer; import java.io.IOException; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import com.buglabs.application.IServiceProvider; import com.buglabs.application.RunnableWithServices; import com.buglabs.application.ServiceTrackerHelper; import serviceproducer.pub.RemoteServiceDefinition; import ch.ethz.iks.r_osgi.RemoteOSGiException; import ch.ethz.iks.r_osgi.RemoteOSGiService; import ch.ethz.iks.r_osgi.RemoteServiceReference; import ch.ethz.iks.r_osgi.URI; import ch.ethz.iks.r_osgi.channels.NetworkChannelFactory; public class Activator implements BundleActivator, RunnableWithServices { private RemoteOSGiService remote; private URI connURI; private ServiceTracker st; public void start(BundleContext context) throws Exception { st = ServiceTrackerHelper.createAndOpen(context, new String [] {RemoteOSGiService.class.getName(), NetworkChannelFactory.class.getName()}, this); } public void stop(BundleContext context) throws Exception { st.close(); } public void allServicesAvailable(IServiceProvider serviceProvider) { remote = (RemoteOSGiService) serviceProvider.getService(RemoteOSGiService.class); connURI = new URI("r-osgi://10.10.10.10:9278"); try { RemoteServiceReference[] svcRef = remote.getRemoteServiceReferences(connURI, RemoteServiceDefinition.class.getName(), null); if (svcRef != null && svcRef.length > 0) { RemoteServiceDefinition svc = (RemoteServiceDefinition) remote.getRemoteService(svcRef[0]); System.out.println("Remote Service: " + svc.getMessage()); } else { System.out.println("Service unavailable."); } } catch (RemoteOSGiException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void serviceUnavailable(IServiceProvider serviceProvider, ServiceReference sr, Object service) { remote.disconnect(connURI); } }

Notice I'm connecting to my BUG which is connected via USBNET on a static IP address of 10.10.10.10.   9278 is the standard R-OSGi port.  In my service tracker, I get a reference to the remote service and then get a reference to a RemoteServiceDefinition implementation. 

But wait, there is a problem!  When the Virtual BUG starts you will notice an error message: ch.ethz.iks.r_osgi.RemoteOSGiException: No NetworkChannelFactory for r-osgi found. at ch.ethz.iks.r_osgi.impl.RemoteOSGiServiceImpl.connect(RemoteOSGiServiceImpl.java:564) at ch.ethz.iks.r_osgi.impl.RemoteOSGiServiceImpl.getRemoteServiceReferences(RemoteOSGiServiceImpl.java:620) at serviceconsumer.Activator.allServicesAvailable(Activator.java:41) at com.buglabs.application.ServiceTrackerCustomizerAdapter.doStart(ServiceTrackerCustomizerAdapter.java:69) at com.buglabs.application.ServiceTrackerCustomizerAdapter.addingService(ServiceTrackerCustomizerAdapter.java:94) at org.osgi.util.tracker.ServiceTracker$Tracked.track(ServiceTracker.java:815) at org.osgi.util.tracker.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:747) at ch.ethz.iks.concierge.framework.Framework.notifyServiceListeners(Framework.java:1227) at ch.ethz.iks.concierge.framework.Framework$BundleContextImpl.registerService(Framework.java:1916) at ch.ethz.iks.concierge.framework.Framework$BundleContextImpl.registerService(Framework.java:1937) at ch.ethz.iks.r_osgi.impl.RemoteOSGiActivator.start(RemoteOSGiActivator.java:93) at ch.ethz.iks.concierge.framework.BundleImpl.startBundle(BundleImpl.java:446) at ch.ethz.iks.concierge.framework.Framework$SystemBundle.setLevel(Framework.java:2468) at ch.ethz.iks.concierge.framework.Framework$SystemBundle.access$0(Framework.java:2428) at ch.ethz.iks.concierge.framework.Framework.startup(Framework.java:485) at ch.ethz.iks.concierge.framework.Framework.main(Framework.java:315)

What's happening here is that our ServiceTracker is running before R-OSGi is fully loaded.  Unfortunately in the current SDK (1.2.2) there is no way to fix this, because you can't set bundle start order.  However you can simply restart the bundle after everything has been loaded and it should work, like so:

(: stop 18 ServiceConsumer: active -> resolved (: start 18 Remote Service: armv6l ServiceConsumer: resolved -> active

And viola!  You've called a OSGi service on the BUG from a Virtual BUG.  Notice my machine is now an armv6l. 

In summary we've covered the basics of R-OSGi: calling a service remotely.  This, however, isn't as cool as it could be.  First of there seems to be more code than necessary to do all this, and I have to hardcode the connections from client to server.  Don't fret because R-OSGi has more tricks up it's sleave to relieve these problems!  Stay tuned for the next post in the R-OSGi HOWTO!

 

Sven Efftinge
Sven Efftinge

EMFatic implemented in TMF Xtext (Screencast)


Michael Clay is working on a TMF Xtext implementation of EMFatic (see this screencast).
He's also prepared a screencast showing template proposals on Martin Fowler's DSL example.

We'll show more of TMF Xtext at EclipseCon in march.

Denis & Karl
Denis & Karl

Karl and I will be at EclipseCON

Karl and I will both be at EclipseCON this year, representing the Eclipse Webmasters. Karl will be there for most of the systems support (download mirror, registration system, badges, etc) and I’ll be there for Phoenix (Eclipse website), infrastructure and Babel talks and BoFs.

EclipseCON is always a fun time, and I always attend as many technical sessions I can.  The depth of Eclipse knowledge at that conference is simply amazing, and I always discover new and cool stuff related to Eclipse. Plus, meeting up with old friends, and making new ones, is infinitely cool.

Thankfully, Matt will be staying here in freezing cold Ottawa to make sure all the servers work, and to take care of everyone who unfortunately can’t make it out to California.

See you there!

Annamalai Chockalingam
Annamalai Chockalingam

Eclipse Con 2009 - Me Speaking there !!

Hey Guys !!
Meet me @ Eclipse Con 2009 ... Me looking forward to my 1st visit to Eclipse Con in Silicon Valley. Looking forward to meet you all as i proudly bring to you the ever growing Eclipse Ecosystem in India under a short talk http://www.eclipsecon.org/2009/sessions?id=242

Also would be a great opportunity to present ANCIT, an Indian Eclipse Company.
Thanks for your support. Looking forward to meet you all @ Eclipse Con 2009.

Regards
Malai

Dave Carver
Dave Carver

XSL Tools Adopters

There is a new wiki page for those that are adopting XSL Tools in their own project or applications. If you are using XSL Tools in a project or commercial application please consider adding some information to the XSL Tools Adopters wiki page.

This information will help the committers on the XSL Tools project to get a better guage of the plugins use and where it is being used. With this information we can help better plan and prioritize our efforts to better serve the entire user community.

Wayne Beaton
Wayne Beaton

Tom Schindl and the Future of Nebula

In this video recorded at Eclipse Summit Europe 2008, Tom Schindl, new co-lead of the Eclipse Nebula project, discusses the future of the project.

EclipseLive
EclipseLive

Tom Schindl and the Future of Nebula

Wayne Beaton (Eclipse Foundation)
 
Abstract:
In this video recorded at Eclipse Summit Europe 2008, Tom Schindl, new co-lead of the Eclipse Nebula project, discusses the future of the project.

Total running time 01:05 minutes


delicious delicious | digg digg | dzone dzone

Jan Koehnlein
Jan Koehnlein

Proposal for new Eclipse Project: EMF Index

In the Modeling Symposium at Eclipse Summit Europe 2008 we discussed the necessity of an index for EMF models. Such an index would allow efficient queries for EMF model elements without actually loading the model resources, which is an enabling feature for powerful EMF modeling tools.

The proposal is now online. Please use the EMFT newsgroup for discussion. I am looking forward to your feedback.

Nick Boldt
Nick Boldt

The EMF Bible, New Testament

As you may have heard last month from Ed, the book EMF: Eclipse Modeling Framework, 2nd Edition is out now. Order now and get free shipping and an online copy too.

warning label generator

Tasktop Team
Tasktop Team

Vancouver Eclipse DemoCamp

The love of camping, for many, is rooted in the experiences we had as kids being dropped off in the great outdoors for a week of fun, food, and friendship. We'd learn how to create shelter from branches and fire without matches; survival skills we'd hopefully never have to rely ...

Tasktop Team
Tasktop Team

Mylyn is turning Japanese

While Mylyn will happily display other languages and character sets coming from the task repository, the Mylyn UI has never been internationalized. The Eclipse Babel project has provided a great service by enabiling the community to contribute translations. But to support Babel, a project needs to update its ...

January 05, 2009

Seva Lapsha
Seva Lapsha

Aptana “steals” PDT code

Long time ago I set up Google alerts to receive new search results related to myself. And today I’ve discovered that Aptana steals prepares derivative work of PDT code.

The only visible “derivation” there is they changed package names, though. :)

EclipseLive
EclipseLive

Upcoming Event: Introduction to Eclipse PHP Development Tools (PDT) 2.0

Event Date: January 21, 2009 9:00 am GMT-8

Register Now

Roy Ganor (Zend)
 
Abstract:

Fully compliant with Eclipse standards, the new PHP Development Tools (PDT) 2.0 release enables developers to leverage a wide variety of Eclipse projects, such as Web Tools Project (WTP) and Dynamic Language Toolkit (DLTK), for faster and easier PHP development. PDT is an open source development tool that provides all the code editing capabilities needed to get started with developing PHP applications.

Join Roy Ganor, Zend Studio Project Leader at Zend, as he demonstrates the tool and new features including creating a new project, source editing, code assist, type hierarchy, mark occurrences, PHP search and more.


delicious delicious | digg digg | dzone dzone

Prakash G.R.
Prakash G.R.

Commands Part 2: Selection and Enablement of IHandlers

 

In the last tip, we saw that a Handler can be declared separately from a Command. This enables for multiple handler declarations for the same command. We can also customize when a handler is active and visible, thru plugin.xml itself. A handler that doesn't have any of these conditions is called as "default handler". When no other handler is associated with a command in a particular context, then the default handler will be the handler that gets executed. Remember, at any given point of time, there is at most only one handler is associated with a command. Lets have a look into how a particular handler is selected for a given context.

A handler can be specified with activeWhen condition using the expression language. Say for our command, we have two different handlers. One should be active when the current selection is an IFile and the other should be active when the current selection is IFolder. The expression for these would look like:

<handler
      class="com.eclipse_tips.commads.SomeCommandHandler1"
      commandId="com.eclipse-tips.commands.someCommand">
   <activeWhen>
      <with
            variable="selection">
         <iterate
               operator="or">
            <instanceof
                  value="org.eclipse.core.resources.IFile">
            </instanceof>
         </iterate>
      </with>
   </activeWhen>
</handler>
<handler
      class="com.eclipse_tips.commads.SomeCommandHandler2"
      commandId="com.eclipse-tips.commands.someCommand">
   <activeWhen>
      <with
            variable="selection">
         <iterate
               operator="or">
            <instanceof
                  value="org.eclipse.core.resources.IFolder">
            </instanceof>
         </iterate>
      </with>
   </activeWhen>
</handler>

I'll save the explanation for the expression language for a separate tip, but for now a short one line desc: the first handler will be enabled when the selection current contains at least one IFile and the second handler will be enabled when the selection contains at least one IFolder. This raises to two questions.

1) What if the selection is just an IProject?

In this case, as none of the handlers are eligible, the command is disabled. This is where the default handler, if you have provided one, would be associated with the command (and the command will be enabled).

2) What if the selection contains both IFile and IFolder?

Now both the handlers are equally qualified to handle the command. But since the framework cannot pick one randomly the command is simply disabled. Even if you have provided a default handler, it won't be associated with the command, because the other two handlers are more specific than the default one.

How is the "specificness" of a handler is defined? It depends on the conditions that you give in the activeWhen expression. The order is defined in the ISources class. You can go thru the complete set there, to get a glimpse of the most commonly used ones, the order from least specific to most specific is like this:

  • Active Context (activeContexts)
  • Active Actions Sets (activeActionSets)
  • Active Shell (activeShell)
  • Active Workbench Window (activeWorkbenchWindow)
  • Active Editor Id (activeEditorId)
  • Active Part Id (activePartId)
  • Current Selection (selection)

If a handler has activeWhen defined with active context and the other one with current selection, the second one will be selected as the selection is more specific than the active context. The activeWhen for all the handlers are evaluated and the one that returns true for the most specific condition is selected. When two handlers return true for the available most specific condition (like the selection having both IFile & IFolder in our case), no handler will be associated with the command.

All these things are done without even loading your handler in the memory. Even without loading your plugin! 

In the previous tip, we saw how a handler is selected with the activeWhen expression, when more than one handler is declared. Now assuming a handler is selected, whether to enable the command or not, is determined by the enabledWhen expression.

In our previous example, we saw the handler that is active when the selection at least contained one IFile. Now lets we want to enable it only when the total count of the selection is 2. We can specify it as:

<handler
      class="com.eclipse_tips.commads.SomeCommandHandler1"
      commandId="com.eclipse-tips.commands.someCommand">
   <activeWhen>
      <with
            variable="selection">
         <iterate
               operator="or">
            <instanceof
                  value="org.eclipse.core.resources.IFile">
            </instanceof>
         </iterate>
      </with>
   </activeWhen>
   <enabledWhen>
      <with
            variable="selection">
         <count
               value="2">
         </count>
      </with>
   </enabledWhen>
</handler>

So the handler will be active and associated with the command, if the selection contains at least one IFile. Still the command will be enabled only if selection has exactly 2 elements. activeWhen and enabledWhen are similar - with respective to the expression language and lazy loading of the plugin until the command is executed. But there is small difference - your handler might be loaded iff the enabledWhen expression returns true and your plugin is already loaded. The enablement algo works this way:

  • No enabledWhen specified, plugin is not loaded - command is enabled
  • No enabledWhen specified, but plugin is loaded - consult handler.isEnabled() and set command accordingly
  • enabledWhen specified, returns false, command is disabled (no matter plugin is loaded or not)
  • enabledWhen specified, returns true, plugin is not loaded - command is enabled
  • enabledWhen specified, returns true, plugin is loaded - consult handler.isEnabled() and set command accordingly

So far we saw commands, handlers and their enablements. But what about generalizing a command? That can be done by adding parameters for a command. And that would be the next tip in this series.

Doug Gaff
Doug Gaff

Tech Support for Geeks

Over the holiday break, I waited on the phone 30 minutes to hear a tech support person sing Celine Dion in my ear while telling me to reset my cable modem.

Ok, let me back up a bit.

I switched to a new Cable/Phone/Internet provider last week. You know the drill – the promotional period expires on your current plan and your monthly bill goes up 30%. Fortunately, there are two Cable providers (Comcast and RCN) in my town, and Verizon FiOS is coming this year. Hooray for competition, although would it kill these companies to just make the promotional price the regular price and keep me as a customer? Oops my bad. I forgot that Capitalism = bilking money from as many customers as possible for as long as possible.

Anyway, post-install my internet kept dropping for a couple of seconds every few minutes. This "feature" really upset my Software VPN client. Plus, I was nowhere near the peak bandwidth provisioning for my new service. So I placed the dreaded call to Tech Support. After 30 minutes, I get the aspiring American (ahem) Idol contestant singing Celine under his breath while telling me to reset my modem. Um, thanks dude. Can we try something else? He says I have to call back when the connection is down. I reply that hitting a 2 second window might be tough with a 30 minute call wait time. Long story short: threatening call to salesperson, visit by computer-savvy tech, removed hardware, and things are working.

<sigh.> I hate Cable companies, perhaps even more than I hate Cellular companies.

Attention service providers of the world: I, and vast numbers like me, know more than every single one of your first line tech support people. I will pay you extra money to let me talk to a real engineer when I have a problem. Save Celine for my grandmother.

Eclipse Enthusiasts Poznań
Eclipse Enthusiasts Poznań

Eclipse Debugger, part III

Let's continue our tour through the features of the Eclipse debugger. In the last parts (Part I, Part II) I was writing mostly about breakpoints and this time won't be any different. When we look at the views provided by the debugger we will find

the Breakpoints view.


The main purpose of this view is to manage the breakpoints - it allows to easily (going from left to right through the buttons on the view's toolbar):

  • remove selected breakpoints - I guess it's self explaining
  • remove all breakpoints - I guess it's self explaining
  • show breakpoints supported by selected target - when you debug different kind of artifacts (code in java or C or ant build script) you can make the Breakpoints view show only the breakpoints that are supported by this type of the given artifact [Thanks Jacek for helping with figuring this out!]
  • go to the file for breakpoint - it will show the place where the breakpoint is set in the editor
  • skip all breakpoints - when you don't want any breakpoint to be active check this option
  • add java exception breakpoint - I was writing about this in the first part
More cool features can be found in the view's menu, you can:
  • group the breakpoint by many criteria, e.g. type, project, files, etc.
  • define breakpoints working set
  • check the option to show qualified names in the view
The view allows you also to change the breakpoints' properties directly from the context menu - just right click on any breakpoint and you would see the options to:
  • change the hit count value
  • make the breakpoint suspend the VM or suspend the thread
To finish the breakpoints story it has to be said that breakpoint can be imported and exported - you can open the appropriate wizards from the Breakpoints menu or from the File->Export->Run/Debug->Breakpoints option.

Is there anything I have missed about breakpoints? Please, share!

That's it for this week - next time I will focus on the Variables view, which is essential for efficient debugging.

Nick Boldt
Nick Boldt

The Group Of Seven

Seven things about me, as inspired by Roy's tag:

  1. In just under 3 weeks I've become utterly obsessed with my Blackberry. My wife, who at first was apprehensive of hers (along with all new technology), has been using it non-stop as well. It's been a good text'mas. :)

  2. My wife and I live with two American Pointers, two horses*, three laptops, two smartphones, and many, many usb peripherals. The office is the warmest room in the house.

  3. My day job consists of maintaining and improving the build systems for JBoss Tools and JBoss Developer Studio. My night job involves numerous Eclipse projects, including Modeling and Dash. Basically, I hibernate in the winter in front of the computer.

  4. My parents - divorced - are of Jewish/American (dad) and German/Canadian (mom) decent. They've now been separated longer than they've been together. With the subprime mortgage crisis in the US, he recently moved back to Canada to seek more gainful employment. Unfortunately, he chose Calgary which isn't faring much better, now that gas prices are finally coming back down. My mom now lives in Scaborough near us, having returned from her self-imposed escape to Vancouver, and is more or less retired.

  5. I graduated from the University of Waterloo back in '99 with a BASc in Chemical Engineering, having spent the balance of my last two years learning about programming, workflow design, process control, and optimization. In retrospect, it seems I was always headed for release engineering.

  6. Much like Andi Gutmans, I too hate shaving... but as I work from home, I can get away with not doing so for days at stretch. I love my 30-second commute to work, which offsets my 8-to-10-hour workdays quite nicely. Why commute 2-plus-hours a day when you can use that time to get real work (or at least email) done? Thankfully, more and more companies are realizing this and are letting us work remotely.

  7. I try to find time - when not working or hacking - to walk my dogs, hike, cycle, kayak & swim: sometimes several in series. One favourite route involves cycling from my house to the beach at maximum speed, swimming in the lake to cool off, then portaging the bike up the side of Bellamy ravine and home. This past season I rode over 750KM and kayaked over 75KM, mostly in and around Toronto, Scarborough and Pickering.

So, then, here are 7 more in this chain, in no particular order...

  1. Opal Aristizabal, tech writer and Insight driver
  2. Jamie Callingham, one of the few teacher-types I know who actually has time to maintain a blog
  3. Alain Cloutier, graphic designer with a slightly insane blog, two great kids, and horse-addicted wife. He and I share a similar pain -- horsefolk are a special (wonderful) breed of crazy. :)
  4. Kenn Hussey, IBM ex-pat and blogger with great frequency, especially this past Blaugust.
  5. Wassim Melhem, overworked - but always well-dressed - project manager
  6. Julia Raphael Morgan, opera singer sans blog at the moment...
  7. Andrew Overholt, Linux evangelist and fellow cyclist

And here are the rules I'm supposed to pass on to the above bloggers:

  • Link your original tagger(s), and list these rules on your blog.
  • Share seven facts about yourself in the post - some random, some weird.
  • Tag seven people at the end of your post by leaving their names and the links to their blogs.
  • Let them know they've been tagged by leaving a comment on their blogs and/or Twitter.

* - The horses don't live with us, thankfully -- it's someone else's job to feed and muck them.

Doug Schaefer
Doug Schaefer

Zune 30, Killed by Complexity