Full Stack Engineer

What qualifies a software developer as a “FSE” (Full Stack Engineer)? Having a definition is useful because it can help identify skill gaps, it provides context for specializations and provides a map of practices, technologies and tools used at a company and in a software system.

Below is a comprehensive definition of “FSE” that goes well beyond just listing the technologies that a FSE should be proficient in.  It’s a generic list of skills, knowledge and practices that can be applied to different domains and technology stacks.

Generic definition of a FSE:  A software developer who can do the following:

  1. Analyze requirements, formulate a system design and devise an implementation strategy.
  2. Provision and configure the systems necessary to support a solution.
  3. Develop all the components necessary to build a complete solution.
  4. Assure the quality of a software solution.
  5. Deploy a software solution into production.
  6. Monitor and manage the solution in production.
  7. Iteratively develop and deploy new features and improvements.
  8. Evaluate the usefulness of features and components based on usage patterns.
  9. Use observations to make inferences and predictions.
  10. Do all the above in collaboration with other stakeholders and engineers.

The list of skills is surprisingly long, yet incomplete; much more needs to happen to bring a software solution to customers. We omitted product ideation and product management, marketing, advertising, legal work, etc. It’s a rabbit hole, so we’ll stick to the 10 core skills listed above and elaborate on them.

The generic FSE definition can be applied to software solutions in various domains, like mobile applications, desktop applications, home automation, robotics, console games, etc.  Let’s apply it to user facing internet applications.

Definition of a Full Stack Engineer in the Internet Domain:  A software developer who can do the following:

  1. Analyze, design and plan.
    1. Analyze
      1. Identify system inputs, outputs and external interfaces.
      2. Identify user interactions that the system must support.
      3. Define the data that must be collected and stored.
      4. Define data transformations.
      5. Sketch out a user interface.
      6. Maintain a record of requirements and analysis.
    2. Design
      1. Determine an appropriate technology stack.
      2. Identify off-the-shelf systems that can be leveraged.
      3. Determine and design the components that must be built.
      4. Design component interfaces and APIs.
      5. Design data storage schemas.
      6. Design for security, reliability, resilience, scalability, usability, maintainability and configurability.
    3.  Strategize
      1. Prioritize and track requirements.
      2. Break work into appropriate components and phases.
      3. Identify risks and ways to mitigate them.
  2. Provision and configure:
    1. Databases, application servers, compute clusters, LB’s, message queues, backup storage, etc.
    2. Environments for development, QA/staging and production.
    3. Networking between environments and between services within environments.
    4. Additional services required during development and deployment (build servers, source code repositories, etc.)
  3.  Develop:
    1. The “front end” user interface
    2. Develop the online middle tier (controllers, REST APIs, business logic, etc.)
    3. Develop offline processes (data transformation and aggregation, asynchronous event processors, etc.)
    4. Implement security, logging, monitoring, test groups, feature flags, dynamic configuration and artifact updates, monetization, customer support, etc.
    5. Develop code that is secure, reliable, scalable, maintainable, testable, resilient and usable.
    6. Research technologies and solutions and integrate them into the system as needed.
  4. QA:
    1. Devise, develop and execute manual tests.
    2. Develop and execute automated tests.
    3. Test for correctness, load, resilience, reliability, speed, consistency, and throughput.
    4. Log and track bugs and anomalies.
    5. Identify and implement process improvements.
  5.  Deploy:
    1. Deploy all software components to QA and production environments.
    2. Apply configuration changes to QA and production environments.
    3. Automate and validate deploys.
    4. Deploy updates.
  6. Monitor and manage:
    1. Monitor resource usage, transaction counts, throughput, response times, errors, and anomalies.
    2. Implement backup and recovery.
    3. Respond to software and system failures.
      1. Take corrective action to maintain availability.
      2. Perform root cause analyses and implement improvements.
  7. Iterate:
    1. Identify, prioritize and track requirements for improvements.
    2. Modify existing code, configurations and tests to implement improvements.
    3. Evolve code structure, data schemas and architecture to mitigate and manage increased complexity.
  8.  Evaluate:
    1. Identify events and attributes to log.
    2. Log events along with test groups.
    3. Consolidate, combine and aggregate event logs.
    4. Query and analyze raw and processed data.
    5. Calculate statistical significance of events.
  9. Predict:
    1. Select inputs and outputs for predictions and inferences.
    2. Select ML strategies (supervised-, unsupervised- or reinforcement learning) and algorithms (classification, regression or clustering)
    3. Perform offline model training.
    4. Implement online model evaluation and apply it.
    5. Iterate on the above.
  10. Collaborate:
    1. Communicate plans and status.
    2. Garner support, solicit input, adapt.
    3. Identify and motivate prospective stakeholders, build a team.
    4. Manage conflicting priorities.

