Exception handling patterns and resource cleanup
Proper exception handling is an important part of writing correct Java programs, and unfortunately also a rather complex one. You need to be aware of how exceptions work for two reasons:
- Error reporting, and gracefully handling of errors generated by subsystems.
- Guarding resources, preventing resource leaks
This article will describe useful patterns in both categories.
Exception Basics
Exceptions can occur at any line of your program. If an exception is thrown, the code that is currently running will be aborted and control will jump to the nearest enclosing exception handler. As such, Exceptions are very useful to signal error conditions without cluttering your code with a cascade of if statements to see whether calls to statements succeeded. Your code will describe the Success flow of your program, while error handling will be confined to specific areas of code (so-called Exception handlers).
You define exception handlers in the following way:
try {
.
.
.
} catch (SomeExceptionType ex) {
.
} catch (OtherExceptionType ex) {
.
} finally {
.
}
catch and finally clauses can be ommitted if you don’t need them. That is, you can just define a try…catch or try…finally handler if you don’t need the other one.
This article assumes you know how the try… blocks work, what is caught by catch(...) clauses (viz. the Exception class hierarchy) and when the finally clause is executed. If you don’t yet, JFGI
.
Checked vs. Unchecked Exceptions
Java introduces the concept of Checked Exceptions. Checked Exceptions are special exception types of which the compiler checks whether you handle them, or pass the responsibility of handling them off to your caller. It is forbidden not to handle or pass off responsibility for checked exceptions. These are the exceptions that your editor warns you about if you fail to handle them (and it will usually offer to generate a default exception handler for you that will simply log the error and not do anything else).
Checked exceptions sound like a good idea in theory (more help from the compiler preventing you from making stupid mistakes!). In practice it turns out that this concept needlessly litters your code with exceptions-related boilerplate code: can you really “handle” a FileNotFoundException gracefully deep in the call stack where your openFile() method is called? What, do you retry with a different filename? No, the proper response is to display this error to the user, have him enter a different filename and then try again. However, because FileNotFoundException is a checked exception, you’re forced either to deal with the exception then and there (you can’t) or add the clause throws FileNotFoundException to every method signature in the call chain. If one of those methods is in an external library that you can’t modify, you’re SOL.
A more practical way to deal with checked exceptions that you can’t handle on-the-spot is to turn them into unchecked exceptions. Unchecked exceptions are exceptions that inherit from RuntimeException, so you can simply wrap the checked exception in a RuntimeException and throw that instead:
try {
.
.
.
} catch (IOException ex) {
throw new RuntimeException(ex);
}
Yes, you will lose exception type information in this way. In 90% of cases this doesn’t matter; when it does, define a custom subclass of RuntimeException and throw that instead, then catch it in some exception handler somewhere. Alternatively, you can inspect the exception stack with Exception.getCause().
Error Handling: Logging vs. Rethrowing vs. Doing something intelligent
“Dealing with them” can be as complex as retrying the operation or choosing a different strategy, or as simple as showing an error message to the user. Most errors you can’t do anything about, so your only recourse is to show them to the user, and let him figure out what is wrong and how to correct the situation. In fact, you should always put the infrastructure to do this in place anyway, even if you intend to catch and really handle some exceptions along the way. There is no way you can handle all exceptions, and keeping the user informed with error messages is always a good idea. Even if the user can’t correct the error immediately, he will come to you with a descriptive error message readily burned into his mind, instead of a generic “something went wrong” message after which you can go dig through logs.
With regards to logging: log as much as you want, but be careful: you may be logging the exact same exception many times in the log, which will confuse you later on as you start digging through the log. There’s no real need to do this, as the final stack trace of the exception will show all the root exception causes and their stack traces as well.
Error pattern: log and show error to user
Idea: you install a generic error handler at the very highest level in your application. Normally, it is bad form to catch exceptions of all types but in this case it is acceptable since you really want to catch any and all errors to prevent a system abort of your application.
In a web application, you typically install this error handler before you start handling a HTTP request. In a GUI application, you install the error handler in the event loop. In case you use a framework, that framework should provide a way to install an exception handler at the dispatcher level.
try {
switch (whatToDo) {
case 1: doAction1(); break;
case 2: doAction2(); break;
case 3: ...; //
// The actual handler methods called here are expected to throw exceptions
// in case anything goes wrong, and not to handle those themselves
.
.
}
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
displayErrorToUser(ex.getMessage());
}
Use Exception.getMessage() to obtain the error message for the exception. Conversely, if you throw exceptions, include a descriptive message to make the contents of this field useful to the user.
In a web application, displayErrorToUser() will simply output a nicely formatted error page, in a GUI application it may popup an alert box, etc. In a console application, it would typically print the error message to System.stderr and exit with an error code. In all cases, the state of the application returns to where the user can make another call: for the web application and the console application, the request/application is finished and the user can try another invocation with different parameters. In the GUI application, the event loop continues and the user can click another button to try again.
Error pattern: retry N times
In some cases of errors, you may want to retry an operation a number of times. In these instances, you typically only do this under very specific circumstances, in which you know it makes sense to retry. In this case, you don’t catch Exception but the specific exception type that you’re trying to recover from.
In this example, we try retrieving a webpage N times in the face of a NoSuchHostException (indicating that we are currently not connect to a network).
int tries = 10;
while (true) {
try {
readWebPage();
} catch (NoSuchHostException ex) {
tries—;
if (tries <= 0)
throw ex; // All tries used up, give up and throw exception to caller
try {
Thread.sleep(10000); // Sleep to avoid hammering the server and our CPU
} catch (InterruptedException ex) {
// Java threading exception that we can ignore
}
}
}
Resource Cleanup
It is important to always guarantee freeing up external resources that the JVM does not have control over. Typical examples of these that you will use in your application include database connections, file handles, network sockets etc. Anything that deals with the outside world (that is to say, anything that does I/O) typically needs to be cleaned up.
In the face of exceptions, it is tricky to guarantee cleanup of allocated resources. See the following piece of code:
Resource r = allocateResource(); doSomethingWith®; r.free();
If an exception is thrown in doSomethingWith(), the execution of this piece of code will abort, and hence r.free() will never be called: your program has a resource leak! If this happens often enough, the system may run out of resources and your application will cease to work, necessitating an application/server restart.
Fortunately, this is what the finally block was invented for.
The proper way to write this code is:
Resource r = allocateResource();
try {
doSomethingWith®;
} finally {
r.free();
}
This guarantees that:
- The resource will be released if it was allocated, whether or not doSomethingWith() succeeds or not.
- The resource will not be released if it was never succesfully acquired: that means an exception would have occurred within allocateResource(), before the try block was even started. It is the responsibility of allocateResource() to either allocate and return or don’t allocate at all; we will describe how to guarantee this in a following chapter.
Guarding multiple resources
A typical example of where you need resource guarding is when doing database operations. These typically involve a Connection, PreparedStatement and ResultSet, each of which must be closed separately or you will have a database connection leak!
The simple (and proper) way to deal with this is to guard every resource individually:
Connection c = openConnection();
try {
PreparedStatement s = c.prepareStatement(“...”);
try {
ResultSet r = s.execute();
try {
doSomethingWith®;
} finally {
r.close();
}
} finally {
s.close();
}
} finally {
c.close();
}
If you don’t like the christmas tree-like indenting of this piece of code, you can also achieve (almost) the same effect with a single try…finally block:
Connection c = null;
PreparedStatement s = null;
ResultSet r = null;
try {
c = openConnection();
s = c.prepareStatement(“...”);
r = s.execute();
doSomethingWith®;
} finally {
if (r != null) r.close();
if (s != null) s.close();
if (c != null) c.close();
}
This code has almost the same behaviour, except for one tricky detail: the close() methods can also throw exceptions! For example, if an exception happens while executing r.close(), the finally handler will be aborted and the ResultSet and Connection will not be closed, again leaking resources.
It is actually rather annoying that closing these resources can throw exceptions, because there is nothing that we can (or want to) do about this anyway. Either the resource doesn’t need to be closed because it already was (good enough for cleanup purposes!) or it can’t be closed for some other reason, and we can’t do much about that anyway except logging it. An easy fix is to create a helper close() method that will eat (and log) exceptions related to closing resources, guaranteeing that our finally block will run to completion:
try {
.
.
.
} finally {
if (r != null) close®;
if (s != null) close(s);
if (c != null) close©;
}
// ...
void close(ResultSet r) {
try {
r.close();
} catch (Exception ex) {
log.error(ex);
}
}
void close(PreparedStatement s) { /* ... */ }
void close(Connection c) { /* ... */ }
Resource ownership, and writing a resource allocator function
In the previous sections, we took for a given that the allocateResource() function makes the following guarantee:
- The resource is allocated if and only if the method returns without throwing an exception
At that point, the caller of the allocateResource() method becomes the owner of the resource, and becomes responsible for deallocating it. Thinking about the ownership of a resource is very useful if you’re trying to decide who is responsible for deallocating an allocated resource. For example, the following is typically an antipattern:
void foo() {
Resource r = allocateResource();
bar®;
}
void bar(Resource r) {
try {
// Do something with r
// ...
} finally {
r.close();
}
}
foo() triggers allocation of the resource, and then becomes the owner of that resource. However, the resource is ultimately cleaned up by bar(). Apparently, ownership of the resource is passed off along the way, but this is not clearly defined and behaviour is non-local (you cannot tell from looking at foo() that the resource is eventually cleaned up). Also, now you cannot call bar() on the resource anymore without the resource being released (which may be something that you want to do). All in all, it is better to keep the ownership of the resource confined to foo().
In some exceptional cases, it may be necessary to deviate from this pattern (due to constraints imposed by external APIs). If a method or class assumes ownership of a resource that is passed into it, document this fact clearly in its docstring!
Now let’s look at how to write an allocator function that deals properly with resource ownership and makes the proper guarantees about the resource (that is, allocated and ownership is passed off, or not allocated at all). Note: you might not need to do this! Often, allocator functions provided by various framework APIs may very well suffice for your purposes, and you could regard the resource setup phase discussed below could be rolled into your “do something with r” phase. Nevertheless, if you do design convenience functions or otherwise, the patterns described here still apply.
An allocator function typically looks like this:
Resource allocateResource() {
// Create
Resource r = createResource();
// Setup
r.setFoo(foo);
r.setBar(bar);
// Pass to caller
return r;
}
The point is that there are two steps:
- Creating the resource, typically done in a library function
- Initializing the resource, setting up various members and other stuff
The catch is that during setup, exceptions can happen, causing the allocator functions to abort. At this point, the resource to the reference will be lost and it will remain unreleased forever and, hence, leak. The trick is to catch any exceptions inside the setup block and in the exception handler, release the resource and re-throw the exception. This guarantees that the exception is signaled to the caller and the resource will be released properly. In Java, we have to deal with checked vs. unchecked exceptions. We could choose to declare checked exceptions, or simply convert all exceptions to unchecked exceptions. In the following example, we’ll do the latter:
Resource allocateResource() {
Resource r = createResource();
try {
r.setFoo(foo);
r.setBar(bar);
return r;
} catch (RuntimeException ex) {
r.free();
throw ex; // Unchecked, simply throw
} catch (Exception ex) {
r.free();
throw new RuntimeException(ex); // Checked, wrap
}
}
As you can see, the exception handlers are rather ugly because we have to deal with the checked/unchecked distinction. Another way that is slightly less repetitive code but also more obscure would be to do run-time type inspection on the exception object:
Resource allocateResource() {
Resource r = createResource();
try {
r.setFoo(foo);
r.setBar(bar);
return r;
} catch (Exception ex) {
r.free();
if (ex instanceof RuntimeException)
throw (RuntimeException)ex;
else
throw new RuntimeException(ex);
}
}
You can spot the similarities between the try…finally pattern used for guarding resources where you assume ownership, and the try…catch pattern used for guarding resources where you prepare to pass off ownership.
Combining error handling with resource cleanup
A lot of I/O related code throws IOException exceptions, and it is declared to throw these both on resource allocation, resource use and resource cleanup. Because IOException is a checked exception, you are required to catch these exceptions (or declare that you pass responsibility for catching these exceptions off to your caller). If you want to transform the checked exception into an unchecked exception, do so at the highest level.
Wrap your entire method body in a try…catch block that transforms the checked exception into an unchecked exception, and don’t try to deal with each invocation that can trigger an unchecked exception separately. Then, put nested try…finally blocks inside that exception handler to guard resources allocated inside the block.
Bad:
void writeOut(File file) {
Reader r;
try {
Reader r = new InputStreamReader(new BufferedInputStream(new FileInputStream(file));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
try {
String s = null;
do {
try {
s = r.readLine();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
if (s != null) System.out.println(s);
} while (s != null);
} finally {
try {
r.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
Good:
void writeOut(File file) {
try {
Reader r = new InputStreamReader(new BufferedInputStream(new FileInputStream(file));
try {
for (String s = r.readLine(); ; s = r.readLine())
System.out.println(s);
} finally {
r.close();
}
} catch (IOException ex) {
throw new RuntimeException(ex); // Checked to unchecked
}
}
Of course, the “bad” example here is quite pathological, but the difference illustrates the difference between integral and ad-hoc exception handling quite well.
Studious readers may notice that even the so-called “good” example is not free from a resource leak! If an exception is thrown inside either the InputStreamReader or BufferedInputStream constructors (unlikely as it is), the open file handle resource held by the FileInputStream will be leaked. That is why I usually overload functions that do I/O to accept both an InputStream as well as a File: the version that handles the File input will take ownership of the file and guarantees that the file handle will be released. As an added bonus, our API just became more flexible because it now can deal with data that arrives from other sources than just a file, such as over the network.
void writeOut(File file) {
try {
InputStream is = new FileInputStream(file);
try {
writeOut(is);
} finally {
is.close();
}
} catch (IOException ex) {
throw new RuntimeException(ex); // Checked to unchecked
}
}
void writeOut(InputStream is) {
try {
Reader r = new InputStreamReader(new BufferedInputStream(is));
for (String s = r.readLine(); ; s = r.readLine())
System.out.println(s);
} catch (IOException ex) {
throw new RuntimeException(ex); // Checked to unchecked
}
}
We do not close the Reader anymore because closing the Reader would also trigger a close() on the underlying InputStream, and the writeOut(InputStream) method does not have ownership of that stream. Instead, we rely on the fact that there are no external resources associated with the Reader, and that it will eventually be garbage collected so we can avoid cleaning up that resource. However, in the writeOut(File) call is used, note that the FileInputStream will be cleaned up regardless (because that method owns that stream).
Conclusion
This article has shown a number of principles and patterns to apply when writing code that deals with exceptions, and should help you writing write code that behaves properly and safely in the face of exceptions. If you disagree with any of this, don’t hesitate to leave a comment!
Foldable CD sleeves, with covers!
Holy crap! Two posts in one week?
Yep, you’re reading that right. Again it’s for some tool that I built. I’ve convinced myself that I should be producing something instead of sitting on my ass and/or playing StarCraft II, so there you go.
I’ve long been interested in handcrafting and folding useful things, and some of the most practical (and easiest) things to fold are CD sleeves. You can basically fold a very simple CD sleeve out of any piece of paper, by using any CD as a sizing measure (here’s a nice video demonstrating that). However, if you use this method, you just have a plain white CD sleeve. It would be nice to have a nice cover picture describing what’s on the CD.
It’s quite complicated to get such a cover positioned properly on a piece of paper. But hey, that’s what computers are for, right? So you can probably guess where this is going: yes, I made a website that you can feed an image to and it will generate a PDF that, when printed out and folded, will turn into a CD sleeve with a nice graphic cover.
I shall call it: the Foldable CD Sleeve Generator! Inator!
Enjoy, if you like to fold stuff.
readTHERE: move that hyperlink to another computer
I haven’t posted here in a while… so what better way to start again than by presenting a new tool I’m rather proud of?
It happens quite a lot that I’m reading some website on my phone while I’m on the go (probably one I found through Hacker News). But then, when I get to a spot where I have a PC or my iPad, I’d like to continue reading on the bigger screen. Or alternatively, maybe I want to take some page that I’m reading on my desktop computer with me to read while underway.
Problem is, there’s not really a comfortable way to get the link to my other machine. I could mail the link to myself, or use some bookmark-synchronizing service, but that all seems rather heavy-handed for what should be a disposable “copy and paste” action.
To scratch my own itch, I created readTHERE. You add a single bookmarklet to all your browsers, and from then on you simply activate the bookmarklet to copy the page you’re viewing at that moment to the central clipboard, and again on another machine to retrieve it.
Everyone wanting to use this service is free to do so, of course. Feel free to drop me a line with any comments!
Back of the Envelope: bike locks
Do you drive a bike regularly? And do you have one of those locks that are attached to your frame and put a bolt through your rear wheel? You know, the kind of lock that Wikipedia calls an O-lock? Here in the Netherlands, nearly everyone has one of these. But if you stop to lock your bike, you’ll notice that it has the tendency to hit one of the spokes in your wheel fairly often. So often that I was wondering:
What is the chance that if you randomly stop your wheel, the lock will jam on a spoke?
Now we’ll need some numbers for this, and I’ll use my own bike as an example to calculate this number. Here’s a model of my bike:
The model has the following parameters:
- Radius of the wheel where the lock bolt crosses it (r).
- Width of the bolt (w).
- Number of spokes in the wheel (n).
For my bike, the numbers are:
- r = 277mm
- w = 9mm
- n = 36
To answer the question, I’ll assume that the bolt is infinitely thin, and each of the spokes is twice the width of the bolt, at radius r. Physically, the chances of the bolt catching on the spokes are the same, but the problem now nicely reduces to:
What percentage of the circumference at radius r of the wheel is taken up by the bolt-wide spokes?
Although you can’t tell from the drawing I make, spokes don’t overlap at the radius of the wheel where the bolt crosses it. This is actually a requirement for my reduction of the problem, but one that all bike wheels will satisfy.
The question is now easy to answer. For my bike, it works out to:
As it turns out, the chance is better than 1 in 3 that my lock will catch on a spoke. Suspicion confirmed!
Me so sexy!
(This post is about a joke in Dutch, so feel free to not get it if you don’t speak the language…)

Yes please
I’ve wanted to make this joke for a couple of months… every time my train arrived at platform 7 of Utrecht’s central station, and I passed this Kiosk on my way out. Yesterday was finally the day, with many thanks to Jan Ouwens
. And Berns, who didn’t want to have anything to do with the whole spectacle and was playing on his Nintendo DS a couple of meters away.
Oh, and there’s also a YTMND (warning: probably NSFW
).
A look into prebuffering
The QuickTime playback bar
I’ve been interested for a while in the prebuffering algorithm that QuickTime uses… you know, where it loads a movie clip and automatically starts playing it as soon as the clip can be finished playing without interruptions. I was wondering about the equation they were using for that, especially since a friend told me it was an equation that couldn’t be solved.
So today I tried to drill down and see if I could come up with a solution (and it’s a good opportunity to plug one of my recent applications
).
First off, a few definitions:
The input parameters to the equation:
- Download rate d (in bytes/second)
- Sample rate s (b/s)
- Video clip length n (s)
Output of the equation:
- Prebuffer length b (s)
We pick a time b.
- At that point, the bytes downloaded so far is

- That means that there is still left to download:

- That means we simply have to pick b so that the time needed to download the remaining file size (
, or simply
) is smaller than or equal to the time it takes to play the entire clip.
In short:

Well, what are the solutions to that? (Excuse me if I’m being too verbose here)

Which is, come to think of it, not all that surpising: the buffer b has to accomodate for the difference in download and sample rate (s – d), for the entire length of the clip (times n).
So what’s the final solution, should you ever need to implement such a beast? Here it is:
Equation to find the minimum fill level of the autoplay buffer
I hope you’ve enjoyed my deriving and stating the semi-obvious. Have a nice day
.
I hate the Dell Inspiron 1100
I hate it with a vengeance. Don’t get me wrong, I’m very grateful to my current employer for providing me with a notebook to use since I butchered my last one[1], but that doesn’t change the fact that I hate the guts of the thing. Don’t buy one. Seriously.
It began with the confusion I felt the first time I turned it on: there’s a big, round, invitingly large power button at the top, with an array of LEDs nearby, and I happily pressed the big button to see my new worktoy in action. Except none of the LEDs lit up, and the device didn’t seem to do anything. I press the button again. Nothing. And again. Nothing.
Closer inspection revealed that the three LEDs, at least one of which I had mistaken for a power LED, were actually the keyboard’s NumLock, Caps lock and Scroll lock LEDs. The actual power LEDs are at the front of the device, conveniently located out of sight when you’re interacting with the power button. And yes, I had turned the device on properly at the first press.
I hesitate to think about the design choice that was made to put those LEDs there, because they are confusing and annoying. Annoying, because if you try to watch a movie on the laptop in a darkened room, you’ll constantly see a bright green LED just below the image. And in my case, also a flickering orange light… my battery light is busted and keeps indicating the battery is empty — even if I’m plugged into a wall socket. Oh plus, there’s another button there whose function I haven’t figured out yet. Pressing it does absolutely nothing…
The Inspiron 1100′s LED anatomy:

As long as we are on the subject of hardware design, I think the top lid deserves mention. It feels like it can break off at any moment just by handling it. To say it’s wobbly is just not doing it justice. As my device is second-hand, I don’t know if it has always been this way, but I strongly suspect it has. It’s like the lid is pretty tight if you flip it open or closed, but then has some added wobble room of a few centimeters, just to give you the impression the thing will fall apart if you touch it the wrong way. Which I imagine is probably true…
Ah, and who can rant about a notebook without forgetting the keyboard? Notebook keyboards are horrible by default, so there’s not much that needs to be said. Yes, the keys themselves are fine (although they require at least twice as much pressure as my previous notebook)… it’s just… the layout is simply abysmal. Of course that’s par for the course on notebooks. It seems just about every notebook manufacturer feels the need to reinvent the key layout, merrily moving around commonly required editing keys like Home, PgUp and Down, End and Delete. For me, the biggest annoyances with the Inspiron:
- Who needs the Windows and Context keys on the lower row? We’ll move them to the top right!
- You know the Delete key that used to be there? Now there’s room for that on the lower row, where it never ever ever ought to be!
- And just for good measure, we’ll also move the tilde/backquote (~`) key, traditionally found left of the number keys, to the top right. Will we put another key in its place? Nah, we’ll just leave the space half-empty.
So far I’ve covered the front, but here’s another interesting design desicision for you: we’ll put the air vent on the bottom! That’s right. You can take this lap-top you’ve just bought, but if you go ahead and put it on your lap, you pretty much get the top of them burned. I know my previous laptop was pretty hot to have on my lap, but this one is blowing hot air onto my legs! (We’ll I’m told the hole there is for sucking in cool air, but I really can’t tell the difference, except the effect it is having on my thighs, and it’s not a good one).
On to peripherals: there’s not much I expect from a laptop in that area. Except this: a PS/2 port! Instead of a regular PS/2 port, there’s two USB connectors and that’s it. Yes, I realize that in the year 2000, we will all go to our jobs in flying hovercars and all peripheral devices will use USB, but right now, there’s still a whole lot of PS/2 keyboards and mice lying around. Not offering support for them is just cheap. The keyboards I like best are the cheap, plastic, standard PS/2 keyboards. Forget hooking them up: right now I’m typing on a shitty Trust Slimline keyboard, that also insists a ridicilous key layout (because let’s face facts: who would want any key where they can find them blindly?). And don’t forget: if you’ve hooked up a keyboard and a mouse, you can forget another USB device like a memory stick. Granted, the keyboard problem is more one of my workplace than one of the laptop itself… but it annoys me nonetheless.
But there’s good news! It has a built-in modem, for all your 56k pleasure! I guess it must have slipped by the banish antiquated standards committee. Needless to say, I haven’t used it once.
I guess that pretty much covers the hardware on the outside. On to the juicy center!
The Inspiron 1100 is powered by a 2.4GHz Pentium. Rather than feeling “Holy jeepers Batman!”-fast, it feels okay. I guess being on a notebook will do that to a 2+GHz CPU. On the other hand, there’s the point of diminishing returns: from a certain point, if you’re not doing heavy calculations, you won’t notice the difference in speed from just using Windows.
I do suspect some kind of a bus problem though. Don’t call me on the specifics, because I’m not much of a hardware man, but CPU usage increases extremely when downloading files over a network connection: downloading files from an FTP server with ~500KB/s takes 70% CPU. I haven’t done enough testing to determine whether the CPU usage stems from the network card or the harddisk, but fact remaings that this is extremely annoying. Continuing to work with a download in the background becomes a chore because of sluggish response. However, I seem to recall my old laptop had the same problem, so it may just have something to do with the inherent architecture of a notebook.
And last but not least, there’s the video card, an Intel 82845G. The funny thing is that on Intel’s site, it’s not listed under “Laptop graphics controller”… instead it’s filed under “Desktop graphics controller”. Oh Dell, what have you been up to?
It’s an Intel Extreme Graphics card, who — as you may know — are far from. I’d say it’s decidedly un-Extreme. On the other hand, perhaps they meant to say Extremely Slow. You can pretty much forget playing games on this thing, because although the notebook advertises to have a pretty beefy CPU, the graphics card pretty much cancels out any performance you might have hoped to gain.
Too bad, but that’s not the worst of it. One of the great things about working on a laptop is that it’s a breeze to get multi-monitor setups working. All you need is an spare monitor and *bam*, double the desktop, double the fun! Right? Nope, not on the Inspiron. As per Intel’s site:
Multi-monitor is supported on most Intel® 82845G graphics controller-based systems using PCI video cards to support additional monitors. With the latest Intel® Extreme Graphics Drivers for the Intel 82845G graphics controller, the integrated video can be either the primary or the secondary display adapter. Multi display is not possible with the onboard display and an AGP add-in card (the AGP card will disable the onboard graphics).
That’s right. You’re on a laptop, you could have the easiest dual-head setup possible, just plug in a monitor and go, but you can’t because of a shitty video card. So what is the VGA ext connector good for? Clone display. Excuse me while I go contain my excitement.
Actually, come to think of it: I suppose the above excerpt reads something different than I thought it did. But that doesn’t change the fact that I still can’t use the “extend desktop” feature. So the verdict stands, and the card is still shitty.
But wait, I’m not done yet! Here’s another interesting tidbit about the video card: if you close the lid of the laptop, and reopen it, the video card gets reinitialized! That’s right. I can’t imagine why, but it really does that. It’s only really a problem with mplayer: I guess from the way it works, it depends on some kind of open connection with the video driver. In any case, if mplayer is running, and I close and reopen the lid, mplayer crashes as the video card reinitializes (I make it a point to disable the “on lid close go to standby” option). And it’s not like the video card goes down when the lid closes, and comes back up when the lid is reopened; no, that would have been too logical. In fact, it happens a good second after I’ve opened the lid, and it goes something like this:
- Close lid
- Backlight switches off
- mplayer keeps running
- Open lid
- Backlight comes on
- mplayer still running
- SCREEN GOES BLACK
- Screen comes back on
- mplayer kicks the bucket
Is this something that occurs in daily life? It does for me: see, I have a fairly long commute to work (50 minutes by train, then 20 minutes by bus), and I like to pass the time by watching a movie or TV show. When I have to transfer between train and bus, I like to just close the lid and put the laptop in my bag, go to the bus, take the laptop out and continue watching — saves me the hassle and the time of shutdown/startup, and again startup when I arrive at my workplace. Except each time I do this, my media player crashes and burns because of the stupid behaviour of the video card. I’d really like to see some justification for this behaviour, because it seems completely pointless to me. Just one more factor in my hatred of the Inspiron 1100…
I believe that pretty much covers my beefs with this inane piece of technology. Each one of them may not be a big problem, but they add up and the total picure is that this is just not a well thought-out machine. And news is not all bad on the Dell front. I have some friends claiming to be very satisfied with their Dell laptops. I guess it’s just my luck.
Despite this all, is there nothing good to say about the Dell Inspiron 1100? Oh sure… it performs its job adequately, and judging from the various lids on the bottom, maintenance of the thing will be pretty easy (something I’m not surprised of, coming from Dell).
It’s just, bitching is a lot more fun
…
Peace out y’all!
Footnotes:
[1] A trusty Fujitsu-Siemens Lifebook C. Yeah it was old and slow, but sturdy and reliable! Except it doesn’t survive coffee spills and it certainly doesn’t survive dropping it on the floor from 2 meters…
Oh noes! Teh Microsofts are teh sux0rz!
Some things annoy me to no end. Lots of things actually J. But one of the top-ranking things on those list is the ongoing notion many people seem to have that in Windows, clicking “Start” to shut down your computer, is one of the stupidest things since peeing on electrified fence (which is, admittedly, pretty stupid).
Just now, I was reading an amusing rant about the poor state of graphical user interfaces, when I came across this little gem of sit-down comedy:
Situations like these make me feel sorry for the spacebar. So big and strong… He totally rules over the other keys, and yet all he produces is… nothingness. I hope I never find myself in the situation of having to explain to aliens what the LARGEST KEY ON THE KEYBOARD does. »Well… this key? Right over here? Ah, the chubby one! It.. spaces… kind of… leaps.. a tiny bit. In the text… <demonstrates> See…? Nothingness! Hey, I know how this must sound… Hey! Wait!! No!! Come back!! But we just met!! COME BACK!!«
That’s alright, they would probably have left anyway as soon as they saw me clicking »Start« in order to shut the computer down.
And this is not the only time the world has been exposed to this unimaginable sense of funny. How many times have I not encountered a joke like this: “Typical Microsoft logic: clicking Start to shut down”.
OMIGOD MICROSOFT ARE SUCH IDIOTS I DON’T WANT TO START I WANT TO STOP OMG LOLOL!!1one
Oh come on people. First of all it’s not funny, and second of all — if you want to be serious — it’s not even valid criticism!
Disregard for a moment that the button is labeled “Start”. This is just The Menu. The only one at that. You click on The Menu if you want to perform a task, such as execute an application. After that, The Menu just needs a name. Preferably an evocative one, so that it turns into a easily recognizable concept with the users.
Start Menu is just right for that:
- It does not have pre-existing connotations;
- It’s short and easily remembered;
- It’s kind of appropriate too. If you want to perform a task, you start by clicking this menu. Yes, that means, even when you want to shut down your computer, you start by clicking “Start”.
Why not call it something else, like “Application Menu”? Well, that doesn’t quite fit. For one thing, the Start Menu contains more than just applications. And besides that, “Application Menu” just sounds dull and uninspired.
So “Start Menu” it is. I challenge you to come up with a better name.
And if all else fails… you can’t really be calling for something like this:
Err… can you?
Bluetooth between phone and PC
I’ve spent the last two days pulling out my hair, trying to get an application on my PC talking to my Bluetooth phone. If you have an inbuilt aversion of using Java for PC apps (like I do), there is preciously little documentation about this. Benhui shows how to do this particular thing between two Java applications (one running on the phone, and one on the PC). But if you don’t want to use Java on the PC, you’re pretty much stuck using sockets, and there is little documentation example material out there on the net.
So this is where this blog item comes in. I’m going to tell you how I did it, and share my source code.
This code uses the Microsoft Bluetooth Stack Socket API. You require WinXP SP2 for this, or — reputedly — WinXP SP1 with the Bluetooth stack downloaded and installed separately. Linux uses a completely different stack, obviously, with BlueZ and Affix being the most popular. These stacks also have socket APIs, so you may find the code presented here useful, but remember that this code is specifically for Windows.
On your PC, you will need some constants and structs from the MS Bluetooth SDK. I implemented these in Delphi, but you can use them equally well in any language.
I did this in Delphi so that’s the language these definitions will be in. You should be able to translate them easily into your programming language of choice:
// Bluetooth address family
AF_BTH: Integer = 32;
// Bluetooth SPP protocol
BTHPROTO_RFCOMM: Integer = $0003;
// Bluetooth service namespace
NS_BTH: Integer = 16;
// Bluetooth address struct
PSockAddrBth = ^TSockAddrBth;
_SOCKADDR_BTH = packed
record
addressFamily: U_SHORT;
btAddr: Int64;
serviceClassId: System.TGUID;
port: ULONG;
end;
TSockAddrBth = _SOCKADDR_BTH;
For Delphi, you’ll also need a copy of the winsock2 headers, because we require theWSASetService call, which is not available in the winsock header that is shipped with Delphi. You can find it via Google.
The (simplified) code goes like this:
// ———— Variables ———————–
var
s,t : TSocket;
sa, ta : TSockAddrBth;
sasize, tasize : Integer;
ca : CSAddr_Info;
qs : TWSAQuerySetA;
// ———— Code ————————-
// Create Bluetooth socket
s := socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if s = INVALID_SOCKET then RaiseLastOsError;
// Bind to listening address
sa.addressFamily := AF_BTH; // Address family
sa.btAddr := 0; // Address not set
sa.serviceClassId := NullGuid; // NullGuid is simply a GUID with all zeroes
sa.port := ULONG(-1); // Let OS select port
if bind(s, PSockAddr(@sa), sizeof(sa)) = SOCKET_ERROR then RaiseLastOsError;
// Get the bound name back, required for WSASetService
sasize := sizeof(sa);
if getsockname(s, @sa, sasize) = SOCKET_ERROR then RaiseLastOsError;
// We need to register this socket with WSASetService, so that it can be
// discovered by other Bluetooth devices. Filling
FillChar(ca, sizeof(ca), 0);
ca.LocalAddr.lpSockaddr := @sa;
ca.LocalAddr.iSockaddrLength := sizeof(sa);
ca.iSocketType := SOCK_STREAM;
ca.iProtocol := BTHPROTO_RFCOMM;
// Set service record
FillChar(qs, sizeof(qs), 0);
qs.dwSize := sizeof(qs);
qs.lpszServiceInstanceName := 'My service';
qs.lpServiceClassId := @MyGuid; // MyGuid is an application-specific GUID
qs.lpszComment := 'This is a test service';
qs.dwNameSpace := NS_BTH;
qs.dwNumberOfCsAddrs := 1;
qs.lpcsaBuffer := @ca;
// Register service
if WSASetService(@qs, RNRSERVICE_REGISTER, 0) = SOCKET_ERROR then RaiseLastOsError;
// Set-up is complete. You can now use the other socket functions,
// listen(), accept(), recv() and send() as usual.
On the mobile phone, you will need to write a J2ME application that uses the JSR-82 API, which is a standardized Java API for Bluetooth. To write the application, you will need to install 250MB’s worth of Java SDK (the J2SE SDK and J2ME SDK). I based my application on the BluetoothDemo application that is included with the J2ME.
Key points:
- Use the same GUID as MyGuid used above, as the only GUID in the UUID list when specifying a device search. You don’t need to use the attribute set used in the example.
- Make sure you are not connected to some other device (such as the Nokia PC Suite) when doing a device discovery — otherwise it won’t work.
If everything goes well, you should be able to discover the socket you just created (provided you have set your computer to discoverable in the Bluetooth settings), and connect to it. After that, you can exchange application-specific data in the same way as a regular socket/stream connection.
This post does not cover using Bluetooth standards, such as the OBEX protocol. I might post something about that when I figure it out, but since it doesn’t interest me very much at the moment, don’t count on it anytime soon.
