<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
    <title>mkale.com/blog</title>
    <link>http://mkale.com/</link>
    <atom:link href="http://mkale.com/blog/rss.xml" rel="self" type="application/rss+xml" />
    <description>Rss feed for mkale.com/blog</description>
    <lastBuildDate>Sun, 18 Dec 2016 22:03:13 PST</lastBuildDate>
    <item>
        <title>Language State of the World 2014</title>
        <link>http://mkale.com/blog/2014/06/language-state-of-the-world-2014.html</link>
        <description>
WWDC 2014 brought many exciting announcements for developers, but for me the most interesting was the new programming language, Swift.  To me, this immediately removes any desire I once had to write utility code in Objective-C.  For the next couple years, it will still often make sense to write UI and Cocoa-touch facing code in Objective-C, especially if you intend to target iOS devices prior to iOS 7 (or OSX prior to Mavericks).  Where are we with languages today?

For UI code, I still belive in writing to the platform's native API.  This means Objective-C or Swift for Apple platforms, Java for Android, C# for Windows platforms.  For utility code, libraries, business logic, and other non-UI code, we have several options.  For casual, home, or tinkering projects, from modeling data, generating this blog, automating rote tasks, parsing log files, and moving bits around, I still love Ruby or Python.  Ruby has a greater mindshare among non-scientists and though I find python to be a more elegant language, it's hard to argue with the success of Ruby.  For most tasks they exist at a similar level and are for my purposes equivalent.  Ruby also has just enough of Perl's "just get it done" attitude to be a very effective language.  In many ways it's a greater joy to program in Ruby than anything else.

For library code that's going to ship on client devices though, it's too bad that there is no common langauge that can easily target iOS, Android, and Windows Phone.  (Honestly, I'd settle for a language that hit the first two.)  C++ comes close: support is excellent on iOS but calling C++ code from Android requires a tedious JNI bridge and the complexity of compiling separately for many target CPU architectures.  For large libraries it may be worth it but for the code I tend to write I find it easier to do a translation port over to Java for Android (and C# for Windows).  If you leave the object models and code structures the same, translating utility (i.e. non-UI) code across languages is not very difficult.  But it does require typing everything twice and keeping changes in sync.  There are also some javascript solutions which are promising but still involve too many dependencies and are more complex than I'd like.  Maybe in another year or four this will change.

I prefer C++ if I also plan to use the library from Linux or Windows on the desktop.  Otherwise, I plan to start using Swift for code destined for Apple platforms.  I'm going to be porting the Apple-platform utility-code to Java anyway for Android, so I might as well get started using the new Apple language for Apple platforms.  If we're lucky, Apple will open-source Swift and we'll see an implementation targeting Linux or Windows and I can begin to write all my library code in Swift.  (If we're _really_ lucky I'll be able to target Android too but I'm not holding my breath on that one.)

I have of course completely ignored web and internet-server code.  This is not where I spend very much of my time so it's likely that my opinions would change with some more experience.  But for very simple web projects, PHP may still be a good choice.  Its server requirements are light and it's easy to throw something together that works.  But for any project that goes beyond a couple files and a few pages, I would probably use Rails.  There are many compelling alternatives to Rails though and I would like to spend some time in the second half of 2014 exploring them.  Maybe my language state of the world 2015 will have some better or different options here.

It's, as always, a great time to be a programmer.
</description>
        <pubDate>Tue, 17 Jun 2014 20:56:35 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2014/06/language-state-of-the-world-2014.html</guid>
    </item>
    <item>
        <title>Super Soakers and Patent Lawsuits</title>
        <link>http://mkale.com/blog/2013/11/super-soakers-and-patent-lawsuits.html</link>
        <description>
