Saturday, July 30, 2005

Graphics File Formats

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

I get screenshots every now and then in the mail, and frequently in bad formats, so perhaps the following is not known to all:

  • Do NOT send BMP files! They are uncompressed. A simple screenshot, which should be a something like a 50k gif, will be a 5 megabyte attachment - 100 times larger than necessary! Unfortunately, BMP is what you get by default when you grab screenshots with Ctrl-Printscreen
    in Windows and paste it from the clipboard. TIFF, common on the Mac, suffers from a similar bloated file size problem since it too typically
    is not compressed.

  • Do NOT use JPEG for screenshots! Unless all compression is turned off (which it never seems to be), JPEG is a spectacularly
    bad format for uniform color surfaces like those you get from application screenshots. JPEG is great for photos - much better than GIF or PNG.
    But for screenshots it introduces all kinds of ugly visual artifacts.

...and finally, a related issue: If you're going to show a scaled down version of a picture in a web page (e.g. a thumbnail),
don't just use the width and height attributes on the image tag! Not only does that require the full image to be downloaded anyway,
but worse yet, most browsers do a horrible job scaling pictures. Prescale the picture in an image editor instead.

Friday, July 29, 2005

Navigation Wildcards

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

Most problems in computer science can be solved by adding a level of indirection!

In JSF, navigation is done through an indirection table. Rather than having each button that navigates to another page know its destination, a level of indirection has been added such that the buttons only specify a navigation case name, and then there is a central navigation table which records the actual destination to navigate to for a given navigation case. (A navigation case is simply a short string that describes the navigation intent, like "failure", or "loggedin", or "next" and "previous" in a wizard scenario for example.)

This has some really important advantages. It makes it extremely easy to change the page flow later, since it is not spread out across all the web application pages. The indirection also makes it possible to add a some additional logic to the destination lookup. One such feature offered by JSF is wildcards.

For example, let's say you want to have a Help button. The navigation associated with the help button is "help" - in other words, its action property is set to "help".

<ui:button text="View Help" action="help" binding="#{Page1.button1}" id="button1" />

Navigation Screenshot

We can obviously link this particular button directly to the Help page. That will
result in the following navigation rule being added to the navigation rule file:


But what if we had a help button on every page? Would we have to repeat this

rule for each and every from-page?

No. This is where wildcards come in. You don't have to specify the
source page in the above rule; you can use "*" instead which means "any" page:


Now, ANY page specifying a navigation case of "help" will result
in navigaton to the given Help page.

Wilcards play a very important role with page fragments. A page fragment
is essentially a "static" include of a portion of a page: it literally gets
copied into the referencing page at deployment time. Thus, if you have a Page fragment (such
as a Footer page fragment listing copyrights as well as a Contact Info
button), every single page including this page fragment will have the
Contact Info button. If you bring up the page navigation editor and zoom
a page, you'll see buttons and links from fragments that are included in the
page too. However, note that there is only a single JSP for the fragment
with the button, even if it's included in multiple pages. Thus, its action
property can only be set to one thing. If you drag this button to a destination
page, this both adds a navigation rule from this Page and sets the
action property of the fragment. This action property will now be seen in
all other pages including the fragment too. You cannot set the action property
to different values for different including pages. (You can however
have different navigation rules for the same action when used in different pages,
as discussed shortly.)

Because of this, you usually want to use wildcards when you're using navigation
components (like buttons and links) in fragments. This will ensure that
regardless of which page the fragment button is clicked from, the same
target page is chosen. This will for example ensure that your "Contact Info"
button will bring up your page with Address, Phone, and E-mail information regardless
of which page the user clicked the fragment button from.

Note however that you don't have to use wildcards with fragments - using
normal navigation rules also gives you some really powerful possibilities. For example,
if we go back to the Help example, your Footer fragment could have a Help button,
but you can bind it to -different- destination pages for each different source page.
Thus, you can have context sensitive help!

Unfortunately, the navigation editor doesn't help you with wildcard rules. You'll
have to add these by switching to the XML view. Also, wildcard rules are shown as
erroneous rules - the arrow flows into the destination
pages and show the case names, but the page flows from an error icon. It should
flow from a wildcard icon instead.