While the list is still at a rather high level it can be used to:

  1. Identify skill gaps and strengths.
  2. Provide context for areas of specialization.
  3. Create a map of practices, technologies and tools used within a solution space.

Let’s call the map mentioned in bullet #3 a PTT-map: the Practices, Technologies and Tools used to build out a software solution. A PTT-map can be created for a company, a team or software system.  Individuals can also map out their own personal technology stack and also their (best) practices for analysis, design, collaboration, etc.

Using the Full Stack Engineer in the Internet Domain as a starting point, I’d like to now create a PTT-map for a typical user facing web application deployed on AWS, augmented with resources to help learn the listed skills.

I’d appreciate any feedback you have.  What’s missing from the generic definition, what’s superfluous?

WY 2016

Shujie planned a 9 day family road trip to Yellowstone and Grand Teton national parks.  She took care of all the logistics, all the food and most of the packing.  Amelia and I just had to show up, and we were on our way!

We drove from San Francisco to Auburn where we picked up this T@G teardrop trailer:

The back of the trailer holds an outdoor kitchen (see photos below for days 3 and  8).  The inside is really just a bed – but large enough for our family of 3 to sleep very comfortably.

The total distance for the trip was just under 2400 miles, of which about 1700 miles were with the trailer.  We did about 40 hours of driving over the 9 days.

We had a mishap the 2nd day and another on the 3rd-last day; all part of the adventure, though both events could have ended our trip abruptly and badly, we fortunately discovered the problems in time and were able to continue our trip safely.

Here is our route with all the places we stayed over: http://goo.gl/87AI5N

Day 1 (Sunday): We drove from San Francisco and picked up the trailer from http://sierrateardrops.com/. The original plan was to then drive to Winnemucca NV and stay at a KOA campsite there.  However, because of a late start we only got as far as Lovelock – 1 hour drive short of Winnemucca – when we started looking for a place to spend the night.  We then spent about 15 minutes driving through Lovelock looking for an RV site, and another 15 minutes looking for a site at Rye Patch dam.  We couldn’t find a place we wanted to sleep and was then tired enough that we decided to spend the night at a gas station:

It worked out really well.  The gas station was open 24 hours so we could use the bathroom in the middle of the night.  (And it was free!)

We got up early the next morning to find a praying mantis on the hood of the car:

Day 2 (Monday): We got up at 6 AM, washed up at the gas station’s bathroom and headed out.  We stopped in Winnemucca for a sit-down breakfast at a Casino restaurant where I ordered a cup of coffee, and got a whole flask.  So about 30 minutes after leaving Winnemucca we had to make a quick pitstop at a roadside stop (Valmy Rest Area).  Here we noticed our first mishap: The 4-pin plug connecting the trailer wiring to the car was gone.  The plug had come loose and was destroyed while dragging on the ground at 75mph.  So we had no break lights or turn signals on the trailer.

