<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Ethan Nicholas&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/" />
<modified>2008-04-29T20:20:34Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/enicholas/320</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, enicholas</copyright>
<entry>
<title>Java Secrets Revealed #1</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2008/04/java_secrets_re.html" />
<modified>2008-04-29T20:20:34Z</modified>
<issued>2008-04-29T20:19:44Z</issued>
<id>tag:weblogs.java.net,2008:/blog/enicholas/320.9635</id>
<created>2008-04-29T20:19:44Z</created>
<summary type="text/plain">The first of hopefully many articles detailing little-known facts about the inner workings of the JRE.  In this episode: Java Plug-In vs. Java Web Start; Class Data Sharing.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>J2SE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>I know, I know, it's been far too long since I've made an entry.  My younger son is ten months old now, so I suppose I should probably stop using "new baby" as an excuse for my laziness... </p>

<p>Ahem.</p>

<p>Before I joined Sun, I thought I knew a lot about Java.  I had been using it for a decade and had dug into its innards more times than I could count.  Anytime I ran into inexplicable Swing weirdness or whatnot I wouldn't hesitate to dive into the JRE's source code and study it, or even recompile the classes with my own diagnostic code added.  I wrote my own classloaders, I manipulated bytecode on the fly, I even wrote my own compiler for a JVM-targeted language.  I had earned the right to call myself a guru.</p>

<p>Or so I thought.</p>

<p>Joining Sun nearly two years ago was a humbling experience.  You see, it turns out that knowing a lot about Java works as a third-party developer is very different than, say, having to figure out how to rip the JRE apart and reassemble it on the fly without running programs noticing (<a href="http://weblogs.java.net/blog/enicholas/archive/2007/05/java_kernel_unm.html">Java Kernel</a>, for the uninitiated).  I have had to learn more about Java's inner workings than I ever really wanted to know, and maybe you'll find some of it interesting.  Towards that end I'm going to pick a couple of random topics to blather about here, with the intent of hopefully making this a semi-regular feature.</p>

<h1>Why can Java Web Start specify JRE versions, but the Java Plug-In can't?</h1>

<p>If you have worked with both JNLP programs and applets, you are no doubt aware of the incongruities.  JNLP programs can specify which JRE version they need to run with, their memory settings, command-line arguments, and so forth.  Applets, on the other hand, are stuck with whichever JRE is registered with the web browser, and have no control over any JRE settings.  (JRE Settings can be changed via the Java Control Panel, but cannot be specified by or for individual applets.)</p>

<p>The limitation arises because the JRE which handles applets runs inside the web browser.  It lives within the browser process and address space, and as far as the OS is concerned is merely another chunk of the browser's code, just as with any other plug-in.  And you can't simply load more than one JRE into the same OS process, because they would have conflicting symbol definitions, entry points, and so forth.  It would be like trying to boot two different operating systems on the same computer, without the benefit of (very sophisticated) tools like <a href="http://www.vmware.com/">VMWare</a>.</p>

<p>To fix this, you've got to run the JRE in a separate process, but have the applets appear within the web browser window.  This, of course, introduces all sorts of challenges and requires some clever engineering, but fortunately people smarter than me were assigned to the task.  A group led by <a href="http://blogs.sun.com/kbr/">Ken Russell</a> has done just that, resulting in what is officially (and wordily) named <a href="https://jdk6.dev.java.net/plugin2/">Next-Generation Java™ Plug-In Technology</a>.  </p>

<p>The new plug-in behaves much more like Web Start, in that you can use JNLP files to specify JRE versions, memory settings, and command line arguments.  It's smart enough to consolidate multiple applets into the same JRE if their settings are compatible, or spawn additional JREs as needed to make everyone happy.  It also has some <i>extremely</i> cool tricks up its metaphorical sleeve which we will be revealing at JavaOne.</p>

<h1>What is Class Data Sharing?</h1>

<p>Prior to joining Sun, I had read a paragraph about Class Data Sharing somewhere, but didn't know much about it.  Since then I have found that pretty much nobody outside of Sun seems to know anything about it either.  That's a shame, because it's actually quite neat.</p>

<p>One of the JRE's biggest jobs when booting up is classloading.  Hundreds and hundreds of classes are needed just to get the JRE up and running, and not just the obvious ones like Class, Object, and String.  You're also going to need URL and its entourage (for URLClassLoader), PrintStream and related I/O classes (for System.out and System.err), lots of different collection and utility classes, reflection support, charset support, and hundreds more.</p>

<p>There are two huge drawbacks to this: first, the JVM has to parse the Java class file for each of these classes, as well as resolve and link the symbols, and (for commonly-used methods) compile the methods using HotSpot.  And, of course, all of this work happens every time the JRE starts up.  Second, because each individual JRE is parsing and possibly compiling the code independently, they all end up with their own independent copies of the resulting memory structures.</p>

<p>To combat this problem, Java 5 introduced a new feature called <a href="http://java.sun.com/j2se/1.5.0/docs/guide/vm/class-data-sharing.html">Class Data Sharing</a>.  The idea is that the JRE does all of the basic classloading and parsing just once, and stores the resulting memory structures in a file (<code>bin/&lt;jvm&gt;/classes.jsa</code>, with jsa standing for Java Shared Archive).  The next time the JRE boots, it simply maps this file into memory, and can skip all of the messy classloading.  In addition to performance, another benefit is the fact that a big chunk of the mapped bytes can be shared by all running JREs, so they do not each need an independent copy of all of the code.</p>

<p>Of course, as with everything the devil is in the details.  Some of the classes in the archive perform initialization which isn't guaranteed to alway be the same (the AWT classes, for example, will do different things depending upon your display configuration), and I'm told that there are enough such cases that the feature was a lot trickier to implement than it might sound.  Plus you've got to detect the cases where the rt.jar file has been modified, or the boot class path has been overridden, or something else has changed which makes the inherent assumptions burned into the classes.jsa file incorrect, so that class data sharing can be disabled for that particular JRE invocation.</p>

<p>If you use <code>diff</code> or a similar tool to compare JRE directories from various machines running the same JRE version, you'll most likely find that the classes.jsa files, and only those files, are different.  That's because classes.jsa is actually generated on your machine, instead of packaged with the installer.  One of the last things the JRE installer does is run the magic incantation <code>java -Xshare:dump</code>, which causes the shared archive to be generated.  That way we don't have to increase the size of the installer further, and I don't know for sure but I suspect that some aspects of the file may be machine-dependent which would necessitate this approach anyway.</p>

<h1>Until next time...</h1>

<p>Hopefully that little look inside wasn't too boring.  Provided anyone is interested, I'll continue to share tidbits about the inner workings of Java in future installments.  Unless of course I forget, or get sidetracked...</p>]]>

</content>
</entry>
<entry>
<title>Java Kernel Unmasked</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2007/05/java_kernel_unm.html" />
<modified>2007-05-24T18:29:07Z</modified>
<issued>2007-05-24T16:40:48Z</issued>
<id>tag:weblogs.java.net,2007:/blog/enicholas/320.7503</id>
<created>2007-05-24T16:40:48Z</created>
<summary type="text/plain">A complete overview of what Java Kernel is, how it works, and what sort of results you can expect to see.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>In my <a href="http://weblogs.java.net/blog/enicholas/archive/2007/05/announcing_the.html">last entry</a>, 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.</p>

<h1>Overview</h1>

<p>As <a href="http://weblogs.java.net/blog/enicholas/archive/2006/09/java_browser_ed.html">previously mentioned</a>, the idea is to create a 'minimal' JRE which has enough code to run <tt>System.out.println("Hello world!")</tt> and... well, that's about it.  Every class or native library that isn't strictly necessary to boot up the JVM is excluded.</p>

<p>This minimal JRE has a few tricks up its sleeve, of course.  It can detect when you try to access a class, such as <tt>javax.swing.JFrame</tt>, 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 <tt>javax.swing.JFrame</tt>, it got <tt>javax.swing.JFrame</tt>.  The only real difference is that (due to the required download) the classload took longer than usual.</p>

<h1>User Interface</h1>

<p>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.  </p>

<p>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).</p>

<p>Other than this, the Kernel JRE looks and feels exactly like any other JRE.</p>

