mkale.com

Language State of the World 2014

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.

Super Soakers and Patent Lawsuits

Lonnie Johnson, the inventor of the Super Soaker, has prevailed 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 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. 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 "I know it when I see it" 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 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.

Fusion

These guys 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, but this is at least step in the right direction.

Boosters

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 describing their pros and cons, noting that:

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?

Google's Missed Earnings

Someone (inadvertently) leaked Google's quarterly earnings report early, which shows falling advertising prices and lower income than expected, despite growing revenues. 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.

Microsoft Surface Surfaces

The Surface is here! 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.

Books

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, 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.

iOS 6 and Wacky Rotations

While updating my apps 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

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

message on rotation. I know that iOS 6 deprecates -shouldAutorotateToInterfaceOrientation, but near as I could tell -didRotateFromInterfaceOrientation 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 -application:didFinishLaunchingWithOptions

[self.window addSubview:[self.myRootViewController view]];

changed to:

self.window.rootViewController = self.myRootViewController;

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 -didRotationFromInterfaceOrientation 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.

Hockey

I'd love to love hockey.

Hockey Players
Practicing at the local ice rink

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. I can't bring myself to become a fan of a sport that condones this much violence.

Adam Gopnik's piece in the New Yorker puts it well:

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.

Servlets in Tomcat, Part 1

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.
  2. Download Ubuntu Server 12.04 LTS 64 bit
  3. Create a new VM with 1024 MB of RAM and bridged networking.
  4. Boot the VM using the Ubuntu .iso and install with defaults.

Booting the ISO

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

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, but you may also wish to use the official Oracle Java. Also install Ant, 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. 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):

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyTest" default="compile">
  <property file="build.properties" />
  <property name="appname" value="MyTest" />
  <property name="appversion" value="0.9" />
  <property name="src.dir" value="src" />
  <property name="web.dir" value="web" />
  <property name="lib.dir" value="lib" />
  <property name="build.dir" value="build" />
  <property name="dist.dir" value="dist" />
  <property name="publish.dir" value="${tomcat.dir}/webapps" />

  <path id="project-classpath">
    <fileset dir="web/WEB-INF/lib" includes="*.jar" />
    <fileset dir="${tomcat.dir}/bin" includes="*.jar" />
    <fileset dir="${tomcat.dir}/lib" includes="*.jar" />
  </path>

  <target name="mkdirs">
    <mkdir dir="${build.dir}" />
    <mkdir dir="${build.dir}/WEB-INF/classes" />
    <mkdir dir="${build.dir}/WEB-INF/lib" />
    <mkdir dir="${dist.dir}" />
  </target>

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

  <target name="build" depends="compile">
    <copy todir="${build.dir}" includeemptydirs="false">
      <fileset dir="${web.dir}" />
    </copy>
    <copy todir="${build.dir}/WEB-INF/lib" includeemptydirs="false">
      <fileset dir="${lib.dir}" />
    </copy>
  </target>

  <target name="dist" depends="build">
    <jar jarfile="${dist.dir}/${appname}.war" basedir="${build.dir}"/>
  </target>

  <target name="publish" depends="dist">
    <copy todir="${publish.dir}">
      <fileset dir="${dist.dir}" />
    </copy>
  </target>

  <target name="clean">
    <delete dir="${build.dir}" />
    <delete dir="${dist.dir}" />
  </target>

  <target name="all" depends="clean,compile" description="re-build all source"/>

</project>

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("<html>");
        out.println("<head>");
        out.println("<title>Hello World!</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

web/index.html (Static resource):

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

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

<html>
<head>
<title>My JSP Page</title>
</head>
<body>
<h1>My JSP Page</h1>
<p>Some static text</p>
<p><%= new String("Some dynamic text") %></p>
</body>
</html>

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

<?xml version="1.0" encoding="ISO-8859-1"?>
<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">
  <display-name>My Test Application</display-name>
  <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.test.BasicTomcatTest</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/myservlet</url-pattern>
  </servlet-mapping>
</web-app>

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!

History | Blog | mkale.com