P.S. If you're wondering why there's a blue border around the left page
in the screenshot, that's because my coworker
Winston implemented
full keybord support for the navigation editor recently, and the blue border signifies that
the page is current. Tabbing switches pages, z/u zooms and zooms a page, b adds a
button, s selects start page, tab to switch, then e ends and creates link, Ctrl-A adds a new page, etc.

Thursday, July 28, 2005

I'm back

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

I'm finally back. I've been sick, my kids were sick, and I've taken some time off, so I've only worked a little bit now and then the last couple of weeks. But I'm feeling energized again and ready to go!

A couple of miscellaneous pointers:

  • There's a new
    article in eWeek on AJAX that talks about some trends
    and mentions Creator.
  • I did a chat on TopCoder a couple of weeks ago; the
    transcript is now available.
    I'm sun_1 - my responses are the lines colored in red.

  • I haven't tracked podcasting much, but that will have to change. The new
    JavaCast site looks interesting. I've
    met one of the guys behind it, Dick Wall, who in addition to being a really great guy is
    also a great engineer (check out some of his articles on, so I'm sure the content will
    be interesting!

Friday, July 22, 2005

R.I.P. Red Boxes

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

One of the really nice things about Creator and JSF is that we're able to provide WYSIWYG editing of components.
We do this by actually running the components' renderers at designtime. This does however have one problem: What if
the component renderers aren't happy?

Lots of things can go wrong. For example, let's say you have a databound JSF table. If you kill the database connection,
the component renderer will abort with a SQLException. Incorrect expression language bindings, missing converters and
a whole host of other potential problems have similar issues.

How do we handle this in the IDE? In Creator 1.0, we had the "Red Boxes" scheme, as shown in the first screenshot on the right.
In the designer, components which aborted during
rendering would be shown partially (as much as possible depending on how far along the renderer got before dying),
but all the markup would be changed to have a red background. That way you could
sort of see the component if it had rendered enough before giving up. This is better than not showing the component at
all, since (1) it makes it really obvious that there is a problem, and (2) it makes the troubled component easy to select so you
can inspect the property sheet and try to fix the problem. We also opened the Output window with an error message trying
to explain what had happened, and what to do about it.

In Creator 2 this behavior has changed. Instead of the red boxes, you first get an error screen (similar to the one you
get if you introduce parsing errors in the JSP, or syntax errors in the Java file). This error screen includes portions of
the stacktrace, which in many cases might reveal what the problem is (don't forget to look for a cascaded exception1)

You can also click through to the
design view, and now you'll see the component. However, rather than an ugly red box you'll see a small error icon in the
component's place along with an error message associated with the render problem. It should also be much better about
not repeating the error screen until you've resolved the problem and encounter a new problem (although there was a bug
in this area fixed shortly after EA).

Wednesday, July 13, 2005

com.sun.* classes in Creator applications

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

One of the nice people I met at JavaOne was Dave Johnson, the guy behind
Roller, which is the open source blog server software we're using at Sun.
this blog entry he describes his
recent experiments with learning JSF and using Creator 2:

I was hoping to build a simple JSF front-end for Roller, just for fun. Creator looks great and the form designer works well, but when I noticed how many com.sun.* classes end up in the generated code I backed off. According to the release notes the whole JSF implementation and com-sun-web-ui-appbase jars are redistributable (...), but the idea of IDE specific code makes me uncomfortable -- especially in an open source context.

The same issue came up last year when we released Creator 1.0 beta.
So in this blog entry I'd like to explain why you'll notice
a number of com.sun classes in your Java files maintained by Creator, what they're
for, and what you can do about it.

Creator 1.0 provided only the standard JSF components
(javax.faces). If you drop a command button, you get
a <h:commandButton value="Submit"/> entry in your
JSP - just like your JSF books tell you.

The big problem is that the standard components are extremely limited.
When you build applications using the standard components, you've created
a web page that would look right at home in 1995.

In addition, the component set shipping with JSF is limited in functionality.
We've gotten tons of requests for additional components: file upload,
tree, tabs, calendar, etc. Therefore, in Creator 2 we're no longer
focusing on making web applications that look identical to what you'd
find in an off-the-shelf JSF book. Instead, we've provided a new
component library, consisting of pure JSF components obviously, which
have additional value add. Buttons can be configured to be primary or
secondary (affects visual appearance), they can be configured to disable
themselves when clicked (so you don't get double submits on forms), they
follow theme styling, etc. And of course, we have new components like
trees and calendars to address those needs. Obviously, if you use these components,
your page beans will include references to additional com.sun.* classes.

src="" />
Don't despair however - if you want to use the standard JSF
components, you can do that - just look in the palette for the
component categeory named "Standard". This is where the standard
JSF components live - drop these and you'll get your familiar
JSF commandButton, outputText, panelGrid, etc. components. To
make it easier to spot these in the palette, so you don't grab the
"wrong" button for example, all the icons for these components are now
tinted blue as shown in the screenshot on the right.

There are a couple of more areas where you wind up with
com.sun classes. First, your page and session
beans themselves. If you look at your Java files corresponding
to your pages, you'll notice that they're very small and simple;
you basically have several empty stub methods where you can add
code that is run during different parts of the page's life cycle:
initialization, render, and cleanup. JSF doesn't make it that easy.
That's why we've created an abstract class you can extend (and our
page beans automatically do this) where the super class has all
the convenience methods you want. For example, your page beans code
can simply call getFacesContext() to get the FacesContext
object, or it can call getValue to perform value binding
expression evaluation. Just look at the code in the ancestor classes
to see the PhaseListener magic that is necessary on the programmer's
part to make these simple callbacks possible.

So this was a deliberate choice in order to make it really trivial
and easy to write "event handlers" for your web component's events,
like button presses and text field validations. There is nothing
special about this code - its source is fully included and in Creator 1.0
you can simply press Alt-G over the parent class name in the java file
to open it. Unfortunately this doesn't seem to work in Creator 2 EA.
But the source code is all there; go extract rave2.0/docs/
and you'll
see it. (It's in the wrong place which is why the normal IDE facilities
for warping to it doesn't work. This will be fixed before ship date.)

There's one final area where you can end up with com.sun
classes: data providers. Standard JSF lets you hook its Data Table
up to arbitrary data structures (and I've
described how
before). However, it's pretty inconvenient
and not done in a general fashion. In Creator 2 we have a new
abstraction layer in the middle, which all components know how to
talk to. We then implement these interfaces for a wide variety of
data sources. The net result is that you can drop not only a JDBC table,
but a web service method or even an EJB method on GUI components, and
all the binding is handled correctly. These data provider wrappers
can also end up in your code.

So in short, yes, if you choose to use the new components and databinding
facilities, you end up with additional com.sun.* classes in
your code. You also get this in the page beans from the app model.
Our focus in Creator has been to make web apps easy and feature rich,
which resulted in adding some convenience classes around the standard
primitives provided by JSF, and of course a new set of JSF components.

As JSF matures there will hopefully be fewer and fewer areas where this
is needed.

Don't Code Like This!

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

I was trying an open source web framework yesterday, and couldn't get it to work so I stepped through some of the code on the server with a debugger, and came across some code fragments that I thought I would submit to the Hall of Shame.

Besides, it's fun to blog about this, because each time I mention coding style I invariably get passionate responses from people defending their beloved style.

In the following, the class and method names have been changed to protect the guilty.

At first, I simply got a generic JspException. The code was doing this:

} catch (ConfigNotFoundException ex) {
throw new JspException(msg);

The original stack trace is not chained to the new exception! Please pass it in - JspException
has a constructor which takes both a message and the root cause exception, ex in the above.
If you're using some Exception class which is older and doesn't let you pass in the root cause,
such as DOMException,
then first create the exception, then call the
method on it, and finally throw the exception object.

The second code fragment I came across was this:

try {
return findConfig(servletContext).getResult(foo, servletContext);
} catch (NullPointerException ex) {
throw new ConfigNotFoundException("Can't find configuration");

The above code is using exceptions for flow control. Rather than first
calling findConfig, then checking if it is null, it just goes
ahead and tries calling it anyway, relying on the NullPointerException to
handle this case.

The code also has the bad effect of catching all unintended null pointer
exceptions in the subsequent getResult method call. These are
unrelated to the ability to find the configuration, so the error message would
be misleading. (And again the original exception is not chained).

Saturday, July 9, 2005

Creator and AJAX: The Demo

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

I did a
demo at JavaOne
during Monday's keynote on Creator 2
and AJAX. Being a keynote demo, it was obviously stripped down to the
bare minimum with a three minute timeslot. Therefore, I didn't have time
to motivate the example, or build up the demo in gradual steps.
But in three minutes, starting from an empty project and using no code clips,
I built a web page that does a google-suggest
like thing where as you're typing in a textfield,
you get autocompletion on words from a 180,000 word dictionary.
I've received a number of questions about it, and so have the
people who were working in the Creator booth at the conference, so
I'm hoping a blog entry will clear some things up.

First, let's talk about AJAX. One of my favorite uses of AJAX is
providing auto completion in text fields. You've probably used address
forms where the State or Country fields use dropdowns with 50 or
more items. You typically KNOW which state or country you want to
select, so being able to type three or four characters to limit your
visible choices is a lot more usable than scrolling through large popups.

However, doing autocompletion smoothly as a partial page refresh
(e.g. no page submission) is somewhat tricky. It takes lots of
JavaScript plumbing to do that - and to get it working correctly
on lots of browsers.

This is an ideal domain for a JSF component. The JSF component
can encapsulate all the hard work in its renderer, meaning that
your JSP files contain no JavaScript code whatsoever.
You get the benefits of AJAX without its usual high development cost.

So let's jump right into it. One of the points that was made in the
keynote, but people have confused in their JavaOne summaries that I've
read, is that the AJAX component I demonstrated is not part of Creator 2;
it's developed in open source on
Thus, you can get all the source code for this and enhance the component
(or create similar components) to your heart's desire.

In fact, it gets even better than that. There's a whole
on this component which explains exactly how it works. It comes with a working
sample application - a JSF address form providing city completion for all 25,000 U.S. cities.
And if you want a more generic overview on how to create JSF and AJAX components, check
out this paper
written by Greg Murray, Ed Burns and me, which covers
some different approaches and trade-offs for this technology.

One of the things you'll find in there is code to wrap the
component up as a Creator component library that you can import
right into the IDE. Once you've
downloaded it,
you can install it by right clicking on a palette category, bringing
up Manage Component Libraries..., select Import, and drill to the
component library jar. Ok your way out. You should now find a new
"Ajax Component Library" palette category at the bottom containing
the completion text field.

(What, only one AJAX component? Yes, we'll add more components there. If you look at the blueprints
page I pointed to earlier, you'll see several additional JSF components
written by Greg Murray, Ed Burns, and more are on the way. These will
be packaged up as Creator importable components as well.)

Now, drop the text field on the page. Then double click on it.
Notice how it will warp to the source code and show you a new event
handler. This event handler has already been bound to the text field
when you double clicked on the text field. (If you study the JSP
you'll see that it has a completionMethod attribute
set to a method binding expression pointing to the method you're
currently editing.)

Take a look at the screenshot. That's what it looks like in my
editor - and what it looked like at JavaOne. But it's not what you're
seeing in Creator 2 Early Access. Here you have a component-specific
event handler, with properly named method parameters, and a default
event body that gives you some suggestions for what to do.
This was added right after Early Access froze so your bits don't
include this functionality, but needless to say it will be in the
shipping release. This will make it easier to write editor validation
event handlers or even button action handlers too, since the default
bodies will guide you in the right direction.

Study the trivial sample code in the comment:

public void ajaxTextField1_complete(FacesContext context, String prefix, CompletionResult result) {
// TODO: Return your own list of items here based on the prefix


If you simply uncomment the last two lines, and hit Run, you'll get an
editor which contains two items in the popup: "Hello", and whatever the user
has typed in the browser - but uppercased:

That's a big deal. Notice that we've written simple Java code which runs
on the server, yet as the user is typing in the browser,
results are dynamically shown without any kind of page submit. The user
gets nearly instant feedback. All the plumbing is taken care of
by the component. So while writing one of these components is tricky
(see the documents referenced above), using an AJAX component
is downright trivial.

Ok, I know what you're thinking. "What, every keystroke in every client's
browser is hitting the server? You're crazy!!". I addressed this point
in the AJAX full hour session at JavaOne. AJAX functionality does
have a price. Your users are getting a better user experience. It doesn't
come for free. You need to have good server resources to support this
type of interaction. (I know a company which will sell you a good server! :-)
Think of Google Suggest for example. Every time one of their users types
a character*, it hits their servers and returns a portion of their index.
(Yes, I'm aware that if users are typing fast multiple keystrokes get
coalesced into a single request). This is clearly not free - they're
using additional servers to be able to handle this load. But to them,
and perhaps to you, the added user benefit justifies the additional

Anyway, back to the AJAX demo. The previous step (where I simply
do a trivial computation to show server computation reflected in the browser)
was eliminated from the keynote demo due to time constraints.
I jumped right to the part where I do something more complicated on the
server with the prefix we're getting from the user's text field.
I call a web service, which returns a small set of words that start
with the given prefix. Calling a web service is easy. First I have
to import the web service (by pointing to the relevant WSDL file),
then drag the web service onto the canvas (to get a local proxy object
I can make calls on), and finally I change the autocompletion event
method to simply call the web service to get a String array of words,
and then I add those words to the completion result object.
(It has an addItem(String[]) method as well). Thus,
after dragging the dictionary web service onto the page (which gives
me a local field dictionaryServiceClient1), I replace
the code in the event body with:

public void ajaxTextField1_complete(FacesContext context, String prefix, CompletionResult result) {
try {
String[] items = dictionaryServiceClient1.matchPrefix(prefix);
} catch (Exception ex) {
log("Error Description", ex);

The try/catch skeleton here came from me typing "trc ",
and I just typed dict followed by Ctrl-K to type in the
full name of the service client object.

During the keynote demo, I had a typo - I wrote


rather than the correct code above. When I hit Deploy the compiler rightly complained.
Somebody asked afterwards if that was intentional, since having errors in my code
has happened a couple of times during keynote demos in the past. For example
during James
Gosling's keynote last year

In another coding process, Norbye skipped a step, which Gosling noticed. Norbye quipped, "It's really great to have your very own James Gosling to help you code," which drew a big audience laugh.

Let me assure you that the step last year was accidentally missed, not skipped, and again
this year it was definitely not intentional. You try to code in front
of ten thousand people and see if you can do it flawlessly :) I'm only
glad the mistake was trivial and easy to spot. It sure would have been
annoying if I hadn't been able to catch it before getting chased off
the stage. I gave a full-hour Creator 2 demo at NetBeans day the day before JavaOne,
and towards the end I was going to build a nice demo utilizing the new
file upload component. But each time I tried to submit, the file upload component
threw an exception. We spent 5-10 minutes debugging it with the audience's
help but to no avail. Annoyingly, shortly after the demo, Craig McClanahan
(who was in the audience, and also works on Creator) discovered that the problem
had been that I was doing the demo on Internet Explorer (which neither Craig
nor I normally use). I hadn't noticed that on the demo box I was using
it was the default. And it turns out that there is a bug in the EA version
of the upload component where it doesn't work correctly with IE in a couple
of cases. Oh well.

Anyway. Back to the scheduled programming. With the above code change,
and deployment, you run and get the screen shown below. As you type,
dictionary completions from a dictionary of 180,000+ words are instantly

In the AJAX session I also went on to hook it up so that there's
a lookup button which looks up the definition for the selected word and
displays it below. I'll leave that simple exercise to the reader (hint:
it took less than a minute in the session demo.)

One of the things I wished I would have thought of before the keynote, is
a better "sample word" to type to show the application working.
I typed "Java", but it would have been a lot more fun if I had typed "Brazil" !!
(For those who don't know, many keynote speakers make a point
of mentioning the word "Brazil" in their speeches because it invariably
draws cheer and applause from the Brazillian delegation, each and every

So that's the spiel. At this point you may wonder where the dictionary
web service came from. I had really wanted to motivate the AJAX example
with the simple deployment step first, such that it gets the "look how easy"
point across. The web service call makes everything more
"magical", especially when it happens so quickly during a 3 minue demo - but
it's important to understand that it's just a method call
which returns some good matches for a string.

The web service was deployed locally. It was extremely easy to create.
I did it in one evening - and that includes the learning curve, since I
had never created a web service before. However, I found
this tutorial
which shows how trivial it is to build one with NetBeans 4.1.
So I went on the internet, found a free dictionary file, wrote a small program
to take all those html files, extract all the words and definitions from
them, and then sorted those and wrote them into two files: and index file,
and a definition file.

The web service is very trivial. It has an interface with two methods:
a method for looking up the definition of a word, and a method for
returning the 10 closest matches to a prefix. The second method simply
does a binary search in the word index, but rather than returning the
matched word or null it returns the index of the closest match, so that
the web service can return the 10 closest words in the sorted word array.
Trivial, eh? You can
download the web service project yourself,
as a .zip file. Unzip it and open it in NetBeans 4.1.

It might complain about a missing server. Use the Server Navigator
in the Tools menu to point to your Creator App Server 8.1 installation;
it's running on port 28080 with username admin and
password adminadmin.

You can now
first run the project to deploy it, and then register the web service
by going to the Web Service node in the project manager, right click
and select Add To Registry... (or something like that). It will show
you the WSDL URL for the deployed web service. In my case it was


In Creator, you now go to the Web Services node, select Add, point
to the above WSDL file, hit OK, and you've imported the web service
into your Server Navigator. (You can test it too - look at the context
menus for the web service method nodes.)
Now you can simply drag the web service onto pages to
get a local client object like dictionaryServiceClient1
in the code above.

Hopefully the use of a web service doesn't confuse the AJAX component
issue too much. One of the nice things about separating the dictionary
code into a web service (rather than having it included locally) is
that the dictionary is only deployed once, not each time you deploy
your Creator project. Thus, the 10 megabyte dictionary file doesn't
get reparsed each time you start the project. (It takes a couple of
seconds the first time it's called to "warm up", e.g. read its
dictionary list into memory) but once it's up and running there's
no delay at all.

....and that's all I have to say about that...

F. Gump

Thursday, July 7, 2005

Code Completion in JSPs

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

Somebody asked how to find out more about the new "ui" tags in Creator 2. This seems like a good opportunity to point out that we have code completion, and popup javadoc, for JSP tags as well. In particular, if you switch to the JSP view of your source files, put the caret over a tag like <ui:button>, and hit Ctrl-Space or Ctrl-\, you get a completion popup listing possible alternatives. As you walk around in the list with the arrow keys, the TLD doc for the tag is listed in the popup (which for java files show javadoc documentation for the methods). There's quite a bit of documentation for all the new components - look at the size of the scrollbar to get a sense of the size of the button help. Or better yet, go try this yourself!

Of course, you don't have to go to the JSP view and read tag documentation to learn about the components. In the Early Access version we don't have all the help for the new components written, but if you for example select the Button in the JSF Standard palette, you'll see that the dynamic help window begins with a help topic for the Button component. Double click on it and you can read component-oriented documentation on the button component. We'll be filling this out as we finish Creator 2.

(As always in this blog, click on the thumbnail to see the full picture.)

Generics Considered Harmful? Nope.

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

I just came across this blog entry by
Ken Arnold (who's writing a book on the Java language) where the author argues that generics should not have been included in JDK 5.0:

I don't know how to ease into this gently. So I'll just spit it out.

Generics are a mistake.

This is not a problem based on technical disagreements. It's a fundamental language design problem.

and then the concluding remarks:

... it feels like the JSR process ran far ahead, without a step back to ask “Is this feature really necessary”. It seemed to just be understood that it was necessary.

It was understood wrong.

I disagree with Ken. The big point of adding generics is allowing people to use type checked collections and so on. Nearly all Java programmers use the Collections API. Using the genericized collections in JDK 5.0 is not hard - it's really easy, makes the code cleaner, and detects programmer errors. The fact that creating generic collections classes is hard is besides the point - most programmers don't have to. Yes, there's a price for having more flexible libraries: they're harder to write. That is nothing new. Developers can continue to write JDK 1.4-style APIs and libraries if they want to.

Perhaps the comparison is a bit unfair, but take EJBs. Prior to EJB3, developers had to work really hard to write an EJB. With EJB3, all they have to do is add some metadata annotations to their simple Java code, and everything else is handled automatically. Did this make writing an app server harder? You bet. But that's a fair trade-off - there will be a lot more programmers using EJBs than programmers writing app servers. While not a perfect analogy, I think the same principles apply here. For a few library designers, who now want to create generic types (they still have the option of creating old style types), life just got more complicated. However, for all their clients, life got easier. Easier is good.

Wednesday, July 6, 2005

July Todo List

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

Beach in Kauai

Fire dancers

Todo list, July 2005:

  • JavaOne

  • Relax 5 days in Hawaii

  • Finish and re-enable hidden feature X in Creator

  • Blog on Creator 2 and AJAX

  • Fix bugs

  • Performance tuning