tag:blogger.com,1999:blog-88079102024-03-07T07:02:22.361+01:00Mutant WorldSimone Bordet's perspective on life ~ science ~ softwareSimonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comBlogger45125tag:blogger.com,1999:blog-8807910.post-3923311060297260382011-05-14T21:04:00.003+02:002011-05-14T21:19:59.782+02:00Natty Narwhal's Unity, final takeI have previously blogged on Ubuntu's Natty Narwhal <a href="http://bordet.blogspot.com/2011/04/natty-narwhals-unity-is-not-for-me-yet.html">Unity shortcomings</a>, and added <a href="http://bordet.blogspot.com/2011/05/natty-narwhals-unity-take-two.html">some additional thoughts</a> on my own configuration.<br /><br />With a non-hiding Unity launcher that works as an old-style launcher and as a windows list, what I really missed were the applets.<br /><br />It turns out that there are many efforts to replace those applets with "indicators", for example see <a href="http://www.techdrivein.com/2011/05/10-useful-application-indicators-for.html">this link</a>.<br /><br />So I installed the weather indicator, the system load indicator and this allowed me to get back to a decent configuration that I find efficient enough for my daily work.<br /><br />Considering that <a href="http://www.omgubuntu.co.uk/2011/04/ubuntu-11-10-will-not-ship-with-classic-gnome-desktop/">Ubuntu will drop the "classic" mode for 11.10</a>, I felt it was better to get used to Unity as soon as possible.<br /><br />I am confident the application indicators will improve over time, so eventually - hopefully - Unity will be as good as the classic mode.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-5778012947751175042011-05-05T00:38:00.002+02:002011-05-05T01:35:27.538+02:00Natty Narwhal's Unity, take twoI have previously blogged on Natty Narwhal's <a href="http://bordet.blogspot.com/2011/04/natty-narwhals-unity-is-not-for-me-yet.html">Unity shortcomings</a>, but I decided to give it few more days, and I here are my further comments.<br /><br />I configured the launcher with 32 pixels icons and disabled auto-hiding.<br />This basically brought me back an old-style launcher and a windows list that is always visible, allowing to glance at it for visual information regarding running applications.<br /><br />Unity's launcher seems to be designed to play the role of both an application launcher (via icon clicking) and of a windows list (via small arrows and additional icons). I still think that the two concepts needs to be separated, but I am starting to get used to it.<br /><br />It's still not like the classic mode; for example, there is one icon only in the launcher for all the Terminal instances, which gives less information on what is the Terminal window you are currently working on.<br /><br />I discovered that middle-clicking on a launcher icon creates a new instance of the application, so this issue always had a solution.<br /><br />Disabling auto-hiding made usage of the browser's application tabs easier, since now the launcher does not pop up overlapping the browser's application tabs when you hover with the mouse in the top left corner.<br /><br />I still really miss the applets, and I hope that Unity will be improved to allow an additional panel (at the bottom, say) to make room for the applets.<br />This new panel could be missing by default (but could be added if one wants to).<br />And I am really missing the old date/time/locations applet: the new one is just too bare bones for my taste.<br /><br />Finally, I noticed that Unity is way slower to start, but that's once in a day pause for me, so it's tolerable.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-46980312794384394152011-04-29T11:00:00.005+02:002011-04-30T01:59:16.192+02:00Natty Narwhal's Unity is not for me yetI have upgraded to Natty and I am trying out Unity, but I am afraid I am not the right user for it.<br /><br />Unity does not seem to be designed for power users like me (which is fine), but unfortunately it is not yet flexible enough to support both casual users <span style="font-style:italic;">and</span> power users like me.<br /><br />The new user interface is clean and polished, but did not impress me much, visually (not after wobbly windows and the desktop cubes). It's a couple of panels of which one autohides.<br />And a big step back on the user interface of available applets (see below).<br /><br />What I miss most is the lack of applets support, as I often glance at the CPU, network and disk I/O indicators; and the lack of the windows list, as I often glance there to see what I am running.<br /><br />For example, how do I know if I am running XChat so that colleagues can contact me ?<br />Previously, a glance to the windows list was enough; now I have to alt+tab or, if I have a maximized window (which is often the case), make the launcher visible (move mouse there, wait). Both are way slower than a glance. You need to operate instead of just glancing.<br /><br />As another example, I often run a "server" terminal and a "client" terminal, and I know that the server comes before the client in the windows list. A glance at the windows list is again enough to tell which terminal is what. Not possible with Unity.<br /><br />Compiz Config Settings Manager allows to fine tune the configuration of various effects, but sometimes it's just too sparse.<br />For example, alt+tab has a popup delay of 200 ms (it's a lot for a me... I started thinking my computer had become slower with the upgrade to Natty). Where is that settings ? In "Effects" ? In "Static Application Switcher" ? Somewhere else ?<br />You need to navigate CCSM and find it, and decrypt the various configuration options (for example, can anyone tell me what is the "timestep" option of the switcher ?)<br /><br />Firefox allows you to create "application tabs" that have a small icon to represent a page. If you want to go to one of those tabs, you need to be precise in clicking it (because it's small).<br />If you have Firefox maximized, the first application tab (GMail in my case) is dangerously close to both Unity's home button and Unity's launcher; if you are few pixel off and hover on the home button, the launcher starts to reveal, but by doing so it will partially cover Firefox first application tab; few pixels off on the left border, and the launcher appears, covering again Firefox first application tab.<br /><br />Multi instance applications like Gnome's Terminal cannot be easily instantiated from Unity's launcher: you can do that easily for the first instance, but trying to open a second Terminal in the same way brings you to the first Terminal. I think the principle of least surprise is violated here (or to say it less politely, WTF ?!).<br />Double clicking on the icon reveals all instances, and right clicking shows a menu that does not have an entry that allows to create a new instance.<br /><br />And yes, I do know that I can configure Unity and Compiz, I also know that Terminal has a special Unity keyboard accelerator, but the accelerator does not work if you have a maximized application focused (it will be interpreted by the application, not by Unity).<br />It's just that Unity is more complicated than the classic mode, and less customizable.<br /><br />Most of the applets for the Unity panel are a step back, especially the Time/Location applet (no icons, no solar light projection on Earth), and the Configure Display applet. The latter does not ask you anymore if you want to use the proprietary driver tool instead... now how do I find the proprietary tool ?<br />Exploring Unity's launcher is no help (in which category could they have put it ?) until you type "nvidia" in Unity's dash (and you start thinking "thank god it had 'nvidia' in the name, otherwise I'd be seriously screwed in finding it").<br />And I am the guy that knows its video card is an NVidia one, otherwise, well...<br /><br />The visual cue for notifications is a (really) small triangle in the top left corner.<br />You can't tell if it was a Skype notification, XChat notification or something else, it's one cue for all, and you need to click on it to figure out which notifications.<br />Before, the windows list gave different cues for different application, and a glance was enough to figure out which notifications.<br /><br />All in all, I am disappointed even if I set my expectations really low.<br />I will give Unity a bit more time, but I am resisting the urge to switch back to the classic mode.<br /><br />I really hope that the classic mode will not be removed, or at least I hope that Unity will improve so much that will be more friendly and configurable for power users as well (or for me at least - but I am guessing I am not the only one).<br /><br />I personally care about number of eye glances, number of mouse clicks and number of switches between keyboard and mouse of my hand. I would like all of them to be reduced at minimum and right now Unity forces me to a lot more effort to get the same things done, so it's a (big) step back.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-4292038525957757202009-08-04T18:24:00.004+02:002009-08-04T18:33:46.281+02:00Jetty Support for Cross-Domain XMLHttpRequestsRemember the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a> that restricts most of our JavaScript applications ?<br /><br />Seems that we can finally get rid of it, thanks to a <a href="http://dev.w3.org/2006/waf/access-control/">new W3C specification</a> already implemented by Firefox 3.5 and, on server side, by the <a href="http://eclipse.org/jetty">Jetty Servlet Container</a>.<br /><br />I blogged about all the details <a href="http://blogs.webtide.com/sbordet/entry/jetty_supports_cross_domain_xmlhttprequests">here</a>.<br /><br />Oh, if you're using Ubuntu Jaunty, you can install Firefox 3.5 via <a href="apt://firefox-3.5">apt://firefox-3.5</a>. It is named "Shiretoko" (its codename), but it's exactly Firefox 3.5.<br /><br />Time to move on !Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-85213830574801523242009-07-29T17:01:00.003+02:002009-08-04T18:24:01.569+02:00JavaScript CometdLately I have been working with JavaScript, in particular I have written a JavaScript library that implements the <a href="http://cometd.org/documentation/bayeux/spec">Bayeux specification</a> for the <a href="http://cometd.org">Cometd project</a>.<br /><br />I have to say that I really like JavaScript, the language.<br /> <br />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 <a href="http://javascript.crockford.com/javascript.html">misunderstood</a>.<br /><br />You can write nice applications in JavaScript and today JavaScript toolkits (such as <a href="http://dojotoolkit.org">Dojo</a> or <a href="http://jquery.com">jQuery</a>) 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.<br /><br />I have blogged about the Cometd library I have written <a href="http://blogs.webtide.com/sbordet/entry/jquery_comet_implementation_available">here</a>.<br /><br />Enjoy !Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-55106060617965343102009-01-13T00:28:00.002+01:002009-01-13T00:50:20.370+01:00Creative Webcam Live! on Ubuntu Intrepid IbexI received the Creative Webcam Live! as a gift quite some time ago, but never had the time to use it or install it properly.<br />My good ol' Thinkpad T43p was maybe bleeding edge in 2005, but not as far as having already an incorporated webcam <img src="http://wolverinex02.googlepages.com/icon_wink.gif" alt=":)" /><br /><br />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.<br />This camera appears using <code>lsusb</code> as:<br /><pre><br />Bus 003 Device 008: ID 041e:4036 Creative Technology, Ltd Webcam Live!/Live! Pro<br /></pre><br /><br />The solution is quite easy though: you need to set this variable before launching the program that uses the webcam:<br /><pre><br />export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so<br /></pre><br /><br />I tested this with camorama and skype, and in both cases it works just fine.<br />For skype, I created a wrapper script that first set the variable as above and then invokes <code>/usr/bin/skype</code> and modified the menu entry to point to my wrapper script.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-83205298585406688902008-12-29T14:39:00.008+01:002008-12-30T17:51:21.039+01:00Visibility in JavaScriptThe 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 <a href="http://javascript.crockford.com/private.html">Private Members in JavaScript</a>.<br /><br />Here I just recap my experience for my own (and for anyone interested) future reference.<br /><br />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.<br /><br />JavaScript can have private members and functions, and I mostly use two idioms for this: <a href="#ctor">the constructor function</a> and the <a href="#init">the object initializer</a>.<br /><h4><a name="ctor">The constructor function</a></h4><br />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).<br /><pre><br />var MyNS = {}; // An optional namespace<br />MyNS.Service = function(offset)<br />{<br /> var _privateMember = offset;<br /><br /> function _privateFunction(value)<br /> {<br /> return _privateMember + value;<br /> }<br /><br /> this.myFunction = function(value)<br /> {<br /> _privateMember = _privateFunction(value);<br /> return _privateMember;<br /> }<br />};<br /></pre><br />The common convention is that function names beginning with an upper case letter are constructor functions, in this case <code>Service</code>.<br /><br />From the example above, private members are defined within the constructor function using the keyword <code>var</code>, private functions are just nested functions within the constructor function, and publicly accessible functions are defined with the <code>this.<functionName></code> idiom. <br />The function <code>myFunction</code> 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.<br />From the example above, you see that <code>myFunction</code> can refer to private members and functions.<br /><br />However, referring to publicly accessible functions from private functions is not possible:<br /><pre><br />// A constructor function without namespace; does not work<br />function Service2()<br />{<br /> var _open;<br /><br /> function _clean()<br /> {<br /> if (_open) close(); // Does not work: ReferenceError<br /> }<br /> <br /> this.close = function()<br /> {<br /> ...<br /> }<br />}<br /></pre><br />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 <code>close()</code> into a private function <code>_close()</code> and call the private version from both <code>_clean()</code> and <code>close()</code>.<br /><br />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:<br /><pre><br />var s1 = new MyNS.Service(1);<br />var result1 = s1.myFunction(5); // returns 6<br /><br />var s2 = new MyNS.Service(2);<br />var result2 = s2.myFunction(0); // returns 2<br /></pre><br />As you would expect, object <code>s1</code> and <code>s2</code> have different internal state and can be used independently.<br /><h4><a name="init">The object initializer</a></h4><br />I use the object initializer technique when I want to create a singleton object.<br />My preferred way of using the object initializer technique is via a function with immediate invocation, which allows to have private members and functions:<br /><pre><br />MyNS.EventHandler = function()<br />{<br /> var _queue = [];<br /><br /> function _privateFunction(event)<br /> {<br /> ...<br /> }<br /> <br /> return {<br /> handle: function(event)<br /> {<br /> _privateFunction(event);<br /> },<br /> get size()<br /> {<br /> return _queue.length;<br /> }<br /> };<br />}();<br /></pre><br />Note the parenthesis at the end of the function definition, which perform the immediate invocation of the function.<br /><br />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 <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters">getter and setter notation</a>.<br />In the example above I used the getter notation to define a read-only property called <code>size</code>, which can be accessed like this:<br /><pre><br />var s = MyNS.EventHandler.<b>size</b>;<br /></pre><br />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).<br /><h4>Caveats</h4><br />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.<br /><br />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.<br /><br />Unfortunately I could not figure out how to do it, not even reading JavaScript library code such as <a href="http://dojotoolkit.org/">Dojo</a> or <a href="http://jquery.com">jQuery</a>.<br /><br />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".<br /><h4>Public members and prototype</h4><br />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.<br />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.<br /><pre><br />MyNS.Event = function(source) <br />{<br /> this._source = source;<br />};<br />MyNS.Event.prototype = function()<br />{<br /> var _privateStatic;<br /><br /> function _privateFunction()<br /> {<br /> }<br /><br /> return {<br /> consume: function() <br /> {<br /> this._consumed = true;<br /> },<br /> get source()<br /> {<br /> return this._source;<br /> }<br /> };<br />}();<br /></pre><br />In this example, <code>MyNS.Event</code> is a constructor function that allows to create events via:<br /><pre><br />var source = window;<br />var event1 = new MyNS.Event(source);<br /></pre><br />The constructor function defines a public member called <code>_source</code>, which can be later referred from functions. <br />Also functions in the prototype can define public members (like <code>_consumed</code> in function <code>consume()</code>).<br /><br />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.<br /><br />The interesting part comes when you define private members in the prototype, like <code>_privateStatic</code>.<br />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 <code>_privateStatic</code> (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.<br /><br />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:<br /><pre> <br />function A(value)<br />{<br /> this._field = value;<br />}<br />A.prototype = function()<br />{<br /> var _staticField;<br /> return {<br /> staticGetter: function() <br /> {<br /> return _staticField;<br /> },<br /> staticSetter: function(value) <br /> {<br /> _staticField = value;<br /> },<br /> instanceGetter: function()<br /> {<br /> return this._field;<br /> },<br /> };<br />}();<br /><br />var a1 = new A(1);<br />var a2 = new A(2);<br />a1.instanceGetter(); // returns 1<br />a1._field; // public field, returns 1<br />a1._field = 3;<br />a1.instanceGetter(); // returns 3<br />a2.instanceGetter(); // returns 2<br />a2.staticSetter('foo');<br />a1.staticGetter(); // returns 'foo'<br /></pre><br />I'd be interested in any solution that will allow private members with prototype-shared functions, if this is possible in JavaScript.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-67216543031303944662008-08-14T23:39:00.002+02:002008-08-15T00:33:43.274+02:00Java's uncertain futureJava's future looks to me very uncertain in this period.<br /><br />I started studying Java during 1999 summer, and working with it since then.<br /><br />Many things happened since the release of JDK 5. <br /><br />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.)<br /><br />Sun itself is not performing very well these days (profit plunged 73% in the last quarter).<br /><br />Sun has open sourced Java.<br /><br />Yet, there is no JDK 7 plan.<br />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. <br />But not this time, and noone seems able to predict neither <span style="font-style:italic;">when</span> JDK 7 will be released, nor <span style="font-style:italic;">what</span> it will contain.<br /><br />There is OpenJDK.<br />Can anyone tell me the difference between JDK 7 and OpenJDK ?<br />And I am not meaning the obvious ones, but why two efforts, and how are they synchronizing ?<br />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.<br /><br />There is JDK 6 and JDK 6 update 10. Mmm. More confusion.<br /><br />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.<br /><br />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.<br /><br />It appears as if Sun released the command of the Java ship and let its best commanders flew away.<br />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.<br /><br />It's 2008 summer, and I am studying Ruby.<br /><br />But the worst indicator is that Hani and its Bileblog are quiet: he cannot desecrate the last moments of a dying era, can he ?Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-87983459674480283762008-07-27T01:17:00.003+02:002008-07-28T00:59:40.377+02:00Static Fields in EnumsEnums in Java have a numeric, read-only, property called <code>ordinal</code> that is a strictly consecutive integer (starting from 0).<br /><br />Sometimes, however, it is necessary to associate to an Enum another numeric property, let's call it <code>code</code>, 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 <code>code</code>.<br /><br />It seems totally trivial to write an Enum that has a static map from codes to Enum instances:<br /><pre><br />public enum Port<br />{<br /> SSH(22), TELNET(23), HTTP(80), POP3(110), HTTPS(443);<br /><br /> // The static map from codes to Enum instances<br /> private static final <br /> Map<Integer, Port> ports = new HashMap<Integer, Port>();<br /> private final int code;<br /><br /> private Port(int code)<br /> {<br /> this.code = code;<br /> ports.put(code, this);<br /> }<br /><br /> public int getCode()<br /> {<br /> return this.code;<br /> }<br /><br /> // Lookup method that returns the Enum instance from the given code<br /> public static Port from(int code)<br /> {<br /> return ports.get(code);<br /> }<br />}<br /></pre><br />Note the method <code>static from(int code)</code> that returns an Enum instance from the given <code>code</code>.<br /><br />Unfortunately, this will not compile. The compiler reports that it is illegal to access the static member <code>ports</code> from the constructor.<br /><br />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 <code>Ports</code> instances, in this case SSH, TELNET, etc.; this static initializer is the first initializer run when the <code>Ports</code> 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 <code>ports</code> has not been created yet.<br />See <a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#301020">http://java.sun.com/docs/books/jls/third_edition/html/classes.html#301020</a> for further details.<br /><br />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:<br /><pre><br />public enum Port<br />{<br /> SSH(22), TELNET(23), HTTP(80), POP3(110), HTTPS(443);<br /><br /> private final int code;<br /><br /> private Port(int code)<br /> {<br /> this.code = code;<br /> Ports.ports.put(code, this);<br /> }<br /><br /> public int getCode()<br /> {<br /> return this.code;<br /> }<br /><br /> // Lookup method that returns the Enum instance from the given code<br /> public static Port from(int code)<br /> {<br /> return Ports.ports.get(code);<br /> }<br /><br /> private static class Ports<br /> {<br /> // The static map from codes to Enum instances<br /> private static final <br /> Map<Integer, Port> ports = new HashMap<Integer, Port>();<br /> }<br />}<br /></pre>Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-15887543592751765472008-07-27T00:57:00.002+02:002008-07-27T01:16:28.146+02:00Randy Pausch Last LectureI just watched <a href="http://www.youtube.com/watch?v=ji5_MqicxSo&NR=1">Randy Pausch last lecture</a>, and found it absolutely incredible, one of those gems that cannot be missed.<br /><br />If you want to spend 1hr 16 mins in something really worth, then go watch it.<br /><br />My favorite quote:<br />"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."<br /><br />Thanks Randy: for the head fake that I've got from your last lecture.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-8412185906600872602007-09-20T22:40:00.000+02:002007-09-20T23:19:25.154+02:00JSP page encodingI 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 <span style="font-style: italic;">ù</span> or <span style="font-style: italic;">è</span> resulted in garbage characters stored in the database and consequently garbage displayed by the browser.<br /><br />The application was developed in Linux, using an IDE configured to save files using UTF-8 encoding, and deployed on a Linux box.<br /><a href="http://postgresql.org/">The database</a> was configured to use UTF-8 encoding.<br />Every page contained the directive <code><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></code> in the <code><head></code> section.<br /><br />I thought that given these premises, there was no chance of misbehaviors with respect to character encoding, but I was wrong.<br />The browser kept telling me that the page it was displaying had ISO-8859-1 encoding.<br /><br />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 (!).<br />The <a href="http://jetty.mortbay.org">Jetty servlet container</a> was correctly setting the HTTP header as: <code>Content-Type: text/html; charset=ISO-8859-1</code>, following the specification.<br /><br />The fix is simple, just add this to <code>web.xml</code>:<br /><pre><br /><jsp-config><br /> <jsp-property-group><br /> <url-pattern>*.jsp</url-pattern><br /> <page-encoding>UTF-8</page-encoding><br /> </jsp-property-group><br /></jsp-config><br /></pre><br />It will be interesting to know why the JSP expert group did not pick up UTF-8 as the default character encoding.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-42933770157452105252007-07-26T21:23:00.000+02:002007-07-26T22:53:35.194+02:00Upgrading to SSL an existing socket connectionSSL 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.<br /><br />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 <span style="font-weight: bold;">upgrade</span> the existing socket connection to SSL, exchange some private message with confidentiality (for example a password that would have traveled in clear text), then <span style="font-weight: bold;">downgrade</span> back to the plain the socket connection; all this without closing the original socket nor creating a new one on a different port.<br /><br />Let's see how.<br /><h3 style="margin:2em 0 0 0;padding:0">The server</h3><br />The server class creates a plain ServerSocket, and calls <code>accept()</code> on it; when a client connects, <code>accept()</code> returns a socket that is normally handed to a different thread (details omitted):<br /><pre><br />Socket socket = serverSocket.accept();<br />threadPool.execute(new Handler(socket));<br /><br />class Handler implements Runnable<br />{<br /> private final Socket socket;<br /> Handler(Socket socket) { this.socket = socket; }<br /> public void run()<br /> {<br /> Socket currentSocket = this.socket;<br /> while (isConnectionOpen(currentSocket))<br /> {<br /> String message = readMessage(currentSocket);<br /> if (upgradeToSSL(message))<br /> {<br /> SSLSocketFactory sslSocketFactory =<br /> (SSLSocketFactory)SSLSocketFactory.getDefault();<br /> SSLSocket sslSocket =<br /> (SSLSocket)sslSocketFactory.<br /> createSocket(currentSocket,<br /> currentSocket.getInetAddress().getHostAddress(),<br /> currentSocket.getPort(),<br /> false);<br /> sslSocket.setUseClientMode(false);<br /> sslSocket.startHandshake();<br /> currentSocket = sslSocket;<br /> }<br /> else if (downgradeFromSSL(message))<br /> {<br /> currentSocket.close();<br /> currentSocket = this.socket;<br /> }<br /> else<br /> {<br /> handleNormalMessage(currenSocket, message);<br /> }<br /> }<br /> }<br />}<br /></pre><br />When upgrading, the server wraps the current (plain) socket using <code>SSLSocketFactory.createSocket(socket, address, port, autoClose)</code>, 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.<br /><br />When downgrading, the current (ssl) socket is just closed and, thanks to the <code>autoClose</code> argument set to false (which will not close the underlying plain socket), the original plain socket is still operative.<br /><br />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).<br /><h3 style="margin:2em 0 0 0;padding:0">The client</h3><br />The client connects to the server using a plain Socket, then upgrades the socket connection (details omitted):<br /><pre><br />// Connects to server<br />this.socket = new Socket(serverAddress, serverPort);<br />...<br />Socket currentSocket = this.socket;<br />while (moreMessagesToSend)<br />{<br /> if (upgradeToSSL)<br /> {<br /> SSLSocketFactory sslSocketFactory =<br /> (SSLSocketFactory)SSLSocketFactory.getDefault();<br /> SSLSocket sslSocket =<br /> (SSLSocket)sslSocketFactory.<br /> createSocket(currentSocket,<br /> currentSocket.getInetAddress().getHostAddress(),<br /> currentSocket.getPort(),<br /> false);<br /> sslSocket.setUseClientMode(true);<br /> sslSocket.startHandshake();<br /> currentSocket = sslSocket;<br /> }<br /> else if (downgradeFromSSL)<br /> {<br /> currentSocket.close();<br /> currentSocket = this.socket;<br /> }<br /><br /> sendMessage(currentSocket);<br /> readReply(currentSocket);<br />}<br /></pre><br />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 <code>autoClose</code> argument prevents the original plain socket to be closed when the SSL socket is closed.<br /><br />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).<br /><br />If you're writing custom network protocols that require confidentiality, the above may come handy. Enjoy !Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-55488387688301609402007-01-17T00:46:00.000+01:002007-01-17T01:03:09.391+01:00Jonas Bonér @ JUG Torino - January 19th<a href="http://jonasboner.com">Jonas Bonér</a> of <a href="http://terracottatech.com">Terracotta Tech</a> will be our guest speaker at the monthly meeting of the <a href="http://www.jugtorino.it">JUG Torino</a> on January 19th, 18:30.<br /><br />The title of his talk is: <span style="font-weight:bold;">How to write scalable, highly available web applications</span>.<br /><br />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.<br /><br /><a href="http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingGennaio2007">Here</a> you can find more information on this meeting.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-16427672476814527792007-01-01T23:49:00.000+01:002007-01-04T23:37:50.463+01:00UTF-8 handling for ResourceBundle and PropertiesEvery new version of the JDK comes with small improvements, often unnoticed, that however correct long-standing bugs or request for enhancements.<br /><br />One such improvements is - finally! - the ability for <tt>java.util.Properties</tt> to handle <span style="font-weight:bold;">non ISO-8859-1</span> properties files.<br />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.<br /><br />JDK 5 added a new API, namely <tt>Properties.loadFromXML(InputStream)</tt>, 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):<br /><pre><br /><?xml version="1.0" <span style="font-weight:bold;">encoding="UTF-8"</span> ?><br /><properties><br /> <entry key="hello.world">Καλημέρα κόσμε</entry><br /></properties><br /></pre><br />JDK 6 went further, adding <tt>Properties.load(Reader)</tt>: in case the encoding is known <span style="font-style:italic;">a priori</span> by the program, it is possible to create a <tt>Reader</tt> that uses the specific encoding to read the properties file.<br /><br />However, in JDK 5, <tt>java.util.ResourceBundle</tt> 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:<br /><pre><br />hello.world=\u039A\u03B1\u03BB\u03B7\u03BC\u03AD\u03C1\u03B1 \u03BA\u03CC\u03C3\u03BC\u03B5<br /></pre><br />Pretty ugly, especially when you think that the API to read properties file in XML format is already present in JDK 5, only that <tt>ResourceBundle</tt> has not been updated to use it.<br /><br />Fortunately, with JDK 6 it is possible to solve this problem, although requires a bit of coding (see below).<br /><br />In JDK 6 <tt>ResourceBundle</tt> has been extended to give the user more control on how to load resources, by subclassing <a href="http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.Control.html"><tt>ResourceBundle.Control</tt></a>, and passing an instance of the <tt>ResourceBundle.Control</tt> subclass like this:<br /><pre><br />ResourceBundle bundle = ResourceBundle.getBundle("messages", new MyControl());<br /></pre><br />where <tt>MyControl</tt> is the <tt>ResourceBundle.Control</tt> subclass.<br />The class <tt>ResourceBundle.Control</tt> allows to tune:<br /><ul><li>the kind of resource to load (a Java class, a properties file, a properties file in XML format, or any other format you decide)</li><br /><li>the policy of expiration of the resource, thus allowing reload the resource upon some condition</li><br /><li>the <tt>ResourceBundle</tt> subclass to instantiate, normally depending on the kind of resource</li></ul><br />Here's the JDK 6 class that allows to load XML properties files as resource bundles.<br /><pre><br />/**<br /> * JDK 6's {@link ResourceBundle.Control} subclass that allows<br /> * loading of bundles in XML format.<br /> * The bundles are searched first as Java classes, then as<br /> * properties files (these two methods are the standard<br /> * search mechanism of ResourceBundle), then as XML properties<br /> * files.<br /> * The filename extension of the XML properties files is assumed<br /> * to be *.properties.xml<br /> */<br />public class ExtendedControl extends ResourceBundle.Control<br />{<br /> private static final String FORMAT_XML_SUFFIX = "properties.xml";<br /> private static final String FORMAT_XML = "java." + FORMAT_XML_SUFFIX;<br /> private static final List<String> FORMATS;<br /> static<br /> {<br /> List<String> formats = new ArrayList<String>(FORMAT_DEFAULT);<br /> formats.add(FORMAT_XML);<br /> FORMATS = Collections.unmodifiableList(formats);<br /> }<br /><br /> @Override<br /> public List<String> getFormats(String baseName)<br /> {<br /> return FORMATS;<br /> }<br /><br /> @Override<br /> public ResourceBundle newBundle(String baseName, Locale locale,<br /> String format, ClassLoader loader,<br /> boolean reload)<br /> throws IllegalAccessException, InstantiationException, IOException<br /> {<br /> if (!FORMAT_XML.equals(format))<br /> return super.newBundle(baseName, locale, format, loader, reload);<br /><br /> String bundleName = toBundleName(baseName, locale);<br /> String resourceName = toResourceName(bundleName, FORMAT_XML_SUFFIX);<br /> final URL resourceURL = loader.getResource(resourceName);<br /> if (resourceURL == null) return null;<br /><br /> InputStream stream = getResourceInputStream(resourceURL, reload);<br /><br /> try<br /> {<br /> PropertyXMLResourceBundle result = new PropertyXMLResourceBundle();<br /> result.load(stream);<br /> return result;<br /> }<br /> finally<br /> {<br /> stream.close();<br /> }<br /> }<br /><br /> private InputStream getResourceInputStream(final URL resourceURL,<br /> boolean reload)<br /> throws IOException<br /> {<br /> if (!reload) return resourceURL.openStream();<br /><br /> try<br /> {<br /> // This permission has already been checked by<br /> // ClassLoader.getResource(String), which will return null<br /> // in case the code has not enough privileges.<br /> return AccessController.doPrivileged(<br /> new PrivilegedExceptionAction<InputStream>()<br /> {<br /> public InputStream run() throws IOException<br /> {<br /> URLConnection connection = resourceURL.openConnection();<br /> connection.setUseCaches(false);<br /> return connection.getInputStream();<br /> }<br /> });<br /> }<br /> catch (PrivilegedActionException x)<br /> {<br /> throw (IOException)x.getCause();<br /> }<br /> }<br /><br /> /**<br /> * ResourceBundle that loads definitions from an XML properties file.<br /> */<br /> public static class PropertyXMLResourceBundle extends ResourceBundle<br /> {<br /> private final Properties properties = new Properties();<br /><br /> public void load(InputStream stream) throws IOException<br /> {<br /> properties.loadFromXML(stream);<br /> }<br /><br /> protected Object handleGetObject(String key)<br /> {<br /> return properties.getProperty(key);<br /> }<br /><br /> public Enumeration<String> getKeys()<br /> {<br /> final Enumeration<Object> keys = properties.keys();<br /> return new Enumeration<String>()<br /> {<br /> public boolean hasMoreElements()<br /> {<br /> return keys.hasMoreElements();<br /> }<br /><br /> public String nextElement()<br /> {<br /> return (String)keys.nextElement();<br /> }<br /> };<br /> }<br /> }<br />}<br /></pre>Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-75612189718087641122006-12-21T23:53:00.000+01:002006-12-22T01:25:38.254+01:00Java Memory Model: down to the metal<a href="http://www.javapolis.com/">Javapolis</a> is over, and among the sessions that can be seen and heard online, there's Brian Goetz's on the <a href="http://www.bejug.org/confluenceBeJUG/display/PARLEYS/The+new+Java+Memory+Model">Java Memory Model</a>.<br /><br />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.<br /><br />One thing that always intrigued me, however, is: How is the new memory model actually implemented ?<br /><br />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.<br /><br />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):<br /><pre><br />public class Singleton<br />{<br /> private static Object singleton;<br /> public static Object getInstance()<br /> {<br /> if (singleton == null)<br /> {<br /> synchronized (Singleton.class)<br /> {<br /> if (singleton == null)<br /> singleton = new Object();<br /> }<br /> }<br /> return singleton;<br /> }<br />}<br /></pre><br />How is it possible that the double checked locking does not work ?<br /><br />It is possible because in JDK 1.4 the memory model, i.e. the interaction between threads and memory, was not well defined. <br />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 <tt>singleton</tt> (for example in a registry) so that the second processor, running the second thread, would have read the stale value of <tt>null</tt>, even if the first thread already updated it.<br /><br />Fortunately, in JDK 5 the memory model has been fixed, so that now the effects of <tt>synchronized</tt>, <tt>volatile</tt> and <tt>final</tt> with respect to the memory model have been precisely defined.<br /><br />These effects are outlined in Brian's presentation, and defined <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/">here</a> so you may want to refer to these resources for further details.<br />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.<br /><br />In JDK 1.4, the <tt>synchronized</tt> 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).<br /><br />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 ?<br /><br />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.<br />For example to implement a particular memory barrier called <em>fence</em>, in a x86 the assembler instruction is <tt>lock addl 0,(sp)</tt> where <tt>sp</tt> is the stack pointer, while in a ia64 there is a dedicated assembler instruction called <tt>mf</tt> (memory fence).<br /><br />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 :DSimonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-85620902264064958102006-12-19T23:17:00.000+01:002006-12-20T18:08:31.227+01:00Java ClosuresJava Closures seem to be the buzzword of the moment.<br />Unfortunately I missed the (I'm told great) JavaPolis conference in Antwerpen, Belgium, but fortunately the JavaPolis guys have put videos of the sessions <a href="http://www.bejug.org/confluenceBeJUG/display/PARLEYS/Home">online</a> !<br /><br />I recommend all people interested to watch or listen to <a href="http://gafter.blogspot.com/">Neal Gafter's</a> session on closures.<br /><br />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.<br />Neal Gafter himself said that if closures where in the language before JDK 5, the new <tt>for</tt> loop syntax would probably not have been introduced.<br /><br />How do closures look like ?<br /><br />The proposed syntax for the closures in Java allows to write code such as:<br /><pre><br />Collection<T> elements = ...;<br />forEach (T element : elements) { doSomething(element); }<br /></pre><br />The <tt>forEach</tt> 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 <tt>import static java.util.Collections.forEach</tt>).<br /><br />Another example is iterating over entries of a <tt>java.util.Map</tt>:<br /><pre><br />Map<K, V> props = ...<br />eachEntry(K key, V value : props) { doSomething(key, value); }<br /></pre><br />where again the <tt>eachEntry</tt> statement is a static method call to (for example) <tt>java.util.Collections</tt>.<br /><br />One can even think of replacing the <tt>synchronized</tt> keyword with the classes from <tt>java.util.concurrent.locks</tt>:<br /><pre><br />final Lock lock = ...;<br />sync(lock) { oneThreadAtATime(); }<br /></pre><br />where <tt>sync</tt> is a method call, and not a keyword. <br />It is impressive how closures make <tt>sync</tt> look like a keyword, when compared to the real <tt>synchronized</tt> keyword.<br /><br />Possibilities are endless: from automatically closing streams, to measuring elapsed time, to adding functional programming to collections, to simplify <tt>java.util.concurrent.Executor</tt> usage, etc.<br /><br />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.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-87127816540917739032006-12-16T22:00:00.000+01:002006-12-16T22:06:29.881+01:00Hibernate blog interviewMichele Sciabarrà interviewed me on Hibernate in a short, blog-like style interview available <a href="http://www.javajournal.it/blog/">here</a> (in Italian).Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-51314425412372652662006-11-16T15:09:00.000+01:002006-11-16T15:16:05.322+01:00JUG Torino MeetingToday, November 16th, the <a href="http://jugtorino.it">Java User Group Torino</a> organizes its nth (we lost the exact count :-) meeting.<br /><br />The meeting agenda is composed of a quickie on Subversion, hosted by me, and a session on EJB 3 and J2EE 5 hosted by <a href="http://www.diotalevi.com/weblog/">Filippo</a>.<br /><br />Check out the meeting details and directions here: <a href="http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingNovembre2006">http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingNovembre2006</a>Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-54331626286569664172006-11-16T01:03:00.000+01:002006-11-16T01:14:56.441+01:00How fast are you ?A friend sent me this link today: <a href="http://www.speedtest.net/">http://www.speedtest.net/</a><br />How fast are you ?Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-1154106613951122582006-07-28T18:33:00.000+02:002006-11-16T01:01:03.683+01:00ICMP and InetAddress.isReachable()In Java it is only possible to work with two types of sockets: stream based ones (or TCP ones - <code>java.net.Socket</code> and <code>java.net.ServerSocket</code>) and datagram based ones (or UDP ones - <code>java.net.DatagramSocket</code> and <code>java.net.MulticastSocket</code>).<br />The open bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4727550">4727550</a> 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.<br /><br />To implement an ICMP ping, a partial solution has been introduced in J2SE 5: a way to check if some address is reachable, via <code>java.net.InetAddress.isReachable()</code> methods.<br />The implementation of these methods goes native and tries to do its best to "ping" the address represented by the <code>InetAddress</code>.<br /><br />Surprisingly, there are many differences between the Windows and the Linux/Unix implementation of <code>java.net.InetAddress.isReachable()</code>.<br /><br />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.<br /><br />Linux/Unix, instead, supports an ICMP "ping" system call. So the implementation of <code>java.net.InetAddress.isReachable()</code> 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.<br /><br />It turns out that in Linux/Unix the ping system call requires root privileges, so most of the times <code>java.net.InetAddress.isReachable()</code> will fail, because many Java programs are not run as root, and because the target address unlikely has the echo service up and running. <br />Too bad.<br /><br />But why on Linux, for example, I can use the ping program without being root ? <br />It's because ping has the <a href="http://en.wikipedia.org/wiki/Setuid">setuid bit</a> set:<br /><pre><br />$> ls -l /bin/ping<br />-rwsr-xr-x 1 root root 30724 2005-11-11 01:15 /bin/ping<br /></pre><br />When a user invokes ping, it will run as root (see the "rws" permission for the owner ?).<br /><br />But why on Windows there is a ping executable that does the job ?<br />It seems that this executable is relying on undocumented features, so everyone tries to avoid binding to those features.<br /><br />So, for now, writing portable Java code that wants to send ICMP ping is quite an adventure.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-1152748538432684372006-07-13T01:08:00.000+02:002006-11-16T01:01:03.466+01:00Why Thread.currentThread().getContextClassLoader() ?I recently been involved in a discussion where I questioned that <code>Thread.currentThread().getContextClassLoader()</code> was the right way to implement the accessibility of a ClassLoader from any point in the code from a thread.<br />I very much preferred that <code>ClassLoader.getContextClassLoader()</code> was available, thus freeing class <code>Thread</code> of any reference to class loading.<br /><br />Other examples of accessibility of thread local information are present in the Java libraries, most notably <code>TransactionManager.getTransaction()</code>, that returns the Transaction currently associated with the thread (though the call is not static).<br />There is also a RFE for having the <code>Locale</code> available, see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6197800">RFE 6197800</a>.<br /><br />Both follow the model of not being implemented in class <code>Thread</code>, so I wonder why for <code>ClassLoader</code> it was implemented in this way. Some historical reason maybe, and probably right now is not practical to deprecate that call in favor of <code>ClassLoader.getContextClassLoader()</code>.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-1151943127211594812006-07-03T17:48:00.000+02:002006-11-16T01:01:03.248+01:00JavaDay event in Torino, July 7th<a href="http://www.jugtorino.it">JUG Torino</a> is proud to organize the first <a href="http://www.javaday.it">JavaDay</a> conference in Torino, on July 7th.<br />JavaDay travelling conferences will be held (in different dates) in many major cities of Italy, and Torino is the first installment.<br /><br />The conference schedule is <a href="http://www.jugtorino.it/vqwiki/jsp/Wiki?JavaDay06">pretty good</a>, and features also two international speakers: <span style="font-weight:bold;">Jason van Zyl</span> of <a href="http://maven.apache.org">Maven</a> fame, and <span style="font-weight:bold;">Greg Wilkins</span> of <a href="http://jetty.mortbay.com">Jetty</a> and <a href="http://www.webtide.com">WebTide</a> fame.<br /><br /><span style="font-weight:bold;">Sessions Highlights</span>: Object-Oriented development, Ajax, Maven, Jetty, Struts and more.<br /><br />The JavaDay conference is free, just register at the <a href="http://www.javaday.it">JavaDay site</a>.<br /><br />See you there !Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-1149107954968622922006-05-31T22:23:00.000+02:002006-11-16T01:01:02.577+01:00TestNG and MavenI've been working with JDK 5, and some time ago I decided to try <a href="http://testng.org">TestNG</a> as test framework, leaving back JUnit.<br /><br />Since then, I got addicted to TestNG, and if possible, will never go back to JUnit, as really TestNG is leaps beyond JUnit.<br /><br />Now I am working also on a JDK 1.4 application that I build using <a href="http://maven.apache.org">Maven</a>.<br />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:<br /><br />Before:<br /><pre><br />public class MyTest extends junit.framework.TestCase<br />{<br /> public void testSomething() throws Exception<br /> {<br /> assertTrue(true);<br /> }<br />}<br /></pre><br /><br />After:<br /><pre><br />public class MyTest<br />{<br /> /**<br /> * @testng.test<br /> */<br /> public void testSomething() throws Exception<br /> {<br /> assert true;<br /> }<br />}<br /></pre><br /><br />Plus, you get all cool <a href="http://testng.org/doc/documentation-main.html">TestNG features</a>:<br /><ul><br /><li>configurable advice methods (that run before/after the suite, the groups, the class, the test)</li><br /><li>configurable dependencies among tests</li><br /><li>configurable number of runs</li><br /><li>configurable parameters to pass to the test</li><br /><li>...and much more</li><br /></ul>Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-1148649136231309842006-05-26T14:57:00.001+02:002008-04-09T15:28:37.878+02:00Big Changes and 2 Linux hacksLong time, no blog entries.<br />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.<br /><br />Another thing that I changed (less important than the above, but daily used) is the operative system: I've switched from Microsoft Windows to <a href="http://www.kubuntu.org">Kubuntu Linux</a>.<br />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.<br /><br />However, I recently found 2 useful Linux hacks.<br /><br />First Hack: How to avoid duplicate commands in the bash history (when you hit arrow up in a shell).<br />Open <code>~/.bashrc</code>; at the beginning of the file there is an entry such as:<br /><code><br />export HISTCONTROL=erasedups<br /></code><br />It's probably remarked, or has another value. Setting it to 'erasedups' made the hack.<br /><br />Second Hack: How to correctly configure /etc/hosts when using DHCP.<br />It turns out that the dhcp client may run scripts when it binds (and when it releases).<br />The scripts for binding are <code>/etc/dhcp3/dhclient-enter-hooks</code>, and all the scripts inside directory <code>/etc/dhcp3/dhclient-enter-hooks.d/</code>.<br />Correspondent scripts for releasing are <code>/etc/dhcp3/dhclient-exit-hooks</code> and those inside directory <code>/etc/dhcp3/dhclient-exit-hooks.d/</code>.<br /><br />The script <code>dhclient-enter-hooks</code> was missing in my configuration. I created it and put this inside:<br /><pre><br />#!/bin/bash<br />#<br /># This script updates /etc/hosts with the address received by the DHCP server<br />#<br />HOSTS=/etc/hosts<br />BACKUP=${HOSTS}.original<br />LOCAL=${HOSTS}.local<br /><br />make_etc_hosts ()<br />{<br /> cp -a $HOSTS $BACKUP<br /> cat <<EOF > $HOSTS<br /># This file is generated by a script: do no edit; edit instead $LOCAL<br /># Created by $0 on `date`<br />127.0.0.1 localhost localhost.localdomain<br />$new_ip_address `hostname`<br /><br /># The following lines are desirable for IPv6 capable hosts<br />fe00::0 ip6-localnet<br />ff00::0 ip6-mcastprefix<br />ff02::1 ip6-allnodes<br />ff02::2 ip6-allrouters<br />ff02::3 ip6-allhosts<br /><br /># Entries from file $LOCAL, if any<br />EOF<br /><br /> test -f $LOCAL && cat $LOCAL >> $HOSTS<br />}<br /><br />if [ "$new_ip_address" ]; then<br /> make_etc_hosts<br />fi<br /></pre><br /><br />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.<br />Still not perfect (if you have multiple network interfaces), but it's possible to improve it. <br />For me, for now, does the job :)Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.comtag:blogger.com,1999:blog-8807910.post-1138555054629146122006-01-29T18:06:00.000+01:002006-11-16T01:01:02.253+01:00Job ChangeAfter more than 6 years in Hewlett-Packard, I decided to resign and take new challenges as a consultant.<br /><br />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 <a href="http://www.torino2006.org">Torino</a>.Simonhttp://www.blogger.com/profile/05495107326237735379noreply@blogger.com