There’s no root of all evil these days. You’re supposed to create an EvilContextFactory to obtain an initial EvilContext, use that to get an EvilEnumeration, and then iterate through the EvilBindings in a thread-safe manner.
Please create the following Java MIDP application for my phone:
When you run the application and take a picture of a barcode using the phone’s camera, it decodes the barcode, and adds the item to my Amazon wish list or some other Amazon list of my choice.
If Amazon doesn’t carry the item, it should add an “unrecognized item with UPC code xxxxx” item instead.
P.S. Please don’t try to patent it.
J2SE 6 has some interesting new XML functionality called JAXB. Using JAXB, you can take an XSD file and compile it into Java classes. You can then add those classes to your project, create an Unmarshaler object, feed it some XML which meets the XSD, and it will pass you back a tree of appropriate POJOs you can mess with.The only problem is that the XML file my source application generates refers to a DTD which JAXB tries to load via xerxes, causing epic fail.
Clearly I could rewrite the XML on the fly, perhaps even using XSLT to make the code even more enterprisey. However, I can’t help thinking that there should be a simpler way to either make xerxes/JAXB ignore the DTD (which, after all, it doesn’t need), or tell it how to find it.
Anyone happen to know?
[And yes, this is horribly enterprisey, but the benefit of being able to unmarshal a large population of XML-represented objects in only 20 lines of code is too good to pass up. Plus, I already know that the bottleneck in the intended application will be database speed.]
In mid November, our contract with AT&T (formerly Cingular) expired. We switched to T-Mobile and got BlackBerry Curve phones.
I was a BlackBerry skeptic for a long time. I didn’t think I wanted a phone with a full QWERTY keyboard. This changed when we looked at the phones available. It turned out that the Curve was only marginally wider than the average phone, perhaps a centimeter or so. It’s otherwise comparable to mid-range phones in size. It ends up being pretty much as portable as our Sony Ericsson Z520a phones.
The BlackBerry UI is best described as “retro”. The icons look like 1990s Windows, the text fonts look like 1980s Atari ST, and the general method of navigation most resembles Palm OS. This is both a good thing and a bad thing. Starting with the good, the UI is clearly designed from first principles to work well on a handheld device. The central trackball handles scrolling, pointing and clicking. It sits easily and naturally under the thumb. You can do pretty much everything with one hand, including browsing the web and checking e-mail.
This is in marked contrast to the iPhone, which pretty much requires two-handed operation. Windows Mobile devices suffer from having a desktop UI squeezed into a handheld form factor, and also require two hands, and often a stylus. Symbian is designed for phones, but the UIQ interface for smartphones uses a stylus. Overall, then, the BlackBerry works better than other phones I’ve tried when you’re standing in an airport with a coffee in one hand.
On the downside, it’s hard to find the icon you want in a hurry, because of their visual clutter. Perhaps a replacement UI theme would help; I’m a little tempted to grab the theme designer and start working on one, but it’s Windows only. The fonts were initially problematic too; nowhere near as nice as Apple’s, and they took some getting used to.
But when it comes time to reply to an e-mail, niggling issues with fonts were forgotten as I got to grips with the keyboard. Yes, it requires both hands, or more accurately both thumbs. It’s not as fast as a full size keyboard, but it’s faster than Palm Graffiti or Windows Mobile pen input, and much faster and less frustratingly error-prone than I found the iPhone’s on-screen keyboard to be. Unless Steve relents and allows a Son of Newton to use the Newton’s non-cursive text recognition, I can’t see it being bettered.
Textual messaging is where the BlackBerry really shines. It’s quite possible to thumb out fairly lengthy e-mail responses, or even update your web site. As far as IM, there’s support for Google Talk and AIM built in, as well as Yahoo Messenger, Windows Live Messenger and ICQ if you know anyone who still uses only those. There are third party clients for non-Google Jabber and other protocols, and in addition, there’s BlackBerry’s own BlackBerry Messenger, previously called PIN messaging.
If you have a friend who also has a BlackBerry, PIN messaging is definitely the way to go. The manual doesn’t cover its benefits, so I’ll digress a little here. Unlike other IM systems, PIN messaging is tied to the BlackBerry device by a unique ID. You connect with another person initially by sending them an invite via their BlackBerry-specific e-mail address, or any other address they access via BlackBerry e-mail. When they reply, their device records the device ID you sent, and sends you theirs.
The primary benefit of PIN messaging is that it’s push-based. The recipient doesn’t need to be logged in. If their phone is switched off, the message will be queued until they log on.
The second benefit of PIN messaging is that it’s reliable. Unlike SMS, messages don’t get randomly dropped. In addition, you get delivery confirmation automatically for every message: when you hit enter, the line you typed appears in the transcript with a small icon next to it indicating that the message is going out over the network. When your device receives positive confirmation that the recipient’s device has displayed the line you sent, the icon changes.
If that’s not enough, there’s a third benefit over IM or SMS: there’s a separate “ping” option. So you can set up your regular notification to be something discreet, and know that your spouse can ping you to set off something more noticeable if necessary.
Other than that, PIN messaging has the usual file transfer, allows you to send voice memos, and looks and behaves like regular IM. For us, it has completely replaced SMS, not least because it doesn’t cost 15¢ a message.
One interesting feature of the BlackBerry is that as well as individual icons for each messaging system, there’s also a unified inbox that shows IM, SMS and e-mail in one place. This makes sense, as they all have pretty much the same UI on the Curve; the protocol is almost an irrelevant detail. I believe that if you attempt to send pictures via SMS, the phone automatically uses MMS, but I haven’t tried it.
An alternative is Opera Mini, which takes the “thumbnail of page with moveable active area” approach to web browsing. It works surprisingly well with sites that the built-in browser can’t cope with, like zagat.com. (Yeah, good move, make a web site of restaurant reviews that doesn’t work with a phone browser.)
Maps are another strong point. There’s a map application supplied, but I downloaded Google Maps for BlackBerry, which is free and offers pseudo-GPS location by correlating your active cell to its geographical location. Accuracy can be as little as 50m or so in cities, up to 1km in the countryside. The Google Mail application also works well once downloaded.
The BlackBerry OS appears to be Java based, and is pretty solid. It’s more reliable than a Palm; I’ve only managed to crash it once, which is comparable to Linux on the N800 in solidity. Initial bootup (after inserting a battery) is horrendously slow, but once running it seems to use a soft power off which doesn’t require a full boot. The UI is generally responsive at all times, unlike some Sony Ericsson phones. You can put the phone into standby mode by holding down the power switch. In standby the screen and keyboard deactivate, but you can still receive messages and calls. The same hold-down-button action brings the phone out of standby instantly.
The one bug I’ve found so far is in the BlackBerry web browser. After a while the cache gets full and slows browsing down tremendously. The workaround is to empty the cache once a week.
The phone shows a lot of attention to the details of how a mobile device should best operate. For example, an ambient light sensor behind the notification LED turns the screen brightness down in dark areas, and automatically turns on the keyboard backlight. The LED itself has behavior customizable through the notification options; each event (phone call, IM, SMS) can have any or all of a user-chosen sound, vibration, and LED flashes. You can even set different messaging systems to have different notification; for example, I have IM just flash the LED a few times, unless it’s a PIN message from the spouse.
Mac sync is a bit of a sore point. There’s a package called PocketMac that BlackBerry purchased and now give away for free. It worked for me, more or less, but had some annoying bugs. (For example, syncing with a subset of address book records didn’t work, and editing records on the BlackBerry resulted in duplicates.) The solution is simple enough: Mark/Space have a Missing Sync for BlackBerry, which makes everything work, and even syncs user pictures so you can see the face of the person calling you if you’ve given them a picture in OS X.
Overall, it’s the best mobile phone I’ve used. Whether it’s good for you will of course depend on your use cases. If you’re someone who likes to talk to people or use voicemail rather than IM or e-mail, or if you have little patience for customizing software, the iPhone is probably a better bet. It certainly look prettier. But if you prefer text to voice and prefer functionality to prettiness, the Curve beats the iPhone hands down. This may change once they stop crippling the iPhone and open it up to third party applications; we’ll see. For now, I’d pick the Curve again, even if the iPhone wasn’t tied to AT&T.
Update: Oh yeah, the Curve is also a quad band phone. That’s de rigeur, so I didn’t even think it was worth mentioning.
You’re so almost there with your new Kindle e-book. There are just a few minor details you need to fix to get me on board.
First of all, you need Mac support, and preferably Linux support as well, both for content creation and for reading books. There’s really no excuse for not having reader support, as you have a working Mobipocket reader in Java that will run on Mac and Linux, you just haven’t taken the time to package it up properly. The creation tools ought to be a pretty simple task to port too; a command line version would be fine. I don’t even care if it can’t apply DRM; I just want a way to be able to package up free text.
Secondly, you need to either drop the DRM, or drop the price of the books. Let’s consider a real example here. I’m about to start reading Charlie Stross’s The Atrocity Archives.
Let’s get one thing straight here: because there’s DRM, I can’t sell the book when I’m done with it, which breaks the first sale doctrine. Therefore, you’re not actually selling e-books, you’re renting them to me for an indefinite period of time, a bit like Netflix does with DVDs. I’d respect you more if you admitted that.
Anyhow, If I go the Kindle route, it’s $9.99 for the book.
Suppose I go the paper route instead. I can pick up a new copy on amazon.com marketplace for $12 plus $4 shipping = $16. When I’m done reading it, I can sell it for $9 second hand. Total cost to me = $7.
So the Kindle is more expensive, and I can’t actually buy the books. That to me is a poor deal.
Oh, sure, Kindle prices include network bandwidth… but with paper books, I had to include the cost of physically shipping dead tree across the country, and I still came out ahead. If you can’t beat the paper book price-per-reading, you’re doing something seriously wrong.
We’ve all watched the music industry flail around overcharging for DRM-burdened files and get nowhere. Learn from their mistakes. Drop the DRM, or drop the book prices to $5 or so (comparable to a DVD or video game rental, plus some markup to cover network costs) and I’ll order my Kindle tomorrow.
Update: Of course, if you gave me the Kindle for free, I’d use it to buy books from you, and look on the extra cost as a convenience fee.
One of the things I found confusing about bash was its startup scripts: there were so many of them. Eventually I snapped and sat down with a terminal and the man pages, and worked out how it actually behaves. Here’s a summary.
On startup, bash executes any script labeled A in the table above, followed by the first script B it finds. On exit, it executes any script labeled C above.
Let’s look at the column headings in a little more detail.
- An interactive login shell is a shell that you are typing into, that is the first such shell you execute on the machine. Typically you will have had to log in immediately before the shell starts. For example, when you SSH to a remote system and type commands to that system, you are typing into an interactive login shell.
- An interactive non-login shell is a new shell started once you have already logged in; one which doesn’t require that you log in again.For example, if you open a new terminal window in your graphical user interface and get a shell prompt, that’s an interactive non-login shell. Another example of an interactive non-login shell would be a sub-shell started from inside a text editor; for example, typing :sh in vi.
- A non-interactive shell is a shell which doesn’t prompt you; it just runs a program and then exits. The most common example of this is any program written in shell script, such as a configure script, a startup script in /etc/init.d, or any other file marked as executable that has #!/bin/bash on the first line.
- A remote shell is a shell started by a program such as SSH or rsh in order to run a command on a remote machine.For example, the rsync and scp commands use SSH remote shells in order to copy files between machines.
So looking at the second column, an interactive login shell will execute /etc/profile always. It then looks for ~/.bash_profile, ~/.bash_login, and ~/.profile in turn, and executes the first of those it finds. On logout, it executes ~/.bash_logout.
The /etc/bash.bashrc A† item is special; whether bash searches for it is dependent on a compile-time option.
BASH_ENV is an environment variable which allows you to make non-interactive non-login shells (such as shell scripts) execute a startup script. Set BASH_ENV to the filename of a script and then invoke a sub-shell, and the script will be executed when the sub-shell starts up.
Problems with bash’s behavior
Given the above table, the short summary is:
- If you want something executed only when you first log in, put it in ~/.bash_profile
- If you want something executed only for additional shells (such as OS X terminal windows and xterms), put it in ~/.bashrc
But there are a couple of problems with this arrangement, problems which suggest that bash’s startup behavior wasn’t really thought out with users in mind.
Firstly, if you are anything like me, most of the things you want to put in shell startup scripts are things you always want executed. Command aliases, for example; or environment variables that tell pieces of software where to find their bits (JAVA_HOME, ECLIPSE_HOME).
You could put those in both .bashrc and .bash_login, but that represents a maintenance problem: if you change something, you have to remember to change it in both places. So, you might set up a third file for global stuff, and use the shell command source to read it in from both .bashrc and .bash_login. I’ve seen some Linux distributions set this up as the default. I don’t like it, however, because it means you now have 3 different startup files floating around, and when you want to change something you have to remember which file it’s in (or sit and work it out).
The second issue with bash startup scripts is that the distinction between login shell and non-login shell isn’t a very useful one these days. Most of us use graphical user interfaces, so we never see a login shell on the machine we’re using. (For example, any terminal window you open on OS X is a non-login one.) Even when I use SSH to shell into a remote system, I don’t generally want that first login to behave differently to any other shell I start (such as shells inside screen).
What I do care about, on the other hand, is whether the shell is interactive. I don’t want my reminder program printing stuff when rsync is trying to connect and transfer files. I don’t want all my custom commands and aliases getting in the way when running scripts to configure or build software. And I don’t want to slow things down loading cdargs unless I’m actually going to be maneuvering around the directory structure by typing.
So what I want is to have a single customization script, and be able to split it into stuff that is always run, and stuff that is only run when I’m using the shell session interactively. Here’s how to do that.
Simple all-purpose bash initialization script
Start off by moving all your current bash startup scripts into a temporary directory, so you have a clean slate. Then, create a skeleton ~/.bashrc that looks like this:
### Start of universal section ### # Commands in this section will be executed by both interactive and # non-interactive shells. # Commands here must produce no output, or they will break commands # like scp and rsync. ### End of universal section ### [ -z "$PS1" ] && return ### Start of interactive section ### # Commands in this section will be executed only by interactive shells. ### End of interactive section ###
Next, cd ~ if you’re not already in your home directory, then ln -s .bashrc .bash_login
Now you have a single customization file for all your shell sessions, called ~/.bashrc. You can copy in each command from your old customization files, placing them in the appropriate section according to whether you need them all the time, or just in shells that you’re typing in to.
If you really care about login shells
If for some reason you do want to have login shells behave differently from non-login, that’s pretty simple too. Instead of the ln -s command above, create the following ~/.bash_login file:
if [ -f ~/.bashrc ]; then source ~/.bashrc fi # Commands for login shells only go under here
Now you have two places customization commands may be placed, but you get the option of having login-specific stuff.
Dealing with multiple systems
Another trick I use is to examine the host name of the machine. This lets me use the same .bashrc everywhere; my Mac’s .bashrc is the same as the one I use on my Linux box and the System z mainframe at work. Here’s the code:
if [ "$HOSTNAME" = "T41p" ]; then # Customizations specific to the ThinkPad laptop go in here fi
You can use code like this in either the interactive or non-interactive section of the .bashrc above.
As the reality distortion field begins to fade, people are starting to wake up to the iPhone’s shortcomings. I’ve been assembling a list of issues I’ve seen mentioned:
- No SDK.
- No Flash.
- No Java.
- No Bluetooth file transfer.
- No DIY MP3 or AAC ringtones.
- Although the camera takes 2 megapixel photos, the only way to get them out is to e-mail them, which resizes them to 640×480.
- No Bluetooth keyboard support.
- Need a new battery? $80 and you have to mail the phone to Apple and wait 3 business days.
- Poor talk time.
- No instant messaging.
- No modem support for using it with your laptop.
- Recessed 3-pole headphone jack doesn’t work with regular headphone plugs.
- No video support from the camera.
- No MMS (multimedia SMS).
- Glass front invites disaster.
- No unread mark support in mail (IMAP).
- No filters in mail.
- No voice dial.
- Regular SIM cards don’t work, so you can’t get an overseas SIM and avoid roaming charges.
So yeah, definitely not buying one. But I bet iPhone 2.0 in a year or so will rock.
I’m an iPhone skeptic. While I appreciate good UI design considerably more than the average person, a good UI alone is not enough to make me accept a crippled and overpriced product.
At WWDC today, Steve Jobs has announced that the third party SDK for the iPhone is…make all your applications web applications, and access them from the Safari browser. Which means the user has to pay network bandwidth charges to run the application, and can’t make or receive any calls while it’s running. And of course, no service means your applications all stop working.
So basically, the iPhone is a closed platform, a very pretty but underpowered cellphone. It’s not a smartphone. It lacks even the capabilities of many low-end handsets offered by GSM networks, but it’s going to be sold at a premium price.
Let’s see how it compares with my current 2-year-old phone, for example:
|Sync with Mac||Yes||Yes|
|Photos of incoming callers||Yes||Yes|
|Play MP3, AAC audio||Yes||Yes|
|Play MP4 movie||Yes||Yes|
|Familiar telephone keypad||No||Yes|
|3rd party applications||No||Yes|
|Fits in jeans pocket||No||Yes|
To me, that’s a hell of a tough sell.
You may point out that my tiny phone’s screen isn’t great for browsing the web, but that’s just tradeoff I made because I like a phone that’s truly pocketable. If you prefer a big screen, you can get a Blackberry or Treo for $150 or less. Right now, Cingular has refurb 8525 devices for $99.
I prefer the hybrid solution: pair a small phone with my Nokia N800, and browse the web at triple the resolution of the iPhone. You can get an N800 plus a small Bluetooth phone and you’ve still saved $200 over buying an iPhone.
In addition, most of today’s phones take SD cards for memory expansion. I can dump movies onto a 4GB SD card and stick it in the Nokia. If I need more space, I’ve got a couple of extra 1GB cards floating around. What happens when you use up all the memory in your iPhone? You’re stuck, there’s no expansion option.
If the iPhone was $99, or even $199 at the most, I might be interested. At $599, it ought to sell like the similarly-priced PlayStation 3. It’s the most overpriced Apple product since the Mac Cube. (Which I loved the design of, but didn’t buy because it was overpriced.) It’s the most overhyped since the first Newton.
Oh, I’m sure Apple will sell some. I mean, the Motorola RAZR sucked, but plenty of people had to have it because it looked so cool. But then, the RAZR wasn’t $600…
You know how DST rules for the USA have been changed this year, and every OS needs patches?
You know how Java doesn’t use the OS’s info, so you have to patch all your Java VMs separately?
Well, it turns out that Sun’s “fix” was broken, in that it changed the behavior of the (deprecated) 3-letter time zones EST, MST and HST so that they now no longer reflect daylight saving time at all.
So, chances are you need to check every Java runtime again, and maybe delete 3 files, or run the fix again with a -bc flag.
But hey, you’ve got until 1am on Sunday to fix all your production systems. No big deal, right?
While I’m on the subject of Java’s date/time handling being a confusing mess, let’s talk about a few of the other things wrong with it…
Java.util.Date represents a date/time, i.e. an instant in time.
Java.sql.Time represents a date/time as well. It is a subclass of Java.util.Date, yet you can’t cast a Date to a Time. Instead, you have to get the epoch time in milliseconds from your Date, and use that long value to construct a Time.
To get the epoch time/date from your Date, you use the getTime() method, which gives you a long rather than a Time. Java.util.Calendar also represents a date/time. It also has a getTime() method. However, that getTime() method returns a Date object, not a Time object or a long epoch time.
Next: Calendar numbers months from zero, so January is month 0, February is month 1. This makes it unlike any calendar in human history.
Next: If you read a Time value from a database, you can’t examine it (e.g. check the hour is AM or PM) until you convert it into a Calendar. You can’t do that by simply constructing a Calendar with the Time value. The only way to create a Calendar with a particular time value is to construct an empty Calendar, then call setTime(). And of course, setTime takes a Date, not a Time. So you have to convert your Time to a long, convert the long to a Date, create a Calendar, then call setTime() on the Calendar with the Date as argument.
In fact Date objects are pretty much a useless relic, almost all date and time handling is done with Calendar objects. For example, SimpleDateFormat allows you to convert String objects to and from date/time values. However, it only returns Date objects. So your String gets parsed into fields, which are then converted by Java to a Calendar-like representation, which is then converted to a Date object passed back to you; you then convert the Date object back into fields in a Calendar so you can work with it.
Still, it’s a much more enterprisey way to do things.
The excitement started a week or two ago when I discovered that my ThinkPad laptop’s internal cooling fan had stopped working. As soon as I did something graphically intense for more than a minute or two, the system would overheat and perform an emergency shutdown.
Fortunately, I have a backup laptop.
Unfortunately, the backup ThinkPad laptop had also developed a fault. The fluorescent backlight for the display was failing. The screen was a curious reddish-purple color, and very dim—unless I turned the brightness up, in which case the backlight stopped working entirely, and everything went black. It also tended to crap out when the machine got warm.
So, I called the IBM hardware support line. The next day, the DHL truck showed up and I was handed a shipping box. I followed the instructions and shipped the dying-LCD laptop, which I figured was the less usable of the two. I enclosed the appropriate paperwork and a short description of the problem. Then, I went back to writing Java.
One day later, the DHL truck turned up again. It was my laptop, repaired. New LCD, and they also upgraded the BIOS while they were working on it.
Next, I installed Kubuntu on the repaired machine. I switched to Ubuntu back in June 2006, and had gotten used to GNOME. Unfortunately, the GNOME developers had subsequently decided it was a good idea to include the Mono runtime as a required part of gnome-desktop, and Ubuntu had made it a required part of ubuntu-desktop.
For those who don’t know, Mono is controversial. It’s a Novell project, and Novell just signed a deal with Microsoft to get permission to use patented Microsoft technology in Novell’s Linux distribution (SuSE). Mono is a reimplementation of Microsoft’s .NET, and it’s widely believed that Microsoft hold many patents that cover .NET.
One theory is that Microsoft is encouraging people to become dependent on Mono now so that they can suddenly threaten patent infringement suits and cripple desktop Linux later on. That might sound a little paranoid, but remember that Microsoft already funded SCO during their lawsuit alleging intellectual property infringement in Linux, so plenty of people are suspicious.
Anyway, I want no part of anything to do with .NET, so I had been planning to switch back to KDE and use Kubuntu once the next major release came along. But, with a newly repaired machine and the prospect of upheaval anyway, I decided I might as well make the switch now.
The next piece of excitement was when I discovered that Kubuntu doesn’t support ReiserFS. Regardless of whether Hans Reiser turns out to be guilty of murdering his wife, ReiserFS is on the way out, as Reiser’s team had stopped improving it in favor of Reiser4; and unfortunately, Reiser4 hasn’t made it into the Linux kernel.
So, I had to reformat the entire drive. After some research I decided to go with JFS. (Hey, it’s IBM dog food.) I soon had Kubuntu up and running.
Next I had to move my data over. I tried the direct approach, connecting the two laptops via ethernet and transferring my files over that. After a few minutes the first laptop overheated and shut down. Uh-oh.
I had a fairly recent full backup, so I restored that on the Kubuntu system. I then left rsync running overnight, at nice 19, with a bandwidth limit imposed. This got everything up to date slowly enough to avoid overheating.
Installing Java, Eclipse, VMware and IBM’s VPN software was next. Unpleasant, but it was done soon enough. I logged in and swapped the laptops, putting the newly repaired one on the desk and plugging in the external keyboard and trackball via USB.
Which is when things got really ugly.
The symptoms were unsubtle: the arrow keys, Insert, Delete, Home, End, Page Up and Page Down would all open Ksnapshot every time I pushed one of them. Investigating further with xev revealed that those keys were generating a spurious “release key with keycode 111″ event after each pair of correct events. No “push key with keycode 111″ event was being generated, but that didn’t seem to matter.
I investigated various possible fixes involving xmodmap. I tried unloading the USB HID kernel modules and seeing if X could handle the USB keyboard as an explicit second keyboard. Nothing worked.
Then, as I was staring at the output of lsmod, I had a vague recollection about UHCI and OHCI and EHCI and USB devices and incompatibilities… On a whim, I tried unplugging the keyboard from the USB hub, and plugging it directly into the laptop. Suddenly everything worked.
So it seems there’s some lingering bug in Linux’s USB keyboard support, which is triggered by USB keyboard converters. My guess is that when the keyboard is plugged into the hub, the incoming USB signals are converted to USB 2.0 by the hub, whereas when the keyboard is plugged directly into the laptop everything is done using USB 1.x. Perhaps the buggy module is only used for USB 2.0.
Actually, there’s one last lingering problem… if I type Shift-Insert the system goes insane, launching dozens of Ksnapshot windows. So I think I need to get a genuine USB keyboard. In the mean time, I’m making a mental note not to type shift-insert, which I don’t usually do anyway as most programs recognize the more usual Ctrl-P for paste.