We frantically started looking for a trailer dealer – the next one was 85 miles away in Elko.  Luckily, we found a Napa Auto Parts in Battle Mountain, a mere 20 minutes later.  Even luckier, they had the plug we needed and one of the salesmen attached it to the trailer wiring for us!  (I need to send that shop some steaks or something to show my gratitude).  I also bought electric tape to secure the new plug to the car, to make sure it didn’t come loose again.

We made a long stop for lunch at a beautiful green park in Elko.  We had been awake for 7 hours, and had driven only 175 miles, so we weren’t going to get as close to Yellowstone as we had hoped.  Using her phone, Shujie found a KOA campground at Arco in Wyoming and we started making our way there.  On our way to Arco we passed the Craters of the Moon national monument.

At the Arco campground Amelia set up our sun tent as I read out the instructions:


Day 3 (Tuesday): For lunch we bought Subway sandwiches at a gas station; Amelia picked her own bread and toppings.  But it turns out that Italian bread is white bread.  Do not order this at Subway – it leads to inquiries about what one was thinking, and requests to aid the understanding of why one would order white bread for one’s daughter while one’s own sandwich and that of one’s spouse was made with perfectly fine whole wheat bread.

As we entered Yellowstone, we spotted an large male elk right away. It was too far away to get a good photo with a phone, but here’s our explorer looking at the elk:

Here’s our campsite at Madison Junction:

Day 4 (Wednesday):  On our way to Old Faithful I wanted to do a detour to Mammoth Hot Springs.  Here’s a tip: Driving 34.6 miles in Yellowstone can take as much a 2 hours because of: (a) spectacular sites to see along the way, (b) road construction with one-lane traffic, (c) bathroom breaks, and (d) wildlife sitings.

About 4 hours later than anticipated, we got to the Prismatic Pool:

Stops like this are very popular in Yellowstone and it’s hard to find parking in a regular car, never mind a car with a trailer.  We were lucky to find a place to park.

Next stop: Old Faithful, along with about two thousand other people:


I think we were pretty tired after the day’s driving and site-seeing.  There are no photos of our stay at Bridge Bay Campground.

Day 5 (Thursday): Before heading South to Grand Teeton National Park, we made a stop at Lake Yellowstone hotel.  Here Amelia lost a tooth!


Later that day we set up camp at Colter Bay in Grand Teeton National Park:

In the afternoon it rained.  I’m glad it did, because it made us go into the Visitor’s Center where we watched two great documentaries: A film about the massive 1988 fire at Yellowstone, and another narrating the reintroduction Gray Wolfs in Yellowstone.

In the evening we ate at the Ranch House restaurant.  It’s the only night that Shujie didn’t cook for us, and it underscored how much better it is to eat food from your own kitchen: It’s healthier and way cheaper.  We paid about $90/night for the trailer, which sounds like a lot of money considering that we still had to pay for the campsite, but since the trailer comes with a kitchen we probably saved $90/day in meals.  (And perhaps again as much by stemming high sodium diet healthcare related expenses).

After dinner we paid $15 so all three of us could shower (national parks tend to not have showers at the campsite ablution blocks).

Day 6 (Friday): This was the only day we didn’t have to drive to another campsite. When we do this again we’ll plain on staying 2 nights as often as possible.

In the morning Amelia and I played by the lake while Shujie did laundry.

In the afternoon we took a boat ride to the foot of the Grand Teton mountains.

