Coming soon to a Java SE 6 update release near you

Recently, Thorsten Laux and I gave a talk at JavaOne 2007 about where we are and where we're going in Desktop Java. We covered the download numbers (awesome!), statistics on how many PCs have Java installed (excellent!), and highlighted various desktop applications that use our Desktop Java technologies (fantastic!). We then quickly covered some of the larger features that were implemented in the recent Java SE 6 release (which I won't go into here; check out the various blogs and articles on the topic for more on those features). We concluded with the following technical diagram:

 

victory-sm.gif


 

Clearly, the combination of growing ubiquity, power of the platform, and features in the latest release means that we are done, right?

Well, perhaps not. There are still some outstanding issues that need to be addressed, as we can see in the following diagram:

 

attack-sm.gif

The reality is, we have several outstanding issues with Java as a consumer desktop platform, which need to be fixed soon in order to make us competitive now and in the future.

The good news is that we are, in fact, aware of these issues. The better news is that we're working on the problems. The best news is that we are close to solutions and intend to delilver them as an update to the SE 6 release, in a release that we call theConsumer JRE.

What's In It?

The Consumer JRE consists of several important pieces of functionality, some of which are depicted in detail in the above diagram. One of the keys to getting this release out quickly as an update to an existing release is to only make changes that do not affect API. So, for example, we can add functionality to make startup faster without affecting the APIs or functionality that an application is using. But we cannot add a new animation API in an update release. Fortunately, this constraint is not too cumbersome since the major problems we are trying to solve now are below the level of API changes, and are thus completely suitable for this release.

Here are the main items that we are shooting for in this release:

Quickstarter: Radically reduce the startup time for Java applications and applets.

Java Kernel: Reduce the time-to-install-and-launch when the user needs to install the JRE in order to run an application.

Deployment Toolkit: Enable easy detection and installation of the JRE.

Installer Improvements: Improve the user experience of installation.

Windows Graphics Performance: Enable default graphics acceleration for simple and advanced 2D rendering.

Nimbus Look & Feel : Release a new cross-platform look & feel based on Synth.

Quickstarter

This is probably going to be the most popular item in the mix, making the launch of any Java application or applet much faster. This is one of the most serious holdups to further applet development and deployment today, as the launch of the first applet in a browser can take several seconds. Quickstarter will cut down the launch time significantly, vastly improving the first-launch experience for consumer Java applications.

There are actually 2 issues with Java application startup:warm start and cold start. We define warm start as the time that it takes for a Java application to start when you have recently run Java recently on your system.Cold start, on the other hand, refers to the time that it takes to launch the first Java application after a fresh reboot.

Warm start times are reasonable these days, due to plenty of ongoing work on improving performance, in addition to machines simply getting faster over Java's lifetime. A simple application or applet will take 1-2 seconds to start up, which is in the same ballpark as standard web pages and within an acceptable range for the user.

Cold start, on the other hand, continues to take an unreasonably large amount of time. It is not unusual to see an applet take 5-10 seconds, or even longer, to start. While such a delay might be acceptable for a large desktop application, such as an IDE that's going to run all day after cranking it up in the morning, startup times like this for applets are unacceptable and limit applet viability for lightweight consumer content.

The problem turns out to be at the operating system (OS) level. Don't misunderstand me: I'm not saying, "It's not our fault!, " as tempting as that route always is for any hard problem. Instead, I'm saying that the Java platform is running into some basic physical constraints at the OS and hardware level that we must work within. In particular, the files that make up the complete Java platform are, well, large. For example, a recent version of Java SE 6 that I have sports an rt.jar file of over 40 MB alone. If you add in the various other jarfiles, native libraries, and resource files that get touched at startup, regardless of any application-specific code, that's a lot of data that has to be read in.

At the OS level, this means that all of these megabytes (or, rather, tens of megabytes) have to be read from disk, which is a very (to use a technical hardware term) slow operation. Actually, it's the seek time of the disk that's the killer; reading large files sequentially is relatively fast, but seeking the bits that we actually need is not.  So even though we only need a small fraction of the data in these large files for any particular application, the fact that we're seeking all over within the files means that there is plenty of disk activity. No wonder it takes so long for Java to start up, since we are dependent upon the speed of such an inherently slow operation to begin with.

The reason that warm start is so much faster is that once some data has been read off of disk, the OS places it in the disk cache. The next time that memory is needed, the OS can retrieve it from the disk cache, which is a significantly (again, a technical term here) faster operation.

