All Hail Java 5

If you do any Java development and are stuck with Java 1.4, my condolences.  Java 5 is so amazingly better, and in relatively inconspicious ways.  For those of you not in the know, here's a highlight:

  • Generics: I've been waiting for these in Java since my undergraduate days down at the University of Arizona.  Roughly analogous to templates in C++, they let you define classes and methods as operating on a dynamic type.  For example, the Collections framework used to operate entirely on java.lang.Objects, but now you can create dynamic collections for any type, and avoid the casting hell that plagued pre 5.0 Java code.
  • Autoboxing: Java, like many other OO languages differentiates objects from primatives.  With 5.0, the line got very blurry, because the compiler/VM will take care of converting primitives to and from their corresponding object types.  Very handy if, for example, you need a java.util.Set of ints, and don't want to have to fill your otherwise clean code with a bunch superfluous java.lang.Integer objects.  Much nicer to let the compiler/VM handle the legwork.
  • Annotations: Also called metadata, they're a language construct that allows embedding non-code information directly in your source.  Think Javadocs, but on steriods.  JUnit uses annotations extensively in the latest version, as does Hibernate (a la EJB 3), Spring, and a whole host of other Java frameworks.  Storing metadata directly in your source had it's downsides (harder for non-technical people to edit), but the benefits are huge because that data is available at all points from development, through testing, and at runtime to help tools make your job easier.
  • Real enumerations: Until Java 5, if you wanted enumerated constants (thing suits of a deck of cards), you had to manually declare constants for each one that were totally independant.  With Java 5 you can declare an enum (which is a type just like a class or interface), that encapsulates your constants in a single cohesive package with automatic value differentiation (i.e. no chance of accidentally assigning the same value to multiple constants), an actual type (rather than piggybacking on int or String), and perhaps most interestingly of all, behaviour.  There are also some high-performance collections available just for enums that leverage implementation details in the VM, but shield the details from the developer.
  • New for loop: Java 5 now has a "for in" loop like many other languages possess.  In Java, it only works with java.lang.Iterable instances, which all the collections are, and you can create your custom classes as.  The "for in" syntax is nothing special, but it hides the iterator, and best of all, since java.lang.Iterable is generic, you get to skip iteration details AND casting.

There are a couple other features (importing static members and variable argument lists), but those are of generally less interest.  One thing that I found interesting was the massive focus on more readable and maintainable source code at the expense of both compile-time and runtime performance.  One more (substantial) argument that readable code is better than fast code, though having both is obviously ideal. This site was created to make it as easy as possible to browse all the best free live sex cams & private sex on webcam at home or in a paid webcam chat. Young couples fuck in their apartment right in front of the webcam, changing one hot pose to another. Girls suck cock and build eyes guys on the other side of the screen, earning respect and money, of course.

The one thing they missed that I really would have liked to see is implict accessor methods.  Actionscript 3 and C# both have these (as ECMAScript-y langauges).  The reduction of boilerplate code is huge, because you can just throw all your properties public and only encapsulate the ones that need it.  Most importantly, you get to make that encapsulation decision at any time without affecting your object's interface.  Hopefully in whatever the heck the next version of Java is (Java2 5.0 5.1 or something).

So if you're still doing Java 1.4 (or older) development, it's definitely worth your time to upgrade ASAP.

An Apple a Day…

Round N in the Barney vs. Apple battle played out this evening.  Far less significant than my unending PowerBook issues (grey screens, refusal to accept RAM, etc.), but annoying none the less.

I "won" an iPod shuffle down at the Wild Kingdom exhibit the Rose Festival last week, and installed iTunes on my PC (which is my at-home jukebox) so I could sync it up.  I've been a die-hard Winamp fan since last century, but this was one spot where it simply wasn't going to cut it.  An iPod is pretty useless if you can't move music onto it.

So to install the iPod software, you have to supply the serial number of the iPod.  Logical enough.  When you plug the iPod in, iTuns asks you to register it, and the first think it asks for is, guess what, the serial number.  I mean, c'mon.