Day 7 (Saturday): This was the coldest morning at 38F.  However, it warmed up soon enough. We got a relatively early start, had breakfast, packed up, hooked up the he trailer, checked it, checked it again, and started heading back home.  We left the campsite at 9:15 AM, but had to stop again right away because the trailer in the rearview mirror looked like it was a little further back from the car than what I had gotten used to.  We checked it again.  Lo!  It was 2” too far back from the car!  The pin holding the towing ball to the hitch was gone!  (It looks like this: http://www.homedepot.com/p/Reese-Towpower-5-8-in-Pin-and-Clip-7010500/202282290).

Bliksem!  (Yes, sometimes I swear in front of my daughter).

It’s very hard to imagine how it could have fallen out. It’s even harder to imagine someone taking it (and leaving the hitch in place on top of that).  I prefer to imagine a fairy had unintentionally cast a bad spell: “May your journey go off without a hitch”.

We unhitched the trailer, slid the towing ball out of the hitch, and went looking for a replacement pin. We had to drive all the way to Jackson to get a replacement pin.  We finally were on our way again, with a new locking pin, at 1:15 PM.  Two things about this: One: When you optimistically first look for a pin at the local general store, then at the next service station, then at the RV rental location, etc., etc., it takes two times longer than necessary before you inevitably end up at the closest Napa Auto Parts dealer, which for us was 48 miles away in Jackson.  It’s probably better to just head straight to the Napa dealer, and skip all the other stops. Two: Yesterday (a week too late) I realized I could probably have used a few tent pegs as a temporary pin.

We drove until about 7 PM, with the usual frequent stops, and arrived at Nat-Soo-Pah Warm Springs.  No photos from this day either, but it was a great place to spend the night.

Day 8 (Sunday): We drove toward Truckee through Nevada, which is a semi-dessert.  We decided to stop for lunch in Carlin.  On her phone, Shujie found a very green park.  When we got there it turned out to be a cemetery.  The cemeteries we saw in Nevada and Wyoming had spectacularly lush lawns.  Amelia said cemeteries are for dead people.  I disagreed; I think it’s for their friends and family who are still alive.

Not wanting to picnic in the cemetery, we found another small patch of green grass in front of the Wells Rural Electric Company.  It was Sunday, so all was quiet and nobody came to chase us away.  Shujie used the trailer kitchen to make sandwiches (whole wheat bread):


In the evening we camped at Coachland RV Park in Truckee, and enjoyed another great camping dinner. How idyllic!

Day 9 (Monday): Before heading back to Auburn we organized our stuff so when we dropped the trailer off we just had to transfer a few things from the trailer to our car.  Which we did, except for my computer bag, which I put down on the ground to check out their new Outback trailer (btw, we plan on renting it next year).

I wanted to eat lunch at Ikeda in Auburn, but Shujie wanted to drive for another hour and eat lunch at Whole Foods in Davis.  We got very close to Davis when I remembered my computer bag and we had to go back to Aburn to get it.  On the up side, we then had lunch at Ikeda.

One of the fun things about pulling the little trailer is that it’s a nice conversation piece.  Somebody would ask us about it almost every day.  We’ll probably go with a slightly little bigger trailer next year, but it’ll be a long time before we go this big:

Technical Notes:  The trailer weighed just over 1000lbs, so it was no problem for our 4-cylinder Subaru Outback.  The Outback CVT adjusted smoothly on the hills, and the paddle shifters made it easy to control engine power and reduce speed when going up or downhill. On the way out to Yellowstone I kept the speed at 75 mph; on long steep climbs the RPMs would touch on 5000 to keep us at that speed.  On the way back I was feeling less rushed and the outside temperature approached 100F, so I tried to keep RPMs at ~3000, which still kept us going at 60+mph on the hills.  The average gas mileage for the trip was about 20mpg, which I think is very reasonable.  The speed limit in the national parks is 45mph, which helped keep the gas consumption down.  Without the trailer we probably would have averaged about 30 mpg for the whole trip.

The little T@G trailer uses a 4-pin connector.  On their website, Sierra Teardrops recommends getting a 7 pin connector.  You don’t need it for the T@G, and my car’s hitch came with the 4-pin so we were good to go, but I wished I had gotten the 7 pin.  It wouldn’t have fallen out (Day 2 mishap), and we would have had the option to pull a bigger trailer.

Secrets of Success

I just watched Richard St. John: Secrets of success in 8 words, 3 minutes.  Inspired by a question that a teenager asked Richard – “What leads to success?” – and the fact that he wasn’t able to give her an answer, Richard started asking TED conference attendees what they think leads to success.  After talking to more than 500 people over 7 years, he summarizes the answers in this talk.  Richard says the following factors lead to success:


Do what you do for love, not money.  He quotes Carol Coletta (radio producer of Smart City) as saying “I would pay someone to do what I do”.

Have you ever enjoyed your work so much that you couldn’t believe you were actually getting paid to do it?  The times in my life that I’ve felt like this were also the times during which I excelled.  A boring job makes you goof off and there is no way to be successful at something if you are not paying attention!


Richard quotes Rupert Murdoch: “It’s all hard work.  Nothing comes easily.”

That’s good to know!  Successful people most often make it look so easy!  They tend to make me think “of course they can do it, it’s easy for them!”.  It’s good to know that’s not the norm!


The word Richard used is “good”.  He quotes Alex Garden (a game developer) “To be successful, put your nose down in something and get damn good at it”).  Richard says: “There’s no magic – it’s practice-practice-practice”.