<h1>Bundles</h1>

<p>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.</p>

<p>Some bundles involve more than one package.  <tt>javax.swing</tt>, for example, is entirely useless without <tt>javax.swing.event</tt> 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 <tt>java.awt</tt>, 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 <tt>java.awt.Button</tt>, so we have a separate bundle (internally named <tt>java_awt_core</tt>) which includes only the AWT classes that a typical Swing program would use.</p>

<h1>Still not small enough...</h1>

<p>We've got other space-saving tricks, as well.  Take a look at one of the core, absolutely essential files in Java 6: <tt>jvm.dll</tt>.  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 <i>one</i> of the required files is 2.3MB puts you at a pretty severe disadvantage.</p>

<p>Compression helps, obviously, but it takes more than a good compressor to squeeze things down this small.  Java Kernel has its own version of <tt>jvm.dll</tt>, which omits a lot of optional features like JVMTI and additional garbage collectors.  The current prototype's <tt>jvm.dll</tt> 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.</p>

<h1>Background Downloading</h1>

<p>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.</p>

<p>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 <tt>rt.jar</tt> 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.</p>

<h1>But what if I want to pre-download everything I need?</h1>

<p>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?"</p>

<p>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.</p>

<p>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 <tt>java -verbose</tt> or by using a static analyzer) and then use this list to create the bundle.</p>

<p>(Command names and options likely to change)</p>

<p><tt>&gt; java -verbose -jar MyProgram.jar > class_list.txt<br />
&gt; jkernel -create custom_bundle.zip -classes class_list.txt<br />
</tt></p>

<p>You can then install this bundle into a freshly installed Kernel JRE:</p>

<p><tt>&gt; jkernel -install custom_bundle.zip</tt></p>

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

<p>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.</p>

<h1>Results</h1>

<p>Remember how the Java 6 <tt>jvm.dll</tt> is 2.3MB <i>by itself</i>?  </p>

<p>The Kernel JRE's installer includes <tt>jvm.dll</tt>, 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).</p>

<p>And it's only <b>1.9MB</b>.</p>

<p>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 <b>3.4MB</b> 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.</p>

<p>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.</p>

<p>So, I'm sure you've got lots of questions for me.  Shoot.</p>]]>

</content>
</entry>
<entry>
<title>Announcing the Consumer JRE (again!)</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2007/05/announcing_the.html" />
<modified>2007-05-17T20:59:39Z</modified>
<issued>2007-05-17T20:51:26Z</issued>
<id>tag:weblogs.java.net,2007:/blog/enicholas/320.7442</id>
<created>2007-05-17T20:51:26Z</created>
<summary type="text/plain">With all the fuss about JavaFX, you may have missed an equally important announcement: the new Consumer JRE is on its way, with a host of exciting improvements.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Deployment</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>When Steve Jobs announced the <a href="http://www.apple.com/iphone/">iPhone</a> at MacWorld, Mac fans were understandably upset that no other announcements were made.  There was nary a mention of Macs, Mac OS X, or iPods -- and disgruntled fans pointed to this as evidence that Apple was ignoring these products.</p>

<p>A few of the saner voices in the audience took the stance that since nothing could possibly have competed with the iPhone announcement, there was no point in Apple even trying to talk about anything else until the iPhone furor died down.  After seeing what happened at JavaOne, I'm inclined to agree with this particular theory.</p>

<p>The "iPhone effect" has struck again -- only this time it's the "JavaFX effect".  We announced a bunch of exciting things at JavaOne 2007, but the news of <a href="http://www.sun.com/software/javafx/">JavaFX</a> has inspired so much coverage and discussion that it's hard for anything else to get any press time.</p>

<p>The other big announcement, the one you might not have seen much (or any) coverage of, was the Consumer JRE.  The Consumer JRE is a release of Java 6 targeted at making the end-user experience better, meaning smaller downloads, faster installs, better graphics performance, smoother installation, faster startup, better reliability, and a bunch of other nice enhancements.</p>

<p>The best part is that I've seen several references to a <a href="http://www.theserverside.com/news/thread.tss?thread_id=45377">"rumored" Consumer JRE release</a>.  Considering that we publicly announced the Consumer JRE in front of thousands of developers, I think we can safely move this particular 'rumor' into the "confirmed" column.</p>

<p>In case you missed my JavaOne session about the Consumer JRE, here's what you should know:</p>

<ul>
<li>The Consumer JRE will be a Java 6 update release delivered in the first half of 2008.
<li>It features performance and usability enhancements geared towards easier, better, faster end-user distribution.
<li>Will include the Java Technology Deployment Toolkit, a suite of technologies enabling much simpler JRE detection and installation.
<li>The JRE is being modularized, so that bits and pieces of it can be downloaded as needed.  In the current prototype, the download needed to support a typical Swing program is between 3 and 4MB.
<li>Java Quick Start Service will pre-load portions of the JRE into the system disk cache, substantially decreasing the average start-up time.  
<li>A new and improved installer will streamline, simplify, and speed up the installation process.
<li>Future updates will be delivered in-place -- you will no longer inadvertently end up with fifteen different versions of the JRE on your system.
<li>Some of these features may be delivered sooner than others.
</ul>

<p>I'll go into more details about these specific features in the near future.  But for now, at least be aware that the Consumer JRE is anything but a rumor.</p>

<p>Also, take note of <a href="http://www.java.net/pub/pq/157">this poll</a>.  Despite the dearth of coverage, it sounds like at least <i>some</i> folks caught the announcement.</p>]]>

</content>
</entry>
<entry>
<title>Integrate JAR files into your Windows desktop</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2007/03/integrate_jar_f_1.html" />
<modified>2007-03-15T21:56:49Z</modified>
<issued>2007-03-15T18:01:26Z</issued>
<id>tag:weblogs.java.net,2007:/blog/enicholas/320.6829</id>
<created>2007-03-15T18:01:26Z</created>
<summary type="text/plain">A nifty shell extension which allows you to treat JAR files as ordinary executable programs under Windows, complete with custom icons.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>Dieter Krachtus just sent me a link to a project he's working on, a shell extension which allows you to <a href="http://djproject.sourceforge.net/main/index.html">treat JAR files as executable programs</a> under Windows.  Now, double-clicking on a JAR file has long caused it to be launched under "java -jar", but with the generic "Java document" icon it doesn't exactly scream "executable program".  I'm not sure how many people even know that you can double-click on a JAR to launch it, and between that and the generic icon that probably explains why I've never seen a Java program which took advantage of that ability.</p>

<p>With the ability to embed multiple resolutions / color depths of icons directly into your JAR files, as well as Ant integration and a GUI, this looks like a nifty little project.  It's currently limited by the fact that it has to be installed on the end-user's system to function, but... what if this sort of capability were integrated directly into the JRE?  Is that something you would find useful?</p>

<p>It's also worth mentioning that, as a Mac user, I'm used to being able to "install" most applications by simply dragging them to my Applications folder or other convenient location, and "uninstall" them by dragging them to the trash.  JAR files potentially represent the same capability offered to users of other platforms -- just download the JAR file, and that <i>is</i> the program, with no need to install it before using it or uninstall it when you're done with it.  Just double-click on it to run it, and if you decide you don't want it anymore you merely need to delete it.  I think there's quite a bit of merit to this idea.</p>

<p><b>Update:</b> Sorry, I should have explicitly stated that Dieter does not work for Sun and this is not a Sun project -- it's just something I thought was neat.  I should also mention that most of the credit goes to Chris Deckers, the project lead.</p>]]>