The fix, then, is for us to take advantage of the disk cache to make sure that the memory pages on disk that we must read at startup have already been loaded before we need them. How do we do this? We cannot magically pre-load the pages just prioir to launching; unfortunately, the VM currently lacks the ability to see into the future to detect when the user will be launching Java (we would love to have this feature in the future, but it is not yet present). But we can pre-load at some earlier time, such as Windows boot or login time. And we can keep the pages warm in the disk cache as machine and memory conditions allow.

Note that this approach is not the same as running a full Java VM. That approach would solve some of the same problems, but in a less efficient manner, locking up the memory in a less OS-friendly way. Our approach will work just with the disk cache itself, allowing the operating system to use the system memory and disk cache as it sees fit.

Java Kernel

The Java Kernel project addresses the time-to-launch problem for users that do not have the proper JRE installed. For example, if your application requires the user to hava Java SE 6 and they do not currently have it, then you require that they install that full release prior to launching the application. Given the size of the JRE, and depending on the amount of bandwidth available to the user, the download and installation time can take anywhere from tens of seconds to tens of minutes. The Java Kernel project will cut this time down dramatically, allowing the application to install just what it needs to launch itself.

Just like QuickStarter, the main issue behind the time that download and installation takes is size: Java is large, even when zipped and Pack200 compressed, and there are physical realities to bandwidth and bit copying that we cannot overcome. Of course, one solution would be to simply shrink the platform, but in a world where Java is backward compatible and any Java application compiled to a particular release can expect to run on any release of that version or later, the idea of breaking up the Java runtime into subsets simply doesn't work.

The big idea behind Java Kernel is to take the sub-setting approach, breaking up the monolithic Java platform into discrete chunks of functionality that get downloaded and installed according to what any specific application needs, but to then stream down the rest of the platform in the background. Taking this approach ensures that an application that installs the Java Kernel will have the functionality that it needs with a much faster install and startup, but that any future application can still take advantage of the entire Java platform for that release, since the Java Kernel installation process will ensure that all of the proper bits get installed eventually.

The basic workings of Java Kernel are as follows:

  • Download base functionality that every application needs (VM, garbage collector, security, classloader, and enough basic networking functionality to be able to download the rest of the bits)
  • Download additional dependencies that this application specifies
  • Download any "Class not found" exception culprits as needed
  • Download the rest of the JRE in parallel until the entire release exists on the user's system

Work is still ongoing on Java Kernel (Ethan Nicholas is madly cranking away at it), but initial results show that it is possible to cut the download size by over 60% for mid-sized Swing applications. For example, here are [very] preliminary numbers for some sample applications to show how applications-specific bundle sizes compare with the complete size of the JRE:

KernelComparison-sm.png
Comparison of various Swing application download sizes with the full JRE

Deployment Toolkit

Wouldn't it be nice to be able to detect, from the browser, whether the user has Java installed, and what version they have? The Deployment Toolkit feature will make this process much easier, allowing detection of Java from either JavaScript or browser plugins.

To date, the main mechanism for automatic detection of Java on the user's system was the ActiveX control calledAuto-Install that we released in J2SE 5.0. This mechanism was necessarily limited to Internet Explorer, and only if the user allowed that ActiveX control to run. Other than that, the process was quite manual and usually involved sending the user off to java.com to optionally install Java, from which adventure they might never return. For an example of how the current system works, check out the article Auto-Install: Easier Launching of Java Web Start Applications.

The Deployment Toolkit project is about enabling a much more powerful and ubiquitous system to run across multiple browsers and platforms, allowing developers to more automatically detect what the user has, what to do about it, and how to launch the application when Java is then installed.

There is still a browser plugin that provides a high level of detection, installation, and launching support, but now that plugin has been ported to also work in Firefox on Windows. But if the plugins can not be used, there is also a JavaScript solution, hosted primarly on Sun's site with a small piece of code that runs on the deployer's site, that can do far more than the current manual approach. The plugins can detect Java versions down to the update release, and can automatically trigger an installation of Java, launching the application when installation completes. The JavaScript solution is not as powerful, but still enables detecting Java versions down to the family level (i.e., J2SE 5.0, Java SE 6, etc.). The JavaScript version also cannot start the Java installer directly, but it can redirect the user to the appropriate download page and then poll in the background, waiting to return to the original page and launch the application when installation is complete.

Installer Improvements