But how do you find out what you can become good at?  Is it only the things you have passion for?  How do you discover your passion?  Richard, I think the 3 minute talk was too short!  Could you add another minute and help answer this question?


I like it, but again, what should I focus on?


Meaning “push yourself” (not other people!).  Perseverance.  I’ve heard that before.  But again, some things are better not pursuing.  How do you identify those before putting all your energy into it?


“Perform or provide a service” almost sounds like a charitable activity, but it does not have to be so.  You can get rich if you serve people something of value!


To get good ideas, Richard offers the string: “Listen, observe, be curious, question, problem solve, make connections”.  Good idea!


Persist through failure and “crap” (criticism, rejection, assholes, pressure).  Sounds good, but again I have to ask for more guidance.  Some criticism and rejection is valid (and sometimes unwittingly you are the asshole!)- how can you learn that a course of action should be abandoned?

Richard’s talk is inspiring and a “feel-good” talk, but on the flip side are people trying to do something crazy or impossible things (like trying to sell Hummers or believing in clean coal!)  What guidance can convince these poor souls to abandon their ill conceived causes?

Too much choice

Barry Schwartz wrote the book The Paradox of Choice: Why More Is Less more and gave this TED talk on why too much choice can be a bad thing.

To summarize, too much choice is bad when:

  • It paralyzes decision making because you fear making the wrong choice.
  • You recalculate the benefit of your choice by subtracting the benefits of the choices you didn’t make (i.e., subtracting the opportunity cost).
  • Choices leads to escalation of expectations.
  • You blame yourself for not making the right choice (if you didn’t have to choose then you couldn’t be blamed for making the wrong choice).

A couple months ago I signed up to do the Hood To Coast relay run, which is next weekend.  I’m running with a really well organized and experienced team.  The team captains are taking care of all the organization, pretty much all I have to do is show up and run – so this is a fantastic opportunity!

However, since I signed up for the run I’ve had some regret because I’ve discovered I’m missing out on several other things (the company picnic, the first Chinese class of the new semester, an annual 100 mile cycling event, and watching the last couple of days of the Olympic games).  Why should having all these options available reduce the benefit of my decision to do the HTC run?!  Except for missing the class, none of the other options would even remotely be valid reasons for not doing the run!

Thanks to Barry, I now understand why I feel a little bit of regret, even though I shouldn’t.  However, in his TED talk Barry didn’t say what I should do about it…  it’s not unlike Daniel Gilbert, who explains in his book – Stumbling on Happiness – why we are often unhappy about our choices, without really explain what to do about it!

My /dev directory layout and environment setup

This article describes the directory structure and command shell environment configuration I use on my development machine to help manage tools, source code and dependent libraries.

Directory Layout

On Windows I keep all my development tools and source code under c:\dev.  On Linux I use the same layout under $HOME/dev/