</content>
</entry>
<entry>
<title>Grown-up games</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2007/01/grownup_games_1.html" />
<modified>2007-01-08T16:32:57Z</modified>
<issued>2007-01-08T16:32:51Z</issued>
<id>tag:weblogs.java.net,2007:/blog/enicholas/320.6279</id>
<created>2007-01-08T16:32:51Z</created>
<summary type="text/plain">Five little-known facts about Ethan Nicholas.  Includes photos of my movie theater, tattoo, and mineral collection.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[My sixteen-month-old son is just at the point where he's beginning to play tag, so it's a part of my day-to-day life now.  It's fitting that I find myself tagged by <a href="http://weblogs.java.net/blog/rbair/archive/2007/01/five_little_thi.html">Richard Bair</a> in this grown-up game of tag.  In case you have (somehow) missed the meme, bloggers are supposed to reveal five little-known facts about themselves and then tag five more people.  So, without further ado:

<h1>Five little-known facts about Ethan Nicholas</h1>
<ul>
<li>I ran a BBS (Bulletin Board System) when I was in high school.  This was back before the Web existed and before most people had even heard of the Internet.  A lovely young lady dialed in using a 1200 baud modem attached to an aging Tandy, I struck up a conversation with her, and eventually we started dating.  That lovely young lady is now my wife.  (We met <i>before</i> it was cool to meet people online.)</li>
<li>I'm a college dropout.  During my senior year, GeoCities bought an application I wrote and moved me out to California, so I dropped out of school and never looked back.  That's how I ended up at Yahoo!, also -- they bought GeoCities less than a year later.</li>
<li>I collect gems and minerals.  These are just a few of them (click thumbnails for larger images).  All told, I have over three hundred specimens in several different cases.  This case is my favorite, because the glass platforms rotate.<br>
<a href="http://weblogs.java.net/blog/enicholas/archive/Case.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Case.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Case-thumb.jpg"/></a>
<a href="http://weblogs.java.net/blog/enicholas/archive/Cavansite.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Cavansite.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Cavansite-thumb.jpg"/></a>
<a href="http://weblogs.java.net/blog/enicholas/archive/Goethite.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Goethite.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Goethite-thumb.jpg"/></a>
<a href="http://weblogs.java.net/blog/enicholas/archive/Spinel.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Spinel.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Spinel-thumb.jpg"/></a>
<a href="http://weblogs.java.net/blog/enicholas/archive/Rhodochrosite.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Rhodochrosite.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Rhodochrosite-thumb.jpg"/></a>
<a href="http://weblogs.java.net/blog/enicholas/archive/Wulfenite.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Wulfenite.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Wulfenite-thumb.jpg"/></a>
</li>
<li>I turned the attic of my house into a movie theater.  I like to play video games up there.  The screen in the shot below is 160" diagonal, which is over thirteen feet.  I contracted out the actual construction work (framing the walls, hanging drywall, and so forth) but did all of the electronics, wiring, and such myself.  It has two rows of four seats each.<br>
<a href="http://weblogs.java.net/blog/enicholas/archive/Theater.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Theater.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Theater-thumb.jpg"/></a>
<li>I have a tattoo of a dragon on my left forearm.  Everybody asks me if it hurt.  Yes, it hurt.  It hurt exactly as much as you'd expect getting stabbed with a needle ten thousand times would hurt.  My wife has a tattoo on her back, but she said that getting hers "kind of tickled".  Evidently I'm a sissy.<br>
<a href="http://weblogs.java.net/blog/enicholas/archive/Tattoo Closeup.jpg" onclick="window.open('http://weblogs.java.net/blog/enicholas/archive/Tattoo Closeup.jpg','popup','toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://weblogs.java.net/blog/enicholas/archive/Tattoo Closeup-thumb.jpg"/></a></li>
</ul>

So there you go.  Five things about me, several of which you would probably have been happier not knowing.  And one last thing: <a href="http://weblogs.java.net/blog/chet">Chet Haase</a>, <a href="http://weblogs.java.net/blog/zixle/">Scott Violet</a>, and <a href="http://weblogs.java.net/blog/hansmuller/">Hans Muller</a>, you're it!

(Yes, I know that's only three people.  And I'm sure they've all been tagged before.  But I don't see anything about it in their blogs, so here's hoping they actually produce.)]]>

</content>
</entry>
<entry>
<title>Trying to understand really big numbers</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/12/trying_to_under_1.html" />
<modified>2006-12-21T07:52:00Z</modified>
<issued>2006-12-19T16:12:51Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.6199</id>
<created>2006-12-19T16:12:51Z</created>
<summary type="text/plain">Just how much data would it take to fill a 128-bit filesystem, anyway?</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>Ok, this isn't strictly Java-related, but it's geeky enough that I hope you find it interesting regardless.</p>

<p>Various sites have recently broken the news that the next version of MacOS X, code-named Leopard, will feature support for Sun's <a href="http://en.wikipedia.org/wiki/Zfs">ZFS</a> filesystem.  As a Mac user, I find this news particularly exciting, but those of you still using Windows may want to take note as well.</p>

<p>If I sat down and wrote a list of all the things a super-powerful futuristic filesystem should do, completely without regard for practicality or implementation difficulty, not only would ZFS already do everything I came up with, but I doubt I would have imagined even half of its actual features.  Suppose you want to clone your hard drive, install a test application, and then roll back to the previous state of your hard drive.  How long would that take you?  For most of you, long enough that you'd rather just cross your fingers and hope for the best. </p>

<p>Under ZFS, creation of a writable clone of a filesystem is essentially instant.  It only has to maintain the difference between the two states, rather than two complete copies of the data, so the clone initially takes no space and virtually no time to create.  Once you're done with your tests, destroying the clone is also essentially instant.  The ability to instantly create, restore, and destroy snapshots and clones is incredibly powerful and something I'm very excited about, but it's not the only trick up ZFS' proverbial sleeve.</p>

<p>Among other things, ZFS is a 128-bit filesystem, meaning that the total storage it can manage in a single storage pool is 2<sup>128</sup> blocks, which is a very big number.  In fact, 2<sup>128</sup> is such a big number that I'm going to unequivocally state that we will never, ever need more storage than that.  </p>

<p>That's a bold claim.  Many computational limits have been thought sufficient in the past -- who ever thought we would need more than 4GB of memory in a desktop system?  I've seen people making similar claims in response to ZFS, thinking that we've passed every other limit, so why not this one?  That's a reasonable question to ask, so let's take a look at how much data a 128-bit filesystem can actually hold.</p>

<p>We need to store a lot of data for this thought experiment, and nothing fills hard drives like video.  Let's say it's high-definition video, complete with surround sound -- maybe 10GB / hour after compression.  And you record this  video 24 hours a day, 365.25 days a year.  That's 85.6 terabytes a year, which is certainly a lot of data, but it's well within the reach of modern storage systems.  So let's record this video for a very long time, say since the <i>formation of the Earth</i> 4.5 billion years ago.  That's an inconceivable amount of data, roughly 359 billion terabytes, and is already more than a 64-bit filesystem can handle.</p>

<p>But what good is only one camera?  It might end up at the bottom of the ocean and spend a billion years filming a family of sponges.  We clearly need many, many cameras.  Let's put one camera for each square meter of the Earth's surface, all of them recording high-definition video for 4.5 billion years.  We're up to 2 x 10<sup>38</sup> bytes now, an inconceivably large number.  You could also express it as 200 trillion trillion terabytes, but that doesn't make it any easier to handle -- it's just too big for human understanding.  We <i>must</i> have filled up the filesystem by now, right?</p>

<p>Well, this incomprehensibly gargantuan amount of data has indeed put a dent in our 128-bit filesystem, which is now about 0.1% full.  All the data ever produced by the human race -- all speech, books, plays, movies, music, emails, everything -- is a tiny, tiny drop in the bucket in comparison.</p>

<p>A 128-bit filesystem effectively cannot be filled.  The laws of physics set an upper bound on the amount of information we can cram into a certain amount of mass and volume, which means that it would take at least <a href="http://blogs.sun.com/bonwick/date/20040925">136 billion kilograms</a> worth of matter to hold that much data.  And that's just a lower bound on the amount of matter necessary; it might not be a very tight bound (meaning the actual requirement is probably many orders of magnitude greater).  Even ignoring the obvious impossibility of creating a storage device that large, you could never create enough data to fill it.  Even with a high-definition camera on each square meter of the Earth's surface, it would take almost 4 trillion years' worth of video to fill it.  </p>

<p>I think there's a lesson here.  Our computers are now powerful enough that it's reasonable to choose limits so large that we can be essentially 100% confident that they will never, ever be reached, not in this universe at least.  The question "How large can I imagine this value getting?" is very dangerous, because we humans are creatures of small imaginations.  I'm not suggesting that every single limit must be so ridiculously large as 2<sup>128</sup>, but it's important to remember that arbitrarily chosen small limits have historically been a much, much greater problem than asking the computer to process an extra couple of bytes here and there.</p>

<p>And, because I want to at least <i>mention</i> Java here, take a look at JSR-202, "Java Class file Specification Update".  One of the major changes is increasing various limits, because those initially chosen for the sizes of methods and so forth turned out to be too small.  The limits of human imagination strike again.</p>
]]>