The installation process for a new JRE should be simpler and more user-friendly. Besides the size+time issue that we plan to address with Java Kernel, there needs to be a better overall experience that users have during the installation process. Here are example before and after views of the first installation dialog:

 

 

OldInstaller.png
Current installation dialog  

NewInstaller.png
New installation dialog

Graphics Performance on Windows

We are re-writing the default graphics pipeline on Windows to take advantage of Direct3D for performing everything from simple rectangular fills and copies, which is what you get now by default, to translucency, gradients, arbitrary transformations, and other more advanced 2D operations. Swing applications simple and complex should benefit from much better runtime performance on Windows as a result.

Swing performs its rendering through Java 2D, and is therefore dependent upon the graphics rendering speed of Java 2D for fast Swing performance. In J2SE 1.4, we started accessing native hardware acceleration through DirectX on Windows, but only for the basic operations of filling and copying rectangular areas and horizontal and vertical lines. These simple primitives end up being quite important for Swing rendering, since much of the UI is comprised of these primitives, and the ability to cache the Swing back buffer as a VRAM image enables very fast double-buffering. But UIs are getting more complicated and the ability to accelerate more advanced operations, such as translucency, anti-aliased text, gradients, and scaling operations, is becoming increasingly important.

We have continued to work on the DirectX rendering pipeline in Java 2D, and have the ability to accelerate a wide variety of operations through the native Direct3D library on Windows. However, we have not been able to enable these performance improvements by default due to a combination of speed and robustness issues. Meanwhile, we have also implemented a parallel OpenGL rendering pipeline for Java 2D with even more advanced capabilities, but once again we cannot enable it due to robustness issues on various platforms.

Now we are finally rewriting the DirectX pipeline to mirror the capabilities that we have with our OpenGL pipeline, with fixes for robustness that make it a more viable default rendering pipeline. We should finally be able to enable this feature by default, exposing Swing to extremely fast hardware acceleration through the graphics processor. This should enable faster performance for current Swing applications, but will also enable much more powerful Swing applications to run fast as well, even those incorporating much richer and more dynamic, animated effects in their GUIs.

Nimbus Look & Feel

The Metal look & feel was good in its day. And Ocean was a decent theme for Metal, especially given the backward-compatible constraint of maintaining the metrics used by the UI components. But these cross-platform look & feels are, frankly, dated, and we need a more modern look for Swing applications. Of course there are other look & feels out there, some quite good, and we encourage developers to look to those products and projects as well for possible usage in their applications. But in the meantime, we also feel that we should provide a decent default for Swing developers in the core platform. Nimbus will be that new look & feel.

Here some samples of the the Nimbus look & feel so far:

NimbusWidgets.png
Sample Nimbus components

nimbus-swingset-1.png
SwingSet2, using the Nimbus look & feel

For more information on the Nimbus project, check out Jasper Pott's blog.

When Will It Ship?

As I mentioned earlier, the Consumer JRE will be an update for Java SE 6, which means that we will be able to deliver it much more quickly than we could if we waited for another major release like Java SE 7. But it's still a lot of work, and we're not done yet. Our best estimates now put the release date in early 2008, although we are trying to pull in the date if at all possible. Given the amount and type of changes in this release (especially Java Kernel), we need to send this release through extensive testing to make sure that it's as solid as you should expect it to be.

We will roll out some features as they are available, so that you don't have to wait for early 2008 to get everything here. For example, the improved installation experience should be out in update 2 of Java SE 6, which is currently set for late June.

The Fine Print

Most of these features are still very much in-development, and are thus apt to change scope or be removed from the release if our goals for them are not reachable. One of the main priorities for the release is getting it out to you as soon as we possibly can, with as much of these features as are doable in that timeframe. So if it looks like any particular feature would stall the release too long, we will have to weigh cutting or changing it in order to still keep our tight timeline. One of the things that is very clear to us is that the features we are providing are not things that would be nice to have in the future; they are necessary pieces of functionality that our developers and users want now. So we hope you'll agree that keeping strict control over the timeline is as important as the functionality of any particular feature we've discussed.

And who knows? Maybe we will also get the chance to add other cool and powerful features along the way, as long as they do not mess with our all-important timeline.

Stay Tuned

I will try to post updates to my blog as we know them, so stay tuned. And look forward, as I will, to a new era of consumer-enabled Desktop Java. In the meantime, check out the slides for the relevant talks at JavaOne when they become available. Some of these items were discussed at our Desktop Java overview, Danny Coward's Java SE: Present and Future, and Ethan's Easy Deployment sessions.