Inside the “dev” folder I have the following sub-directories:


/tools – contains executable application, tools and utilities, like Eclipse, DbVisualizer, Tomcat, Maven, HSQLDB, etc.  I only place tools here that you can install manually simply by unzipping them (for example, Ecipse, Maven, Tomcat).  For the tools or applications don’t ship in a zip file but only come with installers (for example, Java, Oracle, TortoiseSVN) – I let these tools install to their default locations (for example, under “C:\Program Files” or  “/usr/local/”).

/lib – contains binary distributions of 3rd-party libraries and documentation, like GWT, JUnit, SpringFramework, Hibernate, etc.  These days this directory is actually pretty empty – since I now mostly rely on the Maven to download 3rd party libraries and store it in the local Maven repository.  However, it is still sometimes useful or necessary to have the documentation and examples handy.

/os – contains source code for 3rd-party Open Source libraries and tools.  I also use it as a sandbox for unpacking and executing 3rd party sample code.  The entries here are usually transient.

For example, on Windows I have:


I also place my own source code projects directly under “dev”, for example:


BTW, “spikes” is a nice “catch all” place for trying new things out before moving them into “real” projects. Even though “spikes” only contains throwaway or proof-of-concept code, I tend to commit the contents to a SVN repository. Some people use the term “sandbox” instead of “spikes”.

Shell Environment Configuration

To set up my environment variables I create a command file in the “dev” folder – usually called “setenv.cmd” on Winows and “setenv.sh” on Linux.  The file sets up the path, environment variables, and on Linux it also sets up aliases.

On Windows I find it far more convenient to manage the environment settings through a command file rather than going through the Control Panel (System > Advanced > User Profiles > Environment Variables) dialog.  It’s also very useful if to set your environment through batch files if you sometimes need to run a different versions of a tool (for example, if you use Java 6 for new projects but sometimes have to run Java 1.4 for legacy projects).

This is an example Windows setenv.cmd file:

SET JAVA_HOME=c:\Progra~1\Java\jdk1.5.0_14
SET ANT_HOME=C:\dev\tools\apache-ant-1.9.0
SET CATALINA_HOME=C:\dev\tools\apache-tomcat-6.0.14
SET DERBY_HOME=C:\dev\tools\db-derby-
SET SPRING_OSGI_LIB=C:\dev\os\spring-osgi-1.0-rc2\lib

@echo off

SET PATH=%PATH%;C:\dev\tools\apache-maven-2.0.9\bin
SET PATH=%PATH%;C:\dev\tools\putty
SET PATH=%PATH%;C:\dev\tools\apache-ant-1.7.0\bin
SET PATH=%PATH%;C:\dev\tools\bnd-0.0.238
SET PATH=%PATH%;C:\dev\tools\db-derby-\bin
SET PATH=%PATH%;C:\progra~1\Subversion\bin

echo on
echo PATH=%PATH%

Osgi Hibernate Spring-DM Sample


I have developed a small sample to demonstrate how to use Hibernate in OSGi with Spring Framework and Spring-DM.  The sample works in either Felix or Equinox. It builds with Maven 2 – the build process automatically downloads the Felix and Equinox jars so there is no need to install either framework separately.

Starting Hibernate in OSGi with the normal Hibernate SessionFactory would allow you to use Hibernate in OSGi – but that would not address the dynamic behavior that an OSGi system is capable of. This sample demonstrates how a Hibernate SessionFactory can be updated dynamically in an OSGi environment. You can dynamically add and remove entity classes to the Hibernate configuration by stopping and starting bundles that contribute clasess to the Hibernate configuration.

This implementation contains a small Swing UI which allows you to see which entity classes are present in the Hibernate configuration. The Swing UI also allows you to issue rudimentary SQL and HQL queries.

The solution is based on this OSGi and Hibernate blog entry by Peter Kriens. The design uses an entry in the manifest file to declaratively add classes to a Hibernate session using an extender model.

