<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.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"><id>tag:blogger.com,1999:blog-8807910</id><updated>2009-09-10T09:11:55.285+02:00</updated><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="alternate" type="text/html" href="http://bordet.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8807910/posts/default?start-index=26&amp;max-results=25" /><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/MutantWorld" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://www.blogger.com/comment.g?blogID=8807910&amp;postID=5510606061796534310" title="6 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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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's uncertain future" /><author><name>Simon</name><uri>http://www.blogger.com/profile/05495107326237735379</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://www.blogger.com/comment.g?blogID=8807910&amp;postID=841218590660087260" title="1 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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</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'/&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="https://www.blogger.com/comment.g?blogID=8807910&amp;postID=4293377015745210525" title="5 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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://www.blogger.com/comment.g?blogID=8807910&amp;postID=1642767247681452779" title="3 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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://www.blogger.com/comment.g?blogID=8807910&amp;postID=115410661395112258" title="2 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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">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'/&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="https://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:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="08231147514151626109" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry></feed>