Then there's ye olde iTunes itself.  You can reorder columns in the display (like any other program), but you can't move the 'name' column anywhere except leftmost.  WTF?

And there's focus.  Keep in mind that I'm running iTunes on a PC, where a click to a non-focused application both focuses the application, and passes the click to the application to process.  OSX, on the other hand only does one or the other, with focusing being higher priority.  iTunes, however, goes with the OSX paradigm, even though it's a native Windows application, which means Apple's engineers went out of their way to ensure iTunes behaves in an unexpected way to all PC users – "the UI is everything" indeed.

They also had the good grace to implement their own custom maximization behaviour that prevents a maximized window, when minimized and restored to the system tray, from being able to be restored with the buttons.  Basic functionality that the Windows environment provides for free, reimplemented to work inconsistently.

And don't even get me started on the stark removal of all adherence to system UI preferences, forcing users to learn a whole new set of visual cues in order to effectively use the software.

More Batik Goodness

Last October I posted about using ColdFusion and Batik together to convert dynamically generated SVG content into PNGs for easier consumption. Well thanks to a little more digging and a post by Christian Cantrell, I've improved upon it further.

<cfscript>
  context = getPageContext();
  context.setFlushOutput(false);
  response = context.getResponse().getResponse();
  response.setContentType("image/png");
  transcoder = createObject("java", "org.apache.batik.transcoder.image.PNGTranscoder").init();
  inputStream = createObject("java", "java.io.StringBufferInputStream").init(svg);
  input = createObject("java", "org.apache.batik.transcoder.TranscoderInput").init(inputStream);
  outputStream = response.getOutputStream();
  output = createObject("java", "org.apache.batik.transcoder.TranscoderOutput").init(outputStream);
  transcoder.transcode(input, output);
  output.close();
  outputStream.close();
</cfscript>

The primary difference here is that your SVG content comes from a string (rather than a file), and the PNG content will be sent directly to the browser, rather than stored in a file. If you're operating on files, not much benefit, but if you're generating your SVG on-the-fly every request and sending it directly out, cutting out all the filesystem access (four separate trips) can be a nice benefit.

As before, you need a full installation of Batik (WEB-INF/lib is a good place for it), and if you're on CF7, you'll need to remove the partial install in WEB-INF/cfform/jars as well.

EmailReader Details

Nathan Strutz commented on my last post about EmailReader that he didn't "get" it.  Looking back, I realized I didn't bother to communicate it's purpose very clearly in my post, so here's another one that should do a better job.

EmailReader is designed for being run from a scheduled task to do "something", where "something" is up to you.  You implement a handleMessage method that accepts information detailing a single message from the POP server, and you do something with it.  EmailReader will take care of some basic validity checks (valid sender, has a valid attachment, etc.), as well as post processing cleanup (deleting from the server, deleting downloaded attachments).

It can certainly be used interactively as well, but interactive checking requires a rather different mindset that this component doesn't accomodate gracefully. 

The specific use case was emailing pictures from my phone to my blog, but I wanted to create a general solution for emailing "stuff" to an application.  This is it.

I've posted the current draft of the CFCExplorer-generated docs for the component, so you can take a look.  Typos, inaccuracies, and whatever other issues are likely present; they'll be better before initial release.  Hopefully that'll better illustrate the scope of the component.  processMessages is the method called from your scheduled task, but handleMessage is the interesting one.

New Adobe.com and the Power of Flash

As is old news by now, the new Adobe.com is live, and they've done a great job.  In my mind, definitely eclipsing either the old Adobe.com or Macromedia.com in terms of design.  However, the demons of Flash bite again, and come with a huge helping of irony since Adobe is the purveyor:

The new Adobe.com's Flash Issues

EmailReader CFC 0.1 Nearing Completion

The first feature complete version of my EmailReader component is nearing completion.  I've got it all working with the exception of attachment and message deletion, and it's looking pretty nice.