Get the code

To get the source code for the hibernate sample, use SVN:

svn checkout http://voluble.googlecode.com/svn/trunk/osgi-samples/hibernate/ osgi-hibernate-sample

Run the code

Run “mvn install” in the new osgi-hibernate-sample folder and see all projects build successfully.

The 2nd last project that builds is “integration-tests”, which uses Spring DM to run an integration test suite in an OSGi container. The integration tests are run against an in-process HSQLDB server.

Continue reading Osgi Hibernate Spring-DM Sample

Introduction to OSGi

This is a quick and practical task-based introduction to OSGi. We avoid any in depth discussion about the purpose or benefits of OSGi or even the tools referenced in this article. Many high level introductions on the technology are available; for examples, please see the webcasts at Eclipse. There’s also a good webcast on the OSGi efforts at Weblogic.

With OSGi it’s possible to run multiple versions of the same classes in the same container. We’ll start from scratch and build services that demonstrate this ability.

I used Apache Felix as an OSGi container. The other two well known open source OSGi container implementations are Equinox and Knopflerfish. Apache Felix actually seems to be the least popular of the three – I wanted to get some experience using the underdog!

Our immediate focus is to create and deploy applications in an OSGi server. We’ll do the following:

  • First we’ll set up a simple OSGi deployment environment.
  • We’ll create a simple OSGi bundle that will export classes and a service, making it available to other bundles. We’ll call this Bundle A, version 1. We’ll install and start the bundle in an OSGi container.
  • To demonstrate the power of OSGi, we’ll create a second version of the same bundle and install it alongside the first version. We’ll call this Bundle A, version 2. This will demonstrate OSGi technology’s ability to seamlessly manage multiple versions of the same classes at the same time, even though the class and package names of both versions will be identical.
  • We’ll create another set of bundles which will import and use the classes and service exported by the first set of bundles. We’ll call them Bundle B, versions 1 and 2. Bundle A, versions 1 and 2 will export services which will be imported by Bundle B versions 1 and 2 respectively. This will demonstrate OSGi technology’s ability to dynamically manage modularized applications.

We will use Spring Dynamic Modules for OSGi(tm) 1.0 (with dependencies), Apache Felix 1.0.3, Apache Felix Maven Bundle Plugin 1.2.0, Apache Maven 2.0.8 and Java 1.5.14. Please refer to the individual project websites for more information and background on these projects. We are avoiding discussion of these tools as we are only focusing on accomplishing the tasks outlined above.

I used Windows XP to create this tutorial. When writing the development and deployment steps it seems much easier and less error prone to reference full path names, rather than relative names. For example, I prefer referencing c:\dev\tools\felix-1.0.3, rather than “your Felix home directory”. You will notice I use the following directory structure for my development environment.

                  lib\   (Libraries)
                  tools\   (Executable tools)

You can change the steps in the tutorial to match your environment, or copy the environment I lay out here. If you use a different layout, simply substitute path references to match your environment. For example, substitute “c:\dev\tools\felix-1.0.3” with whatever you chose for “your Felix home directory”.

To start out I’ll detail where to get the components to build the OSGi deployment environment. I will then use a command file, “setenv.cmd”, to configure my environment variables and system path when operating from a Windows command prompt. I’ll provide a sample “setenv.cmd” file.
Continue reading Introduction to OSGi

Back from China!

Shujie & I returned home yesterday after an 11 day trip to the People’s Republic of China. I uploaded my 400+ photos and Shujie’s 115 photos.

Here are some touristy photos of Shujie and me in the Palace Museum / Forbidden City:

img_4549.jpg img_4548.jpg img_4542.jpg

I learned so much about China, Shujie, her family, and also a little bit more about myself. I learned that China’s incredibly vast and rich 5000 year old history is not only found in great walls, gates, pagodas, tombs, literature or artwork, but also on the table at every meal!