</content>
</entry>
<entry>
<title>My most-used utility methods</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/10/my_mostused_uti.html" />
<modified>2006-10-17T18:48:59Z</modified>
<issued>2006-10-17T18:48:52Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5749</id>
<created>2006-10-17T18:48:52Z</created>
<summary type="text/plain">A brief look at some utility methods I seem to need in every program I ever write.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>I've been writing Java code for more than a decade now, and there are a handful of methods I've ended up copying & pasting (or, sadly, reimplementing) in virtually every program I've ever written.  I'm not sure why these methods in particular seem to keep cropping up again and again, but nevertheless I end up using them <i>everywhere</i>.</p>

<h2>send(InputStream in, OutputStream out)</h2>

<p>This method takes data coming from an <code>InputStream</code> and dumps it into an <code>OutputStream</code>.  This is useful for a lot of different things -- you can take data sent to you by a web server and dump it into a <code>FileOutputStream</code>, you can take the output and error streams of a process and dump them to System.out and System.err, and on and on.</p>

<pre>public static void send(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[2048];
    int c;
    while ((c = in.read(buffer)) > 0)
        out.write(buffer, 0, c);
}</pre>

<p>Over the years I've implemented several variations of this basic idea.  I've had <code>send()</code> methods that would return the number of bytes they copied, or transfer only a certain number of bytes before stopping, but they've all looked pretty similar.</p>

<h2>readFully(InputStream in)</h2>

<p>An extension of the <code>send()</code> method, this takes all of the data retrieved from an <code>InputStream</code> and returns it as a byte array for easy processing.  This is potentially dangerous, and should only be used when you know in advance that the data is small enough to comfortably fit in memory.</p>

<pre>public static byte[] readFully(InputStream in) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    send(in, buffer);
    return buffer.toByteArray();
}</pre>

<p>An obvious variant of this (assuming a similarly modified <code>send()</code> method) is to fail if the data is bigger than some threshold size limit.</p>

<h2>Character-based variants</h2>

<p>The <code>send()</code> and <code>readFully()</code> methods can be trivially modified to work with <code>Reader</code>, <code>Writer</code>, and <code>String</code> instead of streams and byte arrays.</p>

<h2>String replacement</h2>

<p>Once upon a time I had a simple method <code>replaceString(String src, String a, String b)</code>, which takes a String and replaces all occurrences of sequence A with sequence B.  After many RFEs (by myself and others) to include this capability in <code>String</code> itself, along with lots of explanations about how the regular expression features in Java 1.4 did not in fact eliminate the need for this, the <code>replace(CharSequence a, CharSequence b)</code> method was finally added to <code>java.lang.String</code> in Java 1.5.  </p>

<p>Now that the capability is in the JRE itself, my ten-year-old <code>replaceString()</code> method has at last been retired for good, and I couldn't be happier about that.  Sometimes it's the little things in life...</p>

<h2>What about you?</h2>

<p>I've written lots of utility methods, of course, but these are the small handful that I seem to always need no matter what I'm doing.  Given my background in client/server code, it's perhaps not surprising that they have to do with data transfer.  What about you?  Any methods that you just can't live without, that you've been copying from program to program for years?</p>]]>

</content>
</entry>
<entry>
<title>What you should know about Secure Static Versioning</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/10/what_you_should_1.html" />
<modified>2006-10-06T16:21:41Z</modified>
<issued>2006-10-06T14:45:10Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5622</id>
<created>2006-10-06T14:45:10Z</created>
<summary type="text/plain">A recent security patch has caused some confusion, and may have an impact on developers.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Deployment</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>Sun recently released a Java security advisory titled <a href="http://sunsolve.sun.com/search/document.do?assetkey=1-26-102557-1">Java Plug-in and Java Web Start May Allow Applets and Applications to Run With Unpatched JRE</a>.  As with any security advisory, it's important that you take note and ensure that your software is up-to-date -- in this case, the problem is fixed in Java 1.5.0_06 or higher.  But a <a href="http://blog.washingtonpost.com/securityfix/2006/08/sun_acknowledges_major_oops_in.html">blog entry</a> by the Washington Post's Brian Krebs raises some concerns about this particular security advisory and suggests that merely patching your machine may not be enough.</p>

<p>The security advisory admittedly wasn't very clear on this point, but if you have Java 1.5.0_06 or higher installed (which I imagine most of you do by now), you are in <b>no danger</b> from this issue, even if you also have older versions of Java on your system.  While that's obviously good news, the fix for this issue may have an impact on some Java developers.  If you deploy Java applets or unsigned Web Start programs, keep reading.</p>

<p>Java has always allowed you to keep multiple versions installed on the same computer at the same time.  Whether you love this particular feature or hate it, there's no denying that it can be useful at times.  Certainly as a developer I appreciate being able to have Java 5 and Java 6 on the same machine at the same time, and I know enterprises prefer to be able to certify their internal software against exactly one version of Java without worrying about employees accidentally changing the Java version out from under them.</p>

<p>But as with all significant decisions, there is no single right answer.  What's right for developers and enterprises isn't necessarily as great in the consumer market, where users would generally prefer not to leave old versions of the software lying around after an upgrade.  Unfortunately we can't just suddenly start removing older versions -- because Java has <i>always</i> worked this way, many programs depend on this behavior.  They may take the Java VM's location and "burn it in" to their launch scripts or registry entries, and removing the specific version on which a program depends would then cause it to break.  Various ideas on breaking out of this vicious cycle have been tossed around, but for the time being, this is just the way things work.</p>

<p>Unfortunately, it also led to a security hole (again, fixed in Java 1.5.0_06).</p>

<p>Sun has always responded promptly to any security problems with Java, quickly releasing a patched version which fixes the problem.  But since the previous unpatched and unsafe versions have been left on your hard drive, a malicious program could potentially get access to them.  Theoretically, a Java applet could have requested a specific older version of Java and used a known (and long-since patched) security hole in it to compromise your system, even though you had dutifully downloaded the security update.  Clearly, this was a situation that had to be addressed.</p>

<p>The solution is what is known internally as Secure Static Versioning.  Basically it boils down to "untrusted code can't use unpatched older versions of Java".  Previously, if you had several versions of Java installed on your system, a program could request one of the older versions in order to exploit it.  Now, no matter which version of Java an untrusted program requests, it will receive the highest installed version.  The practical upshot of this is that untrusted code will always be run in the most secure Java environment available.</p>

<p>Signed, trusted Web Start programs are allowed to request whatever version of Java they want -- they're trusted, so they have full access to your system anyway.  Applets (even if signed) will always be run in the latest version.  The discrepancy is due to technical differences between Web Start and the Plug-In;  I'll go into the details in a future entry.</p>

<p>With the quick overview out of the way, let me sum up in an FAQ:</p>

<hr>

<p><b>1. How much danger am I in?</b></p>

<p>If you have the latest JRE (1.5.0_06 or later) installed on your system, <b>none at all</b>.  All current JREs include the Secure Static Versioning change, so applets and sandboxed Java Web Start programs are unable to access older versions of Java.</p>

<p>If you don't have Java 1.5.0_06 or higher, you would be wise to go ahead and install the latest version.  I'm not aware of any exploits "in the wild", but it certainly doesn't hurt to be safe.</p>

<p><b>2. Do I need to remove old versions of Java?</b></p>

<p><b>No.</b> Applets and sandboxed Java Web Start programs aren't allowed to access older versions of Java.  They don't pose any threat in the first place, so removing them won't change anything.  If you do decide to remove older versions of Java, you need to be sure that none of the applications on your computer are using them first.</p>

<p><b>3. Do I have to change anything about my Java programs?</b></p>