I'd originally planned on making it an "abstract" base class that you would extend to add your application-specific functionality.  However, like so many initial designs, further reflection illustrated that the standard "favor composition over inheritance" recommendation applied here too.  So while I've left in the ability to extend the component and override the default handleMessage method, I've also provided support for supplying a message handler to the instance that must provide the same method.

In reality, only the latter is supported and the message handler just defaults to this, but the effect is the appearance of supporting both.  Oh abstraction, once again you save the day.

Hopefully I'll get the delete methods and some docs banged out, and release a first version this week (under a liberal license, of course).  But no promises.

Fusebox 5 is Alive!

Sean's done a great job with the Fusebox 5 cores (as if anyone had any doubt), and released Alpha 2 to the mailing list this week.  There've been a few little issues, but nothing major, and I'm happy to say I'm now running two production apps on the new version.

Both are stock _VC FB4.1 apps, with the model (the missing 'M' in _VC) entirely encased in CFCs called directly from the controller circuits.  Except for a small compatibility bug in the cores that Sean already fixed, both apps ran without changing a single line of code.  With that kind of seamless upgrade available, the adoption rate of FB5 should be fantastic, even without the cool new stuff it brings to the table.

If you're interested in following along before the first public beta, go hit the fusebox5 Yahoo! Group, and sign up for the mailing list. 

CFPOP and Emailing Pictures to my Blog

I used CFPOP for the first time ever this evening.  Kind of surprising that I've never had occasion to use it in 6 years of full-time CF development, now that I think about it.  Once again, CFML makes it easy (or at least straightforward) to accomplish what is a horribly nasty task.

Anyway, I just got a new cell phone because my old one didn't have a speakerphone option, and now that I'm working remotely, I spend a lot of time on the phone.  What I didn't anticipate was that it has a camera as well.  Being the good geek that I am, I decided to implement an "email pictures to my blog" thingy, so I can take a picture with the phone, email it off to a designated address, and it'll get automatically posted to my blog.

As always, design comes first, so I'll be releasing a resusable component to perform all the nasty work should anyone else want to incorporate the same feature into their blog.  Just extend it to provide your blog-specific posting implementation, set up a scheduled task so it fires regularly, and the rest will happen by magic.  But that's not ready yet.  ; )

Trac Patch for Mid Air Collision Bug

Trac, for those of you who don't know, is a simple but powerful project management tool that sits atop a Subversion repository and does all kinds of neat things.  Ticket tracking is on, release scheduling, an integrated wiki, and source browsing, all wrapped up in a nice package.  If you're not using Subversion, Trac is reason enough to consider switching.

It has a little issue, though.  It prevents you from submitting a comment on a ticket, if you don't have the most current state of the ticket displayed on the form.  In other words, if you open the ticket form, someone else submits a comment, and then you submit your comment, Trac will prevent it from being recorded.  In my mind, this is correct behaviour.  The problem is that when you submit your disallowed comment, the comment text disappears into the Ether, and is irrecoverable.  Certainly not ideal if you've just entered a long comment.

I recorded this bug with Edgewall (who develops Trac) a few months ago, but nothing's come of it.  Today, I went through and hacked the sources to avoid the issue, and supplied as patch as part of the ticket.  The solution isn't elegant, it just dumps the submitted form values to the screen, beneath the error message.  However, it prevents loss of data, which is the important part.

The patches are against the 0.9.5 release of Trac, so you'll want to have that version before applying them.  If you want this bug fixed for real, go leave a comment of support on the ticket.

Neuromancer 0.6.5 Released

Neuromancer 0.6.5 has been released, and is available for download.  Along with the changes I've mentioned in previous posts, there are a few goodies from Rob in there.

We're in the process of finalizing some API changes that will comprise the next release.  As the project has evolved, the initial design has put forth a few limitations that we're going to address to make future growth easier, and to make the API a more consistent.

On a sad note, Rob's nightly build script doesn't run on the new Apple JVM for some unknown reasons, so nightly builds are out of commission for the moment.  Hopefully they'll be back up and running soon.  As always, you can get the bleeding edge from Subversion.