It’s hard to summarize my impressions of the country or the people, but I can say that I felt completely safe the whole time, everyone seems friendly beyond measure, proud of their heritage, proud of the current pace of development, excited about the future, determined to succeed, well spoken, void of criticism, eager to make visitors feel welcome and unselfishly willing to help out whenever they can.

On the down side, traffic in the cities and towns is a mess – your life hangs in the balance every time you cross the street. Also, pollution is staggering, but as far as I can tell this will improve very rapidly over the next couple of years.

Going to China!

I’m finally going to China, for the first time, tomorrow. I have been dreaming about this for years!  I have seen several documentaries on life in China and have traveled a bit around the globe, so I think I have a pretty good idea what it will be like. However, I still have a feeling that this experience will still touch and change me in unexpected ways. The Twin Peaks quote comes to mind: “When you see me again, it won’t be me.”

My fiancée, Shujie, will be my tour guide. She grew up in China in a small town, Fengqiu, in the Henan province. We actually found the town on Google Earth! It’s ferry cool, and a bit freaky. Here’s the GPS coordinates of a circle in the middle of town, which Shujie says she walked past to school every day: 35.04009 N, 114.41635 E.

We’ll visit Beijing for a couple of days and then go to Fengqiu, where I will meet my future mother-in-law.  Shujie will have to interpret for us, as her mother doesn’t speak English and I speak neither Manderin nor their local dialect.  I’m hoping to take down and memorize some polite words though while we are there.

New Blog!

Today I went through the exercise of setting up a new blog. I prefer to install the blog software myself at a domain that I own and this begs the question: Which blog software should I use?

After a couple of web searches and skimming some results, I looked a little closer at b2evolution, Serendipity, Nucleus, TikiWiki (mostly the blogging module) and WordPress.

b2evolution looked promising, but there are little animated emoticons on the blog editor which I found rather distracting and silly. I couldn’t figure out how to hide them, and promptly gave up.

I’ve tried Serendipity before, but never tried to do any customization. The default theme was rather humdrum. Also, on their feature list they reference WordPress integration, which really made me think I should look more closely at WordPress instead.

I turned away from Nucleus because the screenshots link on their websites took me into the Gallery application. I like Gallery, but I really want a blog system that will make it easy for me to post photos inside the blogs and I reason that, if the Nucleus website doesn’t use the Nucleus software to display screenshots, then it’s probably a little too cumbersome to do.

I’ve played with TikiWiki in the past and it looks extremely powerful. However, after installation, it took me several minutes just to figure out how to enable the blog module, so the whole system seemed a little too much like Linux in the 90’s… it’s very powerful, you have full control, but you really need to put some effort into learning how to tame the beast.

So that left me with WordPress. It’s very popular and extremely well supported, but I used it about 2 years ago and remember that inserting images into blogs were really hard. So I played around for a while on the WordPress site and noticed an example of an image in the Wysiwyg editor. Very encouraging!

I’m very impressed with the wide range of plug-ins for WordPress and the plethora of themes! I settled on this very cool Paalam 1.1 theme by Sadish Bala (“made free by Web Hosting Bluebook“). Uploading my own banner image is dead simple, and WordPress even has a built in image editor to help crop the image. The default Wysiwyg editor I’m using right now (I believe it’s called TinyMCE) is also really cool. I’ve gotten so used to editing Google docs documents – editing WikiText is really awkward by comparison.

The blog research and implementation took me several hours… but I’m happy with the result. Now, lets see how easy it is to add an image to this blog…


Wow! That was fantastic! There’s a file upload form right below the editor. After uploading, a button lets you insert a link to the uploaded image into the document. It couldn’t be simpler (well, without drag & drop at least). I’d like to figure out how to make the text flow around the image (without having to edit the HTML and stilysheet), but this is a great start! BTW, it appears that switching between “Code” and “Visual” input is also really seamless in the Wysiwyg editor.