Lonnie Johnson, the inventor of the Super Soaker, has [prevailed](http://www.ajc.com/news/business/super-soaker-creator-awarded-729m-from-hasbro/nbjmm/#!) in a royalty dispute with toy-maker Hasbro.  I haven't been following the case, but from what I read in that article, it sounds rather clear-cut.  They made an agreement to license his technology and then didn't follow the agreement.  He's due some extra royalty payments as a result.

This is great, but on the surface not really worth much more than a passing glance.  What makes it interesting to me though, is the [discussion on Hacker News](https://news.ycombinator.com/item?id=6702535) about it.  This is a case where an inventor of a piece of technology licensed it to others -- in some sense, he's an [NPE](http://en.wikipedia.org/wiki/Non-practicing_entity).  Creating a strict definition of patent troll which does not also include guys like Johnson would be difficult.  There is a huge grey area, and it becomes more of an &amp;quot;I know it when I see it&amp;quot; kind of thing.

It's not fair to make small inventors build products that they may not have the resources or the inclination to do at a proper scale.  Running a business is a very different set of skills than working in a lab, and while some people can do both and enjoy it, there's nothing wrong with only being good at (or having an interest in) one of those.  Large companies can and do prey upon small inventors, hoping that they won't have the legal resources to fight back.  So in my opinion, there's nothing wrong with selling the intellectual property rights to another entity.

Enter Intellectual Ventures and Lodsys.  How is this different?  To me, the difference is one of originality of the invention.  For something truly original and truly novel, it makes sense to allow a patent and allow the owner of that patent to do whatever they want with it.  Including selling it to a firm like Intellectual Ventures.  The problem with the [Lodsys patents](http://en.wikipedia.org/wiki/Lodsys) and those of similar modern patent trolls are that they're not original and/or that they're being stretched to cover things that have nothing to do with their original invention.

We need to stop granting obvious patents and we need to stop granting overly broad patents.  This is a difficult problem.  The patent office cannot be expected to be experts in all fields, many of which require years or even decades of training and experience to reach proficiency.  And as technology and the world changes, the language in a ten year old patent that didn't seem overly broad at the time can suddenly cover vast new fields and applications that had nothing to do with the original filing.  There is no process to review patents once they're granted other than litigation, the cost of which is prohibitive for most people and small firms.

A bad patent can do much more harm than good by stifling other companies from building things that would make the world a better place.  But whatever we do to reform the system, we need to make sure it doesn't discourage or disincent active inventors like Lonnie Johnson, working away in their labs inventing (among many other vastly more important things) great new ways of blasting water at your friends on a 100 degree July day.
</description>
        <pubDate>Sun, 10 Nov 2013 20:35:23 PST</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2013/11/super-soakers-and-patent-lawsuits.html</guid>
    </item>
    <item>
        <title>Fusion</title>
        <link>http://mkale.com/blog/2013/10/fusion.html</link>
        <description>
[These guys](http://www.bbc.co.uk/news/science-environment-24429621) have done something amazing in fusion research -- they've generated more energy in an experiment than they put in.  We're a long way off from [one-point-twenty-one-jigawatts](https://www.google.com/search?q=mr+fusion&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;ei=75JTUpraKof2iwKO_ICAAw&amp;ved=0CAcQ_AUoAQ&amp;biw=1049&amp;bih=734&amp;dpr=1), but this is at least step in the right direction.
</description>
        <pubDate>Mon, 07 Oct 2013 22:09:03 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2013/10/fusion.html</guid>
    </item>
    <item>
        <title>Boosters</title>
        <link>http://mkale.com/blog/2013/09/boosters.html</link>
        <description>What's the deal with boosters in college football?  Let's compare college football and the NFL, money-wise:

On the revenue side, teams have: ticket sales, TV and Radio contracts, merchandise and stadium subsidies from municipalities/schools.  These are (probably?) largely similar between college and the NFL.  NFL teams probably have more corporate sponsors and luxury boxes in their stadiums.  And of course college teams have boosters.

On the expense side, NFL teams have player salaries which college teams do not.  Both have extensive on- and off-field staffs, and various other expenses which I'm not thinking of but are probably roughly similar between the NFL and colleges.  NFL teams are private businesses and are supposed to pay income taxes, but if MLB teams are any indication, they are likely using all sorts of tricks to show near-break-even operation every year while the owners take their profits when they sell the teams.

So college teams are missing one significant expense (player salaries), and major programs have one significant extra revenue source (boosters).  I have a hard time believing that corporate sponsors are making up this much difference.  I would love to compare the balance sheet of a major college program with that of an average NFL team.  But of course we'll never be able to do that.

Boosters are powerful figures, influential in recruiting players, selecting coaches, changing the entire direction of college programs.  (Oregon's Phil Knight is a prime example.)  Not all of the influence is positive of course.  Evan Brennan has an [interesting 2011 piece on boosters](http://evanbrennan.com/2011/01/12/boosters-and-college-football/) describing their pros and cons, noting that:

&gt; Recruiting violations, financial improprieties, and other NCAA and criminal scandals have occurred hundreds of times over and over again due to the influences of boosters.

Ultimately, I suppose, boosters are just another way in which college sports are becoming increasingly moneyed, increasingly a world of haves and have-nots, and decreasingly about school spirit and fun athletic competitions.  They're just another big-money prime-time sports presentation, no different from the NFL.  Can we pay the players already and remove the silly requirement that they actually be matriculated students at their respective schools?

</description>
        <pubDate>Mon, 30 Sep 2013 22:01:08 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2013/09/boosters.html</guid>
    </item>
    <item>
        <title>Google's Missed Earnings</title>
        <link>http://mkale.com/blog/2012/10/googles-missed-earnings.html</link>
        <description>Someone (inadvertently) leaked Google's quarterly earnings report early, which shows [falling advertising prices and lower income than expected, despite growing revenues](http://blogs.wsj.com/marketbeat/2012/10/18/google-earnings-come-early-shares-drop/).  The stock fell nearly 10% before trading was briefly halted.  Google is of course still making money, still has incredible talent and creates great products, and is still the clear market leader in some very profitable businesses.  They're in this for the long haul and one missed quarter won't throw them off their game too much.  However this reminds us that their growth is not assured and how much their fortunes are tied to advertising rates.

Especially troubling is their Motorola subsidiary, which is losing money.  Any stumbles in the Android or Google world are sure to be music to the ears of Microsoft, which must see Android as its main competitor at this point instead of Apple.  Apple is printing money with their iOS devices, but they don't have the market locked up and Android is happily taking up almost everything else now.  Microsoft is making some nice products but hasn't seen market demand for them yet.  Time will tell whether Microsoft or anyone else is able to wrest away any significant portion of the market from Android, which would give them a foothold to start taking on Apple.  It's an exciting time to be in Mobile.
</description>
        <pubDate>Thu, 18 Oct 2012 12:08:04 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/10/googles-missed-earnings.html</guid>
    </item>
    <item>
        <title>Microsoft Surface Surfaces</title>
        <link>http://mkale.com/blog/2012/10/microsoft-surface-surfaces.html</link>
        <description>The Surface is [here!](http://surface.microsoftstore.com)  Well, not here quite yet, but orderable and priced.  (Well, if I might add.)  Delivery on 10/26 with the rest of Windows 8.  Looks neat.

Pricing is aggressive -- will probably make PC OEMs squirm a bit, but it needed to be priced to match the iPad to have a chance.  Here's hoping Microsoft sells a bunch of these and more importantly, here's hoping it's a good device with good software.</description>
        <pubDate>Tue, 16 Oct 2012 21:40:54 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/10/microsoft-surface-surfaces.html</guid>
    </item>
    <item>
        <title>Books</title>
        <link>http://mkale.com/blog/2012/10/books.html</link>
        <description>More evidence of the ongoing shift away from hard copy: when I read paper books, newspapers, magazines, etc, I occasionally find myself glancing up at the top of the page expecting to find a clock.  More and more, it's just more convenient to read on a screen.  Not to mention the saved paper and distribution logistics.  Sure, books feel nice in your hand and you can use them when the electricity is out.  You can stuff a cheap paperback in your traveling bag and not worry if it gets lost or stolen.

But you can also carry a zillion books and magazines on a digital device that fits in your pocket or briefcase.  You can search through the text.  Copy and paste.  Make annotations without feeling like you're writing in a book (something I could never bring myself to do.)  You can download the content right to your device without having to leave your house.  And, best of all, no dead trees or carbon-fuel-based shipping.  The devices do use (often carbon-based) electricity themselves, but given [how little electricity they do use](http://my.epri.com/portal/server.pt/gateway/PTARGS_0_243352_317_205_776_43/http%3B/uspalecp604%3B7087/publishedcontent/publish/epri_calculates_annual_cost_of_charging_an_ipad_at__1_36_da_855261.html), I expect the carbon footprint is still much lower.

The only content I read in hardcopy anymore is that which I share or lend or borrow.  One copy of a newspaper can be passed between multiple people around a kitchen table.  My local library has a much larger collection in regular books than in e-books.  But these will come, with time.
</description>
        <pubDate>Mon, 15 Oct 2012 20:42:00 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/10/books.html</guid>
    </item>
    <item>
        <title>iOS 6 and Wacky Rotations</title>
        <link>http://mkale.com/blog/2012/10/ios-6-and-wacky-rotations.html</link>
        <description>While updating my [apps](http://earlybirdsoftware.com/) to iOS 6, I noticed that they were handling rotations poorly.  My buttons weren't getting moved correctly when the device switched from portrait to landscape and vice-versa.  Digging into the problem, I found that my UIViewControllers were not getting the

&lt;code&gt;
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
&lt;/code&gt;

message on rotation.  I know that iOS 6 deprecates &lt;code&gt;-shouldAutorotateToInterfaceOrientation&lt;/code&gt;, but near as I could tell &lt;code&gt;-didRotateFromInterfaceOrientation&lt;/code&gt; should still be ok.  After scratching my head a bit, I noticed that my newer apps did not have the problem, only my apps that have been around since the (then)iPhoneOS 2.x days.  With this clue, I was eventually able to track the problem down to some changes in the template app code that Xcode generates for you.  Somewhere along the line, in &lt;code&gt;-application:didFinishLaunchingWithOptions&lt;/code&gt;

&lt;code&gt;
[self.window addSubview:[self.myRootViewController view]];
&lt;/code&gt;

changed to:

&lt;code&gt;
self.window.rootViewController = self.myRootViewController;
&lt;/code&gt;

The rootViewController property was introduced in iOS 4.  My apps that had been around for a while still had the old template code, which unbeknownst to me was working fine up until iOS 5.  Changing my older apps to set the rootViewController property fixed my rotation problems.  The documentation does indicate that the latter is now the preferred way of doing things, so this is a good change to make for every app that does not need to run on iOS 3.x (which should be very few apps at this point).

So: if you're running into rotation wackiness on iOS 6, check to see if your &lt;code&gt;-didRotationFromInterfaceOrientation&lt;/code&gt; is getting called, and if it's not check your app delegate to make sure you're setting UIWindow's rootViewController property rather than just adding a subview.
</description>
        <pubDate>Sun, 07 Oct 2012 14:14:38 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/10/ios-6-and-wacky-rotations.html</guid>
    </item>
    <item>
        <title>Hockey</title>
        <link>http://mkale.com/blog/2012/07/hockey.html</link>
        <description>I'd love to love hockey.

&lt;figure&gt;
    &lt;img alt="Hockey Players" src="/blog/2012/07/hockey.jpg" /&gt;
    &lt;figcaption&gt;Practicing at the local ice rink&lt;/figcaption&gt;
&lt;/figure&gt;

 

It's a fast paced sport, full of constant action.  It combines a lot of the good parts of soccer and basketball.  Who doesn't love a sport with three periods?

But it's [just too violent](http://en.wikipedia.org/wiki/Violence_in_ice_hockey).  I can't bring myself to become a fan of a sport that condones this much violence.

Adam Gopnik's [piece](http://www.newyorker.com/online/blogs/sportingscene/2012/04/hockey-violence-blackhawks.html) in the New Yorker puts it well:

&gt; The real argument made by those who like violence is "If you stop it, I won't be able to enjoy it." At least this is honest, but those aren't the words of a hockey fan: they're the words of a violence fan who happens to have glommed onto ice hockey.

I hope this changes as I'd like a chance to become a hockey fan.
</description>
        <pubDate>Wed, 25 Jul 2012 20:27:53 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/07/hockey.html</guid>
    </item>
    <item>
        <title>Servlets in Tomcat, Part 1</title>
        <link>http://mkale.com/blog/2012/05/servlets-in-tomcat-part-1.html</link>
        <description>
### Introduction
It's been a couple of years since I've done anything serious using Tomcat, or used Java for anything other than Android.  So I thought I'd write a series of HOWTOs to refresh my knowledge a bit.  I hope you find this useful.

I'm going to write these at a level that I would like to read myself, which means I'll assume you're an experienced developer new to Tomcat.  I'll be telling you exactly what code to use and a complete set of steps to get going for our primary items (e.g. the servlet), but I won't be holding your hand through every dialog box for secondary items (e.g. installing Virtual Box, using the shell, etc).  My goal is to keep this concise enough to be useful without needing to skim, but please let me know if anything is unclear or you'd like additional detail for any of the steps and I'll try fix it.

### Server setup
Because we want to start from a clean, nicely reproducible environment, let's do it in a VM.  I'm using OS X 10.7 as my host environment, but anything that supports Virtual Box, Java, and Tomcat should do.  (That's at least Windows, Linux, and OS X but possibly others too.)

1. Install [Virtual Box](https://www.virtualbox.org/wiki/Downloads).
1. Download [Ubuntu Server 12.04 LTS 64 bit](http://www.ubuntu.com/download/server)
1. Create a new VM with 1024 MB of RAM and bridged networking.
1. Boot the VM using the Ubuntu .iso and install with defaults.

![Booting the ISO](/blog/2012/05/bootiso.png)

Do not install the tomcat stuff here, we'll do it later by hand, just in case you're following along from home on an already installed box, or a different distro entirely.

![Don't select Tomcat here](/blog/2012/05/software-selection.png)

Finally, get the box patched and accessible over ssh:

    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install openssh-server

Now log out of the console and login via your favorite ssh client.

### Tomcat setup

Install tomcat:

    sudo apt-get install tomcat7 tomcat7-docs
    # Note: can also install tomcat7-examples

This will install a bunch of things, let it fly.  When it finishes, check for sanity by browsing to `http://vmhostname:8080`, or `http://vmhostname:8080/docs`

You may wish to take a snapshot of your VM at this point, so you can get back to this nice clean slate.

### Tomcat project

On your development machine, install Java.  I'm using the [OpenJDK](http://openjdk.java.net/), but you may also wish to use the official [Oracle Java](http://www.oracle.com/technetwork/java/index.html).  Also install [Ant](http://ant.apache.org/), and a local copy of Tomcat (you'll need the Tomcat libraries to build our project, you can also test locally if you wish).

This basic example is taken heavily from the information [here](http://tomcat.apache.org/tomcat-7.0-doc/appdev/index.html).  I even started with the example application on that page, but found it to be missing a few files (like the ant build xml file).  So I expanded it into what we have here.  We're going to be creating the following files and directories:

    build.properties
    build.xml
    docs/
    lib/
    src/com/example/test/BasicTomcatTest.java
    web/index.html
    web/myjsp.jsp
    web/WEB-INF/web.xml

I'll list them all in turn.

build.properties *(makes version control easier by separating out things likely to be different on different people's boxes)*:

    # Customize this to your local tomcat install
    tomcat.dir=/Users/username/apache-tomcat-7.0.27

build.xml *(the ant build file)*:

    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
    
      
      
      
      
      
      
      
      
      

      
        &lt;fileset dir="web/WEB-INF/lib" includes="*.jar" /&gt;
        &lt;fileset dir="${tomcat.dir}/bin" includes="*.jar" /&gt;
        &lt;fileset dir="${tomcat.dir}/lib" includes="*.jar" /&gt;
      

      &lt;target name="mkdirs"&gt;
        &lt;mkdir dir="${build.dir}" /&gt;
        &lt;mkdir dir="${build.dir}/WEB-INF/classes" /&gt;
        &lt;mkdir dir="${build.dir}/WEB-INF/lib" /&gt;
        &lt;mkdir dir="${dist.dir}" /&gt;
      &lt;/target&gt;

      &lt;target name="compile" depends="mkdirs"&gt;
        &lt;javac srcdir="${src.dir}" destdir="${build.dir}/WEB-INF/classes" classpathref="project-classpath" /&gt;
      &lt;/target&gt;

      &lt;target name="build" depends="compile"&gt;
        &lt;copy todir="${build.dir}" includeemptydirs="false"&gt;
          &lt;fileset dir="${web.dir}" /&gt;
        &lt;/copy&gt;
        &lt;copy todir="${build.dir}/WEB-INF/lib" includeemptydirs="false"&gt;
          &lt;fileset dir="${lib.dir}" /&gt;
        &lt;/copy&gt;
      &lt;/target&gt;

      &lt;target name="dist" depends="build"&gt;
        &lt;jar jarfile="${dist.dir}/${appname}.war" basedir="${build.dir}"/&gt;
      &lt;/target&gt;

      &lt;target name="publish" depends="dist"&gt;
        &lt;copy todir="${publish.dir}"&gt;
          &lt;fileset dir="${dist.dir}" /&gt;
        &lt;/copy&gt;
      &lt;/target&gt;

      &lt;target name="clean"&gt;
        &lt;delete dir="${build.dir}" /&gt;
        &lt;delete dir="${dist.dir}" /&gt;
      &lt;/target&gt;

      &lt;target name="all" depends="clean,compile" description="re-build all source"/&gt;

    


src/com/example/test/BasicTomcatTest.java *(our servlet, just a Hello World)*:

    // Straight from the Tomcat docs, the only change is the package name and class name
    package com.example.test;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class BasicTomcatTest extends HttpServlet {

        public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
        {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("&lt;html&gt;");
            out.println("&lt;head&gt;");
            out.println("&lt;title&gt;Hello World!&lt;/title&gt;");
            out.println("&lt;/head&gt;");
            out.println("&lt;body&gt;");
            out.println("&lt;h1&gt;Hello World!&lt;/h1&gt;");
            out.println("&lt;/body&gt;");
            out.println("&lt;/html&gt;");
        }
    }

web/index.html *(Static resource)*:

    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;Hi There From Tomcat&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;Sample Application&lt;/h1&gt;
    Basic sample test here.  Adapted from the &lt;a href="http://tomcat.apache.org/tomcat-7.0-doc/appdev/index.html"&gt;Apache Tomcat docs.&lt;/a&gt;
    Click on a link to a &lt;a href="myjsp.jsp"&gt;JSP page&lt;/a&gt;, or a &lt;a href="myservlet"&gt;servlet&lt;/a&gt;
    &lt;/body&gt;
    &lt;/html&gt;

web/myjsp.jsp *(Basic JSP, we'll get more advanced later)*: 

    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;My JSP Page&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;h1&gt;My JSP Page&lt;/h1&gt;
    Some static text
    &lt;%= new String("Some dynamic text") %&gt;
    &lt;/body&gt;
    &lt;/html&gt;

web/WEB-INF/web.xml *(This guy tells Tomcat about the webapp)*:

    &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
    &lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
      version="2.4"&gt;
      &lt;display-name&gt;My Test Application&lt;/display-name&gt;
      &lt;servlet&gt;
        &lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
        &lt;servlet-class&gt;com.example.test.BasicTomcatTest&lt;/servlet-class&gt;
      &lt;/servlet&gt;
      &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/myservlet&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
    &lt;/web-app&gt;

### Building and Deploying

To build this guy, just do `ant dist`.  It will create the `dist\MyTest.war` file, which is a "Web Archive" file containing the static and dynamic resources that Tomcat will need to serve up your web app.  The entire app is contained in this one file, which makes deployment very easy.  (Though it makes incremental changes to a running system more difficult.)  You can publish to the local tomcat using `ant publish`.

When you're ready to copy up to the server, just scp the war file over:

    scp dist/MyTest.war vmhostname:.

Then, on the vm:

    sudo mv MyTest.war /var/lib/tomcat7/webapps/

Tomcat will unpack the war file and deploy the webapp.  You don't even have to restart anything.  Browse to `http://vmhostname:8080/MyTest`, and you should be up and running.

### Conclusion

This was a really basic example, just to get you going.  I wanted to show the core servlet and jsp functionality in a tomcat webapp without using a big complicated IDE like Eclipse.  Eclipse is great, and will save you time.  Please use it when you understand the basics.  But it does a bunch of things under the hood which can be distracting when you're learning.  The enterprise Java world is full of technologies and acronyms that all start with J.  They work well together and make a great universe for developing software once you understand them.  But it can be overwhelming to learn all at once, so I'm trying to give you some basics with as little dependencies as possible.  Future entries in the series will expand our world bit by bit.

That's all for now, happy Tomcat-ing!
</description>
        <pubDate>Sat, 19 May 2012 13:48:33 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/05/servlets-in-tomcat-part-1.html</guid>
    </item>
    <item>
        <title>Padres Ownership Saga</title>
        <link>http://mkale.com/blog/2012/04/padres-ownership-saga.html</link>
        <description>The only people who really know what's going on with the Padres ownership are likely the 30 team owners and the commissioner.  But it's interesting to watch from the outside.  Do the other owners not like Jeff Moorad because he's a former player agent?  Or do they not think he's going to run the team the "right" way?  (Meaning aligned with the long term profitability of the entire league, I'm sure they don't care whether he does right from a baseball perspective.)  Or something else entirely?  Given the [astronomical price tag](http://www.latimes.com/sports/basketball/nba/lakers/la-sp-0329-dodgers-magic-20120329,0,5012740.story) for the Dodgers, maybe Moores wanted to kill the deal to hold out for more money?

The Union Tribune has been following the story as best as they can, with [this morning's piece](http://www.utsandiego.com/news/2012/apr/04/how-the-padres-deal-fell-apart/) the most detailed yet.  I found this passage interesting:

&gt; Divorces involving owners of major league clubs command special attention of the commissioner's office, which has no desire for a divorce lawyer to gain access to the financial records of a ballclub, let alone the league's books.

How secretive they are of those precious books.  We wouldn't want the players or the fans to know how obscenely profitable these teams really are!  They might demand bigger contracts or oppose spending so much public money on new ballparks.  Also: wouldn't Moores' wife have had access to the books during the 44 years they were married?  Couldn't they settle the amounts in private?  Oh well, a minor detail in the story.

The timing of this whole thing, right around the start of the season when everyone's interest in baseball is high, is fascinating for an outsider but unfortunate for everyone involved.
</description>
        <pubDate>Thu, 05 Apr 2012 22:47:11 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/04/padres-ownership-saga.html</guid>
    </item>
    <item>
        <title>Advertising</title>
        <link>http://mkale.com/blog/2012/01/advertising.html</link>
        <description>I generally dislike advertising, but why? And how much is ok?

I initially set out to categorize ads into two buckets.  Those I called "passive" ads were ads alongside an app or web page or newspaper article or etc that I'm using, which can catch your eye but do not interfere with the main content. The others I called "active" advertising, which would be something like a TV commercial or splash screen ad that prevents you from using the main content for a short time to (hopefully) make you pay attention to the ad. But then I found a large grey area between them: those little dancing sprites in the corner of TV shows that advertise something. Or any squeaky flash ad that runs alongside the main content of a web page. Or anything really garish and bright that screams at you with colors if not sound, forcing you to look at it.

Instead, let's rank ads according to a spectrum of intrusiveness. A subtle line of text in a light font in the corner of a web page is less intrusive than several lines in a bolder font, is less intrusive than a small static image, is less intrusive than a big static image, is less intrusive than a slide-show of images, is less intrusive than a moving video, is less intrusive than an "interstitial". And different people are willing to tolerate different levels of intrusiveness.

I prefer services that have little or no ads, but not exclusively. I generally avoid live TV and radio because of (among other things) the ads. I instead watch TV on Netflix and listen to Pandora. The free Pandora does have ads but they are (to me) less intrusive than FM radio. For a commonly used app or service, I'd prefer to pay a bit rather than use a free service with ads. Though for a less commonly used app, bring on the ads. I read the print newspaper and some magazines, but generally toss out all the ads without reading through them. (I do of course glance at them as I'm doing this, and the ones that are on the same pages as the articles I can't help but look at.) I don't mind if the bus I'm riding on has a big ad on the side, or if the street I'm riding by has billboards on it. I think the bus and street would look better without them, but I'm happy making the compromise with my bus fare and the ad. Given a chance between paying the true cost of producing all that news content and taking the ads with my subscription, I'll keep the ads. Though I'd be interested to know what the cost would really be. What if the newspaper offered two subscription prices, one with ads and one without? I suppose this is what some newspaper websites do.

What would Times Square look like with no ads? Race cars? Soccer jerseys? Clearly we expect advertising in some places, and tolerate it in others. I also have no problem with advertising as a business model. If Google can make a zillion dollars by making a "free" email service (or video web site, or etc.) where the users really are the product, then that's fine with me as long as those users are happy with the arrangement. Android exists largely to allow Google to send ads to mobile users via lots of "free" apps. (I publish a few free, ad-supported, apps myself, on both Android and iOS, so I'm enjoying a bit of advertising as a business model.)

Advertising does diminish the quality of the product, at least a little bit. Or sometimes a lot -- the worst are those web sites which break up a one page article into five or fifteen "pages" so they can increase the number of (supposed) page views which they make their advertisers pay for. With any luck, one or both of consumers or advertisers will catch on to this and stop frequenting those kinds of pages.  If I painted a big ad on the side of my house, I bet my neighbors would complain that the neighborhood looked worse for it.

Companies that push out a lot of ads (like Google and Facebook) will try to collect more and more information on us, so as to serve more relevant ads and charge advertisers more for the privilege.  To some extent, this is ok -- I'd rather see an ad for a software development tool than for a thousand dollar gold watch that I'm never, ever, going to buy.  Maybe you'd prefer the watch ad to the dev tool ad.  But as technology allows these companies to gather and process more and more data on us, we're going into uncharted territory as to what they can do with it.  Where do we draw the line?  I'll probably draw it in a different place than you.  I hope we're aware of when we cross that line.

What does the future hold? Advertising isn't going away. The intelligent advertisers will learn to make the most of the various mediums without annoying their audiences (too much). Some people will make money peddling products supported by advertising and some will make money by selling products directly. Same as it always has been. We as consumers of products or services should be aware of the various ways in which we're paying for them.  Sometimes by cash out of pocket and sometimes by looking at ads.  Sometimes both.  Same as it always has been, at least as far back as published newspapers and likely even before then.
</description>
        <pubDate>Thu, 05 Jan 2012 14:47:14 PST</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2012/01/advertising.html</guid>
    </item>
    <item>
        <title>Windows Phone Code Sharing</title>
        <link>http://mkale.com/blog/2011/12/windows-phone-code-sharing.html</link>
        <description>I've been working on making two apps (lite and pro) based off a shared codebase.  On iOS, I do this with a single Xcode project with two targets.  I include most of the same source files in both targets and can build each one separately.  For the few differences between the apps, I use compiler flags to #define a different constant in each target and can use different code as needed.

I tried to do something similar on Windows Phone.  I created two separate .csproj files for the Lite and Pro projects, but had trouble including the same files in both of them.  I wanted to include many of the same .cs source files but keep the .xaml different, and the files in the "Properties" directory different.  (i.e., AssemblyInfo.cs and friends.)  I wasn't able to rename the "Properties" directory and have it work correctly, nor was I able to references .cs files that lived outside of the directory containing the .csproj file correctly.  It's possible I was doing something wrong here and there is a better approach, but this is what I came up with.

Top level directory contains .cs files for business logic, model classes, etc.  As much as possible.  It also contains the directories for each project, and the bulk of the code behind logic in files called (e.g.) "MainPageXamlShared.cs".  It looks like this:


directory winphone/
Statistics.cs  (business logic)
Contraction.cs  (model class)
MainPageXamlShared.cs  (shared code-behind)
ContractionTimer/MainPage.xaml
ContractionTimer/MainPage.xaml.cs
ContractionTimer/Properties/...
ContractionTimer/ContractionTimer.csproj
ContractionTimerLite/MainPage.xaml
ContractionTimerLite/MainPage.xaml.cs
ContractionTimerLite/Properties/...
ContractionTimerLite/ContractionTimerLite.csproj
... more files of course


I'm leaving out a bunch of files but this gives you an idea.  The MainPage.xaml in each directory are the full xamls (with differences between the two apps), but the code behind is entirely shared.  MainPage.xaml.cs in each directory looks like this:


using Microsoft.Phone.Controls;

namespace ContractionTimer {
    public partial class MainPage : PhoneApplicationPage {
    }
}


That's it!  All the logic is in the MainPageXamlShared.cs in the parent directory, which I was able to reference from each project with no trouble:


using Microsoft.Phone.Controls;
using System;
using System.Lots.More.Of.These;

namespace ContractionTimer {
    public partial class MainPage : PhoneApplicationPage {
        private readonly TimeSpan TIME_INTERVAL_SECONDS = TimeSpan.FromSeconds(1);
        // ...
        public MainPage() {
            InitializeComponent();
            // ...
        }
        // well, you get the idea ...
    }
}


This allows me to at least share the bulk of the code between two different versions of the app.  A couple of final notes:

* I know that Lite/Pro versions of apps are much less neeed on Windows Phone due to the very nice time-limited demo abilities of the platform.  This works for many people but I wanted to do the traditional Lite/Pro versions for this app.  That allows me to have a truly free (but ad supported) version that won't explode on people when they're in the middle of Labor.  And my app is one that people might only use (intensly!) for a few hours and be done with, so the time-limited demo doesn't work as well here.
* Please excuse my very basic understanding of Windows Phone.  The other reason I started with a Lite (free) app is that I'm stil relatively new to the platform and don't (yet) want to make anyone pay for my Windows Phone apps.  The last time I wrote serious code for a Windows platform, I was writing native C++ and COM based NT services that had no UI (but a lot of uptime!).  I've got a lot of catching up to do in the last few years, including basically all of .NET, C#, Silverlight, XAML, and an alphabet soup of other things.  I spend most of my time on iOS these days, what limited time I have after that on Android, and am attempting to work on Windows Phone here and there as a third platform.  Visual Studio sure is nice though, that's one thing I've missed.
* The method described above feels like a bit of a hack.  If anyone knows of a better way to share code between a Lite and Pro Windows Phone app, please let me know!
</description>
        <pubDate>Fri, 16 Dec 2011 21:44:54 PST</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2011/12/windows-phone-code-sharing.html</guid>
    </item>
    <item>
        <title>iOS 5 and Blank UITableView section headers</title>
        <link>http://mkale.com/blog/2011/10/ios-5-and-blank-uitableview-section-headers.html</link>
        <description>I have an iOS app which uses UITableViews and custom section header views.  Some of the sections are intended to be blank, so my -tableView:viewForHeaderInSection looked like this:



- (UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section {
    if (section == STATUSVC_SECTION_STATUS) {
        return nil;
    } else {
        return plainHeaderViewWithText(
                 NSLocalizedString(@"Recent Entries", @"..."),
                 tableView.bounds.size.width);
    }
}



where plainHeaderVIewWithText() is a funcion I've implemented like this.  (I use it in more than one place).



UIView* plainHeaderViewWithText(NSString *str, CGFloat width) {
    // Note: assumes ARC.  If you're not using it, you'll want
    // to send -autorelease or -release to the UIView and UILabel
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 35)];
    [headerView setBackgroundColor:[UIColor chooseYourColorHere]];
    UILabel *headerText = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, width - 10, 18)];
    headerText.font = [UIFont boldSystemFontOfSize:19.0];
    headerText.shadowColor = [UIColor grayColor];
    headerText.shadowOffset = CGSizeMake(0.0, 1.0);
    headerText.text = str;
    headerText.textColor = [UIColor whiteColor];
    headerText.backgroundColor = [UIColor clearColor];
    [headerView addSubview:headerText];
    return headerView;
}



Starting in iOS 5, though, I started getting unwanted blank headers that looked like this:


   &lt;img src="/blog/2011/10/ios5-extrabar-1.png" /&gt;


Not what I wanted!  Looking at the UITableViewDelegate protocol docs, I noticed [this bit](http://developer.apple.com/library/IOS/#documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html):

&gt; The returned object can be a UILabel or UIImageView object, as well as a custom view.
&gt; This method only works correctly when tableView:heightForHeaderInSection: is also implemented.

A hah!  That must be it.  Indeed, the docs for [that method](http://developer.apple.com/library/IOS/#documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html) mention:

&gt; Prior to iOS 5.0, table views would automatically resize the heights of headers to 0 for
&gt; sections where tableView:viewForHeaderInSection: returned a nil view. In iOS 5.0 and later,
&gt; you must return the actual height for each section header in this method.

So, the fix is to include this method in my tableview delegate:



- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section == STATUSVC_SECTION_STATUS) {
        return 0.0;
    } else {
        return 22.0;
    }
}



This gets me back where I wanted to be:


   &lt;img src="/blog/2011/10/ios5-extrabar-2.png" /&gt;


Lesson learned: read the docs and implement the methods they tell you to, even if it looks like you don't need 'em!

*Update 2012-04-26: converted code above to ARC*
</description>
        <pubDate>Mon, 31 Oct 2011 22:06:51 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2011/10/ios-5-and-blank-uitableview-section-headers.html</guid>
    </item>
    <item>
        <title>Code Prettify</title>
        <link>http://mkale.com/blog/2011/10/code-prettify.html</link>
        <description>I installed the [prettify module from google code] [prettify] so I can write about code here.  Let's test it out!  Just for fun, here are a few time helper functions that I use:


#include &amp;lt;time.h&gt;

time_t midnightOnDay(time_t t) {
    struct tm theday;
    localtime_r(&amp;t, &amp;theday);
    theday.tm_hour = 0;
    theday.tm_min = 0;
    theday.tm_sec = 0;
    return mktime(&amp;theday);
}

time_t todayMidnight() {
    return midnightOnDay(time(0));
}

bool areSameDay(time_t t1, time_t t2) {
    struct tm tm1, tm2;
    localtime_r(&amp;t1, &amp;tm1);
    localtime_r(&amp;t2, &amp;tm2);
    return ((tm1.tm_mday == tm2.tm_mday) &amp;&amp; (tm1.tm_mon == tm2.tm_mon) &amp;&amp; (tm1.tm_year == tm2.tm_year));
}

int daysBetween(time_t t1, time_t t2) {
    // we'll be rounding down fractional days, so set t1 to midnight and then do division
    time_t newt1 = midnightOnDay(t1);
    return ((t2 - newt1) / TWENTYFOURHOURS_SECONDS);
}



Let's see how this works!

### Update November 4th, 3pm

I disabled the module temporarily while I work out the formatting. 


[prettify]: http://code.google.com/p/google-code-prettify/</description>
        <pubDate>Thu, 27 Oct 2011 15:26:38 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2011/10/code-prettify.html</guid>
    </item>
    <item>
        <title>Where's the iPod Touch?</title>
        <link>http://mkale.com/blog/2011/07/wheres-the-ipod-touch.html</link>
        <description>Why is there still no Android / Windows Phone / WebOS / QNX version of the iPod Touch?  A smart-phone sized device roughly equivalent to the current top-of-the-line phone, but without the phone.  (And, crucially, without the monthly data contract that goes along with it).  One that runs most of the same apps as the phones and gives you much the same experience as the phones.

Apple has had an entry-level iOS device for years, which I'm sure has introduced many users and developers alike to the platform.  I got my start writing iPhone apps because of an iPod Touch that I got in the summer of 2008.  I'm now a small, independent mobile app developer and would love to write software for all these platforms.  However, my budget does not justify five monthly data plans.  I can't be the only one in this position.

Having a device is critical for two reasons.  First, you need to test an app on real hardware before releasing it to users.  The simulators / emulators are great for a quick code-build-test loop when doing major feature work, but nothing can replace actual hardware to test the performance and feel of an app.  (Plus, the simulators and emulators can have bugs and different behavior from the devices too.)

The more subtle reason is that you really need to experience a platform before you can write software for it.  Different mobile platforms have different UI paradigms, user expectations, different customs and beliefs.  You don't know how to use the Android menu buttons, or the Windows Phone 7 tile patterns, or whatever it is that QNX has.  Much the same as porting desktop apps between Windows and Mac OS X, you can easily tell when an app written for one platform has been ported straight across to another without really absorbing the UI paradigms of the new platform.  It doesn't feel right and the user experience is almost always bad.

To really get a feel for a new platform, you have to use it -- see what the platform vendor and other third-party developers are doing.  See how the platform works first hand.  You can't get those kinds of experiences from the simulator running on your desktop.  Which brings me back to: where are the entry-level contract-less devices?  If I could buy a sub-$300 device that ran Windows Phone 7 (or WebOS, or..) with the bulk of its features and apps, I would buy it in a heartbeat.  And then I would be able to tinker with creating software for it.  I'm smaller than most software development houses, who could likely afford to buy a handful of devices and the carrier contracts that go along with them before eating breakfast in the morning.  But a lot of great apps have come from small independent developers who would think twice before doing this.

It's possible that hardware manufacturers don't see much profit in these devices.  Indeed, looking at [Apple's numbers] [asymco], the total iPod market is much smaller than the iPhone market, and [Tim Cook says] [macworld] that the iPod Touch is only about half of total iPod sales.  Maybe HTC and Nokia look at those numbers and decide to pass.  (Their profits would likely be even less than Apple's due to Apple's volume purchase agreements with component vendors.)  But even if the hardware manufacturers don't see much/any profit in producing these devices, it should be in the platform vendors' interest that they exist.  Couldn't Microsoft or Google give some incentive to HTC to produce such a device?  And for HP and RIM who control their entire stack, couldn't they do it as a loss-leader for the platform?  (Especially HP and RIM, who are having trouble getting developer adoption on their platforms.)

We're starting to see tablets from various manufacturers running various operating systems that don't require a carrier contract.  They're not really competitive with the iPad yet, but they're getting there.  Wouldn't it be nice to see smaller handheld devices that could compete with the iPod touch?

[asymco]: http://www.asymco.com/2011/07/20/apples-growth-scorecard-for-second-quarter-2011/
[macworld]: http://www.macworld.com/article/161226/2011/07/cook_speaks.html
</description>
        <pubDate>Thu, 21 Jul 2011 16:09:17 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2011/07/wheres-the-ipod-touch.html</guid>
    </item>
    <item>
        <title>Comment Spam</title>
        <link>http://mkale.com/blog/2011/06/comment-spam.html</link>
        <description>On two occasions in the past month, I've gotten a burst of strange comment spam.  First on my [app website] [ebs], and then a couple weeks later on my personal blog.  The spam was unusual in that it didn't contain any offers for pills that alter the size of my waistline or other body parts, mail-order brides, mail-order college degrees, or whatever else the spammers are peddling these days.  Instead, it consisted of short, pleasant-sounding thank-you type messages.  Like the following:

* Real brain power on display. Thakns for that answer!
* That's not just the best ansewr. It's the bestest answer!
* Superior thinking demonstrated above. Takhns!

And on and on like that.  Each contains a misspelling, and there were other similarities as well:

* They were all generic enough to apply (kinda) to any blog post
* They all came from machines running Windows XP (though from various browsers)
* They came in a bunch.  I got about a dozen comments spread out across various blog entries all in the same day.  Then a new wave hit my other blog in a similar manner, but again all in the same day.

I did some research, eventually finding [this page] [research1], and a [hackernews thread about it] [research2] with people describing and talking about similar incidents.

#### Why the weird misspellings?

I imagine a common pattern for blog software is to put unknown commenters into a moderation queue but include a whitelist for previously known commenters, allowing them to post freely.  So it's possible that the spammers start by sending some innocuous-looking comments, hoping to be allowed into the whitelist.  Then, they come back and hit the website hard with spam comments once they are.  The misspellings make those exact phrases rare on the web, which makes them easy to search for using search engines.  The spammer might have a second-round piece of software that searches for blogs where their first-round comments got through, allowing them to focus further spam comments on those blogs where they are likely to be published.  (I hope that by including the phrases above, I'm not going to trigger a wave of second-round spam!)

#### Why no links in the comments?

As above, it might be that the spammers save the links to enhancement pill websites for their second-round of comments, thinking that the first round is more likely to go through without them, allowing them into more whitelists.  Another possible explanation is that my comment box does not have any "website" or "url" field.  Many blogs allow commenters to include a link to their personal website and spammers might think that including their spammy links in those fields makes it less likely that the comments get filtered out.  Their spamming software probably fills out web forms as completely as possible and then hits submit, not noticing that they never got a chance to leave their link as part of the comment.



[ebs]: http://earlybirdsoftware.com/

[research1]: http://www.thepursuitofquality.com/post/22/whats-the-deal-with-these-weird-comments-on-my-blog.html

[research2]: http://news.ycombinator.com/item?id=1332924</description>
        <pubDate>Sat, 11 Jun 2011 13:13:41 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2011/06/comment-spam.html</guid>
    </item>
    <item>
        <title>What's going on here?</title>
        <link>http://mkale.com/blog/2011/04/whats-going-on-here.html</link>
        <description>What's going on here and where is the old blog?  First of all, the old blog still [exists] [usblog], you probably just stumbled over here by mistake.  Click back over there and everything will be right with the world again.

But what's going on *here*?  I spent a large portion of my time at Cisco writing.  Emails.  Specs.  Documentation.  Notes on the bathroom wall.  That kind of thing.  Since leaving Cisco I haven't been writing nearly as much as before.  And I miss it.  So I'm going to try to write some geeky things here every now and then as a form of practice.  I like practice.

Will it be interesting?  Probably not.  Will it be frequent?  Probably not!  I've got a full time job as a stay at home Dad and a part time job as a [mobile app developer] [ebs].  So that doesn't leave much time for writing geeky blog posts that no one's going to read.  But I'll try to write a post or two occasionally when I can.

[usblog]: /us/
[ebs]: http://earlybirdsoftware.com/
</description>
        <pubDate>Sun, 24 Apr 2011 13:31:51 PDT</pubDate>
        <guid isPermaLink="true">http://mkale.com/blog/2011/04/whats-going-on-here.html</guid>
    </item>
</channel>
</rss>
