|
|
|
||
|
While doing my standard early morning web-walk I stumbled on a mother lode of J2SE 1.5 information. JDiff isn't necessarily 1.5 specific, but it allows you to see all changes that occurred in the API. JDiff is one of those thing you wish you stumbled on years ago. While perusing the diff on |
|
||
|
I recently took the opportunity to see Roman Polanski's The Tenant at the Gene Siskel Film Center. I left the theatre completely speachless (and for those that know me, that's no small feat). For anyone that loves independent or avant-garde films, I would add this one to the list. The Tenant reminded me at times of Marc Caro and Jean-Pierre Jeunet's Delicatessen, another wonderful film. I would love to see a modern indie director, such as Darren Aronofsky, do a remake of The Tenant with a Delicatessen flare. I'm adding "create remake of The Tenant" to the list of things that I should do once I'm rid of these shackels that bind me to my computer. |
|
||
|
It is a common belief in the industry that programmers are just interchangable cogs. "Programming is programming", right? I believe that as SOAs, MDAs, RTIs and other "standard" architectures become more prevalent that this "interchangable cog" belief will initially become stronger due to perceived simplification of tasks. Unfortunately, this is exactly opposite from what the reality is. As the nuances, scope and concerns of a specific architecture grows, developers become more and more specialized in that architecture. Specialization limits ones general knowledge (or just pushes it further down the stack) and therefore limits interchangability. This specialization trend can be seen in regards to development languages, platforms and applications. For example, interchanging a C developer fluent on Unix with one fluent on Windows is a recipe for disaster. The same can be true for Java and C#, or PeopleSoft and SAP. I have recently tasked myself with determining how our universities are meeting the demands of greater specialization and addressing this interchangable cog paradox. At first glance it appears that there is little being done but I am only at an initial phase of my research. In a recent conversation that I had with a professor at my alma mater, I learned that most universities purposefully have more generic and abstract courses to separate themselves from trade or vocational schools. I'm a man on a mission and I will post more information as I acquire it. |
|
||
|
Given the plethera of "enabling technologies" such as J2EE, does web programming (specifically, tier two -- business logic) make for a lazy developer? In the recent past, I was prototyping a web application using Spring, Struts, and a few other technologies sprinkled in for good measure. After a few weeks of stateless whos-its and whats-its, injecting transaction doo-dads, and so on, I moved on to a project involving NIO, wire protocols, and high degrees of concurrency. Getting back into the swing of worrying about multi-threaded issues, object creation weight, and the like was not a trivial excercise. Let me stress that I'm not referring to API nuances. I'm speaking to the vastly different sets of skills that need to be employed. I felt that a much larger degree of care and awareness was needed when dealing with "systems programming". The web technologies on the other hand made me feel less concerned: "JTA will handle that for me so I don't need to worry." Don't get me wrong, JTA, JMS, JNDI, etc are wonderful things that eliminate much of the tedium and start-from-scratch'ness that allows projects to get done are the current break-neck pace. (I admit that I am making the overgeneralization that enabling technologies and web development are synonymous.) But does all of this "simplification" provided by enabling technologies allow developers to go lax? ... or has all of the hype and marketing surrounding these enabling technologies simply obscured the diligence required? |
|
||
|
How many times have you seen the following?
public void myMethod(...)
throws ...
{
try {
... entire method is here ...
} catch(SomeException se) {
....
}
}
Consider when entire method is here is more than a dozen lines or so with a number of statements that throw Limiting the scope of A common case to watch out for is one where a There are cases where a large |
|
||
|
I constantly run across code that looks like:
public class FileReader {
...
/**
* <p>Reads the file with the specified name and returns the
* contents in a {@link java.nio.ByteBuffer buffer}.</p>
*
* @param filename the name of the file to read
* @return an allocated (not direct) <code>ByteBuffer</code>
* with the contents of the file
* @throws IOException if an I/O error occurs
*/
public ByteBuffer readFile(final String filename)
throws IOException
{
...
}
...
}
What's wrong with that? you're probably asking yourself. It's even got comments! The title of this entry should give you a little clue. I will spare you the rant and soap box about the proper use of exceptions and attempt to appeal to your common sense: If you, as the developer of the function, couldn't handle or recover from the The interface or contract that you expose should not break encapsulation. The fact that you (as the developer) have I/O issues to deal with doesn't need to be exposed out to the user. What the user cares about is: did the function succeed or not, and if not, are there cases that they can possibly recover from. A more sane interface might look like the following:
public class FileReader {
...
/**
* <p>Reads the file with the specified name and returns the
* contents in a {@link java.nio.ByteBuffer buffer}.</p>
*
* @param filename the name of the file to read
* @return an allocated (not direct) <code>ByteBuffer</code>
* with the contents of the file
* @throws NoSuchFileException if there is no file with the specified
* name
* @throws ReadFailedException if there was any unrecoverable
* problem while reading the file
*/
public ByteBuffer readFile(final String filename)
throws NoSuchFileException, ReadFailedException
{
...
}
...
}
This interface throws two exceptions: What's more is that by not throwing The next time that you are developing an interface, think about how a user will use that interface. Get into their shoes and think about their concerns. And most importantly, make sure that you're not breaking your own encapsulation. |
|
||
|
If you use Perforce I find it best to start off a new change with "New Changelist" and a rough outline of what I intend to do. This is a nice way of informing others (especially in a decoupled work environment) what you are going to be working on. As I begin to make changes I will "Edit spec" to keep the change list description up to date. This ensures that not only will others be aware of what I am doing but I wont run into the dreaded situation where I don't actaually remember all of the changes that I made. Don't forget to add the added, updated, or deleted files to this changelist as you go. |
|
||
|
I end up doing a lot of marshalling between Java and C over the wire. ByteBuffers are a natural fit for this situation given The problem comes in when dealing with Strings. There's no 0062006f 006c006c 006f0063 006b0073 .b.o.l.l.o.c.k.s This is all fine and dandy if you're going to another Java application (or something that's commonly double-byte) but when going to vanilla C you're looking for single byte characters. Your next bet is to try: final String string = "bollocks"; final ByteBuffer buffer = ByteBuffer.allocateDirect(string.length()); buffer.put(string.getBytes()); This is fine and dandy for most applications. (It should be noted that the default character set is used in the transformation and that unless this code is used in a controlled environment, you may end up getting final String string = "bollocks"; final byte[] stringBytes = string.getBytes(); final ByteBuffer buffer = ByteBuffer.allocateDirect(stringBytes.length); buffer.put(stringBytes); Or even better yet, explicitly put the charset in So what am I complaining about? Everything seems fine. That's true up to this point. But what if you need to chunk up the string? CharBuffer provides If you're NIO Charset savvy then you may have said to do:
final String string = "bollocks";
final Charset charset = Charset.forName("UTF-8");
final ByteBuffer buffer = charset.encode(string);
This kills lots of birds with a single stone and is very tight code. ("UTF-8" must be supported by Charset so there's no need to check.) The parallel code for chunking is similar:
final String string = "bollocks";
final Charset charset = Charset.forName("UTF-8");
final CharBuffer charBuffer = CharBuffer.wrap(string, 0, 3);
final ByteBuffer buffer = charset.encode(charBuffer);
(where the loop over the remaining chars is not shown). Again, this is nice code that solves the problem. So what am I still complaining about? Well, it's better on the memory consumption but, even though I know the size of my chunking and can allocate a ByteBuffer of this size, I have to allow it to allocate the buffer for me. If really know your
final String string = "bollocks";
final Charset charset = Charset.forName("UTF-8");
final CharsetEncoder encoder = charset.newEncoder();
final CharBuffer charBuffer = CharBuffer.wrap(string, 0, 3);
final ByteBuffer buffer = ByteBuffer.allocateDirect(3);
final CoderResult encodingResult = encoder.encode(charBuffer, buffer, true/*no more input*/);
This is an "elegant" solution that allows for reuse of the ByteBuffer and fits the bill almost exactly! There is the extra CharBuffer in there that has to suck up space but at least it's limited in size. |
|
||
|
Aristotle stated that heavier objects fell faster than lighter ones. Galileo stated the following thought experiment: Imagine two unequal balls dropped from a height at the same time; according to Aristotle, the heavier ball would drop faster. Now imagine the same experiment with one difference: the two unequal balls are joined by a cable between them. If it was true that the heavy ball moves faster and the light one moves slower, then the light ball will hold back the heavy one. If Aristotle was correct the two balls tied together would not reach the ground as quickly as the heavy ball alone. But if we assume that the cable between the balls has the effect of turning the two balls into a single mass that is heavier than either one by itself, the joined balls should drop faster than either one by itself. Another way of looking at this is the reverse: A heavy object is dropped from a height. As it descends it cracks and splits into two objects, each of which is lighter than the original object. Will the two objects suddendly slow to half speed? One can continue the above thought experiment and question what would occur if each of the two objects divided into two .... If the speed did in fact halve then one could imagine subdividing further to a point at which it appeared that the objects would fall very very slowly. |
|
||
|
I was too lazy to get up and get a CD to burn an ISO to so I went searching for the next best thing: mounting an ISO as a virtual drive. This ISO Recorder for Windows XP SP2 works well. |
|
||
|
The Transit of Venus (where Venus will cross the face of the sun) will occur tomorrow, June 8th, 2004 in the early morning. I'm going to head to my local planetarium if I can get my sorry butt out of bed that early. A little known figure in the history of the transit of Venus is Jeremiah Horrocks. He was a self-trained astronomer whose work Venus in Sole Visa influenced Issac Newton. Take the time to read about this facinating man. |
|
||
|
I was cleaning up some JavaDocs yesterday in a large, multi-project code base. The process was getting tedious so I enlisted the help of my old friend GSR (global search and replace). Since I wanted to update java files, text documents and package HTML files, I opted to use Everything was going well but then my IDE (Eclipse in this case) starting throwing a fit. I was getting AST creation errors all over the place and it seemed as though the world was caving in. I attempted the old tried-and-true technique of software; I restarted the IDE. No go. Same errors. I was near the point of panic when I took a look at the IDE's log. The first thing I see is To make a painful story short, it turns out that the GSR was doing replacement in JARs as well as text files. This was corrupting the header and I want to hand it to the Eclipse people for making the IDE tolerant to the stupidity of the average Joe out there doing his best to muck things up. Sure, I got errors up the wazoo but had I taken a moment to look at what they were really telling me I would have figured out the problem instantly. Perhaps this should have been titled "When programmers are too smart for their own good!". |
|
|
Unless otherwise expressly stated, all original material of whatever nature created by Rob Grzywinski and included in this weblog and any related pages, including the weblog's archives, is licensed under a Creative Commons License. |