<p><b>No.</b>  If you have a Java applet or sandboxed Java Web Start program, it will always run in the latest available version of Java without any changes on your part.  As long as you test your software against newer versions of Java, you shouldn't encounter any problems.</p>

<p><b>4. What does this mean for standalone Java programs?</b></p>

<p><b>Nothing.</b>  Just like native programs, Java programs which run outside of the Java sandbox already have full access to your system.  Requiring them to run in the latest version of Java wouldn't do anything to increase security.</p>

<hr> 

<p>So, that's that.  What might have sounded like a scary security issue (OMG YOU NEED TO UNINSTALL JAVA!!!!11!!!1) turns out to be quite mundane: install the latest patch release of Java and you're completely safe.  This is of course great advice no matter what software we're discussing -- you <i>are</i> running with all of the latest patches for your operating system, web browser, Flash Player, and everything else on your system, aren't you?</p>

<p>Oh, and while we're on the subject of updates...</p>

<p>If you update using Java Update, rather than downloading via <a href="http://java.sun.com/">java.sun.com</a>, you may find that you don't end up with the very latest update release.  That's normal, and it's a result of the fact that Sun distinguishes the latest "consumer version" of Java from the latest "developer / enterprise version".  If you go to java.sun.com, you get the latest developer / enterprise version, which is the very latest and greatest code available.  If you go to <a href="http;//www.java.com">www.java.com</a> or use Java Update, you end up with the latest consumer version, which might be a couple of update releases behind the developer version (but is otherwise identical).  </p>

<p>In order to avoid swamping end-users with too many updates, only two or three versions of Java a year are made available as consumer versions.  Naturally, security fixes (such as the one under discussion here) always warrant a new consumer version, so you're safe no matter how you choose to update your copy of Java.</p>]]>

</content>
</entry>
<entry>
<title>&quot;Java Browser Edition&quot;: New name, first steps</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/09/java_browser_ed.html" />
<modified>2006-09-06T21:29:09Z</modified>
<issued>2006-09-06T21:28:17Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5508</id>
<created>2006-09-06T21:28:17Z</created>
<summary type="text/plain">The fabled &quot;Java Browser Edition&quot; is on its way, in the form of the &quot;Java Kernel&quot; feature of Java 7.  Read on for details.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<h1>"Java Browser Edition" History</h1>

<p>Some time ago I proposed the idea of a <a href="http://weblogs.java.net/blog/enicholas/archive/2006/04/java_2_browser.html">Java Browser Edition</a>.  The basic idea was that the current Java Runtime Environment is simply too big, and most programs require only a small subset of the functionality.  The "browser edition" that I suggested would enable you to install exactly the subset of Java that your particular program required, but would be able to download all of the other functionality on demand (and thus be fully compatible with J2SE).  I wasn't quite prepared for the response that this entry generated.  In addition to generating a lot of comments and further discussions, it ultimately played a role in my getting hired by the deployment team at Sun.</p>

<p>I was cautioned by several folks at Sun that the Browser Edition would simply never happen.  It would never be approved as a feature in the first place, and even if it were approved, we would never be able to actually pull it off.  I'm told that this basic idea has actually been attempted within Sun twice before, and in both cases the resulting size reduction wasn't enough to be worthwhile.  The core VM, it seems, is simply too big, and trying to make it smaller is too hard.  There has even been a detailed <a href="http://blogs.sun.com/alexismp/entry/is_javabe_justified1">analysis</a> of the idea which paints a rather bleak picture of the potential gains.</p>

<h1>New Name: Java Kernel</h1>

<p>The feature did in fact get submitted as a proposal for Java 7, under the name "Java Kernel" (the idea being that you download a small "kernel" of Java functionality, which is in turn capable of downloading the rest of it).  And, amazingly enough, it was accepted.  And, lucky me, I'm part of the team responsible for implementing it.  <i>After</i> having been told that it's been tried a couple of times before and that it's basically impossible -- not a situation which inspires tremendous confidence.</p>

<h1>Building a minimal JRE</h1>

<p>The first thing I have to do is establish that this project is feasible.  Remember that even though it has been approved, it could alway be un-approved (disapproved?) at any point in the future if things aren't looking good.  So I figured I would start out by creating a simple, stripped-down JRE installer that contained only the functionality necessary to run <code>System.out.println("Hello world!")</code>, to get an estimate of the size reduction we could expect.  Stripping out the unecessary classes is easy -- you just run Java with the <code>-verbose</code> option to get a list of all of the classes it loads while running the Hello World program.  Those classes are all that we need to include in <code>rt.jar</code>.</p>

<p>The real problem is the <i>rest</i> of the functionality.  My devel build of the Java 6 JRE contains 683 files totalling 119MB.  Many of them are not necessary to run Hello World, but which ones?  Determining which files were truly necessary and which weren't could be a tough job, so I made my computer determine it for me.  I wrote a simple program which would iterate through all of the files in the JRE.  It would remove a file and then attempt to run the Hello World program using this stripped-down JRE.  If the test succeeded, the file was evidently unnecessary.  If the test failed, the file was deemed necessary and restored.  </p>

<p>After going through all of the files in this fashion, I was left with an extremely minimal JRE that could run Hello World and... well, that's about it.  But it at least provided a starting point.  Building a working installer from this JRE was itself a challenge, because several of the files that weren't necessary to run Hello World were still necessary to successful install the JRE, but I persevered and now have a fully functioning, minimal JRE.</p>

<h1>Results</h1>

<p>I built two JREs using this methodology: one with a program that prints "Hello World" to <code>System.out</code>, and one with a program that displays an empty <code>java.awt.Frame</code>.  Here are the results:</p>

<table border=0>
<tr><td>Java 6 Runtime Environment:</td><td><b>15.5MB</b></td></tr>
<tr><td>"Hello World" JRE:</td><td><b>2.6MB</b></td></tr>
<tr><td><code>java.awt.Frame</code> JRE:</td><td><b>3.5MB</b></td></tr>
</table>

<h1>Things to note</h1>

<p>Before you get excited, remember that this is just an experiment and that the JREs I built aren't the least bit useful.  They don't include the Java Plug-In, Web Start, or indeed much of anything, and any "real" program will need at least some of these components.  These JREs also do not have the ability to download the missing components, and will simply fail if an attempt is made to access missing functionality.  The installers we ultimately ship with Java 7 may well be bigger than this.</p>

<h1>Next steps</h1>

<p>Despite the cautions above, I find these results extremely exciting.  Keep in mind that so far we haven't done anything the least bit sophisticated -- just omitted unnecessary files and classes -- and we've already gotten the JRE below 3MB for a non-visual program.  Classes compress extremely well, so this installer would stay under 3MB mark even with a lot of additional classes included.  And there are still a lot of things we can do to improve the size further, such as break up big DLLs to get better granularity.</p>

<p>It's hard to say how big the final Java 7 installers will end up being, but my personal goal is to make an installer that can handle basic Java applets in under 3MB.  This is a difficult goal, and it may end up being too optimistic, but we're going to get as close as we can.  So, what do you think?  If the Java installer were 3MB instead of 15MB, would you find the idea of using Java applets (or Java Web Start programs) more appealing?</p>]]>

</content>
</entry>
<entry>
<title>Welcome to the Deployment team: My first week at Sun</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/08/welcome_to_the.html" />
<modified>2006-08-04T16:23:33Z</modified>
<issued>2006-08-04T16:23:09Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5302</id>
<created>2006-08-04T16:23:09Z</created>
<summary type="text/plain">It turns out that I joined Sun at a fortuitous moment -- just in time to get involved in the Dolphin (Java 7) planning process.  Read on for a sneak peek at what&apos;s in store for Deployment.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>I mentioned in my <a href="http://weblogs.java.net/blog/enicholas/archive/2006/06/so_long_and_tha.html">last entry</a> that I have left Yahoo! and am now officially a Sun employee.  After an all-too-short break between jobs, my first day with Sun was this past Monday, and it's been quite an experience so far.</p>

<p>As with joining any big company, most of my first week was spent trying to get someone to actually set up my access badge and email account, figuring out how to access documentation on various subjects (there <i>is</i> documentation, right?), and dealing with various other miscellaneous getting-started headaches.  Most of that is sorted out now and I expect that I should actually be able to, you know, <i>work</i> starting next week.</p>

<p>The most exciting part so far has been the fact that I've gotten to be involved in the Dolphin planning sessions we're having this week.  I've <a href="http://weblogs.java.net/blog/enicholas/archive/2006/05/more_deployment.html">requested some deployment features</a> in the past, including a <a href="http://weblogs.java.net/blog/enicholas/archive/2006/04/java_2_browser.html">gigantic whopper of one</a>, and while I can't give away too many details, I can say that there is definitely some hope.  </p>

<p>I mentioned wanting an "updatejava.exe" program which would allow you to install specific versions of Java upon request, tremendously simplifying the process of writing installers for Java programs.  There's actually a very good chance of such a tool making it into Dolphin, although it would probably have a slightly different name.   And lest I erroneously receive credit for this idea, I should point out that this feature was already being investigated before I even suggested it.</p>

<p>The "Browser Edition" I suggested in <a href="http://weblogs.java.net/blog/enicholas/archive/2006/04/java_2_browser.html">this entry</a> is a more complex problem.  When I wrote that entry, I was in the enviable position of being able to request ridiculous improvements and <i>not having to actually write any of the code</i>.  As you can imagine, my position is quickly shifting from "Sun should add support for feature &lt;X&gt; right now!" to "Ummm... well... you see, that's a really hard problem and it would be a lot of work...".  Regardless, I think it's okay if I reveal that there is a feature more-or-less identical to what I suggested in the infamous "Browser Edition" blog entry currently under consideration for Dolphin.  This should not in any way, shape, or form be construed as a promise that we will <i>actually do it</i> -- in other words, don't get your hopes up -- but it's being considered.  At the very least, you should be aware that Java applets are the subject of intense scrutiny around here and we are trying to figure out how to improve them, within the limitations of the time and manpower we actually have available to throw at the problem.</p>

<p>There's a lot of other neat stuff on the table, most of which I probably shouldn't talk about yet.  Hopefully the tidbits I've tossed out so far aren't revealing anything that will get me in trouble...  In any case, expect some neat stuff from Dolphin's deployment enhancements.  It's also not too late to suggest things: we are <i>definitely</i> interested in your feedback.</p>]]>

</content>
</entry>
<entry>
<title>So long, and thanks for everything</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/06/so_long_and_tha.html" />
<modified>2006-06-28T18:26:41Z</modified>
<issued>2006-06-28T18:25:03Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5112</id>
<created>2006-06-28T18:25:03Z</created>
<summary type="text/plain">After eight years with Yahoo!, I just gave notice.  What could lure me away?  Here&apos;s a hint: it starts with &quot;S&quot; and ends with &quot;un&quot;.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>When you work at a major Internet company like Yahoo!, deployment is a Big Deal.  You have millions of customers running every version of every OS imaginable, some with marginally working computers, and they all need to be able to run your software.  And they need to run it <i>now</i> -- make them wait too long, or download too much, and they'll give up and move on to your competitors.</p>

<p>While I'm definitely a huge Java fan, it's a hard technology to deploy to end-users.  If a particular user doesn't have Java installed, or doesn't have the right version of Java installed, there are major challenges surrounding the detection, installation, and upgrading process.  Even if users have the right version of Java installed, its behavior in web browsers isn't necessary all that reliable. I posted a couple of <a href="http://weblogs.java.net/blog/enicholas/archive/2006/04/java_2_browser.html">high-profile</a>  <a href="http://weblogs.java.net/blog/enicholas/archive/2006/05/more_deployment.html">rants</a> about Java deployment issues recently, to try to call some attention to these issues.</p>

<p>I wasn't really expecting much of a response.  I figured some fellow complainers would show up, we'd talk amongst ourselves for a little while, and that would be the end of things.  I wasn't expecting Sun to even <i>notice</i> my complaints, let alone actually do something about them.  I was happy to be proven wrong.</p>

<p>I was asked to put together a resume, and invited to interview with the Java Deployment team.  After two rounds of phone interviews and a grueling eight-hour interview process in Burlington, I accepted an offer to join Sun, and will finally have the opportunity to address some of the problems that have been bugging me for so long.  This is a really exciting change for me -- to finally be working <i>on</i> Java, instead of just <i>with</i> it, and to be able to influence where things are headed... well, it's a Java geek's dream come true.  Or at least it's <i>this</i> Java geek's dream come true.</p>

<p>We're still working out the details, but I should be starting at Sun in about a month.  Yahoo! is a great company, and has been very good to me over the years, but this was an opportunity I just couldn't pass up.</p>

<h2>To dispel any rumors...</h2>

<p>Before any rumors get started, let me be the first to say that just because I blogged about some deployment ideas <i>does not</i> mean that any of those ideas will necessarily get implemented.  Sun obviously found them interesting, or I daresay I wouldn't have been hired, but there's a big difference between finding an idea interesting and actually putting in the time and money necessary to implement it.  In particular, don't expect a <a href="http://weblogs.java.net/blog/enicholas/archive/2006/04/java_2_browser.html">Java Browser Edition</a> -- much as I would love to see it happen, I'm not naive enough to believe that it's at all likely.</p>

<p>I do have a lot of ideas for improvements to the Java Plug-In and Java Web Start;  reasonably small, practical features that will nevertheless make a huge difference in how easy it is to deploy Java programs.  Hopefully some of them will actually get implemented eventually, but at this point it's far to early to speculate on how things will work out.  Rest assured that I will be doing my best to push for easier deployment solutions, and I'm all ears if you have any suggestions of your own.</p>

<h2>What about JAXX?</h2>

<p>What does this mean for <a href="http://www.jaxxframework.org/">JAXX</a>, the declarative XML user-interface language I'm working on?  In the short term, not much.  The position I was hired for has nothing to do with JAXX, and I will still be doing all JAXX work in my spare time, rather than as a Sun-sponsored activity.</p>

<p>What about the long term?  Your guess is as good as mine.  All I know for sure is that I have a <a href="http://weblogs.java.net/blog/enicholas/archive/2006/06/jaxx_new_versio.html">lot of ideas</a> for the future of JAXX, and will continue to crank away on it.  If the Swing team decides to add a user interface language to Java at some point (which I know they have considered), I expect I would at least be involved in the discussion.  Other than that... who knows?</p>

<h2>Looking ahead</h2>

<p>The decision to leave Yahoo! was both difficult and painful, but I think I made the right choice.  I'm very excited to be joining Sun, and I hope that I will be able to really make a difference.  Wish me luck!</p>]]>

</content>
</entry>
<entry>
<title>All about intern()</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/06/all_about_inter.html" />
<modified>2006-06-26T22:17:03Z</modified>
<issued>2006-06-26T22:16:54Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5101</id>
<created>2006-06-26T22:16:54Z</created>
<summary type="text/plain">String.intern() is a widely ignored and misunderstood method which can have serious performance implications.  Let&apos;s dive in and take a look.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Performance</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>Strings are a fundamental part of any modern programming language, every bit as important as numbers.  So you'd think that Java programmers would go out of their way to have a solid understanding of them -- and sadly, that isn't always the case.</p>

<p>I was going through the source code to Xerces (the XML parser included in Java) today, when I found a very surprising line:</p>

<p><b>com.sun.org.apache.xerces.internal.impl.XMLScanner:395</b><br />
<code>protected final static String fVersionSymbol = "version".intern();</code></p>

<p>There are a number of strings defined like this, and every one of them is being interned.  So what exactly is intern()?  Well, as you no doubt know, there are two different ways to compare objects in Java.  You can use the <b><tt>==</tt></b> operator, or you can use the <b><tt>equals()</tt></b> method.  The <tt>==</tt> operator compares whether two references point to the <i>same object</i>, whereas the equals() method compares whether two objects contain the <i>same data</i>.  </p>

<p>One of the first lessons you learn in Java is that you should usually use <tt>equals()</tt>, not <tt>==</tt>, to compare two strings.  If you compare, say, <tt>new String("Hello") == new String("Hello")</tt>, you will in fact receive <tt>false</tt>, because they are two different string instances.  If you use equals() instead, you will receive <tt>true</tt>, just as you'd expect.  Unfortunately, the equals() method can be fairly slow, as it involves a character-by-character comparison of the strings.</p>

<p>Since the <tt>==</tt> method compares <i>identity</i>, all it has to do is compare two pointers to see if they are the same, and obviously it will be much faster than <tt>equals()</tt>.  So if you're going to be comparing the same strings repeatedly, you can get a significant performance advantage by reducing it to an identity comparison rather than an equality comparison.  The basic algorithm is:</p>

<p>1) Create a hash set of Strings<br />
2) Check to see if the String you're dealing with is already in the set<br />
3) If so, return the one from the set<br />
4) Otherwise, add this string to the set and return it</p>

<p>After following this algorithm, you are guaranteed that if two strings contain the <i>same characters</i>, they are also the <i>same instance</i>.  This means that you can safely compare strings using <tt>==</tt> rather than <tt>equals()</tt>, gaining a significant performance advantage with repeated comparisons.</p>

<p>Fortunately, Java already includes an implementation of the algorithm above.  It's the <tt>intern()</tt> method on <tt>java.lang.String</tt>.  <tt>new String("Hello").intern() == new String("Hello").intern()</tt> returns <tt>true</tt>, whereas without the <tt>intern()</tt> calls it returns <tt>false</tt>.</p>

<p>So why was I so surprised to see <tt>protected final static String fVersionSymbol = "version".intern();</tt> in the Xerces source code?  Obviously this string will be used for many comparisons, doesn't it make sense to intern it?</p>

<p>Sure it does.  That's why Java <i>already does it</i>.  All constant strings that appear in a class are automatically interned.  This includes both your own constants (like the above "version" string) as well as other strings that are part of the class file format -- class names, method and field signatures, and so forth.  It even extends to constant string expressions: <tt>"Hel" + "lo"</tt> is processed by javac exactly the same as <tt>"Hello"</tt>, and <tt>"Hel" + "lo" == "Hello"</tt> will return <tt>true</tt>.</p>

<p>So the result of calling <tt>intern()</tt> on a constant string like <tt>"version"</tt> is <i>by definition</i> going to be the exact same string you passed in.  <tt>"version" == "version".intern()</tt>, always.  You only need to intern strings when they are not constants, and you want to be able to quickly compare them to other interned strings.</p>

<p>There can also be a memory advantage to interning strings -- you only keep one copy of the string's characters in memory, no matter how many times you refer to it.  That's the main reason why class file constant strings are interned: think about how many classes refer to (say) java.lang.Object.  The name of the class java.lang.Object has to appear in every single one of those classes, but thanks to the magic of <tt>intern()</tt>, it only appears in memory once.</p>

<p>The bottom line?  <tt>intern()</tt> is a useful method and can make life easier -- but make sure that you're using it responsibly.</p>]]>

</content>
</entry>
<entry>
<title>The Great Switch</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/06/the_great_switc.html" />
<modified>2006-06-20T14:02:36Z</modified>
<issued>2006-06-20T14:02:30Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5059</id>
<created>2006-06-20T14:02:30Z</created>
<summary type="text/plain">After my Windows machine died in a particularly humorous fashion, I finally bit the bullet and switched over to Apple.  I have only one question: why on Earth did I wait so long?</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>I'm on vacation with my family right now.  Vacation time is pretty hard for me to come by -- one of the dangers of being "essential" is that nobody wants to let you leave -- so this is a noteworthy event, made possible only by the fact that I agreed to bring my cell phone and work laptop, ensure the availability of Internet access at my destination, and remain reachable twenty-four hours a day.  When we arrived, I got out my laptop and booted it up to check my email.  It got as far as showing a blank Windows desktop and then... sat there.</p>

<p>Uh-oh.</p>

<p>I spent a while fiddling with it, but sadly when your machine won't even boot into Safe Mode and you have no other bootable disks with you, there really isn't much you can do.  So here I was, stuck without a functioning computer, when having a functioning computer and Internet connection was part of my vacation deal.  A whole week without being able to check email, or read my webcomics, or being able to post blog entries... a whole week without Internet access of any kind.  </p>

<p>I don't think I can take that kind of punishment, so I did whatever any true geek would do: I used this situation as an excuse to buy a new computer.  I (a long-time Windows user) had been lusting after the new MacBooks for quite a while, and my wife was well aware of this.  She was also well aware that Fathers' Day was just around the corner, and, well, to make a long story short I love my wife very much and I'm typing this on my new 13" MacBook.</p>

<p>Obviously I'm not the first Java programmer to realize that a Mac is pretty great Java environment.  When I was at JavaOne, I was shocked at the number of Mac laptops being toted around -- it seemed like every other system was a Mac.  But after setting my system up, installing Eclipse, and getting to work on it, I really don't understand how I managed to put up with Windows for so many years.  My Mac runs all of the software I need, Java programs run as smooth as silk, and (despite having theoretically less power) it feels faster than my most powerful Windows system.  I could spend all day babbling about all of the things I love about it, but one thing is certain: I'm not going back.</p>

<p>Oh, and the Windows laptop?  I decided to leave it on for an extended period of time, and checked on it periodically.  After eight hours, there was still no change, so I went to bed.  When I woke up in the morning, I saw that it had actually managed to finish booting.  So after somewhere between eight and sixteen <i>hours</i> of sitting there, it finally got to the desktop.  I realize that this is pathological -- when your computer takes more than eight hours to boot, something is clearly screwed up and I can't just say "Ha! Windows sucks!", but I sure feel like saying exactly that.  I was eventually able to fix it by disabling some startup items... but hey, I got a new Mac out of the deal.  Thanks for dying, work laptop!</p>]]>

</content>
</entry>
<entry>
<title>JAXX: new version, long-term plans</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/06/jaxx_new_versio.html" />
<modified>2006-06-12T16:46:55Z</modified>
<issued>2006-06-12T16:43:30Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.5004</id>
<created>2006-06-12T16:43:30Z</created>
<summary type="text/plain">JAXX 1.0.1, which contains important bugfixes, has just been released.  Join me in helping to work out the roadmap for future versions of the JAXX user interface language.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>(For an introduction to JAXX, start <a href="http://today.java.net/pub/a/today/2006/03/30/introducing-jaxx.html">here</a>.)</p>
<p>
First things first: JAXX 1.0.1 is finally out.  This version contains a lot of bugfixes and significant improvements to the quality and size of the generated Java code.  Download it <a href="http://www.jaxxframework.org/wiki/Download">here</a>.
</p>
<p>
Now that the major 1.0 bugs are fixed and a solid baseline has been established, I'm making plans for the future.  Where is JAXX headed?  What's next?  I've posted a first pass at the <a href="http://www.jaxxframework.org/wiki/Roadmap">JAXX roadmap</a> and am seeking feedback.  It's still early and subject to change, and there will be a lot more detail added as time goes on -- but I think it's a fairly decent stab at where things are headed.
</p>
<p>
I'm particularly excited about the addition of animation, based on Chet Haase's <a href="https://timingframework.dev.java.net/">Timing Framework</a>.  The first animation features are going to be simple and straightforward, based on the current CSS pseudoclasses.  Right now you can use a pseudoclass to, say, make a label turn blue when moused over:
</p>
<p>
<pre>
&lt;style&gt;
  #hoverLink:mouseover {
    foreground: blue;
  }
&lt;/style&gt;

&lt;JLabel id='hoverLink' text='Mouse over to turn me blue'/&gt;
</pre>
</p>
<p>
This effect is applied instantly -- the second the mouse enters the label, it turns blue.  The initial animation features will allow you to have effects like this be applied gradually over time:
</p>
<p>
<pre>
&lt;style&gt;
  #hoverLink:mouseover[duration=500ms] {
    foreground: blue;
  }
&lt;/style&gt;

&lt;JLabel id='hoverLink' text='Mouse over to turn me blue'/&gt;
</pre>
</p>
<p>
Note the <b>[duration=500ms]</b> on the pseudoclass.  There will be other properties for controlling acceleration, deceleration, and perhaps other features of the animation.  This a simple change, to be sure, but I don't want to go overboard yet.  More dramatic animation features will be added in good time.
</p>
<p>
What else is going on with JAXX?  You'll have to take a look at the <a href="http://www.jaxxframework.org/wiki/Roadmap">JAXX roadmap</a> -- just be sure to let me know what you think!
</p>]]>

