The Source for Java Technology Collaboration
User: Password:



Ethan Nicholas

Ethan Nicholas's Blog

Java Kernel Unmasked

Posted by enicholas on May 24, 2007 at 08:40 AM | Comments (35)

In my last entry, I briefly introduced the major features of the upcoming Consumer JRE. I'd like to now go into details on my pet project, code-named Java Kernel.

Overview

As previously mentioned, the idea is to create a 'minimal' JRE which has enough code to run System.out.println("Hello world!") and... well, that's about it. Every class or native library that isn't strictly necessary to boot up the JVM is excluded.

This minimal JRE has a few tricks up its sleeve, of course. It can detect when you try to access a class, such as javax.swing.JFrame, which isn't currently installed. It will then go download and install a "bundle" containing the required functionality. As far as your program can tell, nothing unusual happened -- it requested javax.swing.JFrame, it got javax.swing.JFrame. The only real difference is that (due to the required download) the classload took longer than usual.

User Interface

Naturally, we display a progress dialog for any downloads taking a meaningful amount of time. If you use a freshly-installed Kernel JRE to run a Java program, you'll see a dialog telling you that a few components are being downloaded, and then the program window will pop up and life will continue as normal.

You usually won't see any other progress dialogs -- most programs download everything they need before the main window shows up. Even with the ones that don't, Swing and AWT are by far the biggest bundles you will end up downloading, and both of them will be there before the main window appears. The other bundles are mostly quite small and won't involve an objectionable delay (and, of course, if the delay is short enough we don't pop up a dialog at all).

Other than this, the Kernel JRE looks and feels exactly like any other JRE.

Bundles

The Kernel JRE is currently divided into a hundred or so different bundles. These bundles generally follow package boundaries -- if you touch any class in (say) java.rmi, the entire java.rmi package will be downloaded. This means you'll end up downloading more classes than strictly necessary to run your program, but the alternative, downloading classes one-by-one, would be ridiculously slow due to all of the individual HTTP requests involved. We are trying to strike the proper balance between reducing the number of bytes downloaded and reducing the number of HTTP requests made.

Some bundles involve more than one package. javax.swing, for example, is entirely useless without javax.swing.event and several other packages. Since they are so tightly interconnected, they are packaged together into a single bundle. A few bundles don't cleanly follow package lines. In java.awt, for example, it makes sense to separate out the subset of AWT used by Swing programs. A Swing program isn't likely to touch AWT components like java.awt.Button, so we have a separate bundle (internally named java_awt_core) which includes only the AWT classes that a typical Swing program would use.

Still not small enough...

We've got other space-saving tricks, as well. Take a look at one of the core, absolutely essential files in Java 6: jvm.dll. This is (obviously) the JVM itself, needed to run all Java code. It's 2.3MB. And that doesn't include any classes, launchers, the installer, the Java Plug-In, Java Web Start, or any of the other essential JRE features. When you're trying to deliver an entire JRE in under 2MB, the fact that one of the required files is 2.3MB puts you at a pretty severe disadvantage.

Compression helps, obviously, but it takes more than a good compressor to squeeze things down this small. Java Kernel has its own version of jvm.dll, which omits a lot of optional features like JVMTI and additional garbage collectors. The current prototype's jvm.dll is a much more svelte 1.1MB. And when the Kernel JRE finishes downloading itself in the background, it will swap in the good old full client JVM, so you won't be without these optional features for long.

Background Downloading

The Kernel JRE will continue to download its missing bundles in the background, whether they were specifically requested or not. Over a broadband connection, this will only take a couple of minutes, so the window of time during which you might run into missing bundles is brief.

After the last bundle is downloaded, the Kernel JRE will reassemble itself into an exact replica of the "normal" JRE. All of the disparate bundles will be repackaged into a unified rt.jar file, the Kernel JVM mentioned above will be replaced with the traditional client JVM, and so forth. A "finished" Kernel JRE will be byte-for-byte identical to a "normal" offline JRE.

But what if I want to pre-download everything I need?

The single most frequently asked question is "Can I force the Kernel JRE to go ahead and download everything I need, so that there are no pauses or download progress dialogs while my program is running?"

I mentioned during my JavaOne session that we were well aware of the need for this, and working on a solution, but that we weren't ready to discuss it yet. I'm pleased to announce that the plans for this have been finalized (well, as final as anything gets in the software industry...) and I can reveal them now.

