<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8807910</id><updated>2011-12-26T16:14:35.390+01:00</updated><category term='ssl'/><category term='ubuntu intrepid webcam skype'/><category term='socket'/><category term='jugtorino'/><category term='enum'/><category term='javascript'/><category term='cometd'/><category term='java'/><category term='jetty'/><category term='encoding'/><category term='cross-origin'/><title type='text'>Mutant World</title><subtitle type='html'>Simone Bordet's perspective on life ~ science ~ software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>45</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8807910.post-392331106029726038</id><published>2011-05-14T21:04:00.003+02:00</published><updated>2011-05-14T21:19:59.782+02:00</updated><title type='text'>Natty Narwhal's Unity, final take</title><content type='html'>I have previously blogged on Ubuntu's Natty Narwhal &lt;a href="http://bordet.blogspot.com/2011/04/natty-narwhals-unity-is-not-for-me-yet.html"&gt;Unity shortcomings&lt;/a&gt;, and added &lt;a href="http://bordet.blogspot.com/2011/05/natty-narwhals-unity-take-two.html"&gt;some additional thoughts&lt;/a&gt; on my own configuration.&lt;br /&gt;&lt;br /&gt;With a non-hiding Unity launcher that works as an old-style launcher and as a windows list, what I really missed were the applets.&lt;br /&gt;&lt;br /&gt;It turns out that there are many efforts to replace those applets with "indicators", for example see &lt;a href="http://www.techdrivein.com/2011/05/10-useful-application-indicators-for.html"&gt;this link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So I installed the weather indicator, the system load indicator and this allowed me to get back to a decent configuration that I find efficient enough for my daily work.&lt;br /&gt;&lt;br /&gt;Considering that &lt;a href="http://www.omgubuntu.co.uk/2011/04/ubuntu-11-10-will-not-ship-with-classic-gnome-desktop/"&gt;Ubuntu will drop the "classic" mode for 11.10&lt;/a&gt;, I felt it was better to get used to Unity as soon as possible.&lt;br /&gt;&lt;br /&gt;I am confident the application indicators will improve over time, so eventually - hopefully - Unity will be as good as the classic mode.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-392331106029726038?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/392331106029726038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=392331106029726038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/392331106029726038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/392331106029726038'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2011/05/natty-narwhals-unity-final-take.html' title='Natty Narwhal&apos;s Unity, final take'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-577801294775117504</id><published>2011-05-05T00:38:00.002+02:00</published><updated>2011-05-05T01:35:27.538+02:00</updated><title type='text'>Natty Narwhal's Unity, take two</title><content type='html'>I have previously blogged on Natty Narwhal's &lt;a href="http://bordet.blogspot.com/2011/04/natty-narwhals-unity-is-not-for-me-yet.html"&gt;Unity shortcomings&lt;/a&gt;, but I decided to give it few more days, and I here are my further comments.&lt;br /&gt;&lt;br /&gt;I configured the launcher with 32 pixels icons and disabled auto-hiding.&lt;br /&gt;This basically brought me back an old-style launcher and a windows list that is always visible, allowing to glance at it for visual information regarding running applications.&lt;br /&gt;&lt;br /&gt;Unity's launcher seems to be designed to play the role of both an application launcher (via icon clicking) and of a windows list (via small arrows and additional icons). I still think that the two concepts needs to be separated, but I am starting to get used to it.&lt;br /&gt;&lt;br /&gt;It's still not like the classic mode; for example, there is one icon only in the launcher for all the Terminal instances, which gives less information on what is the Terminal window you are currently working on.&lt;br /&gt;&lt;br /&gt;I discovered that middle-clicking on a launcher icon creates a new instance of the application, so this issue always had a solution.&lt;br /&gt;&lt;br /&gt;Disabling auto-hiding made usage of the browser's application tabs easier, since now the launcher does not pop up overlapping the browser's application tabs when you hover with the mouse in the top left corner.&lt;br /&gt;&lt;br /&gt;I still really miss the applets, and I hope that Unity will be improved to allow an additional panel (at the bottom, say) to make room for the applets.&lt;br /&gt;This new panel could be missing by default (but could be added if one wants to).&lt;br /&gt;And I am really missing the old date/time/locations applet: the new one is just too bare bones for my taste.&lt;br /&gt;&lt;br /&gt;Finally, I noticed that Unity is way slower to start, but that's once in a day pause for me, so it's tolerable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-577801294775117504?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/577801294775117504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=577801294775117504' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/577801294775117504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/577801294775117504'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2011/05/natty-narwhals-unity-take-two.html' title='Natty Narwhal&apos;s Unity, take two'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-4698031279438439415</id><published>2011-04-29T11:00:00.005+02:00</published><updated>2011-04-30T01:59:16.192+02:00</updated><title type='text'>Natty Narwhal's Unity is not for me yet</title><content type='html'>I have upgraded to Natty and I am trying out Unity, but I am afraid I am not the right user for it.&lt;br /&gt;&lt;br /&gt;Unity does not seem to be designed for power users like me (which is fine), but unfortunately it is not yet flexible enough to support both casual users &lt;span style="font-style:italic;"&gt;and&lt;/span&gt; power users like me.&lt;br /&gt;&lt;br /&gt;The new user interface is clean and polished, but did not impress me much, visually (not after wobbly windows and the desktop cubes). It's a couple of panels of which one autohides.&lt;br /&gt;And a big step back on the user interface of available applets (see below).&lt;br /&gt;&lt;br /&gt;What I miss most is the lack of applets support, as I often glance at the CPU, network and disk I/O indicators; and the lack of the windows list, as I often glance there to see what I am running.&lt;br /&gt;&lt;br /&gt;For example, how do I know if I am running XChat so that colleagues can contact me ?&lt;br /&gt;Previously, a glance to the windows list was enough; now I have to alt+tab or, if I have a maximized window (which is often the case), make the launcher visible (move mouse there, wait). Both are way slower than a glance. You need to operate instead of just glancing.&lt;br /&gt;&lt;br /&gt;As another example, I often run a "server" terminal and a "client" terminal, and I know that the server comes before the client in the windows list. A glance at the windows list is again enough to tell which terminal is what. Not possible with Unity.&lt;br /&gt;&lt;br /&gt;Compiz Config Settings Manager allows to fine tune the configuration of various effects, but sometimes it's just too sparse.&lt;br /&gt;For example, alt+tab has a popup delay of 200 ms (it's a lot for a me... I started thinking my computer had become slower with the upgrade to Natty). Where is that settings ? In "Effects" ? In "Static Application Switcher" ? Somewhere else ?&lt;br /&gt;You need to navigate CCSM and find it, and decrypt the various configuration options (for example, can anyone tell me what is the "timestep" option of the switcher ?)&lt;br /&gt;&lt;br /&gt;Firefox allows you to create "application tabs" that have a small icon to represent a page. If you want to go to one of those tabs, you need to be precise in clicking it (because it's small).&lt;br /&gt;If you have Firefox maximized, the first application tab (GMail in my case) is dangerously close to both Unity's home button and Unity's launcher; if you are few pixel off and hover on the home button, the launcher starts to reveal, but by doing so it will partially cover Firefox first application tab; few pixels off on the left border, and the launcher appears, covering again Firefox first application tab.&lt;br /&gt;&lt;br /&gt;Multi instance applications like Gnome's Terminal cannot be easily instantiated from Unity's launcher: you can do that easily for the first instance, but trying to open a second Terminal in the same way brings you to the first Terminal. I think the principle of least surprise is violated here (or to say it less politely, WTF ?!).&lt;br /&gt;Double clicking on the icon reveals all instances, and right clicking shows a menu that does not have an entry that allows to create a new instance.&lt;br /&gt;&lt;br /&gt;And yes, I do know that I can configure Unity and Compiz, I also know that Terminal has a special Unity keyboard accelerator, but the accelerator does not work if you have a maximized application focused (it will be interpreted by the application, not by Unity).&lt;br /&gt;It's just that Unity is more complicated than the classic mode, and less customizable.&lt;br /&gt;&lt;br /&gt;Most of the applets for the Unity panel are a step back, especially the Time/Location applet (no icons, no solar light projection on Earth), and the Configure Display applet. The latter does not ask you anymore if you want to use the proprietary driver tool instead... now how do I find the proprietary tool ?&lt;br /&gt;Exploring Unity's launcher is no help (in which category could they have put it ?) until you type "nvidia" in Unity's dash (and you start thinking "thank god it had 'nvidia' in the name, otherwise I'd be seriously screwed in finding it").&lt;br /&gt;And I am the guy that knows its video card is an NVidia one, otherwise, well...&lt;br /&gt;&lt;br /&gt;The visual cue for notifications is a (really) small triangle in the top left corner.&lt;br /&gt;You can't tell if it was a Skype notification, XChat notification or something else, it's one cue for all, and you need to click on it to figure out which notifications.&lt;br /&gt;Before, the windows list gave different cues for different application, and a glance was enough to figure out which notifications.&lt;br /&gt;&lt;br /&gt;All in all, I am disappointed even if I set my expectations really low.&lt;br /&gt;I will give Unity a bit more time, but I am resisting the urge to switch back to the classic mode.&lt;br /&gt;&lt;br /&gt;I really hope that the classic mode will not be removed, or at least I hope that Unity will improve so much that will be more friendly and configurable for power users as well (or for me at least - but I am guessing I am not the only one).&lt;br /&gt;&lt;br /&gt;I personally care about number of eye glances, number of mouse clicks and number of switches between keyboard and mouse of my hand. I would like all of them to be reduced at minimum and right now Unity forces me to a lot more effort to get the same things done, so it's a (big) step back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-4698031279438439415?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/4698031279438439415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=4698031279438439415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/4698031279438439415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/4698031279438439415'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2011/04/natty-narwhals-unity-is-not-for-me-yet.html' title='Natty Narwhal&apos;s Unity is not for me yet'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-429203852595775720</id><published>2009-08-04T18:24:00.004+02:00</published><updated>2009-08-04T18:33:46.281+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='cross-origin'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='cometd'/><title type='text'>Jetty Support for Cross-Domain XMLHttpRequests</title><content type='html'>Remember the &lt;a href="http://en.wikipedia.org/wiki/Same_origin_policy"&gt;same origin policy&lt;/a&gt; that restricts most of our JavaScript applications ?&lt;br /&gt;&lt;br /&gt;Seems that we can finally get rid of it, thanks to a &lt;a href="http://dev.w3.org/2006/waf/access-control/"&gt;new W3C specification&lt;/a&gt; already implemented by Firefox 3.5 and, on server side, by the &lt;a href="http://eclipse.org/jetty"&gt;Jetty Servlet Container&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I blogged about all the details &lt;a href="http://blogs.webtide.com/sbordet/entry/jetty_supports_cross_domain_xmlhttprequests"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Oh, if you're using Ubuntu Jaunty, you can install Firefox 3.5 via &lt;a href="apt://firefox-3.5"&gt;apt://firefox-3.5&lt;/a&gt;. It is named "Shiretoko" (its codename), but it's exactly Firefox 3.5.&lt;br /&gt;&lt;br /&gt;Time to move on !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-429203852595775720?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blogs.webtide.com/sbordet/entry/jetty_supports_cross_domain_xmlhttprequests' title='Jetty Support for Cross-Domain XMLHttpRequests'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/429203852595775720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=429203852595775720' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/429203852595775720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/429203852595775720'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2009/08/jetty-support-for-cross-domain.html' title='Jetty Support for Cross-Domain XMLHttpRequests'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-8521383057480152324</id><published>2009-07-29T17:01:00.003+02:00</published><updated>2009-08-04T18:24:01.569+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='cometd'/><title type='text'>JavaScript Cometd</title><content type='html'>Lately I have been working with JavaScript, in particular I have written a JavaScript library that implements the &lt;a href="http://cometd.org/documentation/bayeux/spec"&gt;Bayeux specification&lt;/a&gt; for the &lt;a href="http://cometd.org"&gt;Cometd project&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have to say that I really like JavaScript, the language.&lt;br /&gt; &lt;br /&gt;Don't be fooled by "Oh, it's only for modifying CSS in web pages" because it's really a nice language, although it's &lt;a href="http://javascript.crockford.com/javascript.html"&gt;misunderstood&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can write nice applications in JavaScript and today JavaScript toolkits (such as &lt;a href="http://dojotoolkit.org"&gt;Dojo&lt;/a&gt; or &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;) helps you to figure out browser differences and make a wonderful job at reducing the code that you have to write, allowing you to concentrate on the business and not on the technical details.&lt;br /&gt;&lt;br /&gt;I have blogged about the Cometd library I have written &lt;a href="http://blogs.webtide.com/sbordet/entry/jquery_comet_implementation_available"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Enjoy !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-8521383057480152324?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blogs.webtide.com/sbordet/entry/jquery_comet_implementation_available' title='JavaScript Cometd'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/8521383057480152324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=8521383057480152324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8521383057480152324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8521383057480152324'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2009/07/javascript-cometd.html' title='JavaScript Cometd'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-5510606061796534310</id><published>2009-01-13T00:28:00.002+01:00</published><updated>2009-01-13T00:50:20.370+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu intrepid webcam skype'/><title type='text'>Creative Webcam Live! on Ubuntu Intrepid Ibex</title><content type='html'>I received the Creative Webcam Live! as a gift quite some time ago, but never had the time to use it or install it properly.&lt;br /&gt;My good ol' Thinkpad T43p was maybe bleeding edge in 2005, but not as far as having already an incorporated webcam &lt;img src="http://wolverinex02.googlepages.com/icon_wink.gif" alt=":)" /&gt;&lt;br /&gt;&lt;br /&gt;Under Ubuntu Intrepid, this webcam does not work out of the box, at least for me, and I have a fresh (re)install of Intrepid.&lt;br /&gt;This camera appears using &lt;code&gt;lsusb&lt;/code&gt; as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Bus 003 Device 008: ID 041e:4036 Creative Technology, Ltd Webcam Live!/Live! Pro&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The solution is quite easy though: you need to set this variable before launching the program that uses the webcam:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I tested this with camorama and skype, and in both cases it works just fine.&lt;br /&gt;For skype, I created a wrapper script that first set the variable as above and then invokes &lt;code&gt;/usr/bin/skype&lt;/code&gt; and modified the menu entry to point to my wrapper script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-5510606061796534310?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/5510606061796534310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=5510606061796534310' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5510606061796534310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5510606061796534310'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2009/01/creative-webcam-live-on-ubuntu-intrepid.html' title='Creative Webcam Live! on Ubuntu Intrepid Ibex'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-8320529858540668890</id><published>2008-12-29T14:39:00.008+01:00</published><updated>2008-12-30T17:51:21.039+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Visibility in JavaScript</title><content type='html'>The topic of visibility of members and functions in JavaScript has been figured out already, and there are good resources, among which one of the most important is Douglas Crockford's &lt;a href="http://javascript.crockford.com/private.html"&gt;Private Members in JavaScript&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here I just recap my experience for my own (and for anyone interested) future reference.&lt;br /&gt;&lt;br /&gt;I am pretty paranoid in making all members and methods with the least possible visibility in my Java code. Before opening up a method as protected or public, one should always remind that most of the times, once it's opened up, you cannot close it because other code uses it.&lt;br /&gt;&lt;br /&gt;JavaScript can have private members and functions, and I mostly use two idioms for this: &lt;a href="#ctor"&gt;the constructor function&lt;/a&gt; and the &lt;a href="#init"&gt;the object initializer&lt;/a&gt;.&lt;br /&gt;&lt;h4&gt;&lt;a name="ctor"&gt;The constructor function&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I use the constructor function technique when I want to create few objects that behave the same (in Java you would say "few objects that belong to the same class", but JavaScript does not have classes).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var MyNS = {}; // An optional namespace&lt;br /&gt;MyNS.Service = function(offset)&lt;br /&gt;{&lt;br /&gt;    var _privateMember = offset;&lt;br /&gt;&lt;br /&gt;    function _privateFunction(value)&lt;br /&gt;    {&lt;br /&gt;        return _privateMember + value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    this.myFunction = function(value)&lt;br /&gt;    {&lt;br /&gt;        _privateMember = _privateFunction(value);&lt;br /&gt;        return _privateMember;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The common convention is that function names beginning with an upper case letter are constructor functions, in this case &lt;code&gt;Service&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;From the example above, private members are defined within the constructor function using the keyword &lt;code&gt;var&lt;/code&gt;, private functions are just nested functions within the constructor function, and publicly accessible functions are defined with the &lt;code&gt;this.&amp;lt;functionName&amp;gt;&lt;/code&gt; idiom. &lt;br /&gt;The function &lt;code&gt;myFunction&lt;/code&gt; in the example above is a privileged function, but for the sake of visibility it can be classified as public because anyone can invoke it.&lt;br /&gt;From the example above, you see that &lt;code&gt;myFunction&lt;/code&gt; can refer to private members and functions.&lt;br /&gt;&lt;br /&gt;However, referring to publicly accessible functions from private functions is not possible:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// A constructor function without namespace; does not work&lt;br /&gt;function Service2()&lt;br /&gt;{&lt;br /&gt;    var _open;&lt;br /&gt;&lt;br /&gt;    function _clean()&lt;br /&gt;    {&lt;br /&gt;        if (_open) close(); // Does not work: ReferenceError&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    this.close = function()&lt;br /&gt;    {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is not possible to call privileged functions from private functions. In my experience this is not a big problem, as it is possible to refactor function &lt;code&gt;close()&lt;/code&gt; into a private function &lt;code&gt;_close()&lt;/code&gt; and call the private version from both &lt;code&gt;_clean()&lt;/code&gt; and &lt;code&gt;close()&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;With a constructor function it is possible to create several objects that behave the same. In the example above you can create several service objects using the following syntax:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var s1 = new MyNS.Service(1);&lt;br /&gt;var result1 = s1.myFunction(5); // returns 6&lt;br /&gt;&lt;br /&gt;var s2 = new MyNS.Service(2);&lt;br /&gt;var result2 = s2.myFunction(0); // returns 2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you would expect, object &lt;code&gt;s1&lt;/code&gt; and &lt;code&gt;s2&lt;/code&gt; have different internal state and can be used independently.&lt;br /&gt;&lt;h4&gt;&lt;a name="init"&gt;The object initializer&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;I use the object initializer technique when I want to create a singleton object.&lt;br /&gt;My preferred way of using the object initializer technique is via a function with immediate invocation, which allows to have private members and functions:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyNS.EventHandler = function()&lt;br /&gt;{&lt;br /&gt;    var _queue = [];&lt;br /&gt;&lt;br /&gt;    function _privateFunction(event)&lt;br /&gt;    {&lt;br /&gt;         ...&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    return {&lt;br /&gt;        handle: function(event)&lt;br /&gt;        {&lt;br /&gt;            _privateFunction(event);&lt;br /&gt;        },&lt;br /&gt;        get size()&lt;br /&gt;        {&lt;br /&gt;            return _queue.length;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;}();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note the parenthesis at the end of the function definition, which perform the immediate invocation of the function.&lt;br /&gt;&lt;br /&gt;Similarly to the constructor function technique, it is possible to define private members and functions, but the object initializer technique also allows (for non-crappy JavaScript interpreters) to use the &lt;a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters"&gt;getter and setter notation&lt;/a&gt;.&lt;br /&gt;In the example above I used the getter notation to define a read-only property called &lt;code&gt;size&lt;/code&gt;, which can be accessed like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var s = MyNS.EventHandler.&lt;b&gt;size&lt;/b&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using the getter notation is much nicer than having a getter function, and much better than having a public member (which would be not only readable but also writable).&lt;br /&gt;&lt;h4&gt;Caveats&lt;/h4&gt;&lt;br /&gt;Both solutions outlined above have the problem that for each object created in those ways, the function definitions are also duplicated: each object will have its own copy of the functions, and this will result in more memory occupation. That's why I suggest the constructor function technique when you create few objects and the object initializer technique for singletons.&lt;br /&gt;&lt;br /&gt;At first, I thought that there must have been a way to have private visibility for member and functions, but only one copy of the function definitions, very much like Java does: each Java object has its own copy of the members, but they all share the methods definitions.&lt;br /&gt;&lt;br /&gt;Unfortunately I could not figure out how to do it, not even reading JavaScript library code such as &lt;a href="http://dojotoolkit.org/"&gt;Dojo&lt;/a&gt; or &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;However, there is a different technique that it is possible to use to share the functions definitions, which I will call here "public members and prototype".&lt;br /&gt;&lt;h4&gt;Public members and prototype&lt;/h4&gt;&lt;br /&gt;When you have to create lots of objects with members and functions, the best technique is to define the functions in the prototype, so that they will be shared by all objects, and have public members holding the state.&lt;br /&gt;You have to give up on restricted visibility (members must be public) to save memory (only one copy of the functions is shared by all objects), because functions defined in the prototype can only (to my knowledge) refer to public members.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyNS.Event = function(source) &lt;br /&gt;{&lt;br /&gt;    this._source = source;&lt;br /&gt;};&lt;br /&gt;MyNS.Event.prototype = function()&lt;br /&gt;{&lt;br /&gt;    var _privateStatic;&lt;br /&gt;&lt;br /&gt;    function _privateFunction()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return {&lt;br /&gt;        consume: function() &lt;br /&gt;        {&lt;br /&gt;            this._consumed = true;&lt;br /&gt;        },&lt;br /&gt;        get source()&lt;br /&gt;        {&lt;br /&gt;            return this._source;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;}();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this example, &lt;code&gt;MyNS.Event&lt;/code&gt; is a constructor function that allows to create events via:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var source = window;&lt;br /&gt;var event1 = new MyNS.Event(source);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The constructor function defines a public member called &lt;code&gt;_source&lt;/code&gt;, which can be later referred from functions. &lt;br /&gt;Also functions in the prototype can define public members (like &lt;code&gt;_consumed&lt;/code&gt; in function &lt;code&gt;consume()&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;All function definitions are defined in the prototype. Note how the prototype object is returned via immediate function invocation, which again allows to have private functions and members as in previous techniques.&lt;br /&gt;&lt;br /&gt;The interesting part comes when you define private members in the prototype, like &lt;code&gt;_privateStatic&lt;/code&gt;.&lt;br /&gt;These members can only be modified by functions defined in the prototype, which are shared by all objects. The result is that modifications made by one object to &lt;code&gt;_privateStatic&lt;/code&gt; (via shared prototype functions) are reflected by all other objects created with the same constructor function. This behavior is the same behavior of static members in Java.&lt;br /&gt;&lt;br /&gt;Instead, public members modified by functions defined in the prototype are attached to the object (not to the prototype), so that each different object has its own copy of the members, and therefore they can be modified independently:&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;function A(value)&lt;br /&gt;{&lt;br /&gt;    this._field = value;&lt;br /&gt;}&lt;br /&gt;A.prototype = function()&lt;br /&gt;{&lt;br /&gt;    var _staticField;&lt;br /&gt;    return {&lt;br /&gt;        staticGetter: function() &lt;br /&gt;        {&lt;br /&gt;            return _staticField;&lt;br /&gt;        },&lt;br /&gt;        staticSetter: function(value) &lt;br /&gt;        {&lt;br /&gt;            _staticField = value;&lt;br /&gt;        },&lt;br /&gt;        instanceGetter: function()&lt;br /&gt;        {&lt;br /&gt;            return this._field;&lt;br /&gt;        },&lt;br /&gt;    };&lt;br /&gt;}();&lt;br /&gt;&lt;br /&gt;var a1 = new A(1);&lt;br /&gt;var a2 = new A(2);&lt;br /&gt;a1.instanceGetter(); // returns 1&lt;br /&gt;a1._field; // public field, returns 1&lt;br /&gt;a1._field = 3;&lt;br /&gt;a1.instanceGetter(); // returns 3&lt;br /&gt;a2.instanceGetter(); // returns 2&lt;br /&gt;a2.staticSetter('foo');&lt;br /&gt;a1.staticGetter(); // returns 'foo'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'd be interested in any solution that will allow private members with prototype-shared functions, if this is possible in JavaScript.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-8320529858540668890?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/8320529858540668890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=8320529858540668890' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8320529858540668890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8320529858540668890'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2008/12/visibility-in-javascript.html' title='Visibility in JavaScript'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-6721654303130394466</id><published>2008-08-14T23:39:00.002+02:00</published><updated>2008-08-15T00:33:43.274+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java's uncertain future</title><content type='html'>Java's future looks to me very uncertain in this period.&lt;br /&gt;&lt;br /&gt;I started studying Java during 1999 summer, and working with it since then.&lt;br /&gt;&lt;br /&gt;Many things happened since the release of JDK 5. &lt;br /&gt;&lt;br /&gt;Many key people left Sun for other companies (and wow, the list of those names is truly impressive; among them Josh Bloch, Neal Gafter, Gilad Bracha, most of the Swing core team - Hans Muller, Scott Violet, Chet Haase, etc.)&lt;br /&gt;&lt;br /&gt;Sun itself is not performing very well these days (profit plunged 73% in the last quarter).&lt;br /&gt;&lt;br /&gt;Sun has open sourced Java.&lt;br /&gt;&lt;br /&gt;Yet, there is no JDK 7 plan.&lt;br /&gt;You heard that right, no official JSR has been opened yet, when we were used to have release of version N of the JDK and official JSR for version N+1 almost immediately opened. &lt;br /&gt;But not this time, and noone seems able to predict neither &lt;span style="font-style:italic;"&gt;when&lt;/span&gt; JDK 7 will be released, nor &lt;span style="font-style:italic;"&gt;what&lt;/span&gt; it will contain.&lt;br /&gt;&lt;br /&gt;There is OpenJDK.&lt;br /&gt;Can anyone tell me the difference between JDK 7 and OpenJDK ?&lt;br /&gt;And I am not meaning the obvious ones, but why two efforts, and how are they synchronizing ?&lt;br /&gt;I never thought that open sourcing the JDK was such a great idea, from the point of view of developers, though it was probably such a good move for other fields that developers could be forgotten.&lt;br /&gt;&lt;br /&gt;There is JDK 6 and JDK 6 update 10. Mmm. More confusion.&lt;br /&gt;&lt;br /&gt;The closures will (most likely) not be part of JDK 7, but everyone talks about the "upcoming language changes in JDK 7" yet there is no official JSR, nor for JDK 7 nor for closures. Oops.&lt;br /&gt;&lt;br /&gt;Java blogs are beginning to label Java as the next legacy language, but it surely will still live for many many years. I hear the same of COBOL.&lt;br /&gt;&lt;br /&gt;It appears as if Sun released the command of the Java ship and let its best commanders flew away.&lt;br /&gt;It would not be bad to see a real move from Sun about Java (because strong statements are just that, words), because hey, the ship seems DIW, dead in water.&lt;br /&gt;&lt;br /&gt;It's 2008 summer, and I am studying Ruby.&lt;br /&gt;&lt;br /&gt;But the worst indicator is that Hani and its Bileblog are quiet: he cannot desecrate the last moments of a dying era, can he ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-6721654303130394466?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/6721654303130394466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=6721654303130394466' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/6721654303130394466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/6721654303130394466'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2008/08/javas-uncertain-future.html' title='Java&apos;s uncertain future'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-8798345967448028376</id><published>2008-07-27T01:17:00.003+02:00</published><updated>2008-07-28T00:59:40.377+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='enum'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Static Fields in Enums</title><content type='html'>Enums in Java have a numeric, read-only, property called &lt;code&gt;ordinal&lt;/code&gt; that is a strictly consecutive integer (starting from 0).&lt;br /&gt;&lt;br /&gt;Sometimes, however, it is necessary to associate to an Enum another numeric property, let's call it &lt;code&gt;code&lt;/code&gt;, that it may not be strictly consecutive and normally specifies something different than a sequence number. Furthermore, it may be necessary to be able to lookup the correct Enum from its &lt;code&gt;code&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;It seems totally trivial to write an Enum that has a static map from codes to Enum instances:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public enum Port&lt;br /&gt;{&lt;br /&gt;  SSH(22), TELNET(23), HTTP(80), POP3(110), HTTPS(443);&lt;br /&gt;&lt;br /&gt;  // The static map from codes to Enum instances&lt;br /&gt;  private static final &lt;br /&gt;              Map&amp;lt;Integer, Port&amp;gt; ports = new HashMap&amp;lt;Integer, Port&amp;gt;();&lt;br /&gt;  private final int code;&lt;br /&gt;&lt;br /&gt;  private Port(int code)&lt;br /&gt;  {&lt;br /&gt;    this.code = code;&lt;br /&gt;    ports.put(code, this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public int getCode()&lt;br /&gt;  {&lt;br /&gt;    return this.code;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Lookup method that returns the Enum instance from the given code&lt;br /&gt;  public static Port from(int code)&lt;br /&gt;  {&lt;br /&gt;    return ports.get(code);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note the method &lt;code&gt;static from(int code)&lt;/code&gt; that returns an Enum instance from the given &lt;code&gt;code&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately, this will not compile. The compiler reports that it is illegal to access the static member &lt;code&gt;ports&lt;/code&gt; from the constructor.&lt;br /&gt;&lt;br /&gt;This makes sense when one imagines how an Enum is first translated into a class by the compiler. Roughly, there is a static initializer that creates the &lt;code&gt;Ports&lt;/code&gt; instances, in this case SSH, TELNET, etc.; this static initializer is the first initializer run when the &lt;code&gt;Ports&lt;/code&gt; class is referenced, and it is easy to see that when the static initializer runs, no other initializers have been run yet, and in particular the static Map &lt;code&gt;ports&lt;/code&gt; has not been created yet.&lt;br /&gt;See &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#301020"&gt;http://java.sun.com/docs/books/jls/third_edition/html/classes.html#301020&lt;/a&gt; for further details.&lt;br /&gt;&lt;br /&gt;Fortunately, there is an easy workaround: it's enough to use a different class to store the map from codes to Enum instances, and a private static inner class does the job:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public enum Port&lt;br /&gt;{&lt;br /&gt;  SSH(22), TELNET(23), HTTP(80), POP3(110), HTTPS(443);&lt;br /&gt;&lt;br /&gt;  private final int code;&lt;br /&gt;&lt;br /&gt;  private Port(int code)&lt;br /&gt;  {&lt;br /&gt;    this.code = code;&lt;br /&gt;    Ports.ports.put(code, this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public int getCode()&lt;br /&gt;  {&lt;br /&gt;    return this.code;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Lookup method that returns the Enum instance from the given code&lt;br /&gt;  public static Port from(int code)&lt;br /&gt;  {&lt;br /&gt;    return Ports.ports.get(code);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static class Ports&lt;br /&gt;  {&lt;br /&gt;    // The static map from codes to Enum instances&lt;br /&gt;    private static final &lt;br /&gt;              Map&amp;lt;Integer, Port&amp;gt; ports = new HashMap&amp;lt;Integer, Port&amp;gt;();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-8798345967448028376?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/8798345967448028376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=8798345967448028376' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8798345967448028376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8798345967448028376'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2008/07/static-fields-in-enums.html' title='Static Fields in Enums'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-1588754359275176547</id><published>2008-07-27T00:57:00.002+02:00</published><updated>2008-07-27T01:16:28.146+02:00</updated><title type='text'>Randy Pausch Last Lecture</title><content type='html'>I just watched &lt;a href="http://www.youtube.com/watch?v=ji5_MqicxSo&amp;NR=1"&gt;Randy Pausch last lecture&lt;/a&gt;, and found it absolutely incredible, one of those gems that cannot be missed.&lt;br /&gt;&lt;br /&gt;If you want to spend 1hr 16 mins in something really worth, then go watch it.&lt;br /&gt;&lt;br /&gt;My favorite quote:&lt;br /&gt;"The brickwalls are there for a reason: to give us a chance to show how badly we want something. Brickwalls are there to stop the people who don't want it badly enough."&lt;br /&gt;&lt;br /&gt;Thanks Randy: for the head fake that I've got from your last lecture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-1588754359275176547?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/1588754359275176547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=1588754359275176547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/1588754359275176547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/1588754359275176547'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2008/07/randy-pausch-last-lecture.html' title='Randy Pausch Last Lecture'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-841218590660087260</id><published>2007-09-20T22:40:00.000+02:00</published><updated>2007-09-20T23:19:25.154+02:00</updated><title type='text'>JSP page encoding</title><content type='html'>I recently had a problem with a web application using JSP pages that was not handling non-ASCII characters correctly: submitted text containing characters such as &lt;span style="font-style: italic;"&gt;ù&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;è&lt;/span&gt; resulted in garbage characters stored in the database and consequently garbage displayed by the browser.&lt;br /&gt;&lt;br /&gt;The application was developed in Linux, using an IDE configured to save files using UTF-8 encoding, and deployed on a Linux box.&lt;br /&gt;&lt;a href="http://postgresql.org/"&gt;The database&lt;/a&gt; was configured to use UTF-8 encoding.&lt;br /&gt;Every page contained the directive &lt;code&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&amp;gt;&lt;/code&gt; in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section.&lt;br /&gt;&lt;br /&gt;I thought that given these premises, there was no chance of misbehaviors with respect to character encoding, but I was wrong.&lt;br /&gt;The browser kept telling me that the page it was displaying had ISO-8859-1 encoding.&lt;br /&gt;&lt;br /&gt;It turned out that the JSP specification says that if the page encoding of the JSP pages is not explicitely declared, then ISO-8859-1 should be used (!).&lt;br /&gt;The &lt;a href="http://jetty.mortbay.org"&gt;Jetty servlet container&lt;/a&gt; was correctly setting the HTTP header as: &lt;code&gt;Content-Type: text/html; charset=ISO-8859-1&lt;/code&gt;, following the specification.&lt;br /&gt;&lt;br /&gt;The fix is simple, just add this to &lt;code&gt;web.xml&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;jsp-config&amp;gt;&lt;br /&gt;    &amp;lt;jsp-property-group&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;*.jsp&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;        &amp;lt;page-encoding&amp;gt;UTF-8&amp;lt;/page-encoding&amp;gt;&lt;br /&gt;    &amp;lt;/jsp-property-group&amp;gt;&lt;br /&gt;&amp;lt;/jsp-config&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It will be interesting to know why the JSP expert group did not pick up UTF-8 as the default character encoding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-841218590660087260?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/841218590660087260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=841218590660087260' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/841218590660087260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/841218590660087260'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2007/09/jsp-page-encoding.html' title='JSP page encoding'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-4293377015745210525</id><published>2007-07-26T21:23:00.000+02:00</published><updated>2007-07-26T22:53:35.194+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><category scheme='http://www.blogger.com/atom/ns#' term='ssl'/><title type='text'>Upgrading to SSL an existing socket connection</title><content type='html'>SSL support is in the JDK since 1.4 (and even before as a separate jar), so it is fairly common knowledge how to create and use SSLSocket and SSLServerSocket.&lt;br /&gt;&lt;br /&gt;What is less known, or it was to me at least, is that it is possible to create a plain socket, connect to a server, exchange some message, then &lt;span style="font-weight: bold;"&gt;upgrade&lt;/span&gt; the existing socket connection to SSL, exchange some private message with confidentiality (for example a password that would have traveled in clear text), then &lt;span style="font-weight: bold;"&gt;downgrade&lt;/span&gt; back to the plain the socket connection; all this without closing the original socket nor creating a new one on a different port.&lt;br /&gt;&lt;br /&gt;Let's see how.&lt;br /&gt;&lt;h3 style="margin:2em 0 0 0;padding:0"&gt;The server&lt;/h3&gt;&lt;br /&gt;The server class creates a plain ServerSocket, and calls &lt;code&gt;accept()&lt;/code&gt; on it; when a client connects, &lt;code&gt;accept()&lt;/code&gt; returns a socket that is normally handed to a different thread (details omitted):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Socket socket = serverSocket.accept();&lt;br /&gt;threadPool.execute(new Handler(socket));&lt;br /&gt;&lt;br /&gt;class Handler implements Runnable&lt;br /&gt;{&lt;br /&gt; private final Socket socket;&lt;br /&gt; Handler(Socket socket) { this.socket = socket; }&lt;br /&gt; public void run()&lt;br /&gt; {&lt;br /&gt;   Socket currentSocket = this.socket;&lt;br /&gt;   while (isConnectionOpen(currentSocket))&lt;br /&gt;   {&lt;br /&gt;     String message = readMessage(currentSocket);&lt;br /&gt;     if (upgradeToSSL(message))&lt;br /&gt;     {&lt;br /&gt;         SSLSocketFactory sslSocketFactory =&lt;br /&gt;             (SSLSocketFactory)SSLSocketFactory.getDefault();&lt;br /&gt;         SSLSocket sslSocket =&lt;br /&gt;             (SSLSocket)sslSocketFactory.&lt;br /&gt;                 createSocket(currentSocket,&lt;br /&gt;                              currentSocket.getInetAddress().getHostAddress(),&lt;br /&gt;                              currentSocket.getPort(),&lt;br /&gt;                              false);&lt;br /&gt;         sslSocket.setUseClientMode(false);&lt;br /&gt;         sslSocket.startHandshake();&lt;br /&gt;         currentSocket = sslSocket;&lt;br /&gt;       }&lt;br /&gt;       else if (downgradeFromSSL(message))&lt;br /&gt;       {&lt;br /&gt;         currentSocket.close();&lt;br /&gt;         currentSocket = this.socket;&lt;br /&gt;       }&lt;br /&gt;       else&lt;br /&gt;       {&lt;br /&gt;         handleNormalMessage(currenSocket, message);&lt;br /&gt;       }&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When upgrading, the server wraps the current (plain) socket using &lt;code&gt;SSLSocketFactory.createSocket(socket, address, port, autoClose)&lt;/code&gt;, then configures the SSLSocket to be a non-client one (for the purposes of the SSL handshake), then starts the SSL handshake to secure the connection.&lt;br /&gt;&lt;br /&gt;When downgrading, the current (ssl) socket is just closed and, thanks to the &lt;code&gt;autoClose&lt;/code&gt; argument set to false (which will not close the underlying plain socket), the original plain socket is still operative.&lt;br /&gt;&lt;br /&gt;In order for this mechanism to work, you have to configure the SSL details as usual for a server. This means having created a private/public key pair in a keystore (and optionally having signed the public key with a CA root) and having set the relevant SSL system properties (or having done the equivalent using the SSL APIs).&lt;br /&gt;&lt;h3 style="margin:2em 0 0 0;padding:0"&gt;The client&lt;/h3&gt;&lt;br /&gt;The client connects to the server using a plain Socket, then upgrades the socket connection (details omitted):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Connects to server&lt;br /&gt;this.socket = new Socket(serverAddress, serverPort);&lt;br /&gt;...&lt;br /&gt;Socket currentSocket = this.socket;&lt;br /&gt;while (moreMessagesToSend)&lt;br /&gt;{&lt;br /&gt;  if (upgradeToSSL)&lt;br /&gt;  {&lt;br /&gt;    SSLSocketFactory sslSocketFactory =&lt;br /&gt;      (SSLSocketFactory)SSLSocketFactory.getDefault();&lt;br /&gt;    SSLSocket sslSocket =&lt;br /&gt;      (SSLSocket)sslSocketFactory.&lt;br /&gt;        createSocket(currentSocket,&lt;br /&gt;                     currentSocket.getInetAddress().getHostAddress(),&lt;br /&gt;                     currentSocket.getPort(),&lt;br /&gt;                     false);&lt;br /&gt;    sslSocket.setUseClientMode(true);&lt;br /&gt;    sslSocket.startHandshake();&lt;br /&gt;    currentSocket = sslSocket;&lt;br /&gt;  }&lt;br /&gt;  else if (downgradeFromSSL)&lt;br /&gt;  {&lt;br /&gt;    currentSocket.close();&lt;br /&gt;    currentSocket = this.socket;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  sendMessage(currentSocket);&lt;br /&gt;  readReply(currentSocket);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Upgrading and downgrading the socket connection in the client works like in the server code, the only difference being that the SSLSocket is configured to be a client one (for the purposes of the SSL handshake). The &lt;code&gt;autoClose&lt;/code&gt; argument prevents the original plain socket to be closed when the SSL socket is closed.&lt;br /&gt;&lt;br /&gt;In order for this mechanism to work, you have once again to configure the SSL details as usual for a client. This means having setup properly a trust store (and optionally having imported into it the server certificate if it's not signed by a CA root) and having set the relevant SSL system properties (or having done the equivalent using the SSL APIs).&lt;br /&gt;&lt;br /&gt;If you're writing custom network protocols that require confidentiality, the above may come handy. Enjoy !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-4293377015745210525?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/4293377015745210525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=4293377015745210525' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/4293377015745210525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/4293377015745210525'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2007/07/upgrading-to-ssl-existing-socket.html' title='Upgrading to SSL an existing socket connection'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-5548838768830160940</id><published>2007-01-17T00:46:00.000+01:00</published><updated>2007-01-17T01:03:09.391+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jugtorino'/><title type='text'>Jonas Bonér @ JUG Torino - January 19th</title><content type='html'>&lt;a href="http://jonasboner.com"&gt;Jonas Bonér&lt;/a&gt; of &lt;a href="http://terracottatech.com"&gt;Terracotta Tech&lt;/a&gt; will be our guest speaker at the monthly meeting of the &lt;a href="http://www.jugtorino.it"&gt;JUG Torino&lt;/a&gt; on January 19th, 18:30.&lt;br /&gt;&lt;br /&gt;The title of his talk is: &lt;span style="font-weight:bold;"&gt;How to write scalable, highly available web applications&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If you are in the Torino area, this meeting is one which will be really worth attending, both for the speaker importance and for the arguments.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingGennaio2007"&gt;Here&lt;/a&gt; you can find more information on this meeting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-5548838768830160940?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/5548838768830160940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=5548838768830160940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5548838768830160940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5548838768830160940'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2007/01/jonas-bonr-jug-torino-january-19th.html' title='Jonas Bonér @ JUG Torino - January 19th'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-1642767247681452779</id><published>2007-01-01T23:49:00.000+01:00</published><updated>2007-01-04T23:37:50.463+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='encoding'/><title type='text'>UTF-8 handling for ResourceBundle and Properties</title><content type='html'>Every new version of the JDK comes with small improvements, often unnoticed, that however correct long-standing bugs or request for enhancements.&lt;br /&gt;&lt;br /&gt;One such improvements is - finally! - the ability for &lt;tt&gt;java.util.Properties&lt;/tt&gt; to handle &lt;span style="font-weight:bold;"&gt;non ISO-8859-1&lt;/span&gt; properties files.&lt;br /&gt;At first seems like a very small improvement, but anyone that worked on localizing an application (for example translating messages into a country specific language) knows that encoding problems are just painful, and that is far too easy to waste days trying to get them right.&lt;br /&gt;&lt;br /&gt;JDK 5 added a new API, namely &lt;tt&gt;Properties.loadFromXML(InputStream)&lt;/tt&gt;, that allowed to specify properties using an XML syntax, and hence to specify the encoding of the XML file in the XML declaration (the first line of an XML file):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" &lt;span style="font-weight:bold;"&gt;encoding="UTF-8"&lt;/span&gt; ?&amp;gt;&lt;br /&gt;&amp;lt;properties&amp;gt;&lt;br /&gt;    &amp;lt;entry key="hello.world"&amp;gt;Καλημέρα κόσμε&amp;lt;/entry&amp;gt;&lt;br /&gt;&amp;lt;/properties&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;JDK 6 went further, adding &lt;tt&gt;Properties.load(Reader)&lt;/tt&gt;: in case the encoding is known &lt;span style="font-style:italic;"&gt;a priori&lt;/span&gt; by the program, it is possible to create a &lt;tt&gt;Reader&lt;/tt&gt; that uses the specific encoding to read the properties file.&lt;br /&gt;&lt;br /&gt;However, in JDK 5, &lt;tt&gt;java.util.ResourceBundle&lt;/tt&gt; was only able to read properties files that were encoded in ISO-8859-1, and this forced the translators to put horrible unicode escapes instead of real text. Following the above example, in JDK 5 you have to write the properties file containing translations like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hello.world=\u039A\u03B1\u03BB\u03B7\u03BC\u03AD\u03C1\u03B1 \u03BA\u03CC\u03C3\u03BC\u03B5&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty ugly, especially when you think that the API to read properties file in XML format is already present in JDK 5, only that &lt;tt&gt;ResourceBundle&lt;/tt&gt; has not been updated to use it.&lt;br /&gt;&lt;br /&gt;Fortunately, with JDK 6 it is possible to solve this problem, although requires a bit of coding (see below).&lt;br /&gt;&lt;br /&gt;In JDK 6 &lt;tt&gt;ResourceBundle&lt;/tt&gt; has been extended to give the user more control on how to load resources, by subclassing &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.Control.html"&gt;&lt;tt&gt;ResourceBundle.Control&lt;/tt&gt;&lt;/a&gt;, and passing an instance of the &lt;tt&gt;ResourceBundle.Control&lt;/tt&gt; subclass like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ResourceBundle bundle = ResourceBundle.getBundle("messages", new MyControl());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where &lt;tt&gt;MyControl&lt;/tt&gt; is the &lt;tt&gt;ResourceBundle.Control&lt;/tt&gt; subclass.&lt;br /&gt;The class &lt;tt&gt;ResourceBundle.Control&lt;/tt&gt; allows to tune:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the kind of resource to load (a Java class, a properties file, a properties file in XML format, or any other format you decide)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;the policy of expiration of the resource, thus allowing reload the resource upon some condition&lt;/li&gt;&lt;br /&gt;&lt;li&gt;the &lt;tt&gt;ResourceBundle&lt;/tt&gt; subclass to instantiate, normally depending on the kind of resource&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Here's the JDK 6 class that allows to load XML properties files as resource bundles.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/**&lt;br /&gt; * JDK 6's {@link ResourceBundle.Control} subclass that allows&lt;br /&gt; * loading of bundles in XML format.&lt;br /&gt; * The bundles are searched first as Java classes, then as&lt;br /&gt; * properties files (these two methods are the standard&lt;br /&gt; * search mechanism of ResourceBundle), then as XML properties&lt;br /&gt; * files.&lt;br /&gt; * The filename extension of the XML properties files is assumed&lt;br /&gt; * to be *.properties.xml&lt;br /&gt; */&lt;br /&gt;public class ExtendedControl extends ResourceBundle.Control&lt;br /&gt;{&lt;br /&gt;    private static final String FORMAT_XML_SUFFIX = "properties.xml";&lt;br /&gt;    private static final String FORMAT_XML = "java." + FORMAT_XML_SUFFIX;&lt;br /&gt;    private static final List&amp;lt;String&amp;gt; FORMATS;&lt;br /&gt;    static&lt;br /&gt;    {&lt;br /&gt;        List&amp;lt;String&amp;gt; formats = new ArrayList&amp;lt;String&amp;gt;(FORMAT_DEFAULT);&lt;br /&gt;        formats.add(FORMAT_XML);&lt;br /&gt;        FORMATS = Collections.unmodifiableList(formats);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public List&amp;lt;String&amp;gt; getFormats(String baseName)&lt;br /&gt;    {&lt;br /&gt;        return FORMATS;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public ResourceBundle newBundle(String baseName, Locale locale,&lt;br /&gt;                                    String format, ClassLoader loader,&lt;br /&gt;                                    boolean reload)&lt;br /&gt;            throws IllegalAccessException, InstantiationException, IOException&lt;br /&gt;    {&lt;br /&gt;        if (!FORMAT_XML.equals(format))&lt;br /&gt;            return super.newBundle(baseName, locale, format, loader, reload);&lt;br /&gt;&lt;br /&gt;        String bundleName = toBundleName(baseName, locale);&lt;br /&gt;        String resourceName = toResourceName(bundleName, FORMAT_XML_SUFFIX);&lt;br /&gt;        final URL resourceURL = loader.getResource(resourceName);&lt;br /&gt;        if (resourceURL == null) return null;&lt;br /&gt;&lt;br /&gt;        InputStream stream = getResourceInputStream(resourceURL, reload);&lt;br /&gt;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            PropertyXMLResourceBundle result = new PropertyXMLResourceBundle();&lt;br /&gt;            result.load(stream);&lt;br /&gt;            return result;&lt;br /&gt;        }&lt;br /&gt;        finally&lt;br /&gt;        {&lt;br /&gt;            stream.close();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private InputStream getResourceInputStream(final URL resourceURL,&lt;br /&gt;                                               boolean reload)&lt;br /&gt;            throws IOException&lt;br /&gt;    {&lt;br /&gt;        if (!reload) return resourceURL.openStream();&lt;br /&gt;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            // This permission has already been checked by&lt;br /&gt;            // ClassLoader.getResource(String), which will return null&lt;br /&gt;            // in case the code has not enough privileges.&lt;br /&gt;            return AccessController.doPrivileged(&lt;br /&gt;                    new PrivilegedExceptionAction&amp;lt;InputStream&amp;gt;()&lt;br /&gt;            {&lt;br /&gt;                public InputStream run() throws IOException&lt;br /&gt;                {&lt;br /&gt;                    URLConnection connection = resourceURL.openConnection();&lt;br /&gt;                    connection.setUseCaches(false);&lt;br /&gt;                    return connection.getInputStream();&lt;br /&gt;                }&lt;br /&gt;            });&lt;br /&gt;        }&lt;br /&gt;        catch (PrivilegedActionException x)&lt;br /&gt;        {&lt;br /&gt;            throw (IOException)x.getCause();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * ResourceBundle that loads definitions from an XML properties file.&lt;br /&gt;     */&lt;br /&gt;    public static class PropertyXMLResourceBundle extends ResourceBundle&lt;br /&gt;    {&lt;br /&gt;        private final Properties properties = new Properties();&lt;br /&gt;&lt;br /&gt;        public void load(InputStream stream) throws IOException&lt;br /&gt;        {&lt;br /&gt;            properties.loadFromXML(stream);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected Object handleGetObject(String key)&lt;br /&gt;        {&lt;br /&gt;            return properties.getProperty(key);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public Enumeration&amp;lt;String&amp;gt; getKeys()&lt;br /&gt;        {&lt;br /&gt;            final Enumeration&amp;lt;Object&amp;gt; keys = properties.keys();&lt;br /&gt;            return new Enumeration&amp;lt;String&amp;gt;()&lt;br /&gt;            {&lt;br /&gt;                public boolean hasMoreElements()&lt;br /&gt;                {&lt;br /&gt;                    return keys.hasMoreElements();&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                public String nextElement()&lt;br /&gt;                {&lt;br /&gt;                    return (String)keys.nextElement();&lt;br /&gt;                }&lt;br /&gt;            };&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-1642767247681452779?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/1642767247681452779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=1642767247681452779' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/1642767247681452779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/1642767247681452779'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2007/01/utf-8-handling-for-resourcebundle-and.html' title='UTF-8 handling for &lt;tt&gt;ResourceBundle&lt;/tt&gt; and &lt;tt&gt;Properties&lt;/tt&gt;'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-7561218971808764112</id><published>2006-12-21T23:53:00.000+01:00</published><updated>2006-12-22T01:25:38.254+01:00</updated><title type='text'>Java Memory Model: down to the metal</title><content type='html'>&lt;a href="http://www.javapolis.com/"&gt;Javapolis&lt;/a&gt; is over, and among the sessions that can be seen and heard online, there's Brian Goetz's on the &lt;a href="http://www.bejug.org/confluenceBeJUG/display/PARLEYS/The+new+Java+Memory+Model"&gt;Java Memory Model&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Although I knew (since a while) about the new memory model, I wanted to check out if there was something new. Brian's presentation is quite entertaining (considering the thickness of the argument), but no news with respect to what I already knew.&lt;br /&gt;&lt;br /&gt;One thing that always intrigued me, however, is: How is the new memory model actually implemented ?&lt;br /&gt;&lt;br /&gt;Before we go into the detail, I will make a small preamble about what the problem is in JDK 1.4, and how it has been fixed in JDK 5.&lt;br /&gt;&lt;br /&gt;In JDK 1.4, if two threads are executing the now deprecated double checked locking code (see below), there is no guarantee that the singleton is created only once (it may be created twice) or - hard to believe but true - that a fully constructed singleton is returned (a partially constructed singleton may be returned):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Singleton&lt;br /&gt;{&lt;br /&gt;    private static Object singleton;&lt;br /&gt;    public static Object getInstance()&lt;br /&gt;    {&lt;br /&gt;        if (singleton == null)&lt;br /&gt;        {&lt;br /&gt;            synchronized (Singleton.class)&lt;br /&gt;            {&lt;br /&gt;                if (singleton == null)&lt;br /&gt;                    singleton = new Object();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return singleton;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;How is it possible that the double checked locking does not work ?&lt;br /&gt;&lt;br /&gt;It is possible because in JDK 1.4 the memory model, i.e. the interaction between threads and memory, was not well defined. &lt;br /&gt;In a multi-processor machine it was perfectly legal for the first processor, running the first thread, to cache the value of the data member &lt;tt&gt;singleton&lt;/tt&gt; (for example in a registry) so that the second processor, running the second thread, would have read the stale value of &lt;tt&gt;null&lt;/tt&gt;, even if the first thread already updated it.&lt;br /&gt;&lt;br /&gt;Fortunately, in JDK 5 the memory model has been fixed, so that now the effects of &lt;tt&gt;synchronized&lt;/tt&gt;, &lt;tt&gt;volatile&lt;/tt&gt; and &lt;tt&gt;final&lt;/tt&gt; with respect to the memory model have been precisely defined.&lt;br /&gt;&lt;br /&gt;These effects are outlined in Brian's presentation, and defined &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/"&gt;here&lt;/a&gt; so you may want to refer to these resources for further details.&lt;br /&gt;The short story is that those keywords now impose memory barriers, i.e. they tell the processors to flush the caches to main memory, or to invalidate the caches and therefore read fresh data from main memory.&lt;br /&gt;&lt;br /&gt;In JDK 1.4, the &lt;tt&gt;synchronized&lt;/tt&gt; keyword does not guarantee a memory barrier when the lock is released. In JDK 5 the memory barrier is guaranteed. (Now, you may think that in JDK 5 the double checked locking code above works fine, but it does not - not yet).&lt;br /&gt;&lt;br /&gt;Now that we are done with the preamble, let's go back to my original question: how are these memory barriers implemented in the JVM ?&lt;br /&gt;&lt;br /&gt;It turns out operative systems do not have primitives (system calls) that handle memory barriers, but processors do. So the JVM goes down to the metal, from C++ to assembler, and squeezes in few assembler instructions to tell the processor to perform a memory barrier.&lt;br /&gt;For example to implement a particular memory barrier called &lt;em&gt;fence&lt;/em&gt;, in a x86 the assembler instruction is &lt;tt&gt;lock addl 0,(sp)&lt;/tt&gt; where &lt;tt&gt;sp&lt;/tt&gt; is the stack pointer, while in a ia64 there is a dedicated assembler instruction called &lt;tt&gt;mf&lt;/tt&gt; (memory fence).&lt;br /&gt;&lt;br /&gt;Conclusion: Once again I am thankful that the JVM takes care of these details for me, although it's quite funny to figure them out :D&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-7561218971808764112?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/7561218971808764112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=7561218971808764112' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/7561218971808764112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/7561218971808764112'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/12/java-memory-model-down-to-metal.html' title='Java Memory Model: down to the metal'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-8562090226406495810</id><published>2006-12-19T23:17:00.000+01:00</published><updated>2006-12-20T18:08:31.227+01:00</updated><title type='text'>Java Closures</title><content type='html'>Java Closures seem to be the buzzword of the moment.&lt;br /&gt;Unfortunately I missed the (I'm told great) JavaPolis conference in Antwerpen, Belgium,  but fortunately the JavaPolis guys have put videos of the sessions &lt;a href="http://www.bejug.org/confluenceBeJUG/display/PARLEYS/Home"&gt;online&lt;/a&gt; !&lt;br /&gt;&lt;br /&gt;I recommend all people interested to watch or listen to &lt;a href="http://gafter.blogspot.com/"&gt;Neal Gafter's&lt;/a&gt; session on closures.&lt;br /&gt;&lt;br /&gt;The very interesting idea behind closures in Java (how they are shaped right now, at least) is the ability to write code that somehow "extends" the Java language syntax itself, adding what look like new keywords to the Java language itself.&lt;br /&gt;Neal Gafter himself said that if closures where in the language before JDK 5, the new &lt;tt&gt;for&lt;/tt&gt; loop syntax would probably not have been introduced.&lt;br /&gt;&lt;br /&gt;How do closures look like ?&lt;br /&gt;&lt;br /&gt;The proposed syntax for the closures in Java allows to write code such as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Collection&amp;lt;T&amp;gt; elements = ...;&lt;br /&gt;forEach (T element : elements) { doSomething(element); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;tt&gt;forEach&lt;/tt&gt; statement here looks like a new keyword of the Java language, but in reality is a method call (assume there is a static import such as &lt;tt&gt;import static java.util.Collections.forEach&lt;/tt&gt;).&lt;br /&gt;&lt;br /&gt;Another example is iterating over entries of a &lt;tt&gt;java.util.Map&lt;/tt&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Map&amp;lt;K, V&amp;gt; props = ...&lt;br /&gt;eachEntry(K key, V value : props) { doSomething(key, value); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where again the &lt;tt&gt;eachEntry&lt;/tt&gt; statement is a static method call to (for example) &lt;tt&gt;java.util.Collections&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;One can even think of replacing the &lt;tt&gt;synchronized&lt;/tt&gt; keyword with the classes from &lt;tt&gt;java.util.concurrent.locks&lt;/tt&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;final Lock lock = ...;&lt;br /&gt;sync(lock) { oneThreadAtATime(); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where &lt;tt&gt;sync&lt;/tt&gt; is a method call, and not a keyword. &lt;br /&gt;It is impressive how closures make &lt;tt&gt;sync&lt;/tt&gt; look like a keyword, when compared to the real &lt;tt&gt;synchronized&lt;/tt&gt; keyword.&lt;br /&gt;&lt;br /&gt;Possibilities are endless: from automatically closing streams, to measuring elapsed time, to adding functional programming to collections, to simplify &lt;tt&gt;java.util.concurrent.Executor&lt;/tt&gt; usage, etc.&lt;br /&gt;&lt;br /&gt;Closures in Java are targeted for JDK 7. Seems strange to say, with JDK 6 released few days ago, but I cannot wait to see closures in Java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-8562090226406495810?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/8562090226406495810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=8562090226406495810' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8562090226406495810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8562090226406495810'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/12/java-closures.html' title='Java Closures'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-8712781654091773903</id><published>2006-12-16T22:00:00.000+01:00</published><updated>2006-12-16T22:06:29.881+01:00</updated><title type='text'>Hibernate blog interview</title><content type='html'>Michele Sciabarrà interviewed me on Hibernate in a short, blog-like style interview available &lt;a href="http://www.javajournal.it/blog/"&gt;here&lt;/a&gt; (in Italian).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-8712781654091773903?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.javajournal.it/blog/' title='Hibernate blog interview'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/8712781654091773903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=8712781654091773903' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8712781654091773903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/8712781654091773903'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/12/hibernate-blog-interview.html' title='Hibernate blog interview'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-5131442541237265266</id><published>2006-11-16T15:09:00.000+01:00</published><updated>2006-11-16T15:16:05.322+01:00</updated><title type='text'>JUG Torino Meeting</title><content type='html'>Today, November 16th, the &lt;a href="http://jugtorino.it"&gt;Java User Group Torino&lt;/a&gt; organizes its nth (we lost the exact count :-) meeting.&lt;br /&gt;&lt;br /&gt;The meeting agenda is composed of a quickie on Subversion, hosted by me, and a session on EJB 3 and J2EE 5 hosted by &lt;a href="http://www.diotalevi.com/weblog/"&gt;Filippo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Check out the meeting details and directions here: &lt;a href="http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingNovembre2006"&gt;http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingNovembre2006&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-5131442541237265266?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingNovembre2006' title='JUG Torino Meeting'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/5131442541237265266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=5131442541237265266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5131442541237265266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5131442541237265266'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/11/jug-torino-meeting.html' title='JUG Torino Meeting'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-5433162628656966417</id><published>2006-11-16T01:03:00.000+01:00</published><updated>2006-11-16T01:14:56.441+01:00</updated><title type='text'>How fast are you ?</title><content type='html'>A friend sent me this link today: &lt;a href="http://www.speedtest.net/"&gt;http://www.speedtest.net/&lt;/a&gt;&lt;br /&gt;How fast are you ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-5433162628656966417?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.speedtest.net/' title='How fast are you ?'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/5433162628656966417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=5433162628656966417' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5433162628656966417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/5433162628656966417'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/11/how-fast-are-you.html' title='How fast are you ?'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-115410661395112258</id><published>2006-07-28T18:33:00.000+02:00</published><updated>2006-11-16T01:01:03.683+01:00</updated><title type='text'>ICMP and InetAddress.isReachable()</title><content type='html'>In Java it is only possible to work with two types of sockets: stream based ones (or TCP ones - &lt;code&gt;java.net.Socket&lt;/code&gt; and &lt;code&gt;java.net.ServerSocket&lt;/code&gt;) and datagram based ones (or UDP ones - &lt;code&gt;java.net.DatagramSocket&lt;/code&gt; and &lt;code&gt;java.net.MulticastSocket&lt;/code&gt;).&lt;br /&gt;The open bug &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4727550"&gt;4727550&lt;/a&gt; asks to support other socket types, that will allow, for example, to perform an ICMP ping and, in general, to access the sockets in raw mode.&lt;br /&gt;&lt;br /&gt;To implement an ICMP ping, a partial solution has been introduced in J2SE 5: a way to check if some address is reachable, via &lt;code&gt;java.net.InetAddress.isReachable()&lt;/code&gt; methods.&lt;br /&gt;The implementation of these methods goes native and tries to do its best to "ping" the address represented by the &lt;code&gt;InetAddress&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Surprisingly, there are many differences between the Windows and the Linux/Unix implementation of &lt;code&gt;java.net.InetAddress.isReachable()&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Windows, as strange as it seems, does not officially support an ICMP "ping" system call. The J2SE 5 implementation hence tries to open a TCP socket on port 7 (the echo service) and hopes to get some sort of reply.&lt;br /&gt;&lt;br /&gt;Linux/Unix, instead, supports an ICMP "ping" system call. So the implementation of &lt;code&gt;java.net.InetAddress.isReachable()&lt;/code&gt; first tries to perform the "ping" system call; if this fails, it falls back trying to open a TCP socket on port 7, as in Windows.&lt;br /&gt;&lt;br /&gt;It turns out that in Linux/Unix the ping system call requires root privileges, so most of the times &lt;code&gt;java.net.InetAddress.isReachable()&lt;/code&gt; will fail, because many Java programs are not run as root, and because the target address unlikely has the echo service up and running. &lt;br /&gt;Too bad.&lt;br /&gt;&lt;br /&gt;But why on Linux, for example, I can use the ping program without being root ? &lt;br /&gt;It's because ping has the &lt;a href="http://en.wikipedia.org/wiki/Setuid"&gt;setuid bit&lt;/a&gt; set:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$&gt; ls -l /bin/ping&lt;br /&gt;-rwsr-xr-x 1 root root 30724 2005-11-11 01:15 /bin/ping&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When a user invokes ping, it will run as root (see the "rws" permission for the owner ?).&lt;br /&gt;&lt;br /&gt;But why on Windows there is a ping executable that does the job ?&lt;br /&gt;It seems that this executable is relying on undocumented features, so everyone tries to avoid binding to those features.&lt;br /&gt;&lt;br /&gt;So, for now, writing portable Java code that wants to send ICMP ping is quite an adventure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-115410661395112258?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/115410661395112258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=115410661395112258' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/115410661395112258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/115410661395112258'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/07/icmp-and-inetaddressisreachable.html' title='ICMP and InetAddress.isReachable()'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-115274853843268437</id><published>2006-07-13T01:08:00.000+02:00</published><updated>2006-11-16T01:01:03.466+01:00</updated><title type='text'>Why Thread.currentThread().getContextClassLoader() ?</title><content type='html'>I recently been involved in a discussion where I questioned that &lt;code&gt;Thread.currentThread().getContextClassLoader()&lt;/code&gt; was the right way to implement the accessibility of a ClassLoader from any point in the code from a thread.&lt;br /&gt;I very much preferred that &lt;code&gt;ClassLoader.getContextClassLoader()&lt;/code&gt; was available, thus freeing class &lt;code&gt;Thread&lt;/code&gt; of any reference to class loading.&lt;br /&gt;&lt;br /&gt;Other examples of accessibility of thread local information are present in the Java libraries, most notably &lt;code&gt;TransactionManager.getTransaction()&lt;/code&gt;, that returns the Transaction currently associated with the thread (though the call is not static).&lt;br /&gt;There is also a RFE for having the &lt;code&gt;Locale&lt;/code&gt; available, see &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6197800"&gt;RFE 6197800&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Both follow the model of not being implemented in class &lt;code&gt;Thread&lt;/code&gt;, so I wonder why for &lt;code&gt;ClassLoader&lt;/code&gt; it was implemented in this way. Some historical reason maybe, and probably right now is not practical to deprecate that call in favor of &lt;code&gt;ClassLoader.getContextClassLoader()&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-115274853843268437?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/115274853843268437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=115274853843268437' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/115274853843268437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/115274853843268437'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/07/why-threadcurrentthreadgetcontextclass.html' title='Why Thread.currentThread().getContextClassLoader() ?'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-115194312721159481</id><published>2006-07-03T17:48:00.000+02:00</published><updated>2006-11-16T01:01:03.248+01:00</updated><title type='text'>JavaDay event in Torino, July 7th</title><content type='html'>&lt;a href="http://www.jugtorino.it"&gt;JUG Torino&lt;/a&gt; is proud to organize the first &lt;a href="http://www.javaday.it"&gt;JavaDay&lt;/a&gt; conference in Torino, on July 7th.&lt;br /&gt;JavaDay travelling conferences will be held (in different dates) in many major cities of Italy, and Torino is the first installment.&lt;br /&gt;&lt;br /&gt;The conference schedule is &lt;a href="http://www.jugtorino.it/vqwiki/jsp/Wiki?JavaDay06"&gt;pretty good&lt;/a&gt;, and features also two international speakers: &lt;span style="font-weight:bold;"&gt;Jason van Zyl&lt;/span&gt; of &lt;a href="http://maven.apache.org"&gt;Maven&lt;/a&gt; fame, and &lt;span style="font-weight:bold;"&gt;Greg Wilkins&lt;/span&gt; of &lt;a href="http://jetty.mortbay.com"&gt;Jetty&lt;/a&gt; and &lt;a href="http://www.webtide.com"&gt;WebTide&lt;/a&gt; fame.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Sessions Highlights&lt;/span&gt;: Object-Oriented development, Ajax, Maven, Jetty, Struts and more.&lt;br /&gt;&lt;br /&gt;The JavaDay conference is free, just register at the &lt;a href="http://www.javaday.it"&gt;JavaDay site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;See you there !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-115194312721159481?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/115194312721159481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=115194312721159481' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/115194312721159481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/115194312721159481'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/07/javaday-event-in-torino-july-7th.html' title='JavaDay event in Torino, July 7th'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-114910795496862292</id><published>2006-05-31T22:23:00.000+02:00</published><updated>2006-11-16T01:01:02.577+01:00</updated><title type='text'>TestNG and Maven</title><content type='html'>I've been working with JDK 5, and some time ago I decided to try &lt;a href="http://testng.org"&gt;TestNG&lt;/a&gt; as test framework, leaving back JUnit.&lt;br /&gt;&lt;br /&gt;Since then, I got addicted to TestNG, and if possible, will never go back to JUnit, as really TestNG is leaps beyond JUnit.&lt;br /&gt;&lt;br /&gt;Now I am working also on a JDK 1.4 application that I build using &lt;a href="http://maven.apache.org"&gt;Maven&lt;/a&gt;.&lt;br /&gt;I've been really impressed by the fact that Maven supports TestNG out of the box, even in JDK 1.4 (using Javadoc annotations). Well, time to convert all tests from JUnit to TestNG, and it's very easy:&lt;br /&gt;&lt;br /&gt;Before:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyTest extends junit.framework.TestCase&lt;br /&gt;{&lt;br /&gt;    public void testSomething() throws Exception&lt;br /&gt;    {&lt;br /&gt;        assertTrue(true);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyTest&lt;br /&gt;{&lt;br /&gt;    /**&lt;br /&gt;     * @testng.test&lt;br /&gt;     */&lt;br /&gt;    public void testSomething() throws Exception&lt;br /&gt;    {&lt;br /&gt;        assert true;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Plus, you get all cool &lt;a href="http://testng.org/doc/documentation-main.html"&gt;TestNG features&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;configurable advice methods (that run before/after the suite, the groups, the class, the test)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;configurable dependencies among tests&lt;/li&gt;&lt;br /&gt;&lt;li&gt;configurable number of runs&lt;/li&gt;&lt;br /&gt;&lt;li&gt;configurable parameters to pass to the test&lt;/li&gt;&lt;br /&gt;&lt;li&gt;...and much more&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-114910795496862292?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/114910795496862292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=114910795496862292' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/114910795496862292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/114910795496862292'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/05/testng-and-maven.html' title='TestNG and Maven'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-114864913623130984</id><published>2006-05-26T14:57:00.001+02:00</published><updated>2008-04-09T15:28:37.878+02:00</updated><title type='text'>Big Changes and 2 Linux hacks</title><content type='html'>Long time, no blog entries.&lt;br /&gt;I have to say that my life changed quite a bit: a newborn baby to take care of (Riccardo), a new job and soon a new house.&lt;br /&gt;&lt;br /&gt;Another thing that I changed (less important than the above, but daily used) is the operative system: I've switched from Microsoft Windows to &lt;a href="http://www.kubuntu.org"&gt;Kubuntu Linux&lt;/a&gt;.&lt;br /&gt;The move was painful, especially at the beginning, and IMHO still not possible for an average user. For my mother it would have been impossible to figure out how to make wifi and video card working, let alone the modem, on my Lenovo T43p.&lt;br /&gt;&lt;br /&gt;However, I recently found 2 useful Linux hacks.&lt;br /&gt;&lt;br /&gt;First Hack: How to avoid duplicate commands in the bash history (when you hit arrow up in a shell).&lt;br /&gt;Open &lt;code&gt;~/.bashrc&lt;/code&gt;; at the beginning of the file there is an entry such as:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;export HISTCONTROL=erasedups&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;It's probably remarked, or has another value. Setting it to 'erasedups' made the hack.&lt;br /&gt;&lt;br /&gt;Second Hack: How to correctly configure /etc/hosts when using DHCP.&lt;br /&gt;It turns out that the dhcp client may run scripts when it binds (and when it releases).&lt;br /&gt;The scripts for binding are &lt;code&gt;/etc/dhcp3/dhclient-enter-hooks&lt;/code&gt;, and all the scripts inside directory &lt;code&gt;/etc/dhcp3/dhclient-enter-hooks.d/&lt;/code&gt;.&lt;br /&gt;Correspondent scripts for releasing are &lt;code&gt;/etc/dhcp3/dhclient-exit-hooks&lt;/code&gt; and those inside directory &lt;code&gt;/etc/dhcp3/dhclient-exit-hooks.d/&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The script &lt;code&gt;dhclient-enter-hooks&lt;/code&gt; was missing in my configuration. I created it and put this inside:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;#&lt;br /&gt;# This script updates /etc/hosts with the address received by the DHCP server&lt;br /&gt;#&lt;br /&gt;HOSTS=/etc/hosts&lt;br /&gt;BACKUP=${HOSTS}.original&lt;br /&gt;LOCAL=${HOSTS}.local&lt;br /&gt;&lt;br /&gt;make_etc_hosts ()&lt;br /&gt;{&lt;br /&gt;   cp -a $HOSTS $BACKUP&lt;br /&gt;   cat &amp;lt;&amp;lt;EOF &amp;gt; $HOSTS&lt;br /&gt;# This file is generated by a script: do no edit; edit instead $LOCAL&lt;br /&gt;# Created by $0 on `date`&lt;br /&gt;127.0.0.1 localhost localhost.localdomain&lt;br /&gt;$new_ip_address `hostname`&lt;br /&gt;&lt;br /&gt;# The following lines are desirable for IPv6 capable hosts&lt;br /&gt;fe00::0 ip6-localnet&lt;br /&gt;ff00::0 ip6-mcastprefix&lt;br /&gt;ff02::1 ip6-allnodes&lt;br /&gt;ff02::2 ip6-allrouters&lt;br /&gt;ff02::3 ip6-allhosts&lt;br /&gt;&lt;br /&gt;# Entries from file $LOCAL, if any&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;   test -f $LOCAL &amp;&amp;amp; cat $LOCAL &gt;&gt; $HOSTS&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if [ "$new_ip_address" ]; then&lt;br /&gt;   make_etc_hosts&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With this script, /etc/hosts gets regenerated every time the dhcp client runs, and assigns the IP address received via DHCP to the hostname of the computer.&lt;br /&gt;Still not perfect (if you have multiple network interfaces), but it's possible to improve it. &lt;br /&gt;For me, for now, does the job :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-114864913623130984?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/114864913623130984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=114864913623130984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/114864913623130984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/114864913623130984'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/05/big-changes-and-2-linux-hacks.html' title='Big Changes and 2 Linux hacks'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-113855505462914612</id><published>2006-01-29T18:06:00.000+01:00</published><updated>2006-11-16T01:01:02.253+01:00</updated><title type='text'>Job Change</title><content type='html'>After more than 6 years in Hewlett-Packard, I decided to resign and take new challenges as a consultant.&lt;br /&gt;&lt;br /&gt;In these 6 years I've professionally learnt a lot and met great colleagues and friends, and I will certainly miss them, though many live in &lt;a href="http://www.torino2006.org"&gt;Torino&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-113855505462914612?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/113855505462914612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=113855505462914612' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/113855505462914612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/113855505462914612'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2006/01/job-change.html' title='Job Change'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-113166095404538215</id><published>2005-11-10T23:13:00.000+01:00</published><updated>2006-11-16T01:01:02.120+01:00</updated><title type='text'>Motion Illusions</title><content type='html'>&lt;a href="http://www.psy.ritsumei.ac.jp/~akitaoka/rotsnake7.gif"&gt;This picture&lt;/a&gt; is truly incredible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-113166095404538215?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://gafter.blogspot.com/2005/02/peripheral-motion-illusions.html' title='Motion Illusions'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/113166095404538215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=113166095404538215' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/113166095404538215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/113166095404538215'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/11/motion-illusions.html' title='Motion Illusions'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-113106110347864078</id><published>2005-11-04T00:16:00.000+01:00</published><updated>2006-11-16T01:01:01.894+01:00</updated><title type='text'>Attaching to a Mustang, explained</title><content type='html'>I was intrigued by &lt;a href="http://blogs.sun.com/roller/page/alanb?entry=getting_started_with_jconsole_just"&gt;this blog&lt;/a&gt;, referenced by &lt;a href="http://weblogs.java.net/blog/emcmanus/archive/2005/09/mustang_jdk_now.html"&gt;Eamonn&lt;/a&gt;, so I decided to take a look at the "attach on demand" feature.&lt;br /&gt;&lt;br /&gt;Since J2SE 5, it is possible to instrument a JVM using an "agent" with the following:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;java -javaagent:&amp;lt;jarpath&amp;gt;[=&amp;lt;options&amp;gt;] &amp;lt;mainclass&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;where &lt;code&gt;&amp;lt;jarpath&amp;gt;&lt;/code&gt; is the path to the jar file containing the agent implementation (absolute, or relative to the directory from where the JVM has been started).&lt;br /&gt;The option can be present multiple times, thus instantiating multiple agents.&lt;br /&gt;&lt;br /&gt;The jar's manifest must contain an entry called &lt;code&gt;Premain-Class&lt;/code&gt; that specifies the full qualified name of the agent implementation class.&lt;br /&gt;A side effect of invoking the JVM with the &lt;code&gt;-javaagent&lt;/code&gt; option is that the jar specified by &lt;code&gt;&amp;lt;jarpath&amp;gt;&lt;/code&gt; is added to the system classpath.&lt;br /&gt;&lt;br /&gt;Agent implementations must have a method called &lt;code&gt;premain&lt;/code&gt; that is called by the JVM before the method &lt;code&gt;main&lt;/code&gt; in &lt;code&gt;&amp;lt;mainclass&amp;gt;&lt;/code&gt; is called.&lt;br /&gt;In J2SE 5, the signature of &lt;code&gt;premain()&lt;/code&gt; must be:&lt;br /&gt;&lt;pre&gt;public static void premain(String options, Instrumentation inst)&lt;/pre&gt;&lt;br /&gt;In J2SE 6 the signature can only be:&lt;br /&gt;&lt;pre&gt;public static void premain(String options)&lt;/pre&gt;&lt;br /&gt;That is, if the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/Instrumentation.html"&gt;instrumentation&lt;/a&gt; implementation is not needed, you can drop it from the signature.&lt;br /&gt;&lt;br /&gt;In J2SE 6, the agent mechanism has been extended so it is possible to invoke agents &lt;span style="font-style:italic;"&gt;after&lt;/span&gt; the JVM has been started, and not only at JVM startup using the &lt;code&gt;-javaagent&lt;/code&gt; option.&lt;br /&gt;&lt;br /&gt;The mechanism is slightly different, and requires use of &lt;code&gt;com.sun.*&lt;/code&gt; classes, so it's specific to Sun's (and derived) JVMs.&lt;br /&gt;Let's take a look at how it works.&lt;br /&gt;&lt;br /&gt;First, we need a reference to the JVMs we want to attach to. This is accomplished with the following code (classes are from &lt;code&gt;com.sun.tools.attach.*&lt;/code&gt; package, shipped in &lt;code&gt;$J2SE6/lib/tools.jar&lt;/code&gt;):&lt;br /&gt;&lt;pre&gt;List&amp;lt;? extends VirtualMachineDescriptor&amp;gt; jvms = VirtualMachine.list();&lt;/pre&gt;&lt;br /&gt;Then it's possible to attach to a JVM using:&lt;br /&gt;&lt;pre&gt;VirtualMachineDescriptor vmd = ...;&lt;br /&gt;VirtualMachine jvm = VirtualMachine.attach(vmd);&lt;/pre&gt;&lt;br /&gt;Once we're attached, we can invoke the agent mechanism using:&lt;br /&gt;&lt;pre&gt;String jarPath = ...;&lt;br /&gt;String options = ...;&lt;br /&gt;jvm.loadAgent(jarPath, options);&lt;/pre&gt;&lt;br /&gt;Once the agent is loaded in the target JVM, we can detach from it:&lt;br /&gt;&lt;pre&gt;jvm.detach();&lt;/pre&gt;&lt;br /&gt;Loading the agent with this mechanism has the same side effect of adding the jar specified by &lt;code&gt;jarPath&lt;/code&gt; to the system classpath.&lt;br /&gt;The jar's manifest file must contain, this time, and entry called &lt;code&gt;Agent-Class &lt;/code&gt; specifying the full qualified name of the agent implementation class.&lt;br /&gt;&lt;br /&gt;However, the agent implementation must be slightly different.&lt;br /&gt;Instead of calling the &lt;code&gt;premain&lt;/code&gt; method, the JVM calls this method:&lt;br /&gt;&lt;pre&gt;public static void agentmain(String options, Instrumentation inst)&lt;/pre&gt;&lt;br /&gt;Again, if you don't need it, you can drop the &lt;code&gt;Instrumentation&lt;/code&gt; argument from the signature.&lt;br /&gt;&lt;br /&gt;Inside &lt;code&gt;agentmain()&lt;/code&gt; it's possible to write any code (with the same restrictions of &lt;code&gt;premain()&lt;/code&gt;), so it's basically possible to do whatever one wants.&lt;br /&gt;&lt;br /&gt;For example, using this mechanism in Mustang allows to do, in any moment, the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;add a jar to the system classpath&lt;/li&gt;&lt;br /&gt;&lt;li&gt;be able to invoke a method of an arbitrary class (the agent)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;It is possible to write a completely empty implementation of &lt;code&gt;agentmain()&lt;/code&gt; just to be able to load new jars on demand.&lt;br /&gt;&lt;br /&gt;Another use is to be able to "hot fix" a running JVM, using the &lt;code&gt;java.lang.instrument.Instrumentation&lt;/code&gt; implementation to replace a malfunctioning class (with the restrictions imposed by the instrumentation mechanism).&lt;br /&gt;&lt;br /&gt;Or can be used to tell to the target JVM to collect information about what is doing and dump it somewhere for statistical/monitoring purposes.&lt;br /&gt;&lt;br /&gt;In Mustang there is an example of this mechanism to start a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/JMXConnectorServer.html"&gt;JMXConnectorServer&lt;/a&gt;, so that the JVM becomes remotely manageable. The jar is shipped in &lt;code&gt;$J2SE6/jre/lib/management-agent.jar&lt;/code&gt; and it's completely empty (apart the manifest file) since the agent implementation is shipped in &lt;code&gt;rt.jar&lt;/code&gt; (it's the &lt;code&gt;sun.management.Agent&lt;/code&gt; class).&lt;br /&gt;&lt;br /&gt;Feel free to drop a comment if you have other cool ideas of how to use this mechanism !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-113106110347864078?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/113106110347864078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=113106110347864078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/113106110347864078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/113106110347864078'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/11/attaching-to-mustang-explained.html' title='Attaching to a Mustang, explained'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-112144864774992430</id><published>2005-07-15T19:10:00.000+02:00</published><updated>2006-11-16T01:01:01.701+01:00</updated><title type='text'>A weird particular in java.util.concurrent</title><content type='html'>I am using J2SE 5, and so far I am quite happy. I got used to the generics syntax, and in general I can write less code to do the same things.&lt;br /&gt;&lt;br /&gt;While browsing &lt;code&gt;java.util.concurrent&lt;/code&gt; source code, I found this weird pattern:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class LinkedBlockingQueue&lt;E&gt; extends ...&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;  private final ReentrantLock takeLock = new ReentrantLock();&lt;br /&gt;  ...&lt;br /&gt;&lt;br /&gt;  private void signalNotEmpty() &lt;br /&gt;  {&lt;br /&gt;    final ReentrantLock takeLock = this.takeLock;&lt;br /&gt;    takeLock.lock();&lt;br /&gt;    try &lt;br /&gt;    {&lt;br /&gt;      notEmpty.signal();&lt;br /&gt;    } &lt;br /&gt;    finally &lt;br /&gt;    {&lt;br /&gt;      takeLock.unlock();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The more I looked at the code, the more it seemed to me unnecessary to declare that final local variable in the &lt;code&gt;signalNotEmpty()&lt;/code&gt; method.&lt;br /&gt;The data member is already final, so it's not a question of visibility in multithread environments.&lt;br /&gt;&lt;br /&gt;I decided to investigate more, and went back to &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/"&gt;Bill Pugh's site&lt;/a&gt;, which contains a lot of information about the java memory model and its revision through JSR 133, but I had no luck.&lt;br /&gt;&lt;br /&gt;Finally I discovered that JSR 166 implementation is also under public domain, &lt;a href="http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The CVS log that added the weird pattern above is marked in this cryptic comment:&lt;br /&gt;&lt;br /&gt;"cache finals across volatiles"&lt;br /&gt;&lt;br /&gt;Now, if you have some information about, please drop a comment.&lt;br /&gt;&lt;br /&gt;This reminds me what JSR 133 experts were saying about the memory model: that not even the JLS writers understood it.&lt;br /&gt;Now I am certain that few more people understand it (e.g. Doug Lea, Bill Pugh), but - alas - I guess they can be counted with just one hand.&lt;br /&gt;&lt;br /&gt;I'll let you informed if I found a solution to this arcane.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Doug Lea had the courtesy to answer to my request for clarification. His answer:&lt;br /&gt;&lt;br /&gt;"This was a hopefully temporary performance hack due to a limitation in JVMs that don't realize that final fields are an exception to the rule that you must re-read fields after reading a volatile. &lt;br /&gt;These JVMs, including 1.5.0 hotspot are correct wrt the memory model but inefficient unless helped out in this ugly/weird way. Someday these can disappear. It's&lt;br /&gt;only worth bothering (and even then only sometimes, and even then only marginally so)&lt;br /&gt;for performance-critical code like that inside j.u.c.&lt;br /&gt;It's not a recommended practice."&lt;br /&gt;&lt;br /&gt;It happens that &lt;code&gt;notEmpty.signal()&lt;/code&gt; reads volatile fields and the JVM implementation inefficiently re-reads &lt;code&gt;takeLock&lt;/code&gt; to execute &lt;code&gt;takeLock.unlock()&lt;/code&gt; in the finally block.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-112144864774992430?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/112144864774992430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=112144864774992430' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/112144864774992430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/112144864774992430'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/07/weird-particular-in-javautilconcurrent.html' title='A weird particular in java.util.concurrent'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-111429696205434598</id><published>2005-04-24T00:09:00.000+02:00</published><updated>2006-11-16T01:01:01.391+01:00</updated><title type='text'>Enums as factories</title><content type='html'>I started to enjoy very much J2SE 5, especially generics, &lt;code&gt;enum&lt;/code&gt;s and the &lt;code&gt;java.util.concurrent&lt;/code&gt; package.&lt;br /&gt;&lt;br /&gt;I still don't get static imports, but overall J2SE 5 is been a good experience.&lt;br /&gt;&lt;br /&gt;One thing I found nice about &lt;code&gt;enum&lt;/code&gt;s is the possibility to use them as factories in a simple way.&lt;br /&gt;&lt;br /&gt;For example, &lt;a href="http://www.opensymphony.com/webwork"&gt;Webwork 2&lt;/a&gt; can be configured to use 3 different multipart parsers.&lt;br /&gt;The configuration option is called &lt;code&gt;webwork.multipart.parser&lt;/code&gt; and can have one of 3 possible values: &lt;code&gt;pell&lt;/code&gt;, &lt;code&gt;jakarta&lt;/code&gt; or &lt;code&gt;cos&lt;/code&gt;.&lt;br /&gt;The 3 implementation classes extends the class &lt;code&gt;com.opensymphony.webwork.dispatcher.multipart.MultiPartRequest&lt;/code&gt; so it's possible to write the following &lt;code&gt;enum&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public enum MultipartParsers&lt;br /&gt;{&lt;br /&gt;   PELL(PellMultiPartRequest.class),&lt;br /&gt;   JAKARTA(JakartaMultiPartRequest.class),&lt;br /&gt;   COS(CosMultiPartRequest.class);&lt;br /&gt;&lt;br /&gt;   private final Class&amp;lt;? extends MultiPartRequest&amp;gt; parserClass;&lt;br /&gt;&lt;br /&gt;   private MultipartParser(Class&amp;lt;? extends MultiPartRequest&amp;gt; parserClass)&lt;br /&gt;   {&lt;br /&gt;      this.parserClass = parserClass;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public MultiPartRequest newInstance()&lt;br /&gt;   {&lt;br /&gt;      return parserClass.newInstance();&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using this class is very simple, given the following configuration:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;webwork.multipart.parser=pell&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A &lt;code&gt;Configuration&lt;/code&gt; class can read the configuration, and creating the multipart parser is then very easy:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;String parser = Configuration.getString("webwork.multipart.parser");&lt;br /&gt;MultiPartRequest multipart = MultiPartParsers.valueOf(parser.toUpperCase()).newInstance();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note the &lt;code&gt;MultiPartParsers.valueOf()&lt;/code&gt; method, which is generated by the compiler for each &lt;code&gt;enum&lt;/code&gt; class: it takes a string and returns the &lt;code&gt;enum&lt;/code&gt; instance whose name matches the string.&lt;br /&gt;Using &lt;code&gt;MultiPartParsers.valueOf()&lt;/code&gt; avoid &lt;code&gt;switch&lt;/code&gt; statements or chained &lt;code&gt;if/else&lt;/code&gt; statements.&lt;br /&gt;The possibility to use more verbose values (like 'pell' or 'jakarta') is definitely more appealing than using integer values (like '1' or '2') to distinguish parsers.&lt;br /&gt;&lt;br /&gt;I have used this pattern also for commands, and the &lt;code&gt;newInstance()&lt;/code&gt; method can take parameters to initialize the newly created instance, or even a vararg parameters.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public enum Commands&lt;br /&gt;{&lt;br /&gt;   UPDATE(UpdateCommand.class),&lt;br /&gt;   INSERT(InsertCommand.class),&lt;br /&gt;   ...&lt;br /&gt;   DELETE(DeleteCommand.class);&lt;br /&gt;&lt;br /&gt;   private final Class&amp;lt;? extends Command&amp;gt; commandClass;&lt;br /&gt;&lt;br /&gt;   private MultipartParser(Class&amp;lt;? extends Command&amp;gt; commandClass)&lt;br /&gt;   {&lt;br /&gt;      this.commandClass = commandClass;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public Command newInstance(Configuration config)&lt;br /&gt;   {&lt;br /&gt;      Command command = commandClass.newInstance();&lt;br /&gt;      command.configure(config);&lt;br /&gt;      return command;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-111429696205434598?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/111429696205434598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=111429696205434598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/111429696205434598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/111429696205434598'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/04/enums-as-factories.html' title='Enums as factories'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-111058462393491759</id><published>2005-03-12T00:18:00.000+01:00</published><updated>2006-11-16T01:01:01.188+01:00</updated><title type='text'>Negatable Marker Annotations</title><content type='html'>&lt;a href="http://www.artima.com/weblogs/index.jsp?blogger=dichotomy"&gt;Eamonn&lt;/a&gt; has posted a very interesting blog entry on negatable annotations.&lt;br /&gt;&lt;br /&gt;In the last part of the post, he suggests that such a marker annotation can be used to annotate an MBean-like interface to say that it really is (or not) an MBean interface.&lt;br /&gt;&lt;br /&gt;Such a marker annotation should be meta-annotated with &lt;code&gt;@Inherited&lt;/code&gt;, since it would be inherited, but unfortunately &lt;code&gt;@Inherited&lt;/code&gt; only works if the annotation annotates a class, not an interface.&lt;br /&gt;&lt;br /&gt;I wonder if Eamonn meant to annotate the class, more or less this way:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@Inherited&lt;br /&gt;public @interface MBean &lt;br /&gt;{&lt;br /&gt;  boolean value() default true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@MBean&lt;br /&gt;public class BaseService&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@MBean(false)&lt;br /&gt;public class DerivedService extends BaseService&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In plain JMX, it would be impossible for the MBeanServer to avoid to register DerivedService as MBean.&lt;br /&gt;But a negatable marker annotation enabled MBeanServer can avoid the registration following Eamonn's suggestion:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Class c = mbean.getClass();&lt;br /&gt;MBean ann = c.getAnnotation(MBean.class);&lt;br /&gt;boolean isMBean = (ann != null &amp;&amp; ann.value());&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-111058462393491759?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.artima.com/weblogs/viewpost.jsp?thread=98061' title='Negatable Marker Annotations'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/111058462393491759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=111058462393491759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/111058462393491759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/111058462393491759'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/03/negatable-marker-annotations.html' title='Negatable Marker Annotations'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110812469417229024</id><published>2005-02-11T13:21:00.000+01:00</published><updated>2006-11-16T01:01:00.998+01:00</updated><title type='text'>Do you think it's space you're living in ?</title><content type='html'>Paraphrasing Morpheus, the article at the link above poses some doubt about universe dimensions, or at least on the current theories.&lt;br /&gt;Interesting reading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110812469417229024?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.sciscoop.com/story/2005/1/11/203016/780' title='Do you think it&apos;s space you&apos;re living in ?'/><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110812469417229024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110812469417229024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110812469417229024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110812469417229024'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/02/do-you-think-its-space-youre-living-in.html' title='Do you think it&apos;s space you&apos;re living in ?'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110651875539172695</id><published>2005-01-23T23:19:00.000+01:00</published><updated>2006-11-16T01:01:00.862+01:00</updated><title type='text'>PNG transparency in Internet Explorer</title><content type='html'>&lt;a href="http://www.libpng.org/pub/png/"&gt;PNG&lt;/a&gt; is the format of the icons we use in one of our applications.&lt;br /&gt;I develop the application using &lt;a href="http://www.mozilla.org"&gt;Firefox&lt;/a&gt;, since it has a powerful plugin: the &lt;a href="http://www.chrispederick.com/work/firefox/webdeveloper/"&gt;web developer&lt;/a&gt;.&lt;br /&gt;However, the application will almost certainly be displayed in Internet Explorer, which is unable to display correctly PNG icons, in particular cannot render correctly the PNG transparency.&lt;br /&gt;&lt;br /&gt;While surfing the internet in search of a solution, I found this site: &lt;a href="http://dean.edwards.name/IE7"&gt;IE7&lt;/a&gt;.&lt;br /&gt;Quite impressive the number of features it fixes on Internet Explorer, and I'd like to know if someone has used it and what impressions has got of IE7.&lt;br /&gt;&lt;br /&gt;We fixed the PNG transparency problem in another way, using a script present at &lt;a href="http://homepage.ntlworld.com/bobosola/"&gt;this URL&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110651875539172695?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110651875539172695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110651875539172695' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110651875539172695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110651875539172695'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/01/png-transparency-in-internet-explorer.html' title='PNG transparency in Internet Explorer'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110563706484128737</id><published>2005-01-13T18:00:00.000+01:00</published><updated>2006-11-16T01:01:00.675+01:00</updated><title type='text'>The MBeanServer of a J2EE Application Server</title><content type='html'>During JavaPolis, I've had the chance to discuss with &lt;a href="http://www.artima.com/weblogs/index.jsp?blogger=dichotomy"&gt;Eamonn&lt;/a&gt;, and he &lt;br /&gt;brought to the discussion that right now there is no standard way to access the MBeanServer that is normally instantiated by a J2EE application server.&lt;br /&gt;&lt;br /&gt;Take a servlet or a session EJB, they can only try to call&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;List mbeanServers = MBeanServer.findMBeanServer(null);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and guess which one of the MBeanServers contained in the List is the application server's one.&lt;br /&gt;As an example, the above call returns one MBeanServer (the Application Server's) in J2SE 1.4, but returns two in J2SE 5.0 (the platform MBeanServer and the Application Server's).&lt;br /&gt;&lt;br /&gt;We were discussing that 'something' can be registered in the naming service, say&lt;br /&gt;under java:comp/env/jmx/whatever.&lt;br /&gt;That 'something' can be something new, but that would require new JMX classes (or new J2EE classes): not ideal, since they will be available only in the future, and not widely adopted for a longer time.&lt;br /&gt; &lt;br /&gt;Another solution we discussed was to register in JNDI a JMXConnector, already defined by JSR 160 and present in J2SE 5.&lt;br /&gt;A J2EE specification (most likely JSR 77) may reserve a protocol, say 'j2ee', for such a JMXConnector. JMXServiceURLs would look like service:jmx:j2ee://host/jndi/whatever.&lt;br /&gt;&lt;br /&gt;Specifying a new protocol allows the application server to have full control on the implementation, for example to filter method calls (e.g. to avoid to mess with the Application Server's MBeans).&lt;br /&gt;The binding to the naming service can be defined in a new element in the J2EE deployment&lt;br /&gt;descriptor, and the usual J2EE stuff can be applied with regards to security (I don't think any transaction is needed, nor any thread control, etc.).&lt;br /&gt;&lt;br /&gt;A client application can lookup the JMXConnector, and then connect (possibly providing credentials), and then use the standard API to register, query, unregister, invoke methods on MBeans, if the application server allows that.&lt;br /&gt;&lt;br /&gt;Using standardized classes (JSR 160 classes), standardizing the lookup mechanism (defining a java:comp/env/jmx context) and reserving the JMXServiceURL protocol are the first steps I think, but they're enough, probably, to provide a first implementation by application servers.&lt;br /&gt;A maintenance release of JSR 77 can decide/standardize more, if needed.&lt;br /&gt;&lt;br /&gt;However, application servers like &lt;a href="http://geronimo.apache.org"&gt;Geronimo&lt;/a&gt; may already try to implement this solution and provide good feedback on pros and cons of this solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110563706484128737?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110563706484128737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110563706484128737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110563706484128737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110563706484128737'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/01/mbeanserver-of-j2ee-application-server.html' title='The MBeanServer of a J2EE Application Server'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110462364843824057</id><published>2005-01-02T01:38:00.000+01:00</published><updated>2006-11-16T01:01:00.512+01:00</updated><title type='text'>Ennio Morricone's concert</title><content type='html'>I have enjoyed &lt;span style="font-weight:bold"&gt;very&lt;/span&gt; much the concert master Ennio Morricone gave for end year's day in Rome.&lt;br /&gt;I like very much soundtracks, especially from those great composers such as Ennio Morricone, Hans Zimmer, Danny Elfman, James Horner.&lt;br /&gt;These 4 persons have written most of the soundtracks of the major movies around in the last 10-15 (if not more) years: quite amazing.&lt;br /&gt;While listening to the concert, I was thinking of the privilege that the orchestra has to play and to be directed by the composer itself: not an interpretation, but the composer himself that tells "I want it this way".&lt;br /&gt;&lt;br /&gt;If you like listening music during Java programming, I recommend to buy some soundtrack by those 4 guys: you won't be disappointed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110462364843824057?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110462364843824057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110462364843824057' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110462364843824057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110462364843824057'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/01/ennio-morricones-concert.html' title='Ennio Morricone&apos;s concert'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110462213855374097</id><published>2005-01-02T01:02:00.000+01:00</published><updated>2006-11-16T01:01:00.354+01:00</updated><title type='text'>JavaPolis day 4 &amp; 5</title><content type='html'>&lt;span style="font-weight:bold"&gt;Garbage Collection with JRockit&lt;/span&gt;&lt;br /&gt;Joakim Dahlstedt gave a really good session on memory management and garbage collection on modern JVMs, with particular reference to JRockit.&lt;br /&gt;While I'm quite up-to-date with the JVM technologies (from the user point of view) it's always interesting to listen to the expert (that make the technology).&lt;br /&gt;In particular, it is now quite amazing the level that modern JVMs have reached, especially JRockit.&lt;br /&gt;One thing (among many others) that has stunned me is that JRockit can change the GC algorithm on the fly, while the JVM is running, to adapt to the system runtime load.&lt;br /&gt;Their goal is to keep GC pauses below 50ms for 99.999% of the time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold"&gt;Offshore Java Development&lt;/span&gt;&lt;br /&gt;Vincent Massol (of Cactus and Maven fame) gave a very interesting session on working with offshore (in this case with India) developers in Java projects.&lt;br /&gt;He stressed the importance of the communications and of creating one single team (not "us" and "they", but just "us").&lt;br /&gt;Vincent also gave very practical suggestions on when it is the case to use an offshore team, and how to organize things to work with an offshore team.&lt;br /&gt;Special importance on software engineering and using tools at their best: test coverage tools, bug finding tools, bug reporting tools, instant messaging, continuous integration frameworks are few he mentioned.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110462213855374097?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110462213855374097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110462213855374097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110462213855374097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110462213855374097'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/01/javapolis-day-4-5.html' title='JavaPolis day 4 &amp; 5'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110457721135059363</id><published>2005-01-01T11:24:00.000+01:00</published><updated>2006-11-16T01:01:00.153+01:00</updated><title type='text'>JavaPolis day 3</title><content type='html'>&lt;span style="font-weight:bold"&gt;Open Source Java Programming&lt;/span&gt;&lt;br /&gt;&lt;a href="http://blogs.atlassian.com/rebelutionary/"&gt;Mike Cannon-Brooks&lt;/a&gt; of &lt;a href="http://www.atlassian.com"&gt;Atlassian&lt;/a&gt; gave a great session on using open source to develop (in particular web) applications in Java.&lt;br /&gt;Often, developers tend to use the open source library as is, sticking to the default implementation the library provides.&lt;br /&gt;But more often, open source libraries provide extension points that can be used to extend its behavior in a way that is more suited to developer's needs; it is just a matter of knowing at best what you're using for your daily development, since it can save a lot of time !&lt;br /&gt;Checkout Atlassian's open source stuff at &lt;a href="http://opensource.atlassian.com"&gt;http://opensource.atlassian.com&lt;/a&gt;: great stuff.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold"&gt;&lt;a href="http://groovy.codehaus.org"&gt;Groovy&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://radio.weblogs.com/0112098"&gt;James Strachan&lt;/a&gt; and &lt;a href="http://www.almaer.com/blog"&gt;Dion Almaer&lt;/a&gt; gave a friendly introduction to Groovy.&lt;br /&gt;This language is growing and certainly needs attention (despite &lt;a href="http://jroller.com/page/fate"&gt;Hani&lt;/a&gt;'s bashing ;-). &lt;br /&gt;James and Dion like to be on the stage, and are brave enough to have introduced GStrings in Groovy :-D&lt;br /&gt;Jokes apart, it is quite amazing the number of uses that one can make of Groovy, so if you have some free time, go check it out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110457721135059363?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110457721135059363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110457721135059363' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110457721135059363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110457721135059363'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2005/01/javapolis-day-3.html' title='JavaPolis day 3'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110307041625270895</id><published>2004-12-15T01:45:00.000+01:00</published><updated>2006-11-16T01:01:00.002+01:00</updated><title type='text'>JavaPolis day 2</title><content type='html'>&lt;span style="font-weight:bold;"&gt;&lt;a href="http://www.springframework.org"&gt;Spring&lt;/a&gt; in Action&lt;/span&gt;&lt;br /&gt;Juergen Hoeller and Rod Johnson gave a good introduction to Spring.&lt;br /&gt;I am a Spring newbie, so this session was interesting for me, although quite for beginners. I definitely have to study deeper the matter. &lt;br /&gt;Especially seems to me that Spring (but I guess also other lightweight containers such as &lt;a href="http://jakarta.apache.org/hivemind"&gt;HiveMind&lt;/a&gt;) gathers good ol' ideas into a comfortable place one can call "framework".&lt;br /&gt;&lt;a href="http://opensymphony.com/webwork"&gt;WebWork1&lt;/a&gt; uses *Aware interfaces (not necessarily introduced before Spring, but I think independently), &lt;a href="http://jetty.mortbay.com"&gt;Jetty&lt;/a&gt; uses XML configuration files (same as above) and so on.&lt;br /&gt;Spring ties this and much much more together and gives you a comfortable place to put together your components.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;a href="http://hibernate.org"&gt;Hibernate&lt;/a&gt; in Action&lt;/span&gt;&lt;br /&gt;&lt;a href="http://blog.hibernate.org"&gt;Gavin King and Christian Bauer&lt;/a&gt; gave an introduction to Hibernate2 with some glance to Hibernate3 and to EJB3.&lt;br /&gt;Especially these glances make unmissable their next presentation focused on Hibernate3, since with use of annotations the XML mapping files become history and the entity class ridiculously simple (and similarly will EJB3 entity classes).&lt;br /&gt;Among many new features, Hibernate3 will have filters (never had the problem of filtering the resultset basing - for example - on some property of the user that logged in ?), a complete event model for relevant actions done to the object graph,  JMX performance statistics on queries (how many time each one, how long it took, etc), and much more.&lt;br /&gt;&lt;span style="text-decoration:underline"&gt;Christian's tip of the session&lt;/span&gt;: check out what the "any type mapping" does in Hibernate, sometimes can be useful.&lt;br /&gt;&lt;span style="text-decoration:underline"&gt;Christian's warning of the session&lt;/span&gt;: always use a DB with referential constraints. Remove referential constraints, but then be prepared to see this sentence written on the next door you want to open: "Lasciate ogni speranza, o voi ch'entrate".&lt;br /&gt;&lt;span style="text-decoration:underline"&gt;Gavin's statement of the session&lt;/span&gt; was that JDO vendors should provide a path of migration from JDO to EJB3 since that will be the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110307041625270895?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110307041625270895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110307041625270895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110307041625270895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110307041625270895'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/12/javapolis-day-2.html' title='JavaPolis day 2'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110306788941650023</id><published>2004-12-15T01:23:00.000+01:00</published><updated>2006-11-16T01:00:59.850+01:00</updated><title type='text'>JavaPolis day 1</title><content type='html'>I'm in Antwerp, Belgium, at &lt;a href="http://wiki.javapolis.com"&gt;JavaPolis&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;JDK 5 in Action&lt;/span&gt;&lt;br /&gt;Joshua Bloch and &lt;a href="http://gafter.blogspot.com"&gt;Neal Gafter&lt;/a&gt; are always a pleasure to listen to. They like the stage, and you can feel that.&lt;br /&gt;The main presentation covered basic JDK 5 stuff, and Neal gave a small presentation on generic wildcards, quite interesting. Much information has been written on the topic (see my previous post on the java generics FAQ), but it was a good reminder, especially if you don't use JDK 5 every day.&lt;br /&gt;Did you know that iterators in java.util.concurrent.* are "weakly consistent" and not "fail fast" as they are in java.util.* ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;a href="http://www.javablackbelt.com"&gt;JavaBlackBelt&lt;/a&gt; BOF&lt;/span&gt;&lt;br /&gt;These guys have an interesting idea that can help people (like me) that interviews Java developers for a possible 3rd party contract on a project, without loosing so much time on people with overboosted CVs (never matched in reality). Something to keep an eye on.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110306788941650023?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110306788941650023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110306788941650023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110306788941650023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110306788941650023'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/12/javapolis-day-1.html' title='JavaPolis day 1'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110159920419060113</id><published>2004-11-28T01:05:00.001+01:00</published><updated>2006-11-16T01:00:59.695+01:00</updated><title type='text'>Integrating JOTM 1.5.3 in Tomcat 5.0.x</title><content type='html'>Recently I have integrated &lt;a href="http://jakarta.apache.org/tomcat"&gt;Tomcat 5.0.x&lt;/a&gt; with &lt;a href="http://jotm.objectweb.org"&gt;JOTM 1.5.3&lt;/a&gt;, running on J2SE 1.4.2.&lt;br /&gt;&lt;br /&gt;Needless to say, &lt;a href="http://www.mortbay.com/MB/log/gregw"&gt;Greg&lt;/a&gt; already provides the &lt;a href="http://jetty.mortbay.org/jetty/download.html"&gt;Jetty-Extra&lt;/a&gt; package which already provides the Jetty-JOTM integration.&lt;br /&gt;&lt;br /&gt;The steps for Tomcat-JOTM integration are the following:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Copy to &lt;code&gt;$TOMCAT/common/lib&lt;/code&gt; the following jars:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;carol.jar&lt;/li&gt;&lt;br /&gt;&lt;li&gt;connector-1_5.jar&lt;/li&gt;&lt;br /&gt;&lt;li&gt;jotm.jar&lt;/li&gt;&lt;br /&gt;&lt;li&gt;jta-spec1_0_1.jar&lt;/li&gt;&lt;br /&gt;&lt;li&gt;objectweb-datasource.jar&lt;/li&gt;&lt;br /&gt;&lt;li&gt;xapool.jar&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;I found that carol does not need any stub since it works in local mode (see below).&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Create a &lt;code&gt;carol.properties&lt;/code&gt; file in &lt;code&gt;$TOMCAT/common/classes&lt;/code&gt; containing the following text:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# lmi stands for Local Method Invocation (it's a "fake" RMI)&lt;br /&gt;carol.protocols=lmi&lt;br /&gt;&lt;br /&gt;# do not use CAROL JNDI wrapper&lt;br /&gt;carol.start.jndi=false&lt;br /&gt;&lt;br /&gt;# do not start a name server&lt;br /&gt;carol.start.ns=false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Configure Tomcat's Context (either in &lt;code&gt;$TOMCAT/conf/server.xml&lt;/code&gt; or in &lt;code&gt;$TOMCAT/conf/Catalina/localhost/&amp;lt;mywebapp&amp;gt;.xml&lt;/code&gt; file) so that a UserTransaction object is bound in JNDI, as shown below:&lt;br /&gt;&lt;div style="font-size:11px; overflow:auto"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;Context ...&amp;gt;&lt;br /&gt;  &amp;lt;Resource name="jdbc/mysql" auth="Container" type="javax.sql.DataSource"/&amp;gt;&lt;br /&gt;  &amp;lt;ResourceParams name="jdbc/mysql"&amp;gt;&lt;br /&gt;      ...&lt;br /&gt;  &amp;lt;/ResourceParams&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction"/&amp;gt;&lt;br /&gt;  &amp;lt;ResourceParams name="UserTransaction"&amp;gt;&lt;br /&gt;    &amp;lt;parameter&amp;gt;&lt;br /&gt;      &amp;lt;name&amp;gt;factory&amp;lt;/name&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;org.objectweb.jotm.UserTransactionFactory&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/parameter&amp;gt;&lt;br /&gt;    &amp;lt;parameter&amp;gt;&lt;br /&gt;      &amp;lt;name&amp;gt;jotm.timeout&amp;lt;/name&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;60&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/parameter&amp;gt;&lt;br /&gt;  &amp;lt;/ResourceParams&amp;gt;&lt;br /&gt;&amp;lt;/Context&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Normally there is also a DataSource configured, and this DataSource is also referenced in &lt;code&gt;WEB-INF/web.xml&lt;/code&gt;, but that should be there independently of the transaction manager.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;It is that simple.&lt;br /&gt;&lt;br /&gt;It is very important &lt;span style="font-weight:bold;"&gt;not&lt;/span&gt; to include jotm.jar in WEB-INF/lib of your application.&lt;br /&gt;&lt;br /&gt;If you want to see some extra logging to be sure everything went fine, just drop &lt;a href="http://logging.apache.org/log4j"&gt;Log4J&lt;/a&gt;'s jar into &lt;code&gt;$TOMCAT/common/lib&lt;/code&gt; and add a &lt;code&gt;log4j.properties&lt;/code&gt; in &lt;code&gt;$TOMCAT/common/classes&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Jetty|Tomcat + JOTM + Hibernate does the job for me :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110159920419060113?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110159920419060113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110159920419060113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110159920419060113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110159920419060113'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/11/integrating-jotm-153-in-tomcat-50x_28.html' title='Integrating JOTM 1.5.3 in Tomcat 5.0.x'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-110054819834851420</id><published>2004-11-15T20:30:00.000+01:00</published><updated>2006-11-16T01:00:59.292+01:00</updated><title type='text'>Layout without tables using CSS</title><content type='html'>I am playing with CSS to find the easiest way to layout a common disposition of &amp;lt;div&amp;gt;s for a web page.&lt;br /&gt;I need a simple layout made of a header on top (width 100%); in the middle a left part that will hold a tree (say width 25%) and a content part (say width 75%) on the right; a footer at bottom (also width 100%).&lt;br /&gt;&lt;br /&gt;Needless to say, it's very easy to obtain this using a &amp;lt;table&amp;gt;, but I wanted to go one step further and use CSS only.&lt;br /&gt;&lt;br /&gt;Googling "columns css" returns a lot of stuff, most notably &lt;a href="http://css-discuss.incutio.com/?page=ThreeColumnLayouts"&gt;this page&lt;/a&gt;, which compares various solutions.&lt;br /&gt;&lt;br /&gt;The one I've settled with, since it fits my needs, is this:&lt;br /&gt;&lt;pre style="font-size: 10px;"&gt;&lt;br /&gt;&amp;lt;div id="header" style="background:#AAA;"&amp;gt;HEADER&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="container" style="background: #EEE"&amp;gt;&lt;br /&gt; &amp;lt;div id="left" style="background: #EEE; float:left; width:100px; overflow:auto; border-right:2px solid black"&amp;gt;LEFT&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div id="content" style="background: white; margin-left:100px; border-left:2px solid black"&amp;gt;CONTENT&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="footer" style="background:#AAA; clear:both"&amp;gt;FOOTER&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nothing special about the header.&lt;br /&gt;The container has the same background as the left, so that if the content expands vertically, then the left column expands as well keeping its background.&lt;br /&gt;The left is floating left with a specified width. The same width is the left margin of content (if you want borders/padding you must tweak the content left margin).&lt;br /&gt;The borders of left and content overlaps (and this really surprised me) to form a unique border.&lt;br /&gt;The background of the body and the background of the content should be the same.&lt;br /&gt;Finally, the footer must be clear:both so that no matter if left or content is higher, it will always stays below.&lt;br /&gt;&lt;br /&gt;It works fine in Firefox 1.0 and IE6. If you have feedback about Mac, IE5 and Opera, will be great.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-110054819834851420?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/110054819834851420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=110054819834851420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110054819834851420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/110054819834851420'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/11/layout-without-tables-using-css.html' title='Layout without tables using CSS'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-109932588108976103</id><published>2004-11-01T17:18:00.000+01:00</published><updated>2006-11-16T01:00:59.052+01:00</updated><title type='text'>Online bookmarks, which one ?</title><content type='html'>I've come to a point that I really need to save my bookmarks online, since I have to deal with at least 3 computers.&lt;br /&gt;&lt;br /&gt;Today I spent some time to browse the internet looking for a solution that fitted my needs.&lt;br /&gt;Needless to say there are many, and I mean &lt;a href="http://www.lights.com/pickalink/bookmarks"&gt;really many&lt;/a&gt;, online bookmarks sites out there.&lt;br /&gt;&lt;br /&gt;I have looked at &lt;a href="http://www.pluck.com/"&gt;Pluck&lt;/a&gt;, but found negative recension about its functionality.&lt;br /&gt;Then &lt;a href="http://www.spurl.net/"&gt;Spurl&lt;/a&gt;, but it's not possible to have private bookmarks.&lt;br /&gt;Same for &lt;a href="http://del.icio.us/"&gt;del.icio.us&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://www.blinkto.com/"&gt;BlinkTo&lt;/a&gt; has the opposite problem, it's not possible to share bookmarks with others.&lt;br /&gt;&lt;br /&gt;I've seen many others, but finally settled with &lt;a href="http://www.furl.net/"&gt;Furl&lt;/a&gt;, also seeing that people using it are quite happy.&lt;br /&gt;It is possible to decide to keep a bookmark private or public, it has RSS and search capabilities, bookmarks can be shared with others, it's possible to import/export bookmarks from many formats and many other features.&lt;br /&gt;Furthermore, it has a &lt;a href="http://www.getfirefox.com/"&gt;Firefox&lt;/a&gt; plugin that makes its usage quite simple.&lt;br /&gt;&lt;br /&gt;Now it's time to use it and see if I've made the right choice.&lt;br /&gt;&lt;br /&gt;Which online bookmarks site do you use ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-109932588108976103?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/109932588108976103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=109932588108976103' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109932588108976103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109932588108976103'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/11/online-bookmarks-which-one.html' title='Online bookmarks, which one ?'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-109923146599773033</id><published>2004-10-31T15:04:00.000+01:00</published><updated>2006-11-16T01:00:58.820+01:00</updated><title type='text'>MotoGP championship's end</title><content type='html'>Today in Valencia the 2004 MotoGP championship ended.&lt;br /&gt;&lt;br /&gt;Valentino Rossi dominated the season and this last race; present in the paddocks, among other VIPs, Michael Jordan (former NBA player).&lt;br /&gt;Valentino took the chance to scare Michael to death when they went for a couple of laps on the track with a car (Valentino was driving): Jordan run, literally run, out of the car at the moment Valentino stopped the car :-)&lt;br /&gt;&lt;br /&gt;I've once read of Michael Jordan that he was the man that did his job better than any other man in the world.&lt;br /&gt;It is probably a sign that today he was present in Valencia, passing this definition to another man that really demonstrated to deserve it: Valentino.&lt;br /&gt;&lt;br /&gt;Che Spettacolo !&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-109923146599773033?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/109923146599773033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=109923146599773033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109923146599773033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109923146599773033'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/10/motogp-championships-end.html' title='MotoGP championship&apos;s end'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-109909419778722292</id><published>2004-10-30T01:11:00.000+02:00</published><updated>2006-11-16T01:00:58.628+01:00</updated><title type='text'>JavaLobby Restyle</title><content type='html'>I have noticed that &lt;a href="http://www.javalobby.org"&gt;JavaLobby&lt;/a&gt; has been restyled.&lt;br /&gt;&lt;br /&gt;Being interested in this period in web development, and looking for cool stuff, I browsed the new JavaLobby site and found few things worth of notice:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The glider: just click on any thread, and you'll see a gliding toolbar on the left, following your scrolls. Cool, but to me a little bit distracting. Done using javascript from &lt;a href="http://www.dyn-web.com"&gt;Dynamic Web Coding&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The javascript menus: looks very nice, but the surprise is that they're not javascript: just plain CSS.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I was thinking "How large is the CSS ?", but it's 10KB and looks manageable.&lt;br /&gt;&lt;br /&gt;Seems to me they did a good job, so congrats !&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-109909419778722292?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/109909419778722292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=109909419778722292' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109909419778722292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109909419778722292'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/10/javalobby-restyle.html' title='JavaLobby Restyle'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-109897495963600368</id><published>2004-10-28T15:57:00.000+02:00</published><updated>2006-11-16T01:00:58.386+01:00</updated><title type='text'>Unix, Timezones and Java</title><content type='html'>It happened recently that we wrote a web application for one of our customers, and it turned out that the timestamps in the logs and the database timestamps were 6 hours before the host's time, as returned by the 'date' command.&lt;br /&gt;In HP-UX, the configuration file  that defines the timezone is &lt;span style="font-family:courier new;"&gt;/etc/TIMEZONE&lt;/span&gt;, but it was correctly set to the CEST timezone.&lt;br /&gt;&lt;br /&gt;We went back from the production environment to the development environment, compared the configurations, and they were equal.&lt;br /&gt;But in the development environment the logs were fine.&lt;br /&gt;Mmmh.&lt;br /&gt;&lt;br /&gt;Okay, I wrote a simple program that System.outs the result of new Date() and the value of the system property '&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;user.timezone&lt;/span&gt;'. Running it in the production box yielded the CEST timezone.&lt;br /&gt;Strange.&lt;br /&gt;&lt;br /&gt;The problem shows only because it's a web app ?&lt;br /&gt;Quickly converted the simple program in a simple JSP. Copied in production and invoking it yielded 6 hours before CEST.&lt;br /&gt;Did the same in the development environment: both cases showed the CEST time.&lt;br /&gt;Sgrunt.&lt;br /&gt;&lt;br /&gt;We try hard to pay a lot of attention to have a development environment that is as close as possible to the production environment: OS configuration, JVM configuration, DB configuration. Exactly to avoid this kind of problems.&lt;br /&gt;It turned out that in production Tomcat was launched using&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;su - tomcat -c "startup.sh"&lt;/span&gt;&lt;br /&gt;and for some strange HP-UX machinery, the &lt;span style="font-family:courier new;"&gt;/etc/TIMEZONE&lt;/span&gt; file was not read, while in development Tomcat was launched via the normal &lt;span style="font-family:courier new;"&gt;startup.sh&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Small details, that's where evil is.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-109897495963600368?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/109897495963600368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=109897495963600368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109897495963600368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109897495963600368'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/10/unix-timezones-and-java.html' title='Unix, Timezones and Java'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8807910.post-109837159824408168</id><published>2004-10-21T16:55:00.000+02:00</published><updated>2006-11-16T01:00:57.594+01:00</updated><title type='text'>Blog's Birth</title><content type='html'>Yesterday night I was surfing the Internet, trying to figure out the subtleties of Java Generics.&lt;br /&gt;&lt;a href="http://jcp.org/en/jsr/detail?id=255"&gt;JSR 255&lt;/a&gt; (aka JMX 2.0) expert group is generifying the JMX API for inclusion in J2SE 6.0, and reading &lt;a href="http://gafter.blogspot.com/"&gt;Neal Gafter's blog&lt;/a&gt;, he mentions this great resource for Java Generics doubts: &lt;a href="http://www.langer.camelot.de/GenericsFAQ/JavaGenericsFAQ.html"&gt;Angelika Langer's Java Generics FAQ&lt;/a&gt;.&lt;br /&gt;After a while, I noticed that Neal's blog had a "get your own blog" and decided to take a look.&lt;br /&gt;I discovered that blogger.com is now owned by Google; since I've found the way GMail is written quite impressive, I've finally decided to create my own blog.&lt;br /&gt;Like &lt;a href="http://www.mortbay.com/MB/log/gregw"&gt;Greg&lt;/a&gt;, I have no idea if I can get it right, will see.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8807910-109837159824408168?l=bordet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bordet.blogspot.com/feeds/109837159824408168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8807910&amp;postID=109837159824408168' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109837159824408168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8807910/posts/default/109837159824408168'/><link rel='alternate' type='text/html' href='http://bordet.blogspot.com/2004/10/blogs-birth.html' title='Blog&apos;s Birth'/><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/136/328131172_78b9576bca_s.jpg'/></author><thr:total>0</thr:total></entry></feed>