</content>
</entry>
<entry>
<title>Mnemonic Magic</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/enicholas/archive/2006/06/mnemonic_magic.html" />
<modified>2006-06-09T00:45:50Z</modified>
<issued>2006-06-06T06:18:14Z</issued>
<id>tag:weblogs.java.net,2006:/blog/enicholas/320.4967</id>
<created>2006-06-06T06:18:14Z</created>
<summary type="text/plain">While developing a Swing application, I found Swing&apos;s mnemonic system to be too simplistic.  Take a look at what I did to improve it, and where we can go from here.</summary>
<author>
<name>enicholas</name>

<email>Ethan.Nicholas@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/enicholas/">
<![CDATA[<p>Swing's mnemonic system is based around two properties: <tt>mnemonic</tt> (or <tt>displayedMnemonic</tt>) and <tt>displayedMnemonicIndex</tt>.  They're powerful enough to do everything you need, but then again, so is machine code.  There are a number of problems and limitations with the skeletal mnemonic support built in to Swing.</p>

<h2>The Problems</h2>

<ul>
<li><b>They're annoying to define</b> - One common approach is to use a properties file to define actions.  You generally end up with a property for the action's name, a property for its mnemonic, and an (optional) property for its mnemonic index -- three properties for the name of each action.
<li><b>It's easy to accidentally duplicate mnemonics</b> - if you add new actions, or build a new menu from existing actions, it's incredibly easy to forget that (say) both "Lock" and "Layout" are using 'L' as their mnemonic character
<li><b>It's difficult to spot mistakes</b> - the only visual cue to a mnemonic is an underline.  Using Windows XP with default settings, the underline doesn't even show up unless you hold the Alt key.  Mistakes are easily overlooked, and there is no error reporting.
<li><b>The same action may need different mnemonics in different contexts</b> - If an action appears (say) in both a menubar menu and a right-click context menu, a mnemonic character which works in one menu may conflict in the second menu.  I once ran into a menu item with a short name which, in a particular context menu, conflicted with other menu items on <i>every single character in its name</i>.  With the action defined by static properties, though, you have to use the same mnemonic everywhere... so what do you do?  Not have a mnemonic <i>anywhere</i> just because it conflicts in one rarely accessed location?
<li><b>It poses serious problems for internationalization</b> - A quick survey of the bug database turned up a number of bugs relating to incorrect translations of mnemonics and mnemonic indices: <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6411189">6411189</a>, <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4983399">4983399</a>, <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4664265">4664265</a>, <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4735183">4735183</a>.  There are two general problems: first, all of these properties are interrelated, and it's easy to miss one of them during translation -- leading to incorrect mnemonics or (worse yet) a mismatch between the actual mnemonic and the underlined character.  Second, translation is quite complicated because the translator has to check that the mnemonic doesn't conflict with any other mnemonics in every menu in which the action appears.  If the folks at Sun are making these kinds of mistakes, what hope is there for the rest of us?
</ul>

<p>Because of these annoyances, the unfortunate fact is that most Swing programs (at least among the ones I've seen) don't actually use mnemonics at all.  That's sad, especially when you consider that other toolkits don't seem to share this aversion for mnemonics.</p>

<h2>The Solution</h2>

<p>The solution I propose is twofold.  First, <b>combine all three properties into a single value</b>.  Second, <b>eliminate the need to specify mnemonics at all in most cases</b>.</p>

<p>Combining all three properties is quite easy.  You just need to embed the mnemonic and mnemonicIndex information into the label itself.</p>

<p><b>Before:</b></p>

<pre>
action.saveAs.name          = Save As...
action.saveAs.mnemonic      = A
action.saveAs.mnemonicIndex = 5
</pre>

<p><b>After:</b></p>

<pre>
action.saveAs.name = Save _A_s...
</pre>

<p>I chose to use a pair of underscores surrounding the mnemonic character to identify it, as opposed to most toolkits which use a single escape character.  Windows, for example, would have specified the label as "Save &As...".  The advantage of the underscore encoding is that there is essentially no chance of ever "accidentally" specifying a mnemonic character, whereas you might legitimately try to use an ampersand in a control, which in Windows would lead to an incorrect mnemonic.</p>

<p>Being able to specify the mnemonic character in this fashion carries a lot of benefits.  Because it's a single value, specifying it in properties files is much easier, internationalization is much easier, and it's impossible to accidentally have a mismatch between the index and the mnemonic character.  While this is much easier to deal with than three separate properties, it doesn't solve some of the other thorny problems, like trying to prevent duplicate mnemonics.</p>

<p>The rest of the solution is <b>automatically assigning mnemonics</b>.  This is easier than it sounds, because we tend to follow certain heuristics when assigning mnemonics to actions and labels, and we can just turn those heuristics into a program.  The algorithm I use is as follows:</p>

<ol>
<li>Try the first character in the string.  Check to see if it is available (among other menu items in the menu or components in the window, as appropriate).
<li>If that isn't available, try capitalized letters in the order in which they appear.
<li>If no capitalized letters are available, try lowercase consonants.
<li>If no lowercase consonants are available, try lowercase vowels.
<li>If no lowercase vowels are available, give up.
</ol>

<p>So my framework automatically assigns mnemonics to all actions (and specified components) based on these rules.  99% of the time it picks the same mnemonic you yourself would have.  If it doesn't do what you want, you can manually specify it using a pair of underscores around the character in question.  You can also force it not to choose a mnemonic at all by putting two underscores in a row at the end of the string.  This makes translators' lives far easier, because they can generally just not worry about mnemonics and let the program "do the right thing".  Furthermore, my framework has automatic error checking and will, if assertions are enabled, throw an <tt>AssertionError</tt> when a menu or dialog contains duplicate mnemonic characters.</p>

<h2>Unfortunately...</h2>

<p>There are some other details, of course, like the API calls necessary to actually work with this framework, but they aren't relevant because I can't release the code to the public.  It's part of a proprietary application which my employer owns the rights to, so you'll just have to use your imagination.  Fortunately the code itself is relatively straightforward -- you could easily duplicate this setup if you wanted to, and probably save yourself a lot of time overall (if you're working on a big application).  There is hope, however...</p>

<h2>JSR 296</h2>

<p>JSR 296, "Swing Application Framework", aims to (among other things) define a standard way of representing and managing Actions.  My hope is that, as part of this, JSR 296 will include a better means of managing mnemonics than having to specify three properties individually.  At the <i>very</i> least I'd like to see the mnemonic be able to be embedded directly into the string (as in "Save _A_s...", "Save &As...", or something equivalent), but trust me when I say that the automatic mnemonic management is incredibly nice also.</p>

<p>Considering that I have a seat on the JSR 296 expert group, I will definitely be pushing for some sort of solution to these issues.  I haven't actually discussed this with anyone yet, though, so maybe they already have an even better solution in mind (yay!) or have decided that this issue isn't worth pursuing (boo!).  It's also entirely possible that I'm the only weirdo that considers this a significant issue in the first place.</p>

<h2>JAXX</h2>

<p>If you've used my <a href="http://www.jaxxframework.org/">JAXX framework</a>, you may be a little surprised about this entry, considering that JAXX doesn't do automatic mnemonic management or allow you to embed mnemonic markers directly into the label.  That was a deliberate, albeit painful, decision, and it comes back to JSR 296.  Given that there's eventually going to be a standardized Swing application framework, I'm taking a wait-and-see attitute, carefully avoiding doing anything in JAXX which might conflict with the Swing framework-to-be.  If JSR 296 does define a standard way to identify mnemonics, I'll use the same syntax.  And if it doesn't, I'll do it my way.  Regardless of the outcome, I expect that JAXX will eventually support this sort of mnemonic magic.</p>

<h2>What do you think?</h2>

<p>So, what do you think?  Do you agree that Swing's approach to mnemonics could use some improvements?  Want automatically managed mnemonics?  Hate the idea?  Like being able to specify mnemonics directly in the string, but don't like the syntax?  Or am I just altogether crazy?</p>]]>

</content>
</entry>

</feed>