The JDK will include a tool which allows you to assemble a "custom bundle" containing all of the classes and files needed by your particular program. You determine the entire set of JRE classes needed by your program (for instance by running java -verbose or by using a static analyzer) and then use this list to create the bundle.

(Command names and options likely to change)

> java -verbose -jar MyProgram.jar > class_list.txt
> jkernel -create custom_bundle.zip -classes class_list.txt

You can then install this bundle into a freshly installed Kernel JRE:

> jkernel -install custom_bundle.zip

You can run the jkernel -install command as part of your program's installation or startup. With a custom bundle installed, you can rely upon the absolute minimum set of classes and files needed to support your program, and thus get the smallest possible download size.

This isn't yet optimal for applets or web start programs, as (unlike standalone programs) they don't have the ability to install the bundle before they start to execute, and thus before any bundles are automatically downloaded. Ideally I'd like the ability to simply specify "And my program needs this custom bundle, also" in the applet tag or JNLP file somewhere -- the only question is whether we'll be able to get this into the first release or not.

Results

Remember how the Java 6 jvm.dll is 2.3MB by itself?

The Kernel JRE's installer includes jvm.dll, the other native files and hundreds of classes needed to boot the JVM, the Java Plug-In, Java Web Start, java.exe, javaw.exe, javaws.exe, the installation code, and various support libraries needed to support the installer (such as unpack200).

And it's only 1.9MB.

If you build a custom bundle containing the classes required to run a typical Swing program, it comes out to about 1.5MB, for a total download of around 3.4MB for the JRE + custom bundle. Bigger programs might use as much as 4MB-5MB of the total JRE size, but it would be rare to exceed that.

Compared to the current JRE's size of somewhere between 10MB and 15MB, depending on how you measure it, hopefully you will agree that this is quite an improvement.

So, I'm sure you've got lots of questions for me. Shoot.


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • This will surely be nice to use with standalone desktop applications like those based on NetBeans Platform. I'm pretty sure one can fine-ture a "kernel" with the minimum classes required so that the download is at minimum. Not to mention it makes JNLP really appealing if the user just needs 2MB to start with. A quick remark: the "kernel" word is starting to get overused. Any chance of using something else ?

    Posted by: emilian on May 24, 2007 at 09:12 AM

  • Ethan, great info.

    Few softballs;

    1. ETA for even a preview version?

    2. You had mentioned in your talk that there will still be various download choices (offline, online, Kernel?). I wonder how this will be presented to the user in a non-confusing manner? (Kernel and Consumer JRE might not be terms users might recognize).

    3. Love to see a preview of how that download window looksl like!

    Posted by: augusto on May 24, 2007 at 09:12 AM

  • Thanks for the details. That jkernel bundle thing sounds great. (Catching up with Mono here, and that's good.) I'll assume no support for Mac (sadly). How about Linux? Is it hard to have one build machine that can create bundles for both Windows and Linux?

    Posted by: tompalmer on May 24, 2007 at 09:12 AM

  • Considering that Java is a built-in component on MacOS, and therefore not available for download in the first place, I don't believe this is applicable to MacOS in the first place. (Every computer in my house is a Mac, so trust me that I take the Mac side of things seriously). As for Linux, the initial release is going to be Windows-only, sorry.

    Posted by: enicholas on May 24, 2007 at 09:24 AM

  • Ethan,
    I just want to say; Great Work! Truly Great Work! I hope you get a big pay raise.

    You seem to have analyzed the problems and then solved them in the best possible way. :)

    Cheers,
    Mikael Grev

    Posted by: mikaelgrev on May 24, 2007 at 09:34 AM

  • The JDK will include a tool which allows you to assemble a "custom bundle" containing all of the classes and files needed by your particular program.Cool... kind of reminds me of the old JMF Customizer (maybe the one good idea in JMF). But here's a funny question. What happens when I do this:
    public class TrivialClass {
       public static void main (String[] arrrrImAPirate) {
            Class.forName ("javax.swing.JButton");
       }
    }
    I assume I don't get Swing in my bundle and instead get it on-the-fly? Not that I'd do this; it's stupid. But there might be interesting edge cases with highly reflective scenarios (I'm tempted to say Jini, but that system of on-the-fly remote classloading has already been proven out and need not involve the Java Kernel, right?).

    Posted by: invalidname on May 24, 2007 at 10:26 AM

  • Look at the example commands -- I'm using "java -verbose" to list all of the loaded classes, and then feeding that in as an argument to the command that creates the bundle. With your example, javax.swing.JButton would show up just fine in the output from -verbose. In general, I'm leaving the job of determining the correct list of classes in your hands. The "java -verbose" method is pretty bare-bones, but adequate in many cases, whereas more sophisticated analysis can be done by many freeware and commercial static analyzers.

    Posted by: enicholas on May 24, 2007 at 10:35 AM

  • Thanks for the additional info.

    Posted by: tompalmer on May 24, 2007 at 11:10 AM

  • That "java -verbose" thing would work especially well with unit tests as part of the build. If the unit tests really exercise the app, then the list of classes could be generated on the fly and used for bundling. Hmm.

    Posted by: tompalmer on May 24, 2007 at 11:13 AM

  • This indeed is great and will certainly reduce the size of jre required to run a particular java application. There was a software under the name of ‘rejar’, which looks a java application , determines the classes needed and repackages only the classes needed into a jar file. It seems that jkernel works the similar way.

    Posted by: jdevp2 on May 24, 2007 at 01:20 PM

  • It's a shame about the lack of web start support as I don't really see asking the users to mess around on the command prompt very consumer oriented. I don't see why web start couldn't download the needed bundles while downloading its usual resources listed in the JNLP - except I guess they'll be loaded by the wrong classloader and so might create some interesting security implications. How would installations work in the meantime? do you envisage developers creating native .exe installers? batch files?.

    Also wondered if the bundle creator by example would in practice be sufficient as not all clients are created equal. Some might be using XP l&f, Classic or be using Vista, some will have 3d cards some won't, some might not even be using Windows (shock horror ;). It looks like you'd have to add a fair bit of expert guesswork to the results to create a bunch of targeted platform bundles or else run that tool with every conceivable platform / theme / laf (or avoid giving users any choices)? Or would Swing just come as one or two big lumps all locales, themes, plafs, resources and accessibility apis etc.. included regardless of actual end usage?

    I take it the kernel is showing the progress dialogs as most requests for classes that might lead to downloads will happen on the EDT which'll be too late.. apps frozen. Are the sudden unexpected delays something developers might be expected to code for? what happens if I've just exceeded my monthly broadband cap etc..? Sorry you've lost all your data? (well not even that).

    I also take it the jre and kernel versions won't co-exist on the same machine fully? I mean who gets called when I double click a jar or run a JNLP file? might be a pain for developers testing deployments having to uninstall/reinstall the jre and/or purge kernel caches all the time just to check their apps out (as the end users might experience them). Some dev utils might be nice if I'm guessing correctly.

    Posted by: osbald on May 24, 2007 at 03:07 PM

  • I'm a little skeptical about this downloading-in-the-background idea. It sounds like little more than a warmed over, more granular version of the current network install, without a way to predict exactly when the network activity is going to occur and when the whole process is going to be finished. Technically interesting, but it sounds fragile.

    Instead of treating the initial stages when you only have a partial jre installed as a transient state that you'll grow out of once everything is downloaded, I think it would be more interesting to have permanent partial or subset jres. What I mean is, say I'm distributing a commercial Java program. I have to distribute a 'private' jre with it, to make sure the user gets the right one that I tested with. I'd like to distribute only the bare minimum bits that my application will ever need (e.g., just the 'Foundation' level), and I don't want it to download anything else or pop up any progress bars automatically without my control.

    And are those going to be Swing-based progress dialogs? What if my app doesn't use Swing, say it's a SWT program or it's purely a console/command line program or daemon?

    Posted by: eburnette on May 24, 2007 at 07:35 PM

  • I'm sorry, i must have missed something. How does solve the main problem with java desktop apps - they're incredibly slow to startup? If you're telling me that you can download and install a class almost as fast as you can install it off the disk, then you're solving the wrong problem. For years I've wanted a feature that would take a fully initialized java app and pickle it as a stand alone executable. That would give you decent startup times. This just seems like an amusing intellectual exercise.

    Posted by: lelliot on May 24, 2007 at 07:36 PM

  • @lelliot - read the previous entry on the blog, this is not about faster startup times, it's about download. Different issue.

    Posted by: augusto on May 24, 2007 at 08:15 PM

  • While size improvement is a nice and welcome addition can you go into details about the improved installer/quickstart?
    You mentioned that there were improvements to the installer in your previous post, what are they? Would you solve the administrator requirement?
    You also mentioned a quickstart engine, I understood it will try to bring the Java native libs into memory. Can you elaborate on that? How does it compare to the startup time of current Java/nailgun?
    Thanks.

    Posted by: vprise on May 25, 2007 at 01:53 AM

  • Ethan, Notwithstanding the other comments, you guys've done an amazing job. Just awesome. This is very promising indeed. Just can't wait for the "beta" bits.

    Posted by: bharathch on May 25, 2007 at 02:36 AM

  • Ethan,

    Keep up the great work.

    Rob

    Posted by: rabbe on May 25, 2007 at 05:10 AM

  • Congrats on getting the JRE size down, this is very good news indeed. I have a couple of questions regarding the Consumer JRE that I've not been able to find an answer to: Given that large chunks of the JRE may be downloaded separately from the intial install, will these downloadable libraries require signing? If so, will that result in a required user response to accept any certs? Are the core JRE libraries only downloadable from Sun? If not, how would I guard myself against the situation of a malicious host serving up a "dirty" versions of parts of the JRE that could cause all sorts of mischief? With regard to the downloading mechanism, this sounds all well and good, but I can see potential for long unexplained application pauses. Does the proposed mechanism offer the programmer any control over the download situations? For instance, on initial start-up I would *really* like some control on how the initial download screen is presented, ideally having the ability to replace the current orange blob with my own branding. Also once an app is running, I would like to be able to get notifications of when a background download is about to happen and be able to get feedback on download progress etc so that I can potentially show progress on larger downloads instead of an app just locking. Cheers, Chris.

    Posted by: lowecg on May 25, 2007 at 06:17 AM

  • blah - my html tags didn't take!

    Posted by: lowecg on May 25, 2007 at 06:17 AM

  • All we want is not being affraid of using applet (which made me live for years in intranets) in consumer applcations.
    I have no doubt you will make the jvm start fast and get slim, but don't forget ease of installation.
    Developpers must have this in their heads: "if they don't have the latest Java, no pb, after my site, they will !"

    Posted by: nopjn on May 25, 2007 at 09:51 AM

  • Spare a thought for users that have to negotiate corporate firewalls and what not. Is the Java Kernel going to support my SOCKS or HTTP proxy? What if it requires authentication?

    Posted by: fullung on May 25, 2007 at 10:34 AM

  • What about security? Meaning when the jkernel goes to download a package, say a mallicious DNS points it to a different host and downloads the "tainted" package. Now this particular JRE is potentially compromised. Lastly, what happens if the user runs an application while disconnected? How will this error condition be represented?

    Posted by: atehrani on May 25, 2007 at 11:46 AM

  • Ethan,

    I think you've done an amazing job! I am especially impressed by how you solved the problem of native libs as that one stumped me when I was working on it years back.

    I hope one day an integrated dependency-detector will ship with the bundle builder but that can definately wait until later versions.

    I think that to a large degree the complaints I've read are posted by skeptics. Guys, I think you really need to put things in perspective. It is impossible for Ethan to please everyone on the first version, but a lot of the features you are asking for will follow later on. I also think you misunderstand the target audience of the Consumer JRE. It's obviously going to be better suited for home users than corporate users, that's the entire point. Feel free to use the normal installer for your corporate users until such a time that the Kernel JRE works sufficiently well for them (besides, I suspect it'll work well for most corporate users out of the box but you'll have to wait and see whether I'm right or not). Just my 2 cents :)

    Gili

    Posted by: cowwoc on May 25, 2007 at 05:40 PM

  • What is the relationship between consumer JRE and JSR 277 and JSR 294?

    There is quite a lot of effort in the Java community these days to resolve long standing issues but I am often unsure whether they are coordinated all together (e.g. bean-bindings and new bean-property syntax). Would these 'download bundles' be properly aligned with module system (JSR 277) and superpackages (JSR 294

    Posted by: vtec on May 26, 2007 at 01:27 AM

  • I’m using Debian Linux on embedded systems, servers and desktops. There is not another operating system on the planet that has a so high degree of configurability. Until today, the Java installation on Debian fits perfectly for both servers and desktops, but it is not enough configurable for the needs of embedded systems. Until today, Java was not easily customizable for the different embedded uses. This is clearly visible in the fragmentation of the solutions at this page: http://java.sun.com/javase/embedded/index.jsp Now, thanks to projects like “Java Kernel”, there is the possibility for a big change. Debian is for sure the platform of choice to unleash all the power of the future JRE modularization for embedded systems. Based on the linuxdevices polls, Debian is the most used distributions for the design of embedded systems (http://www.linuxdevices.com/cgi-bin/survey/survey.cgi?view=archive&id=01302007173158). With peoples like Ethan Nicholas and Ian Murdock (http://ianmurdock.com/?p=330) Sun can really pose an end to JRE fragmentation in the embedded market through configurability. By the way, if Solaris will ever try to reach the configurability (consequently communities momentum) of Debian, why not to follow the example of the Pardus distribution: http://www.pardus.org.tr/eng/projects/comar/PythonInPardus.html Python is a great choice to replace all that weird “shell scripting”.

    Posted by: emilmont on May 26, 2007 at 03:43 AM

  • Could this effectively be a runtime version of the Perl CPAN for Java? Kernel libraries and also any 'registered' libraries? I find it's often very burdensome finding compatible packages, a problem which over time could undermine Java's accessibility.

    Posted by: andrewcross on May 27, 2007 at 02:23 AM

  • Good news!!! 1 question, is there any way that we can pack Consumer JRE and only related packages with our application ? Some time we need a smaller size VM like embeded devices, installer and etc. Thanks

    Posted by: ivanooi on May 27, 2007 at 06:11 PM

  • My company uses applets extensively. The problem with applets is not the size of the JRE download, it's the amount of time that it takes for the plug in to start up and begin running the application. I'm all for a smaller download, but a faster start time and more reliable browser plug in would help a lot more.

    Posted by: coffeejolts on May 31, 2007 at 06:58 AM

  • is it possible to get hands on that jkernel utility? i need to shrink rt.jar to fit JRE + linux + a given swing app into a 64meg flash disk on one of those HP thinclients... thks!
    PS. for such resource-constrained situations (eg. swing on mobile?) it might be handy if JVM supported pack200 eg. java -Xbootclasspath/pack200:rt.jar.pack.gz - altho then the startup time would be slower

    Posted by: evanx on July 02, 2007 at 09:53 AM

  • Ethan,

    You said, "All of the disparate bundles will be repackaged into a unified rt.jar file."

    Is the rt.jar per application or per kernel JRE? The former would mean a smaller footprint per application, whereas the latter may grow larger as more programs are run.

    Personally, I'd be thrilled if someone could extend the concepts of "bundles" to the running JVM (rather than just the environment). So that a commandline program that needs java.util, java.io, and java.net can load those parts, and only those parts of the rt.jar. (Those plus java.lang and whatever com.sun.* classes needed to make it run only come to about 8-10MB.)

    Right now, running anything with 1.6 loads a whopping 44MB rt.jar. Most of which (34-38MB in my example) goes unused. With each release rt.jar has grown by about 9MB. (1.4.2 to 1.5.0: 11MB, 1.5.0 to 1.60: 7MB)

    Can you imagine trying to running linux/windows where support for almost everything you might possibly ever need is stuffed into a single sharedobject/dll?

    Posted by: darkling on July 12, 2007 at 09:58 AM

  • Ethan, Just a suggestion for those who have an ear at SUN. What if Netbeans could discover "everything" that is needed in the JRE to run an application that a developer has coded to release level. Then Netbeans could bundle the JRE with the application. This would be a great feature for Netbeans. The idea of a modular JRE leads to a concept of bot-like programs running in or outside of browsers, communicating with all kinds of devices. The easier this could be made for developers, the closer to the "Network is the computer" ,we could get.

    Posted by: fredruopp on September 04, 2007 at 05:31 PM

  • Hello I am a developer of java web service. The size (and not so good java jre detection) is causing me a lot of problems. I make all my wish for "java consure jre" to be made public as soon a s possible. Because we really need this ! Adobe Flash is (for us 3D business ) a concurent. Hope java consurer jre is as quick and fast to install. Wish you a lot of success. Java's future is perhaps on your hand ! Thierry , www.free-visit.com

    Posted by: tmilard on October 02, 2007 at 08:10 AM

  • This can not come out too soon!!!! Is there any ETA yet? I can't find any new announcements

    Posted by: mgiacomi on January 06, 2008 at 01:29 AM

  • Ethan, you said that we can pack the dependent classes up by using jkernel:
    > java -verbose -jar MyProgram.jar > class_list.txt > jkernel -create custom_bundle.zip -classes class_list.txt > jkernel -install custom_bundle.zip
    But I can not found the jkernel command at my computer. (I've installed the kernel jvm 1.6 update 10 beta) Can you tell me how can I get the jkernel? Thanks!!

    Posted by: wannachan on April 21, 2008 at 05:44 AM

  • Is jre kernel can't work with JNI? I have a old project build with the jdk6.0 and it run in normal jre is ok,but it can't work normally when i change to jre kernel.My os is windows.

    Posted by: sonichui on May 08, 2008 at 06:39 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds