<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" version="2.0">
   <channel>
      <title>Remove reviews</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=duu98WR83hGPulUQ_vrsUA</link>
      <atom:link rel="next" href="http://pipes.yahoo.com/pipes/pipe.run?_id=duu98WR83hGPulUQ_vrsUA&amp;_render=rss&amp;page=2" />
      <pubDate>Wed, 19 Jun 2013 13:02:16 +0000</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Hype-free" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="hype-free" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">Hype-free</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
         <title>Passing UTF-8 trough HTTP</title>
         <link>http://hype-free.blogspot.com/2013/05/passing-utf-8-trough-http.html</link>
         <description>&lt;p&gt;These days we should write every code as if it will be used by international people with a wide variety of personal information (just look at &lt;a rel="nofollow" target="_blank" href="http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/"&gt;Falsehoods Programmers Believe About Names&lt;/a&gt; for some headscratchers). I would like to do add my small contribution to this by showing how UTF-8 encoded strings can be passed into GET/POST parameters.&lt;/p&gt;

&lt;p&gt;For this I'll be using the following small PHP script, which can be quickly run by the &lt;a rel="nofollow" target="_blank" href="http://php.net/manual/en/features.commandline.webserver.php"&gt;command line PHP webserver&lt;/a&gt; added in PHP 5.4:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&amp;lt;?php header('Content-Type: text/html; charset=utf-8'); ?&amp;gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;
GETs: &amp;lt;?php print_r($_GET); ?&amp;gt;
POSTs: &amp;lt;?php print_r($_POST); ?&amp;gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;We'll test this with the following Python script:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
#!/usr/bin/python
# vim: set fileencoding=utf-8 :
import urllib
import urllib2

params = {'name': u'東京'}
params = { k: v.encode('utf-8') for k, v in params.iteritems() }
data = urllib.urlencode(params)

url = 'http://localhost:8000/?' + data
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)

print response.read()
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;This all works well and nicely, so here are some conclusions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET and POST variables need to be UTF-8 encoded after which they need to be urlencoded ("% encoded"). See &lt;a rel="nofollow" target="_blank" href="http://stackoverflow.com/a/1549498/1265"&gt;this StackOverflow answer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Based on the same answer: hostnames use Punycode instead (but we are not concerned with hostnames here)
&lt;li&gt;You might need to add the following header for POST requests to work: "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"&lt;/li&gt;
&lt;li&gt;Failing to observe this sequence leads to an UnicodeEncodeError in urllib.urlencode
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JaM4s0Y4d6E:7KV59fzBgZ8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JaM4s0Y4d6E:7KV59fzBgZ8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JaM4s0Y4d6E:7KV59fzBgZ8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=JaM4s0Y4d6E:7KV59fzBgZ8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JaM4s0Y4d6E:7KV59fzBgZ8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-4383322340808660042</guid>
         <pubDate>Wed, 29 May 2013 20:36:00 +0000</pubDate>
      </item>
      <item>
         <title>Connecting to the MtGox market data feed using Perl</title>
         <link>http://hype-free.blogspot.com/2013/05/connecting-to-mtgox-market-data-feed.html</link>
         <description>&lt;p&gt;For a recent project I needed some realistic market data for an electronic exchange. Seeing how MtGox provides free and open access to theirs (thank you!) I chose them. However none of the examples floating around the internet seemed to work, so I whipped one up using &lt;a rel="nofollow" target="_blank" href="http://search.cpan.org/~pevans/Net-Async-WebSocket-0.06/lib/Net/Async/WebSocket/Client.pm"&gt;Net::Async::WebSocket::Client&lt;/a&gt;. Enjoy:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
use IO::Async::Loop;
use Net::Async::WebSocket::Client;

my $client = Net::Async::WebSocket::Client-&amp;gt;new(
        on_frame =&amp;gt; sub {
                my ( $self, $frame ) = @_;
                print "&amp;#92;n", $frame, "&amp;#92;n";
        },
);

my $loop = IO::Async::Loop-&amp;gt;new;
$loop-&amp;gt;add( $client );

$client-&amp;gt;connect(
        host =&amp;gt; 'websocket.mtgox.com',
        service =&amp;gt; 80,
        url =&amp;gt; "ws://websocket.mtgox.com:80/mtgox",
        on_connected =&amp;gt; sub {},
        on_connect_error =&amp;gt; sub { die "Cannot connect - $_[-1]" },
        on_resolve_error =&amp;gt; sub { die "Cannot resolve - $_[-1]" },
);

$loop-&amp;gt;loop_forever;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;(it is basically the sample program for the module, with the MtGox market data URL hardcoded).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Mj0Hh94nc5A:aM9rISuvoE4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Mj0Hh94nc5A:aM9rISuvoE4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Mj0Hh94nc5A:aM9rISuvoE4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=Mj0Hh94nc5A:aM9rISuvoE4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Mj0Hh94nc5A:aM9rISuvoE4:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-2789241351129454146</guid>
         <pubDate>Wed, 29 May 2013 17:52:00 +0000</pubDate>
      </item>
      <item>
         <title>Converting datetime to UTC in python</title>
         <link>http://hype-free.blogspot.com/2013/02/converting-datetime-to-utc-in-python.html</link>
         <description>&lt;p&gt;So you need to convert a python datetime object which has a timezone set ("aware" in the Python nomenclature) to an UTC one with no timezone set ("naive"), for example because NDB on GAE &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/appengine-ndb-experiment/source/browse/ndb/model.py?r=6b3f88b663a82831e9ecee8adbad014ff774c365#1916"&gt;can't store anything else&lt;/a&gt;. The solution will look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;date = date.astimezone(tz.tzutc()).replace(tzinfo=None)&lt;/code&gt;&lt;/pre&gt;

For searcheability: the exception thrown by NDB if you fail to do this is "NotImplementedError: DatetimeProperty updated_at can only support UTC. Please derive a new Property to support alternative timezones."&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=UH_cWdnF-ds:fO4DRo2aVEc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=UH_cWdnF-ds:fO4DRo2aVEc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=UH_cWdnF-ds:fO4DRo2aVEc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=UH_cWdnF-ds:fO4DRo2aVEc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=UH_cWdnF-ds:fO4DRo2aVEc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-1043684528873679745</guid>
         <pubDate>Thu, 07 Feb 2013 19:06:00 +0000</pubDate>
      </item>
      <item>
         <title>Recovering your RoTLD password for domains registered trough Gandi.NET</title>
         <link>http://hype-free.blogspot.com/2013/02/recovering-your-rotld-password-for.html</link>
         <description>&lt;p&gt;If you need to "recover" your &lt;a rel="nofollow" target="_blank" href="http://www.rotld.ro/"&gt;RoTLD&lt;/a&gt; password when the .RO domain is registered trough Gandi.NET (I say "recover" because you didn't set it in the first place :-)) - do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Gandi interface go to Account Management -&amp;gt; Update account information and set "Anti-spam system" to No&lt;/li&gt;
&lt;li&gt;Go to the &lt;a rel="nofollow" target="_blank" href="https://domadmin2.rotld.ro/passwd_rec.html?lang=en"&gt;RoTLD password recovery page&lt;/a&gt; and reset your password. Now the password recovery email should have arrived to your inbox.&lt;/li&gt;
&lt;li&gt;(Optional) go back to the Gandi interface and re-enable the anti-spam system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed to do this to enable &lt;a rel="nofollow"&gt;CloudFlare&lt;/a&gt; on &lt;a rel="nofollow" target="_blank" href="http://it-events.ro"&gt;IT-Events.RO&lt;/a&gt; because RoTLD allows the changing of nameservers only trough their website.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Hrq2C1AuuMw:OE-h5GloAuA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Hrq2C1AuuMw:OE-h5GloAuA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Hrq2C1AuuMw:OE-h5GloAuA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=Hrq2C1AuuMw:OE-h5GloAuA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Hrq2C1AuuMw:OE-h5GloAuA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-8322733885146219521</guid>
         <pubDate>Tue, 05 Feb 2013 16:08:00 +0000</pubDate>
      </item>
      <item>
         <title>Free software for Windows</title>
         <link>http://hype-free.blogspot.com/2013/01/free-software-for-windows.html</link>
         <description>&lt;p&gt;Inspired by &lt;a rel="nofollow" target="_blank" href="http://alexj.info/2012/11/15/open-source-software-on-windows/"&gt;this post&lt;/a&gt; I decided to list the software I use/recommend under Windows.&lt;/p&gt;

&lt;p&gt;Free/Libre Open Source Software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.libreoffice.org/"&gt;LibreOffice&lt;/a&gt; (for of OpenOffice) - a very capable office solution. Most people don't need anything more than this. If you are installing it for a non-technical user, make sure to set the default file formats to the Microsoft ones (.doc, .xls, ...)&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.farmanager.com/opensource.php"&gt;Far Manager&lt;/a&gt; - a very cool two-panel file manager, for those of us who like text-based things (don't let the looks fool you - it is very modern and very capable). You could also take a look at &lt;a rel="nofollow" target="_blank" href="http://ndn.muxe.com/"&gt;NDN&lt;/a&gt; or &lt;a rel="nofollow" target="_blank" href="http://www.dnosp.com/"&gt;DNOSP&lt;/a&gt;, but FAR is my personal favorite.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.videolan.org/"&gt;VLC&lt;/a&gt; - THE video player. It can play 99.999% of the media out there and it won't pollute your system with all kinds of DLLs.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://ffdshow-tryout.sourceforge.net/"&gt;ffdshow-tryouts&lt;/a&gt; - DirectShow / VFW codecs for all the formats VLC can play (in fact they are both based on the &lt;a rel="nofollow" target="_blank" href="http://ffmpeg.org/"&gt;ffmpeg&lt;/a&gt; project). Use this to play back videos in programs which are DirectShow based (like WMP or Winamp).&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.7-zip.org/"&gt;7-zip&lt;/a&gt; - for all your zipping and unzipping needs. It supports a lot of other formats too (mainly for extracting) so no need to install the shareware version of WinRar&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.mozilla.org/en-US/firefox/new/"&gt;Firefox&lt;/a&gt; - 'nuff said. There are also a lot of plugins which one might find useful like &lt;a rel="nofollow" target="_blank" href="https://getfirebug.com/"&gt;Firebug&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://noscript.net/"&gt;NoScript&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="https://www.requestpolicy.com/"&gt;RequestPolicy&lt;/a&gt;, etc. As a download manager I would recommend &lt;a rel="nofollow" target="_blank" href="https://addons.mozilla.org/en-US/firefox/addon/downthemall/"&gt;DownThemAll&lt;/a&gt;, but I found that with recent increases in Internet access speeds I don't need a download manager.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.flos-freeware.ch/notepad2.html"&gt;Notepad2&lt;/a&gt; for your small (text) editing needs. There is also &lt;a rel="nofollow" target="_blank" href="http://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://xhmikosr.github.com/notepad2-mod/"&gt;notepad2-mod&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pdfforge.org/"&gt;PDFForge&lt;/a&gt; to create PDFs from any program which can print (it acts as a virtual printer which outputs its results to a PDF file). Sidenote: LibreOffice can natively save to PDF, no need for this if you're using it only for that.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pidgin.im/"&gt;Pidgin&lt;/a&gt; - you might know it as GAIM, a multi protocol instant messenger. And it is &lt;em&gt;very&lt;/em&gt; multi protocol. The only downside is that some advanced protocol features are not always functional (*cough* file-transfer, *cough*), but I find that I rarely use those anyways. If you are installing it for someone else however, make sure to ask them what features they consider essential (like custom background/emoticons) and act accordingly.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://winscp.net/eng/index.php"&gt;WinSCP&lt;/a&gt; to copy files trough SSH/SCP, and the &lt;a rel="nofollow" target="_blank" href="http://filezilla-project.org/"&gt;FileZilla client&lt;/a&gt; to do the same over FTP.&lt;/li&gt;
&lt;li&gt;Various specialized programs: &lt;a rel="nofollow" target="_blank" href="http://www.gimp.org/"&gt;GIMP&lt;/a&gt; for photo-editing, &lt;a rel="nofollow" target="_blank" href="http://inkscape.org/"&gt;Inkscape&lt;/a&gt; for vector-based graphics, &lt;a rel="nofollow" target="_blank" href="http://www.virtualdub.org/"&gt;VirtualDub&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://fixounet.free.fr/avidemux/"&gt;Avidemux&lt;/a&gt; for (linear) video editing, &lt;a rel="nofollow" target="_blank" href="http://www.wireshark.org/"&gt;Wireshark&lt;/a&gt; for network analysis, &lt;a rel="nofollow" target="_blank" href="http://audacity.sourceforge.net/"&gt;Audacity&lt;/a&gt; for audio editing, &lt;a rel="nofollow" target="_blank" href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;PuTTY&lt;/a&gt; as an SSH client, &lt;a rel="nofollow" target="_blank" href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt; for running virtual machines and &lt;a rel="nofollow" target="_blank" href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; for development (it can do more than Java!). There is also the &lt;a rel="nofollow" target="_blank" href="http://www.jetbrains.com/idea/free_java_ide.html"&gt;IntelliJ Community Edition&lt;/a&gt; for developement which &lt;em&gt;is&lt;/em&gt; Open Source Software, but be aware of &lt;a rel="nofollow" target="_blank" href="http://www.jetbrains.com/idea/features/editions_comparison_matrix.html"&gt;the limitations&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.apachefriends.org/en/xampp.html"&gt;XAMPP&lt;/a&gt; for quickly setting up a LAMP environment under Windows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free (as in beer) - these may try to trick you into installing toolbars / changing your homepage / your search engine so watch out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.teamviewer.com/"&gt;TeamViewer&lt;/a&gt; - a nice remote control solution (also cross platform - although it doesn't run perfectly on other OSs). I especially like the fact that it can run as a service and that it takes care of the NAT traversal problem.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://cdburnerxp.se/"&gt;CDBurnerXP&lt;/a&gt; - for burning optical media. Nothing special, but it works. &lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.irfanview.com/"&gt;IrfanView&lt;/a&gt; - a very capable image viewer / converter. Don't forget to install the plugins to take full advantage of its features! It is also so lightweight that won't believe how quickly the installation finishes. Watch out though, it tries to install sponsored programs :-(&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.freecommander.com/"&gt;FreeCommander&lt;/a&gt; - a two panel graphic file manager. Recommended if you're a Total/Windows Commander fan rather than a Norton Commander one :-)&lt;/li&gt;
&lt;li&gt;The &lt;a rel="nofollow" target="_blank" href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products"&gt;MS Visual Studio Express series&lt;/a&gt; - a good way to get your feet wet with MS specific development (also good for university projects), but be aware that you'll quickly hit a wall with it on professional projects.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.utorrent.com/"&gt;uTorrent&lt;/a&gt; for my downloading needs.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.daemon-tools.cc/eng/downloads"&gt;Daemon Tools Free&lt;/a&gt; for my ISO (CD/DVD/BR) mounting needs. Attention during install! It will try to "upgrade" you several times during install and also try to install additional software / change your home page / search provider if you just click trough next. Don't let it, form a technical point of view it is a great product. There is also the unsupported &lt;a rel="nofollow" target="_blank" href="http://www.softpedia.com/get/CD-DVD-Tools/Virtual-CD-DVD-Rom/Virtual-CDROM-Control-Panel.shtml"&gt;Virtual CD&lt;/a&gt; product from Microsoft and Windows can mount ISOs natively starting from Windows 7 I think.&lt;/li&gt;
&lt;li&gt;The &lt;a rel="nofollow" target="_blank" href="http://www.foxitsoftware.com/downloads/index.php"&gt;FoxIt PDF Reader&lt;/a&gt; - a lightweight PDF reader, although Adobe Reader X caught up nicely I feel (and they also auto-update to eliminate security vulnerabilities), so you could give it a second go.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.bbsoftware.co.uk/bbflashback.aspx"&gt;BB FlashBack Express&lt;/a&gt; for screen recording. Little annoying to install (you need to give them an email account, they try to upgrade you to the paid version and you need to "register" afterwards), but after installing it is all good and I found it to be a very capable product (even at the free version level).&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="https://www.google.com/intl/en/chrome/browser/"&gt;Chrome&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://www.opera.com/"&gt;Opera&lt;/a&gt; as alternative browsers (and no, Chrome is not Open Source, Chromium is).&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.getpaint.net/"&gt;Paint.NET&lt;/a&gt; for advanced but "not photoshop level" image editing.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.foobar2000.org/"&gt;foobar2000&lt;/a&gt; or &lt;a rel="nofollow" target="_blank" href="http://www.winamp.com/"&gt;Winamp&lt;/a&gt; (with the classic skin :-)) for music. foobar is very lightweight and quick, but it might lack some features. Winamp is very complete, but tries to make all kinds of changes to your system. You also probably don't need the Winamp Agent to run in the background all the time :-)&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="https://www.dropbox.com/"&gt;Dropbox&lt;/a&gt; for file synchronization / small-scale file serving. Alternatively there is &lt;a rel="nofollow" target="_blank" href="https://skydrive.live.com/"&gt;SkyDrive&lt;/a&gt;, but it isn't very Linux friendly.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://windows.microsoft.com/en-US/windows-live/essentials-other-programs?T1=t4"&gt;Windows Live Writer&lt;/a&gt; - the best blog publishing software I could find. Unfortunately Microsoft ruined it with the Office 2007 look and now seems to want to abandon it completely&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.skype.com/"&gt;Skype&lt;/a&gt; for video-call / teleconference, although lately I've been dropping it in favor of Google Hangouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: this software looks very promising: &lt;a rel="nofollow" target="_blank" href="http://ninite.com/"&gt;Ninite&lt;/a&gt;. It purports to auto-install and auto-update a lot of common Windows software. Will take it for a spin the next time I install Windows.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=H_Q_KKX3Axs:D_-LDwG--NQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=H_Q_KKX3Axs:D_-LDwG--NQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=H_Q_KKX3Axs:D_-LDwG--NQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=H_Q_KKX3Axs:D_-LDwG--NQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=H_Q_KKX3Axs:D_-LDwG--NQ:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-1060677568997250746</guid>
         <pubDate>Fri, 04 Jan 2013 01:36:00 +0000</pubDate>
      </item>
      <item>
         <title>What every programmer should know about X</title>
         <link>http://hype-free.blogspot.com/2012/12/what-every-programmer-should-know-about.html</link>
         <description>&lt;p&gt;Piggybacking on some memes floating around on the internet I would like to publish my list of "what every programmer should know".&lt;/p&gt;

&lt;p&gt;A couple of introductory words: in my opinion the two most important things to learn for new programmers are terminology - to know what things / ideas / algorithms / concepts are called so that they can search for them on the internet and discuss their ideas) and humility (if something doesn't exists or doesn't work the way we expected, the first thing we should ask ourselves is: "what am I missing?" instead of proclaiming the predecessors to be idiots). Moving along to the list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://multimedia.cx/eggs/what-every-programmer-should-know/"&gt;What every programmer should know about X&lt;/a&gt; - the Breaking Eggs And Making Omelettes blog contains a very eclectic list of articles. The only thing I would add is the &lt;a rel="nofollow"&gt;PDF link to "What every programmer should know about memory"&lt;/a&gt; rather than the LWN version. Also worth checking out the discussion in the comments.&lt;/li&gt;

&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.eecs.berkeley.edu/~rcs/research/interactive_latency.html"&gt;Latency numbers every programmer should know&lt;/a&gt; and the &lt;a rel="nofollow" target="_blank" href="https://news.ycombinator.com/item?id=4966363"&gt;discussion on hackernews&lt;/a&gt; (this is not the original source of the data, but a particularly good visualization of it nevertheless - see also &lt;a rel="nofollow" target="_blank" href="https://hype-free.googlecode.com/svn/trunk/latency.html"&gt;my extended version&lt;/a&gt; which allows you to transform the numbers into whichever time-unit - s, ms, us - you need).&lt;/li&gt;

&lt;li&gt;From the "Falsehoods programmers believe about X" department comes:
&lt;ul&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://pozorvlak.livejournal.com/174763.html"&gt;Falsehoods programmers believe about build systems&lt;/a&gt; (additionally to the comments on the post, also see &lt;a rel="nofollow" target="_blank" href="http://www.reddit.com/r/programming/comments/14eo9w/falsehoods_programmers_believe_about_build_systems/"&gt;the discussion on Reddit&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://www.evanjones.ca/build-java.html"&gt;a follow-up blogpost&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/"&gt;Falsehoods Programmers Believe About Names&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time"&gt;Falsehoods programmers believe about time&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time-wisdom"&gt;More falsehoods programmers believe about time&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;A video giving an overview of the different Google systems (search, map-reduce, GFS, etc). Nothing revolutionary, but a good first-time overview:&lt;br /&gt;&lt;/li&gt; 
&lt;/ul&gt;

&lt;p&gt;Happy holiday reading/watching to all!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=O5YpgzKylik:LhmCywgrs2I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=O5YpgzKylik:LhmCywgrs2I:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=O5YpgzKylik:LhmCywgrs2I:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=O5YpgzKylik:LhmCywgrs2I:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=O5YpgzKylik:LhmCywgrs2I:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-2206062760796395245</guid>
         <pubDate>Mon, 31 Dec 2012 11:24:00 +0000</pubDate>
      </item>
      <item>
         <title>Ensuring the order of execution for tasks</title>
         <link>http://hype-free.blogspot.com/2012/12/ensuring-order-of-execution-for-tasks.html</link>
         <description>&lt;p&gt;&lt;em&gt;This post was originally published as part of the &lt;a rel="nofollow" target="_blank" href="http://www.javaadvent.com/2012/12/ensuring-order-of-execution-for-tasks.html"&gt;Java Advent series&lt;/a&gt;. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the Java Advent blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! &lt;a rel="nofollow" target="_blank" href="mailto:dify.ltd@gmail.com"&gt;Contact Attila Balazs&lt;/a&gt; to contribute!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sometimes it is necessary to impose certain order on the tasks in a threadpool. &lt;a rel="nofollow" target="_blank" href="http://www.javaspecialists.eu/archive/Issue206.html"&gt;Issue 206 of the JavaSpecialists newsletter&lt;/a&gt; presents one such case: we have multiple connections from which we read using NIO. We need to ensure that events from a given connection are executed in-order but events between different connections can be freely mixed.&lt;/p&gt;

&lt;p&gt;I would like to present a similar but slightly different situation: we have N clients. We would like to execute events from a given client in the order they were submitted, but events from different clients can be mixed freely. Also, from time to time, there are "rollup" tasks which involve more than one client. Such tasks should block the tasks for all involved clients (but not more!). Let's see a diagram of the situation:&lt;/p&gt;

&lt;div class="separator" style="clear:both;text-align:center;"&gt;
&lt;img border="0" height="153" width="320" src="http://1.bp.blogspot.com/-TuCHb25JBqM/UNOOV5-EjwI/AAAAAAAAFo4/KoIJZOXz2Y8/s320/Untitled%2Bdrawing%2B%25281%2529.png"/&gt;&lt;/div&gt;

&lt;p&gt;As you can see tasks from client A and client B are happily processed in parallel until a "rollup" task comes along. At that point no more tasks of type A or B can be processed but an unrelated task C can be executed (provided that there are enough threads). The skeleton of such an executor is available &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/hype-free/source/browse/trunk/java-grouped-threadpool/src/main/java/com/blogger/hypefree/GroupedThreadPool.java"&gt;in my repository&lt;/a&gt;. The centerpiece is the following interface:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;public interface OrderedTask extends Runnable {
    boolean isCompatible(OrderedTask that);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using this interface the threadpool decides if two tasks may be run in parallel or not (A and B can be run in parallel if &lt;code&gt;A.isCompatible(B) &amp;&amp; B.isComaptible(A)&lt;/code&gt;). These methods should be implemented in a fast, non locking and time-invariant manner.&lt;/p&gt;

&lt;p&gt;The algorithm behind this threadpool is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the task to be added doesn't conflict with any existing tasks, add it to the thread with the fewest elements.&lt;/li&gt;
&lt;li&gt;If it conflicts with elements from exactly one thread, schedule it to be executed on that thread (and implicitly &lt;em&gt;after&lt;/em&gt; the conflicting elements which ensures that the order of submission is maintained)&lt;/li&gt;
&lt;li&gt;If it conflicts with multiple threads, add tasks (shown with red below) on all but the first one of them on which a task on the first thread will wait, after which it will execute the original task.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="separator" style="clear:both;text-align:center;"&gt;
&lt;img border="0" height="161" width="320" src="http://4.bp.blogspot.com/-IcwKi0hwcyA/UNSsiYecUPI/AAAAAAAAFpU/zk41QVcuxLo/s320/Untitled%2Bdrawing%2B%25282%2529.png"/&gt;&lt;/div&gt;

&lt;p&gt;More information about the implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code is only a proof-of-concept, some more would would be needed to make it production quality (it needs code for exception handling in tasks, proper shutdown, etc)&lt;/li&gt;
&lt;li&gt;For maximum performance it uses lock-free* structures where available: each worker thread has an associated ConcurrentLinkedQueue. To achieve the sleep-until-work-is-available semantics, an additional Semaphore is used**&lt;/li&gt;
&lt;li&gt;To be able to compare a new OrderedTask with currently executing ones, a copy of their reference is kept. This list of copies is updated whenever new elements are enqueued (this is has the potential of memory leaks and if tasks are infrequent enough alternatives - like an additional timer for weak references - should be investigated)&lt;/li&gt;
&lt;li&gt;Compared to the solution in the JavaSpecialists newsletter, this is more similar to a fixed thread pool executor, while the solution from the newsletter is similar to a cached thread pool executor.&lt;/li&gt;
&lt;li&gt;This implementation is ideal if (a) the tasks are (mostly) short and (mostly) uniform and (b) there are few (one or two) threads submitting new tasks, since multiple submissions are mutually exclusive (but submission and execution isn't)&lt;/li&gt;
&lt;li&gt;If immediately after a "rollup" is submitted (and before it can be executed) tasks of the same kind are submitted, they will unnecessarily be forced on one thread. We could add code rearrange tasks after the rollup task finished if this becomes an issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have fun with &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/hype-free/source/browse/trunk/java-grouped-threadpool/src/main/java/com/blogger/hypefree/GroupedThreadPool.java"&gt;the source code&lt;/a&gt;! (maybe some day I'll find the time to remove all the rough edges).&lt;/p&gt;

&lt;p&gt;* somewhat of a misnomer, since there are still locks, only at a lower - CPU not OS - level, but this is the accepted terminology&lt;/p&gt;

&lt;p&gt;** - benchmarking indicated this to be the most performant solution. This was inspired from the implementation of the ThreadPoolExecutor.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Meta: this post is part of the &lt;a rel="nofollow" target="_blank" href="http://javaadvent.com/"&gt;Java Advent Calendar&lt;/a&gt; and is licensed under the &lt;a rel="nofollow" target="_blank" href="https://creativecommons.org/licenses/by/3.0/"&gt;Creative Commons 3.0 Attribution&lt;/a&gt; license. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! &lt;a rel="nofollow" target="_blank" href="mailto:dify.ltd@gmail.com"&gt;Contact Attila Balazs&lt;/a&gt; to contribute!&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=yHNZ7CtN4PQ:K_WXwD0RLwk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=yHNZ7CtN4PQ:K_WXwD0RLwk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=yHNZ7CtN4PQ:K_WXwD0RLwk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=yHNZ7CtN4PQ:K_WXwD0RLwk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=yHNZ7CtN4PQ:K_WXwD0RLwk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-8791452078127574531</guid>
         <pubDate>Fri, 21 Dec 2012 21:13:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://1.bp.blogspot.com/-TuCHb25JBqM/UNOOV5-EjwI/AAAAAAAAFo4/KoIJZOXz2Y8/s72-c/Untitled%2Bdrawing%2B%25281%2529.png" width="72" />
      </item>
      <item>
         <title>Java Runtime options</title>
         <link>http://hype-free.blogspot.com/2012/12/java-runtime-options.html</link>
         <description>&lt;p&gt;&lt;em&gt;This post was originally published as part of the &lt;a rel="nofollow" target="_blank" href="http://www.javaadvent.com/2012/12/java-runtime-options.html"&gt;Java Advent series&lt;/a&gt;. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the Java Advent blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! &lt;a rel="nofollow" target="_blank" href="mailto:dify.ltd@gmail.com"&gt;Contact Attila Balazs&lt;/a&gt; to contribute!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Java runtime is a complex beast - and it has to be since it runs officially on seven platforms and unofficially on many more. Give this, it is normal that there are many knobs and dials to control how things function. The more well known ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;-Xmx for the maximum heap size&lt;/li&gt;
&lt;li&gt;-client and -server for selecting the default set of parameters from classes of defaults&lt;/li&gt;
&lt;li&gt;-XX:MaxPermGen for controlling the permanent generation size&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other than these, it is (very) rarely the case that you need to change the defaults. However, thanks to Java being open source you can see the list of options, their default values and a short explanation directly &lt;a rel="nofollow" target="_blank" href="http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/b92c45f2bc75/src/share/vm/runtime/globals.hpp"&gt;from the source code&lt;/a&gt;. Currently there are almost 800 options in there!&lt;/p&gt;

&lt;p&gt;An other way to see the options (but one which doesn't display the explanations unfortunately) is the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code style=""&gt;java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These options are well worth studying. Not for tweaking them (since there is a wealth of testing behind the defaults the extent of which would be very hard to replicate), but rather to understand the different functionalities offered by the JVM (for example &lt;a rel="nofollow" target="_blank" href="http://hype-free.blogspot.com/2009/07/why-cant-i-see-stacktrace-under-java.html"&gt;why you might not see stacktraces in exceptions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Meta: this post is part of the &lt;a rel="nofollow" target="_blank" href="http://javaadvent.com/"&gt;Java Advent Calendar&lt;/a&gt; and is licensed under the &lt;a rel="nofollow" target="_blank" href="https://creativecommons.org/licenses/by/3.0/"&gt;Creative Commons 3.0 Attribution&lt;/a&gt; license. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! &lt;a rel="nofollow" target="_blank" href="mailto:dify.ltd@gmail.com"&gt;Contact Attila Balazs&lt;/a&gt; to contribute!&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=ckiBUUaE5VE:b8jxsyj6Ybo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=ckiBUUaE5VE:b8jxsyj6Ybo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=ckiBUUaE5VE:b8jxsyj6Ybo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=ckiBUUaE5VE:b8jxsyj6Ybo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=ckiBUUaE5VE:b8jxsyj6Ybo:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-5208867376045395362</guid>
         <pubDate>Fri, 21 Dec 2012 21:06:00 +0000</pubDate>
      </item>
      <item>
         <title>Changes to String.substring in Java 7</title>
         <link>http://hype-free.blogspot.com/2012/12/changes-to-stringsubstring-in-java-7.html</link>
         <description>&lt;p&gt;&lt;em&gt;This post was originally published as part of the &lt;a rel="nofollow" target="_blank" href="http://www.javaadvent.com/2012/12/changes-to-stringsubstring-in-java-7.html"&gt;Java Advent series&lt;/a&gt;. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the Java Advent blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! &lt;a rel="nofollow" target="_blank" href="mailto:dify.ltd@gmail.com"&gt;Contact Attila Balazs&lt;/a&gt; to contribute!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is common knowledge that Java optimizes the substring operation for the case where you generate a lot of substrings of the same source string. It does this by using the &lt;code&gt;(value, offset, count)&lt;/code&gt; way of storing the information. See an example below:&lt;/p&gt;

&lt;div class="separator" style="text-align:center;"&gt;
&lt;img border="0" height="124" width="320" src="http://4.bp.blogspot.com/-gnaLPXGMeUQ/UMIaKhQ5wsI/AAAAAAAAFn8/wNPgGPtE2qY/s320/Untitled%2Bdrawing.png"/&gt;&lt;/div&gt;

&lt;p&gt;In the above diagram you see the strings "Hello" and "World!" derived from "Hello World!" and the way they are represented in the heap: there is one character array containing "Hello World!" and two references to it. This method of storage is advantageous in some cases, for example for a compiler which tokenizes source files. In other instances it may lead you to an OutOfMemorError (if you are routinely reading long strings and only keeping a small part of it - but the above mechanism prevents the GC from collecting the original String buffer). Some even &lt;a rel="nofollow" target="_blank" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4513622"&gt;call it a bug&lt;/a&gt;. I wouldn't go so far, but it's certainly a leaky abstraction because you were forced to do the following to ensure that a copy was made: &lt;code&gt;new String(str.substring(5, 6))&lt;/code&gt;.&lt;/p&gt;

&lt;div class="separator" style="text-align:center;"&gt;
&lt;img border="0" height="107" width="320" src="http://3.bp.blogspot.com/-NGSJS_psCIc/UMW40g0NLXI/AAAAAAAAFoQ/7kfOVA8JdC0/s320/Untitled%2Bdrawing.png"/&gt;&lt;/div&gt;

&lt;p&gt;This all changed in &lt;a rel="nofollow" target="_blank" href="http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-May/010257.html"&gt;May of 2012&lt;/a&gt; or Java 7u6. The pendulum is swung back and now full copies are made by default. What does this mean for you?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For most probably it is just a nice piece of Java trivia&lt;/li&gt;
&lt;li&gt;If you are writing parsers and such, you can not rely any more on the implicit caching provided by String. You will need to implement a similar mechanism based on buffering and a custom implementation of CharSequence&lt;/li&gt;
&lt;li&gt;If you were doing &lt;code&gt;new String(str.substring)&lt;/code&gt; to force a copy of the character buffer, you can stop as soon as you update to the latest Java 7 (and you need to do that quite soon since &lt;a rel="nofollow" target="_blank" href="https://blogs.oracle.com/java/entry/end_of_public_updates_for"&gt;Java 6 is being EOLd as we speak&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thankfully the development of Java is an open process and such information is at the fingertips of everyone!&lt;/p&gt;

&lt;p&gt;A couple of more references (since we don't say pointers in Java :-)) related to Strings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are storing the same string over and over again (maybe you're parsing messages from a socket for example), you should &lt;a rel="nofollow" target="_blank" href="http://hype-free.blogspot.ro/2010/03/stringintern-there-are-better-ways.html"&gt;read up on alternatives to String.intern()&lt;/a&gt; (and also consider reading chapter 50 from the second edition of Effective Java: Avoid strings where other types are more appropriate)&lt;/li&gt;
&lt;li&gt;Look into (and do benchmarks before using them!) options like UseCompressedStrings (which &lt;a rel="nofollow" target="_blank" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7129417"&gt;seems to have been removed&lt;/a&gt;), UseStringCache and StringCache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope I didn't strung you along too much and you found this useful! Until next time&lt;br&gt;
- Attila Balazs&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Meta: this post is part of the &lt;a rel="nofollow" target="_blank" href="http://javaadvent.com/"&gt;Java Advent
Calendar&lt;/a&gt; and is licensed under the &lt;a rel="nofollow" target="_blank" href="https://creativecommons.org/licenses/by/3.0/"&gt;Creative Commons 3.0 Attribution&lt;/a&gt; license. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! &lt;a rel="nofollow" target="_blank" href="mailto:dify.ltd@gmail.com"&gt;Contact Attila Balazs&lt;/a&gt; to contribute!&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=KD1G7hQwpYQ:BXkK3Q62Hc8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=KD1G7hQwpYQ:BXkK3Q62Hc8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=KD1G7hQwpYQ:BXkK3Q62Hc8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=KD1G7hQwpYQ:BXkK3Q62Hc8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=KD1G7hQwpYQ:BXkK3Q62Hc8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-5507142286564464246</guid>
         <pubDate>Wed, 12 Dec 2012 10:37:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://4.bp.blogspot.com/-gnaLPXGMeUQ/UMIaKhQ5wsI/AAAAAAAAFn8/wNPgGPtE2qY/s72-c/Untitled%2Bdrawing.png" width="72" />
      </item>
      <item>
         <title>(Re)Start me up!</title>
         <link>http://hype-free.blogspot.com/2012/12/restart-me-up.html</link>
         <description>&lt;p&gt;&lt;em&gt;This post was originally published as part of the &lt;a rel="nofollow" target="_blank" href="http://www.javaadvent.com/2012/12/restart-me-up.html"&gt;Java Advent series&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are cases where you would like to start a Java process identical to the current one (or at least using the the same JVM with tweaked parameters). Some concrete cases where this would be useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auto-tuning the maximum memory parameters (ie. you have an algorithm to determine the optimal value - for example: 80% of the system memory - and your JVM wasn't started with that particular value)&lt;/li&gt;
&lt;li&gt;Creating a cluster of processes for high(er)-availability (true HA implies multiple physical nodes) or because processes have different roles (like the components in MongoDB).&lt;/li&gt;
&lt;li&gt;Daemonizing the current process (that is, the background process should run even after the launching process has terminated) - this is a very frequent modus-operandi for programs on *nix systems where you have the foreground "control" process and the background "daemon" process (not to be confused with the "daemon" threads).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing this is relatively simple - and can be done in pure Java - after you find the correct API calls:&lt;/p&gt;

&lt;code&gt;&lt;pre style="overflow:auto;"&gt;
List arguments = new ArrayList&amp;lt;&amp;gt;();
// the java executable
arguments
  .add(String.format("%s%sbin%sjava",
    System.getProperty("java.home"), File.separator,
    File.separator));
// pre-execuable arguments (like -D, -agent, etc)
arguments.addAll(ManagementFactory.getRuntimeMXBean()
  .getInputArguments());

String classPath = System.getProperty("java.class.path"), javaExecutable = System
  .getProperty("sun.java.command");
if (classPath.equals(javaExecutable)) {
 // was started with -jar
 arguments.add("-jar");
 arguments.add(javaExecutable);
} else {
 arguments.add("-classpath");
 arguments.add(classPath);
 arguments.add(javaExecutable);
}

// we might add additional arguments here which will be received by the
// launched program
// in its args[] paramater
arguments.add("runme");

// launch it!
new ProcessBuilder().command(arguments).start();
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Some explanations about to the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is largely inspired from &lt;a rel="nofollow" target="_blank" href="https://github.com/brianm/gressil"&gt;this project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;We suppose that the java executable is named &lt;code&gt;java&lt;/code&gt; and is located in &lt;code&gt;bin/java&lt;/code&gt; relative to &lt;code&gt;&lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getProperties%28%29"&gt;java.home&lt;/a&gt;&lt;/code&gt;. We use &lt;code&gt;File.separator&lt;/code&gt; for the code to be portable.&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments%28%29"&gt;getInputArguments&lt;/a&gt; is used to get specific arguments passed to the JVM (like &lt;code&gt;-Xmx&lt;/code&gt;). It does &lt;strong&gt;not&lt;/strong&gt; include the classpath.&lt;/li&gt;
&lt;li&gt;Which is taken from &lt;code&gt;java.class.path&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Finally, there is one heuristic step: we try to detect if we were launched using the &lt;code&gt;-jar myjar.jar&lt;/code&gt; syntax or the &lt;code&gt;MyMainClass&lt;/code&gt; syntax and replicate it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is it! After that we use &lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html"&gt;ProcessBuilder&lt;/a&gt; (which we should always favour over Runtime.exec because it auto-escapes the parts of the command line for us).&lt;/p&gt;

&lt;p&gt;A final thought: if you intend to use this method to "daemonize" a process (that is: to ensure that it stays running after its parent process has terminated) you should do two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redirect the standard input and output. By default they are redirected into temporary buffers and the JVM will seemingly randomly terminate when those buffers (pipes) fill up.&lt;/li&gt;
&lt;li&gt;Under Windows use &lt;code&gt;javaw&lt;/code&gt; instead of &lt;code&gt;java&lt;/code&gt;. This ensures that the process won't be tied to the console it was started from (however it will still be tied to the user login session and will terminate when the user logs out - for a more heavy-duty solution look into the &lt;a rel="nofollow" target="_blank" href="http://wrapper.tanukisoftware.com/doc/english/download.jsp"&gt;Java Service Wrapper&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is it for today, hope you enjoyed it, fond it useful. If you run the code and it doesn't work as advertised, let me know so that I can update it (I'm especially interested if it works with non Sun/Oracle JVMs). Come back tomorrow for an other article!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Meta: this post is part of the &lt;a rel="nofollow" target="_blank" href="http://javaadvent.com/"&gt;Java Advent Calendar&lt;/a&gt; and is licensed under the &lt;a rel="nofollow" target="_blank" href="https://creativecommons.org/licenses/by/3.0/"&gt;Creative Commons 3.0 Attribution&lt;/a&gt; license.&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=id-uPshflXk:0Zi-eRlJdjU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=id-uPshflXk:0Zi-eRlJdjU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=id-uPshflXk:0Zi-eRlJdjU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=id-uPshflXk:0Zi-eRlJdjU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=id-uPshflXk:0Zi-eRlJdjU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-1364431065495135182</guid>
         <pubDate>Sat, 01 Dec 2012 18:24:00 +0000</pubDate>
      </item>
      <item>
         <title>Upgrading from MySQL to MariaDB on Ubuntu</title>
         <link>http://hype-free.blogspot.com/2012/11/upgrading-from-mysql-to-mariadb-on.html</link>
         <description>&lt;p&gt;So you decided that Oracle doesn't know its left foot from the back of his neck when it comes to open source (how's that for a mixed metaphor), but you are not ready just yet to migrate over to PostgreSQL? Consider &lt;a rel="nofollow" target="_blank" href="https://en.wikipedia.org/wiki/MariaDB"&gt;MariaDB&lt;/a&gt;. Coming from Monty Widenius, the original author of MySQL, it aims to be 100% MySQL compatible while also being truly open-source.&lt;/p&gt;

&lt;p&gt;Give that it's 100% MySQL compatible, you can update in-place (nevertheless it is recommended that do a backup of your data first). The steps are roughly adapted from &lt;a rel="nofollow" target="_blank" href="http://www.sagetree.com/sage-advice/christoph-weber/replace-mysql-mariadb-ubuntu-1204-lts"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a rel="nofollow" target="_blank" href="https://downloads.mariadb.org/mariadb/repositories/"&gt;MariaDB repository configuration tool&lt;/a&gt; and generate your .list file (wondering what's up with the 5.5 vs 10.0 version? See &lt;a rel="nofollow" target="_blank" href="https://en.wikipedia.org/wiki/MariaDB#Versioning"&gt;this short explanation&lt;/a&gt;). You don't know the exact Ubuntu version you're running? Just use &lt;code&gt;lsb_release -a&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save the generated file under &lt;code&gt;/etc/apt/sources.list.d/MariaDB.list&lt;/code&gt; as recommended and do an &lt;code&gt;sudo aptitude update&lt;/code&gt;. You should see an output complaining about some public keys.&lt;/li&gt;
&lt;li&gt;Do &lt;code&gt;sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xCBCB082A1BB943DB&lt;/code&gt; to add those keys (replace the last number with the one you saw in the previous output).&lt;/li&gt;
&lt;li&gt;Issue &lt;code&gt;sudo apt-cache policy mysql-common&lt;/code&gt; and you should see mariadb as an upgrade option.&lt;/li&gt;
&lt;li&gt;Finally do &lt;code&gt;sudo aptitude upgrade mysql-common libmysqlclient18&lt;/code&gt; and watch your MySQL database being transformed into a MariaDB one and all keeping chugging along just as usual!&lt;/li&gt;
&lt;/ol&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=55E7hMkUQ-M:fXq48xwe88A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=55E7hMkUQ-M:fXq48xwe88A:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=55E7hMkUQ-M:fXq48xwe88A:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=55E7hMkUQ-M:fXq48xwe88A:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=55E7hMkUQ-M:fXq48xwe88A:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-7376268120426324490</guid>
         <pubDate>Sun, 25 Nov 2012 11:14:00 +0000</pubDate>
      </item>
      <item>
         <title>Cluj-Napoca (Romania) wins the title of European Youth Capital 2015</title>
         <link>http://hype-free.blogspot.com/2012/11/cluj-napoca-romania-wins-title-of.html</link>
         <description>&lt;p&gt;We interrupt our regular (lack of) posting to bring you this news:&lt;/p&gt;

&lt;div class="separator" style="clear:both;text-align:center;"&gt;
&lt;img border="0" height="213" width="320" src="http://4.bp.blogspot.com/-cJh3GYVhtbA/ULHdZ2-l8pI/AAAAAAAAFkU/CeHgOqxbKhA/s320/18089_10151270244849851_235858203_n.jpg"/&gt;&lt;/div&gt;

&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://youthforum.org/index.php?option=com_content&amp;view=category&amp;layout=blog&amp;id=28&amp;Itemid=89&amp;lang=en"&gt;Cluj-Napoca is European Youth Capital 2015&lt;/a&gt;. Congratulation to everyone involved!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=M_pxKUUbRC0:nhuJOcdcj4g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=M_pxKUUbRC0:nhuJOcdcj4g:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=M_pxKUUbRC0:nhuJOcdcj4g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=M_pxKUUbRC0:nhuJOcdcj4g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=M_pxKUUbRC0:nhuJOcdcj4g:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-6934616080365182407</guid>
         <pubDate>Sun, 25 Nov 2012 10:58:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://4.bp.blogspot.com/-cJh3GYVhtbA/ULHdZ2-l8pI/AAAAAAAAFkU/CeHgOqxbKhA/s72-c/18089_10151270244849851_235858203_n.jpg" width="72" />
      </item>
      <item>
         <title>Writing beautiful code - not just for the aesthetic value</title>
         <link>http://hype-free.blogspot.com/2012/11/writing-beautiful-code-not-just-for.html</link>
         <description>&lt;p&gt;&lt;em&gt;This article was originally published in &lt;a rel="nofollow" target="_blank" href="http://www.todaysoftmag.com/article/ro/6/A_scrie_cod_frumos_-_dincolo_de_valoarea_estetica_159"&gt;the 6th edition of TodaySoftMag in Romanian&lt;/a&gt; and on the &lt;a rel="nofollow" target="_blank" href="http://www.transylvania-jug.org/archives/5477"&gt;Transylvania JUG blog in English&lt;/a&gt;. Reprinted here with the permission of the author / magazine.&lt;/em&gt;&lt;/p&gt;

&lt;center&gt;&lt;/center&gt; 

&lt;p&gt;Most mainstream programming languages contain a large set of features and diverse standard libraries. Because of this it becomes important to know not only “how” you can achieve something (to which there are usually several answers) but also “what is the recommended way”.&lt;/p&gt;

&lt;p&gt;In this article I will argue that knowing and following the recommended ways of coding doesn’t only yield shorter (easier to write), easier to read, understand and maintain code but also prevents programmers from introducing a lot of bugs.&lt;/p&gt;

&lt;p&gt;This particular article needs a drop of Java language knowledge to savour, but the fundamental idea can be generalized to any programming language: there is more to using a language efficiently than just knowing the syntax.&lt;/p&gt;

&lt;h2&gt;&lt;a rel="nofollow" id="h.71vcwrw1xmys" name="h.71vcwrw1xmys"&gt;&lt;/a&gt;Example 1: Double Trouble&lt;/h2&gt;

&lt;p&gt;Lets start with a snippet of code: what does it print out?&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;Double d1 = (5.0d - 5.0d) *  1.0d;
Double d2 = (5.0d - 5.0d) * -1.0d;
System.out.println(d1.equals(d2));
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;What about the following one?&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;double d1 = (5.0d - 5.0d) *  1.0d;
double d2 = (5.0d - 5.0d) * -1.0d;
System.out.println(d1 == d2);
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;The answer seems to be clear: in both cases we multiply zero with different values (plus and minus one respectively), thus the result should be zero which should compare as equal regardless of the comparison method used (calling the equals method on objects or using the equality operator on the primitive values).&lt;/p&gt;

&lt;p&gt;If we run the code, the result might surprise us: the first one displays false while the second one displays true. What’s going on? On one level we can talk the technical reasons behind this result: floating point values are represented in Java (and many other programming languages) using the sign-and-magnitude notation defined in the IEEE Standard 754. Because of this technical detail both “plus zero” and “minus zero” can be represented by variables of this type. And the “equals” method on Double (and Float) objects in Java considers these values to be distinct.&lt;/p&gt;

&lt;p&gt;On another level however we could have avoided this problem entirely by using the primitive values as shown in the second code snippet and as suggested by Item 49 in the Effective Java book&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt1" id="ftnt_ref1" name="ftnt_ref1"&gt;[1]&lt;/a&gt;&lt;/sup&gt;: Prefer primitive types to boxed primitives. Using primitive types is also more memory efficient and saves us from having to create special cases for the null value.&lt;/p&gt;

&lt;p&gt;Sidenote: we have a similar situation with the BigDecimal class&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt2" id="ftnt_ref2" name="ftnt_ref2"&gt;[2]&lt;/a&gt;&lt;/sup&gt; where values scaled differently don’t compare as equal. For example the following snippet also prints false:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;BigDecimal d1 = new BigDecimal("1.2");
BigDecimal d2 = new BigDecimal("1.20");
System.out.println(d1.equals(d2));
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;The answer in this case (given that there is no primitive equivalent for this class) would be to use the compareTo method and assert that it returns zero instead of using the equals method (a method which can also be used to solve the conundrum in the Double/Float case if we are not worried about nulls).&lt;/p&gt;

&lt;h2&gt;&lt;a rel="nofollow" id="h.t3ulkiuv7mcw" name="h.t3ulkiuv7mcw"&gt;&lt;/a&gt;Example 2: Where is my null at?&lt;/h2&gt;

&lt;p&gt;What does the following snippet of code print out?&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;Double v = null;
Double d = true ? v : 0.0d;
System.out.println(d);
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;At first glance we would say: null, since the condition is true and v is null (and null can be assigned to a reference of any type, so we are allowed to use it). The actual result is however a NullPointerException at the second line. This is because the right-hand type of the assignment is actually double (the primitive type) not Double (as we would expect) which is silently converted into Double (the boxed type). The generated code looks like this:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;Double d = Double.valueOf(true ? v.doubleValue() : 0.0d);&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;This behavior is described in the Java Language Specification&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt3" id="ftnt_ref3" name="ftnt_ref3"&gt;[3]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;p&gt;“If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.”&lt;/p&gt;

&lt;p&gt;I would venture to guess that not many of us have read the JLS in its entirety and even if we would have read it, we might not have realized the implications of each phrase. The recommendation from EJ2nd mentioned at the previous example saves us again: we should use primitive types. We can also draw a parallel with Item 43: Return empty arrays or collections, not nulls. Would we have used a “neutral element”, which is analogous to using empty arrays/collections, the problem would not have appeared. (The neutral element would be 0.0d if we use the value later in summation or 1.0d  if we use it in multiplication.)&lt;/p&gt;

&lt;h2&gt;&lt;a rel="nofollow" id="h.1mt6ca4376w9" name="h.1mt6ca4376w9"&gt;&lt;/a&gt;Example 3: We come up empty&lt;/h2&gt;

&lt;p&gt;What is the difference between the following two conditions?&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;Collection&amp;lt;V&amp;gt; items;
if (items.size() == 0) { ... }
if (items.isEmpty()) { ... }
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;One could argue that they do exactly the same thing as being empty is equivalent to having zero items. Still, the second condition is easier to understand (we can almost read it out loud: “if items is empty then …”). But there is more: in some cases it can be much, much faster. Two examples from the Java standard libraries where the time needed to execute “size” grows linearly with the number of elements in the collection while “isEmpty” returns in constant time: ConcurrentLinkedQueue&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt4" id="ftnt_ref4" name="ftnt_ref4"&gt;[4]&lt;/a&gt;&lt;/sup&gt; and the view sets returned by TreeSet’s&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt5" id="ftnt_ref5" name="ftnt_ref5"&gt;[5]&lt;/a&gt;&lt;/sup&gt; headSet/tailSet methods. And while the documentation for the first mentions this fact, it doesn’t for the second.&lt;/p&gt;

&lt;p&gt;This is yet another example how nicer code is also faster.&lt;/p&gt;

&lt;h2&gt;&lt;a rel="nofollow" id="h.orqngpa6ggt9" name="h.orqngpa6ggt9"&gt;&lt;/a&gt;Example 4: Careful with that static, Eugene!&lt;/h2&gt;

&lt;p&gt;What will the following snippet of code print out?&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;public final class Test {
        private static final class Foo {
                static final Foo INSTANCE = new Foo(); // 2
                static final String NAME = Foo.class.getName(); // 3
                Foo() {
                        System.err.println("Hello, my name is " + NAME);
                }
        }
        public static void main(String[] args) {
                System.err.println("Your name is what?&amp;#92;nYour name is who?&amp;#92;n");
                new Foo(); // 1
        }
}
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;It will be&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;Your name is what?
Your name is who?

Hello, my name is &lt;strong&gt;null&lt;/strong&gt;
Hello, my name is Test$Foo
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;The (probably) unexpected null value happens because we obtain a reference to a partially constructed object:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;We start to create an instance of Foo at point 1&lt;/li&gt;
    &lt;li&gt;This being the first reference to Foo, the JVM loads it and starts to initialize it&lt;/li&gt;
    &lt;li&gt;Initializing Foo involves initializing all its static fields&lt;/li&gt;
    &lt;li&gt;The initialization of the first static field contains a call to the constructor at point 2 which is dutifully executed&lt;/li&gt;
    &lt;li&gt;At this point the NAME static field is not yet initialized, so the constructor will print out null&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This code demonstrates that static fields can be confusing and we shouldn’t use them for things other than constants (but even then we should evaluate if the constant is not better declared as an Enum). By the same token we should also avoid singletons which make our code harder to test (thus avoiding them will make the code easier to test).&lt;/p&gt;

&lt;p&gt;We should however favor static member classes over non-static ones (Item 22 in EJ2nd). Static classes in Java are entirely distinct conceptually from static fields and it is unfortunate that the same word was used to describe them both.&lt;/p&gt;

&lt;p&gt;We should also run static analysis tools on our code and verify their output frequently (ideally at every commit). For example the bug presented is caught by Findbugs&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt6" id="ftnt_ref6" name="ftnt_ref6"&gt;[6]&lt;/a&gt;&lt;/sup&gt; and tools incorporating Findbugs.&lt;/p&gt;

&lt;h2&gt;&lt;a rel="nofollow" id="h.26ynxgfuhslr" name="h.26ynxgfuhslr"&gt;&lt;/a&gt;Example 5: Remove old cruft&lt;/h2&gt;

&lt;p&gt;Name four things wrong with the following snippet:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;// WRONG! DON’T DO THIS!
Vector v1;
...
if (!v1.contains(s)) { v1.add(s); }
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;They would be:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;The wrong container type is used. We clearly want to have each string present at most once which suggests using a Set&amp;lt;&amp;gt; which has the benefits of shorter and faster code (the above method gets linearly slower with the number of elements)&lt;/li&gt;
    &lt;li&gt;Doesn’t use generics&lt;/li&gt;
    &lt;li&gt;It unnecessarily synchronizes access to the structure if it is only used from a single thread&lt;/li&gt;
    &lt;li&gt;If the structure is actually used from multiple threads, the code is not thread safe, only “exception safe” (as in: no exceptions will be raised, but the data structure can be silently corrupted possibly creating a lot of headache downstream)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these can be avoided by dropping Vector and its siblings (Hashtable, StringBuffer) and using the Java Collection Framework (available for 14 years&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt7" id="ftnt_ref7" name="ftnt_ref7"&gt;[7]&lt;/a&gt;&lt;/sup&gt;) with generics (available for 8 years&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt8" id="ftnt_ref8" name="ftnt_ref8"&gt;[8]&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt;

&lt;h2&gt;&lt;a rel="nofollow" id="h.t7tt7vdn4ji9" name="h.t7tt7vdn4ji9"&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;There are many more examples one could give, but I think the point is well made that knowing a programming language means more than just knowing the syntax at a basic level. I’m urging you if you are using Java: get yourself a copy “Effective Java, 2nd edition” and “Java™ Puzzlers: Traps, Pitfalls, and Corner Cases” each and read through them if you haven’t done so already. Also, use static analysis on your code (Sonar&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt9" id="ftnt_ref9" name="ftnt_ref9"&gt;[9]&lt;/a&gt;&lt;/sup&gt; is a good choice in this domain) and consider fixing the issues signaled by it, or at least read up on them.&lt;/p&gt;

&lt;p&gt;Again, the conclusions is similar for other languages:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Try reading up on best practices/idiomatic ways to write code in the given language. For example for Perl the best book currently is “Modern Perl&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt10" id="ftnt_ref10" name="ftnt_ref10"&gt;[10]&lt;/a&gt;&lt;/sup&gt;” by chromatic&lt;/li&gt;
    &lt;li&gt;Look to see if there is a good quality static analysis / lint program for your language. For Perl there is Perl::Critic&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt11" id="ftnt_ref11" name="ftnt_ref11"&gt;[11]&lt;/a&gt;&lt;/sup&gt;, for Python there is pep8&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt12" id="ftnt_ref12" name="ftnt_ref12"&gt;[12]&lt;/a&gt;&lt;/sup&gt; and pylint&lt;sup&gt;&lt;a rel="nofollow" href="#ftnt13" id="ftnt_ref13" name="ftnt_ref13"&gt;[13]&lt;/a&gt;&lt;/sup&gt;, all of which are free and open source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being good a programmer (or an architect, or a business analyst, etc) is process of lifelong learning and these are the tools which can help us truly learn a programming language.&lt;/p&gt;
&lt;hr&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref1" id="ftnt1" name="ftnt1"&gt;[1]&lt;/a&gt;Joshua Bloch: Effective Java, Second Edition. ISBN: 0321356683&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref2" id="ftnt2" name="ftnt2"&gt;[2]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html"&gt;http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref3" id="ftnt3" name="ftnt3"&gt;[3]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25"&gt;http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref4" id="ftnt4" name="ftnt4"&gt;[4]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html#size()"&gt;http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html#size()&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref5" id="ftnt5" name="ftnt5"&gt;[5]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html"&gt;http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref6" id="ftnt6" name="ftnt6"&gt;[6]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://findbugs.sourceforge.net/bugDescriptions.html#SI_INSTANCE_BEFORE_FINALS_ASSIGNED"&gt;http://findbugs.sourceforge.net/bugDescriptions.html#SI_INSTANCE_BEFORE_FINALS_ASSIGNED&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref7" id="ftnt7" name="ftnt7"&gt;[7]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Java_version_history#J2SE_1.2_.28December_8.2C_1998.29"&gt;http://en.wikipedia.org/wiki/Java_version_history#J2SE_1.2_.28December_8.2C_1998.29&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref8" id="ftnt8" name="ftnt8"&gt;[8]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Java_version_history#J2SE_5.0_.28September_30.2C_2004.29"&gt;http://en.wikipedia.org/wiki/Java_version_history#J2SE_5.0_.28September_30.2C_2004.29&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref9" id="ftnt9" name="ftnt9"&gt;[9]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://www.sonarsource.org/"&gt;http://www.sonarsource.org/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref10" id="ftnt10" name="ftnt10"&gt;[10]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://www.onyxneon.com/books/modern_perl/index.html"&gt;http://www.onyxneon.com/books/modern_perl/index.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref11" id="ftnt11" name="ftnt11"&gt;[11]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://search.cpan.org/~thaljef/Perl-Critic-1.118/lib/Perl/Critic.pm"&gt;http://search.cpan.org/~thaljef/Perl-Critic-1.118/lib/Perl/Critic.pm&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref12" id="ftnt12" name="ftnt12"&gt;[12]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://pypi.python.org/pypi/pep8"&gt;http://pypi.python.org/pypi/pep8&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div&gt;
    &lt;p&gt;&lt;a rel="nofollow" href="#ftnt_ref13" id="ftnt13" name="ftnt13"&gt;[13]&lt;/a&gt;&lt;a rel="nofollow" target="_blank" href="http://pypi.python.org/pypi/pylint"&gt;http://pypi.python.org/pypi/pylint&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SCKQtHQYRGk:cUweFMVr-jE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SCKQtHQYRGk:cUweFMVr-jE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SCKQtHQYRGk:cUweFMVr-jE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=SCKQtHQYRGk:cUweFMVr-jE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SCKQtHQYRGk:cUweFMVr-jE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-3849740705810411192</guid>
         <pubDate>Tue, 06 Nov 2012 14:33:00 +0000</pubDate>
      </item>
      <item>
         <title>A (mostly) cross-platform clickable map of Romanian counties</title>
         <link>http://hype-free.blogspot.com/2012/11/a-mostly-cross-platform-clickable-map.html</link>
         <description>&lt;div class="separator" style="clear:both;text-align:center;"&gt;
&lt;a rel="nofollow" target="_blank" href="http://hype-free.googlecode.com/svn/trunk/map-romania/index.html" style="margin-left:1em;margin-right:1em;"&gt;&lt;img border="0" height="228" width="320" src="http://2.bp.blogspot.com/-efBtXhgduhw/UJItSwviTnI/AAAAAAAAFjw/-D_TsgQlsUs/s320/Screenshot%2Bfrom%2B2012-11-01%2B10%253A02%253A31.png"/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;TL;DR - I've created a map of Romania's counties (judete) using Javascript which can be used as an alternative for drop-down boxes during form input. It works great with FF and Chrome :-). See it &lt;a rel="nofollow" target="_blank" href="http://hype-free.googlecode.com/svn/trunk/map-romania/index.html"&gt;in action&lt;/a&gt; and browse &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/hype-free/source/browse/#svn%2Ftrunk%2Fmap-romania"&gt;the source code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The map is based on &lt;a rel="nofollow" target="_blank" href="https://commons.wikimedia.org/wiki/Atlas_of_Romania"&gt;the SVG drawings from Wikimedia Commons&lt;/a&gt; postprocessed in Inkscape to simplify the paths (and to remove the Black Sea from it). After that it was converted to &lt;a rel="nofollow" target="_blank" href="http://raphaeljs.com/"&gt;Raphael.js&lt;/a&gt; using &lt;a rel="nofollow" target="_blank" href="http://readysetraphael.com/"&gt;readysetraphael&lt;/a&gt;. I also use &lt;a rel="nofollow" target="_blank" href="http://www.shapevent.com/scaleraphael/"&gt;ScaleRaphael&lt;/a&gt; to be able to render it at an arbitrary size. According to &lt;a rel="nofollow" target="_blank" href="http://www.browserstack.com/"&gt;BrowserStack&lt;/a&gt; (a great service well worth its money BTW if you do web development!) it works with Firefox (starting with version 3.6), Chrome and Safari. IE has a hard time with it, but hopefully as the underlying library improves, it will start to work :-).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=dwXVn7PWhQE:EQ9cei_c3ME:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=dwXVn7PWhQE:EQ9cei_c3ME:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=dwXVn7PWhQE:EQ9cei_c3ME:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=dwXVn7PWhQE:EQ9cei_c3ME:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=dwXVn7PWhQE:EQ9cei_c3ME:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-5779817929010163387</guid>
         <pubDate>Thu, 01 Nov 2012 10:06:00 +0000</pubDate>
         <media:thumbnail height="72" url="http://2.bp.blogspot.com/-efBtXhgduhw/UJItSwviTnI/AAAAAAAAFjw/-D_TsgQlsUs/s72-c/Screenshot%2Bfrom%2B2012-11-01%2B10%253A02%253A31.png" width="72" />
      </item>
      <item>
         <title>Every end is a new beginning</title>
         <link>http://hype-free.blogspot.com/2012/10/every-end-is-new-beginning.html</link>
         <description>&lt;i&gt;TL;DR: I'm shutting down the twitfeeder project (it was on lifesupport for a long time) so I mirrored a technical article from the blog in the hope that it might be useful for somebody someday.&lt;/i&gt;&lt;br /&gt;
&lt;h3&gt;
Proxying URL fetch requests from the Google App Engine &lt;/h3&gt;
&lt;br /&gt;
Hosting on the Google App Engine means giving up a lot controls: your
 application will run on some machines in one of Google's datacenters, 
use some other machines to store data and use yet an other set of 
machines to talk to the outside world (send/receive emails, fetch URLs, 
etc). You don't know the exact identity of these machines (which for 
this article means their external IP address), and even though you can 
find out some of the details (for example by fetching the &lt;a rel="nofollow" target="_blank" href="http://www.ipchicken.com/"&gt;ipchicken page&lt;/a&gt;
 and parsing the result or by sending an e-mail and looking at the 
headers), there is no guarantee made that the results are repeatable 
(ie. if you do it again and again you will get the same result) in the 
short or long run. While one might not care about such details most of 
the time, there are some corner cases where it would be nice to have a 
predictable and unique source address:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;You might 
worry that some of the exit points get blocked because other 
applications on the Google App Engine have an abusive behavior&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;You might want a single exit point so that you can "debug" your traffic at a low (network / tcpdump) level&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;And finally, the main reason for which the Twit Feeder uses it: some third-party services (like &lt;a rel="nofollow" target="_blank" href="http://twitter.com/"&gt;Twitter&lt;/a&gt; or &lt;a rel="nofollow" target="_blank" href="http://delicious.com/"&gt;Delicious&lt;/a&gt;) use the source IP to whitelist requests to their API&lt;/li&gt;
&lt;/ul&gt;
To
 be fair to the GAE Architects: the above considerations don't affect 
the main usecase and are more of a cornercase if we look at the average 
application running on the GAE. Also, having so few commitments (ie. 
they don't stipulate things like "all the URL fetches will come from the
 10.0.0.1/24 netblock") means that they are free to move things around 
(even between datacenters) to optimize uptime and performance which in 
turn benefits the application owners and users.&lt;br /&gt;
&lt;br /&gt;
Back to 
our scenario: the solution is to introduce an intermediary which has a 
static and well known IP and let it do all the fetching. Ideally I would
 have installed &lt;a rel="nofollow" target="_blank" href="http://www.squid-cache.org/"&gt;Squid&lt;/a&gt; and and 
be done with it, but the URL fetch service doesn't have support for 
proxies currently. So the solution I came up with looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Get
 a VPS server. I would recommend one which gives you more bandwidth 
rather than more CPU / memory / disk. It is also a good idea to get one 
in the USA to minimize latency from/to the Google datacenters. I'm 
currently using &lt;a rel="nofollow" target="_blank" href="http://vpslink.com/?ref=PPPMNM"&gt;VPSLink&lt;/a&gt; and I didn't had any problems (full disclosure: that is a referral link and you should get 10% off for lifetime if you use it).&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Install Apache + PHP on it&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Use a simple PHP script to fetch the page encoded in a query parameter using the &lt;a rel="nofollow" target="_blank" href="http://www.php.net/manual/en/book.curl.php"&gt;php_curl&lt;/a&gt; extension.&lt;/li&gt;
&lt;/ul&gt;
To spice up this blogpost ;-), here is a diagram of the process:&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;img height="292" src="https://lh4.ggpht.com/_hrvCBhtWhJ4/S1IPu9C6clI/AAAAAAAACHI/YyuBoNYpXOQ/s800/google_app_engine_proxy.png" width="450"/&gt;&lt;/center&gt;
&lt;br /&gt;
&lt;br /&gt;
A couple of points:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Taking
 care of a VPS can be challenging, especially if you aren't a Linux 
user. However failing to do so can result in it being taken over by 
malicious individuals. Consider getting a managed VPS. Also, three quick
 security tips: use strong passwords. move the SSH server to a 
non-standard port and configure your firewall to be as restrictive as 
possible (deny everything, and open ports to only a limited number of IP
 addresses).&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Yes, this introduces a single point of failure 
into your application, so plan accordingly (while your application is 
small, this shouldn't be a problem - as it grows you can get two VPS's 
at two different data centers for example for added reliability).&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;The
 traffic between Google and your VPS can be encrypted using TLS (HTTPS).
 The good news is that the URL fetcher service doesn't check the 
certificates, so you can use self-signed ones. The bad news is that the 
URL fetcher doesn't check the certificates, so a determined attacker can
 relatively easily man-in-the-middle you (but it protects the data from 
the casual sniffer).&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Be aware that you need to budget for 
double of the amount of traffic you estimate using at the VPS (because 
it needs to first download it and then upload it back to Google). The 
URL fetcher service does know how to use gzip compression, so if you are
 downloading mainly text, you shouldn't have a bandwidth problem.&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;PHP
 might seem like an unusual choice of language, given how most GAE users
 have experience in either Python or Java, but there are a lot of 
tutorials out there on how to install it (and on modern Linux 
distribution it can be done in under 10 minutes with the help of the 
package manager) and it was the one I was most comfortable with as an 
Apache module.&lt;/li&gt;
&lt;/ul&gt;
Without further ado, here are the relevant sourcecode snippets (which I hereby release into the public domain):&lt;br /&gt;
&lt;br /&gt;
The PHP script:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
error_reporting(0);
require 'privatedata.php';

if ($AUTH != @$_SERVER['HTTP_X_SHARED_SECRET']) {
   header("HTTP/1.0 404 Not Found");
   exit;
}

$url = @$_GET['q'];
if (!isset($url)) {
   header("HTTP/1.0 404 Not Found");
   exit;
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

if (isset($_SERVER['HTTP_USER_AGENT'])) {
   curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
}
if (isset($_SERVER['PHP_AUTH_USER']) &amp;amp;&amp;amp; isset($_SERVER['PHP_AUTH_PW'])) {
   curl_setopt($ch, CURLOPT_USERPWD, "{$_SERVER['PHP_AUTH_USER']}:{$_SERVER['PHP_AUTH_PW']}");
}

if (count($_POST) &amp;gt; 0) {
   curl_setopt($ch, CURLOPT_POST, true);
   $postfields = array();
   foreach ($_POST as $key =&amp;gt; $val) {
       $postfields[] = urlencode($key) . '=' . urlencode($val);
   }
   curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&amp;amp;', $postfields));
}

$headers = array();
function header_callback($ch, $header) {
   global $headers;
   // we add our own content encoding
   // also, the content length might vary because of this
   if (false === stripos($header, 'Content-Encoding: ')
       &amp;amp;&amp;amp; false === stripos($header, 'Content-Length: ')
       &amp;amp;&amp;amp; false === stripos($header, 'Transfer-Encoding: ')) {
       $headers[] = $header;
   }
   return strlen($header);
}

curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'header_callback');

$output = curl_exec($ch);
if (FALSE === $output) {
   header("HTTP/1.0 500 Server Error");
   print curl_error($ch);
   exit;
}
curl_close($ch);

foreach ($headers as $header) {
   header($header);
}
print $output;&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The "privatedata.php" file looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php

$AUTH = '23tqhwfgj2qbherhjerj';&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Two
 separate files are being used to avoid submitting the password to the 
source repository, while still keeping all the sourcecode open.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now with the code in place, you can test it using curl:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;curl --compressed -v -H 'X-Shared-Secret: 23tqhwfgj2qbherhjerj' 'http://127.0.0.1:1483/fetch_url.php?q=http%3A//identi.ca/api/help/test.json&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
As
 you can see, a custom header is used for authentication. An other 
security measure is to use a non-standard port. Limiting the requests to
 the IPs of the Google datacenter from the firewall would be the ideal 
solution, but given that this was the problem we are trying to solve in 
the first place (the Google datacenters not having an officially 
announced set of IP addresses), this doesn't seem possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, here is the Python code to use the script from withing an application hosted on the GAE:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;from urllib import quote
from google.appengine.api import urlfetch

# ...

fetch_headers['X-Shared-Secret'] = '23tqhwfgj2qbherhjerj'
result = urlfetch.fetch(url='http://127.0.0.1:1483/fetch_url.php?q=%s' % quote(url), payload=data,
 method=urlfetch.POST if data else urlfetch.GET,
 headers=fetch_headers, deadline=timeout, follow_redirects=False)&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
A little more discussion about the code:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The
 method of using a custom header for authorization was chosen, since the
 forwarding of authentication data (ie. the "Authorization" header) was 
needed (specifically this is what the Twitter API uses for verifying 
identity)&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Speaking of things the script forwards: it does 
forward the user agent and any POST data if present. The forwarding of 
other headers could be quite easily be added.&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Passing 
variables in a GET request is also supported (they would be 
double-encoded, but that shouldn't be a concern in but the most extreme 
cases)&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;If we are talking about sensitive data, cURL (and the cURL extension for PHP) has the ability to fetch HTTPS content &lt;i&gt;and to verify the certificates&lt;/i&gt;.&lt;/li&gt;
&lt;/ul&gt;
While
 this method might look cumbersome, in practice I found it to work quite
 well. Hopefully this information will help others facing the same 
problem. A final note: if you have questions about the code or about 
other aspects, post them in the comments. I will try to answer them as 
fast as possible. I'm also considering launching a "proxy service" for 
GAE apps to make this process much more simpler (abstracting away the 
setup and administration of the VPS), so if you would be interested in 
paying a couple of bucks for such a service, please contact me either 
directly or trough the comments.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=RmUwEUw1--E:YiIsn7O_q5k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=RmUwEUw1--E:YiIsn7O_q5k:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=RmUwEUw1--E:YiIsn7O_q5k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=RmUwEUw1--E:YiIsn7O_q5k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=RmUwEUw1--E:YiIsn7O_q5k:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-4821802379031927005</guid>
         <pubDate>Sat, 27 Oct 2012 23:03:00 +0000</pubDate>
      </item>
      <item>
         <title>Helper for testing multi-threaded programs in Java</title>
         <link>http://hype-free.blogspot.com/2012/10/helper-for-testing-multi-threaded.html</link>
         <description>&lt;p&gt;This post was originally published on the &lt;a rel="nofollow" target="_blank" href="http://www.transylvania-jug.org/archives/5442"&gt;Transylvania JUG&lt;/a&gt; blog.&lt;/p&gt;

Testing multi-threaded code is hard. The main problem is that you 
invoke your assertions either too soon (and they fail for no good 
reason) or too late (in which case the test runs for a long time, 
frustrating you). A possible solution is to declare an interface like 
the following:&lt;br /&gt;
&lt;br /&gt;

&lt;pre&gt;&lt;code&gt;interface ActivityWatcher {
 void before();
 void after(); 
 void await(long time, TimeUnit timeUnit) throws InterruptedException, TimeoutException;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;

&lt;br /&gt;
It is intended to be used as follows:&lt;br /&gt;

&lt;ul&gt;
&lt;li&gt;“before” is called before the asynchronous task is delegated to an 
execution mechanism (threadpool, fork-join framework, etc) and it 
increments an internal counter.&lt;/li&gt;
&lt;li&gt;“after is called after the asynchronous task has completed and it decrements the counter.&lt;/li&gt;
&lt;li&gt;“await” waits for the counter to become zero&lt;/li&gt;
&lt;/ul&gt;
The net result is that when the counter is zero, all your asynchronous tasks have executed and you can run your assertions. See &lt;a rel="nofollow" target="_blank" href="https://code.google.com/p/hype-free/source/browse/trunk/espresso-shots/src/org/transylvania/jug/espresso/shots/d20121009/TestMultithreading.java"&gt;the example code&lt;/a&gt;. A couple more considerations:&lt;br /&gt;

&lt;ul&gt;
&lt;li&gt;There should be a single ActivityWatcher per test (injected trough constructors or a dependency injection framework)&lt;/li&gt;
&lt;li&gt;In production code you will use a &lt;a rel="nofollow" target="_blank" href="https://code.google.com/p/hype-free/source/browse/trunk/espresso-shots/src/org/transylvania/jug/espresso/shots/d20121009/NoopActivityWatcher.java"&gt;dummy/noop implementation&lt;/a&gt; which removes any overhead.&lt;/li&gt;
&lt;li&gt;This only works for situations where the asynchronous are kicked of 
immediately. Ie. it doesn’t work for situations where we have 
periodically executing tasks (like every 5 seconds) and we would want to
 wait for the 7th tasks to be executed for example.&lt;/li&gt;
&lt;/ul&gt;
One thing the above code doesn’t do is collecting exceptions: if the 
exceptions happen on different threads than the one executing the 
testrunner, they will just die and the testrunner will happily report 
that the tests passs. You can work around this in two ways:&lt;br /&gt;

&lt;ul&gt;
&lt;li&gt;use the &lt;a rel="nofollow" target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler%28java.lang.Thread.UncaughtExceptionHandler%29"&gt;default UncaughtExceptionHandler&lt;/a&gt;
 to capture all exceptions and rethrow them in the testrunner if they 
arrise (not so nice because it introduces global state – you can’t have 
two such tests running in parallel for example)&lt;/li&gt;
&lt;li&gt;Extend activity watcher and code calling activity watcher such that it has a “&lt;code&gt;collect(Throwable)&lt;/code&gt;” method which gets called with the uncaught exceptions and “&lt;code&gt;await&lt;/code&gt;” rethrows them.&lt;/li&gt;
&lt;/ul&gt;
Implementing this is left as an exercise to the reader :-).&lt;img alt=";-)" class="wp-smiley" src="http://www.transylvania-jug.org/wp-includes/images/smilies/icon_wink.gif"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Tpj4wtrHaxo:MvF6i6gDdOU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Tpj4wtrHaxo:MvF6i6gDdOU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Tpj4wtrHaxo:MvF6i6gDdOU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=Tpj4wtrHaxo:MvF6i6gDdOU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Tpj4wtrHaxo:MvF6i6gDdOU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-9127672392242972292</guid>
         <pubDate>Sat, 27 Oct 2012 22:48:00 +0000</pubDate>
      </item>
      <item>
         <title>GeekMeet talk about Google App Engine</title>
         <link>http://hype-free.blogspot.com/2012/10/geekmeet-talk-about-google-app-engine.html</link>
         <description>&lt;p&gt;The GAE presentation I've given for &lt;a rel="nofollow" target="_blank" href="http://geekmeet.ro/cluj/2012/10/23/cum-a-fost-la-geekmeet-12-cluj/"&gt;the 12th edition of Cluj Geek Meet&lt;/a&gt; can be found &lt;a rel="nofollow" target="_blank" href="https://hype-free.googlecode.com/svn/trunk/geekmeet-ro/gae_presentation/index.html#/"&gt;here&lt;/a&gt; (created using reveal.js).&lt;/p&gt;

&lt;p&gt;You can find the source code &lt;a rel="nofollow" target="_blank" href="https://code.google.com/p/hype-free/source/browse/#svn/trunk/geekmeet-ro/gae_presentation/code"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=V4z7lDmj3vY:qzltZ7TB_3E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=V4z7lDmj3vY:qzltZ7TB_3E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=V4z7lDmj3vY:qzltZ7TB_3E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=V4z7lDmj3vY:qzltZ7TB_3E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=V4z7lDmj3vY:qzltZ7TB_3E:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-4442486660432298233</guid>
         <pubDate>Sat, 27 Oct 2012 22:45:00 +0000</pubDate>
      </item>
      <item>
         <title>Lightning talk at Cluj.PM</title>
         <link>http://hype-free.blogspot.com/2012/08/lightning-talk-at-clujpm.html</link>
         <description>&lt;p&gt;The slides from my &lt;a rel="nofollow" target="_blank" href="http://cluj.pm/pages/events.html"&gt;Cluj.PM&lt;/a&gt; lightning talk:&lt;/p&gt;

 

&lt;p&gt;It was a stressful (but fun!) experience. Thanks to the organizers!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Ivo0-ZOYhqo:Q7jG80h_KGg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Ivo0-ZOYhqo:Q7jG80h_KGg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Ivo0-ZOYhqo:Q7jG80h_KGg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=Ivo0-ZOYhqo:Q7jG80h_KGg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=Ivo0-ZOYhqo:Q7jG80h_KGg:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-6610506531123469447</guid>
         <pubDate>Sun, 19 Aug 2012 15:22:00 +0000</pubDate>
      </item>
      <item>
         <title>Running pep8 and pylint programatically</title>
         <link>http://hype-free.blogspot.com/2012/08/running-pep8-and-pylint-programatically.html</link>
         <description>&lt;p&gt;Having tools like &lt;a rel="nofollow" target="_blank" href="http://pypi.python.org/pypi/pep8/"&gt;pep8&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://pypi.python.org/pypi/pylint/"&gt;pylint&lt;/a&gt; are great, especially given the huge amount of dynamism involved in Python - which results in many opportunities to shooting yourself in the foot. Sometimes however you want to invoke these tools in more specialized ways, for example only on the files which changed since the last commit. Here is how you can do this from a python script and capture their output for later post-processing (maybe you want merge the output from both tools, or maybe you want to show only the lines which changed since the last commit, etc):&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
import pep8
try:
  sys.stdout = StringIO()
  pep8_checker = pep8.StyleGuide(config_file=config, format='pylint')
  pep8_checker.check_files(paths=[ ...path to files/dirs to check... ])
  output = sys.stdout.getvalue()
finally:
  sys.stdout = sys.__stdout__

from pylint.lint import Run
from pylint.reporters.text import ParseableTextReporter

reporter = ParseableTextReporter()
result = StringIO()
reporter.set_output(result)
Run(['--rcfile=pylint.config'] + [ ...files.., ], reporter=reporter, exit=False)
output = result.getvalue()
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;It is recommended that you use pylint/pep8 installed trough pip/easy_install rather than the Linux distribution repositories, since they are known to contain outdated software. You can check for this via code like the following:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
if pkg_resources.get_distribution('pep8').parsed_version &amp;lt; parse_version('1.3.3'):
    logging.error('pep8 too old. At least version 1.3.3 is required')
    sys.exit(1)
if pkg_resources.get_distribution('pylint').parsed_version &amp;lt; parse_version('0.25.1'):
    logging.error('pylint too old. At least version 0.25.1 is required')
    sys.exit(1)
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Finally, if you &lt;em&gt;have&lt;/em&gt; to use an old version of pep8, the code needs to be modified to the following (however, this older version probably won't be of much use and will most likely annoy you - you should really try to use an up-to-date version - for example you could isolate this version using virtualenv):&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
result = []
import pep8
pep8.message = lambda msg: result.append(msg)
pep8.process_options(own_code)
for code_dir in [ ...files or dirs... ]:
    pep8.input_dir(code_dir)
&lt;/pre&gt;&lt;/code&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=0W8BL4m1go0:Voow9zey9Ss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=0W8BL4m1go0:Voow9zey9Ss:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=0W8BL4m1go0:Voow9zey9Ss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=0W8BL4m1go0:Voow9zey9Ss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=0W8BL4m1go0:Voow9zey9Ss:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-166690756393164471</guid>
         <pubDate>Sun, 19 Aug 2012 15:12:00 +0000</pubDate>
      </item>
      <item>
         <title>Clearing your Google App Engine datastore</title>
         <link>http://hype-free.blogspot.com/2012/08/clearing-your-google-app-engine.html</link>
         <description>&lt;p style="color:red;"&gt;
&lt;b&gt;Warning! This is a method to erase the data from your Google App Engine datastore. There is no way to recover your data after you go trough with this! Only use this if you're absolutely certain!&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;If you have a GAE account used for experimentation, you might like to clean it up sometimes (erase the contents of the datastore and blobstore associated with the application). Doing this trough the admin interface can become very tedious, so here is an alternative method:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start your &lt;a rel="nofollow" target="_blank" href="https://developers.google.com/appengine/articles/remote_api"&gt;Remote API shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use the following code to delete all datastore entities: &lt;code&gt;&lt;pre&gt;while True: keys=db.Query(keys_only=True).fetch(500); db.delete(keys); print "Deleted 500 entries, the last of which was %s" % keys[-1].to_path()&lt;/pre&gt;
&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use the following code to delete all blobstore entities: &lt;code&gt;&lt;pre&gt;from google.appengine.ext.blobstore import *
while True: list=BlobInfo.all().fetch(500); delete([b.key() for b in list]);  print "Deleted elements, the last of which was %s" % list[-1].filename
&lt;/pre&gt;
&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above method is inspired by &lt;a rel="nofollow" target="_blank" href="http://stackoverflow.com/questions/1062540/how-to-delete-all-datastore-in-google-app-engine"&gt;this stackoverflow answer&lt;/a&gt;, but has the advantage that it does the deletion in smaller steps, meaning that the risk of the entire transaction being aborted because of deadline exceeded or over quota errors is removed.&lt;/p&gt;

&lt;p&gt;Final caveats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This can be slow&lt;/li&gt;
&lt;li&gt;This consumes your quota, so you might have to do it over several days or raise your quota&lt;/li&gt;
&lt;li&gt;The code is written in a very non-pythonic way (multiple statements on one line) for the ease of copy-pasting&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JyrEsuiJDXI:3QHvrXidc_o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JyrEsuiJDXI:3QHvrXidc_o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JyrEsuiJDXI:3QHvrXidc_o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=JyrEsuiJDXI:3QHvrXidc_o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=JyrEsuiJDXI:3QHvrXidc_o:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-8137766461360699921</guid>
         <pubDate>Wed, 15 Aug 2012 10:08:00 +0000</pubDate>
      </item>
      <item>
         <title>Relaxed JSON parsing</title>
         <link>http://hype-free.blogspot.com/2011/12/relaxed-json-parsing.html</link>
         <description>&lt;p&gt;&lt;em&gt;This blogpost was originally posted to &lt;a rel="nofollow" target="_blank" href="http://www.transylvania-jug.org/archives/324"&gt;the Transylvania JUG blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;JSON is a good alternative when you need a lightweight format to specify structured data. But sometimes (for example when you want the user to specify JSON manually) you would like to relax the formalism required to specify &lt;a rel="nofollow" target="_blank" href="http://json.org/"&gt;&amp;quot;valid&amp;quot; JSON&lt;/a&gt; data. For example the following snippet is not valid as per the spec, although its intent is quite clear:&lt;/p&gt; &lt;code&gt;   &lt;pre&gt;[{ foo: 'bar' }]&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;To make this standard compliant we would need to write it as:&lt;/p&gt;
&lt;code&gt;
  &lt;pre&gt;[{ &amp;quot;foo&amp;quot;: &amp;quot;bar&amp;quot; }]&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;We shouldn't run out and blame the standard of course since it needs to balance many contradictory requirements (ambiguity of encoded data, ease of understanding, ease of writing parsers, etc). If you decide that you want to strike the balance differently (make the definition of valid data more relaxed) you can do this easily with the &lt;a rel="nofollow" target="_blank" href="http://jackson.codehaus.org/"&gt;Jackson parser&lt;/a&gt;:&lt;/p&gt;
&lt;code&gt;
  &lt;pre&gt;JsonParser parser = new JsonFactory()
	.createJsonParser(&amp;quot;[{ foo: 'bar' }]&amp;quot;)
		.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
		.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
JsonNode root = new ObjectMapper().readTree(parser);

assertEquals(&amp;quot;bar&amp;quot;, root.get(0).get(&amp;quot;foo&amp;quot;).asText());&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;If your tool of choice is &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/google-gson/"&gt;gson&lt;/a&gt;, it is slightly more complicated but still doable. See the &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/hype-free/source/browse/trunk/espresso-shots/src/org/transylvania/jug/espresso/shots/d20111018/TestRelaxedJSONParsing.java"&gt;linked source code&lt;/a&gt; for a complete example.&lt;/p&gt;

&lt;p&gt;JSON is a good tool for semi-structured data and using a relaxed parsing can make the programs you write easier to use.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=E5ki-UxcgHU:VVbKluaCB3Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=E5ki-UxcgHU:VVbKluaCB3Y:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=E5ki-UxcgHU:VVbKluaCB3Y:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=E5ki-UxcgHU:VVbKluaCB3Y:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=E5ki-UxcgHU:VVbKluaCB3Y:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-4115175754941851823</guid>
         <pubDate>Tue, 27 Dec 2011 13:40:00 +0000</pubDate>
      </item>
      <item>
         <title>Updating the root certificates for Java</title>
         <link>http://hype-free.blogspot.com/2011/10/updating-root-certificates-for-java.html</link>
         <description>&lt;p&gt;One usually thinks of SSL in the context of HTTPS, but there are also other protocols which rely on it to provide security. See &lt;a rel="nofollow" target="_blank" href="http://www.google.com/url?q=https%3A%2F%2Fssl.trustwave.com%2Fsupport%2Fsupport-how-ssl-works.php&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzcSKxikCOveGBqInQtKlIeQDxQh1A"&gt;this link&lt;/a&gt; for a short overview of SSL – it only mentions HTTPS, but the same applies for IMAPS, FTPS, etc – SSL is independent of the wrapped protocol. You can have issues with your Java programs in where the party you are communicating with provider changes their certificate and the program rejects it as invalid. The exception is something like:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: 
    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
    unable to find valid certification path to requested target
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One cause of the problem can be that the server uses an SSL provider which is based on a root certificate that wasn’t included with the particular version of Java you are using (this is especially true for really old versions like Java 1.5). The issue can be solved by updating to the latest version, but it might be that this isn't an option. Fortunately I found the following article: &lt;a rel="nofollow" target="_blank" href="http://www.google.com/url?q=http%3A%2F%2Fblogs.sun.com%2Fandreas%2Fentry%2Fno_more_unable_to_find&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzeLX1QgwCxBswOU7p3Y6eb8qpF_0g"&gt;No more ‘unable to find valid certification path to requested target’&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How to use it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compile the program &lt;code&gt;javac InstallCert.java&lt;/code&gt;&lt;/li&gt;

  &lt;li&gt;Run it with the target host/port. For example in our case it would be: &lt;code&gt;java InstallCert imap.mailprovider.com:993&lt;/code&gt; (993 is the port for IMAPS) &lt;/li&gt;

  &lt;li&gt;navigate trough the menus and select which certificate to import &lt;/li&gt;

  &lt;li&gt;now you have a file called &lt;code&gt;jssecacerts&lt;/code&gt;. You need to copy this to &lt;code&gt;$JAVA_HOME/jre/lib/security/cacerts&lt;/code&gt; (&lt;strong&gt;back up the existing file first!&lt;/strong&gt;) &lt;/li&gt;

  &lt;li&gt;Now the root certificate is imported (you can confirm this by rerunning InstallCert)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTH&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SVR5z2i0x60:ac7abyS_L6I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SVR5z2i0x60:ac7abyS_L6I:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SVR5z2i0x60:ac7abyS_L6I:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=SVR5z2i0x60:ac7abyS_L6I:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=SVR5z2i0x60:ac7abyS_L6I:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-7893523570025568989</guid>
         <pubDate>Thu, 20 Oct 2011 15:36:00 +0000</pubDate>
      </item>
      <item>
         <title>Vagrant and VirtualBox on Windows</title>
         <link>http://hype-free.blogspot.com/2011/10/vagrant-and-virtualbox-on-windows.html</link>
         <description>&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://vagrantup.com/"&gt;Vagrant&lt;/a&gt; is a collection of scripts written in Ruby to manage VirtualBox images in a shared environment (like the QA boxes inside a company): install them, update them, etc. Unfortunately installing it under Windows is not as straight forward as one would want, so here are some useful tips:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Read the &lt;a rel="nofollow" target="_blank" href="http://vagrantup.com/docs/getting-started/setup/windows.html"&gt;Windows setup page&lt;/a&gt; and the &lt;a rel="nofollow" target="_blank" href="http://vagrantup.com/docs/getting-started/setup/windows_x64.html"&gt;Windows x64 setup page&lt;/a&gt; (if you are on 64 bit) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you are on a 64 bit Windows install:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Check out &lt;a rel="nofollow" target="_blank" href="http://hype-free.blogspot.com/2011/09/running-jruby-on-64-bit-windows.html"&gt;this post&lt;/a&gt; if your JRuby is using the 32 bit JVM on a x64 Windows setup &lt;/li&gt;    &lt;li&gt;You need to use version 4.0 of VirtualBox (rather than the latest). You can get it from &lt;a rel="nofollow" target="_blank" href="https://www.virtualbox.org/wiki/Download_Old_Builds_4_0"&gt;here&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;You need to use an older version of Vagrant: &lt;code&gt;       &lt;pre&gt;jgem install jruby-openssl jruby-win32ole
jgem install --version '=0.7.8' vagrant&lt;/pre&gt;
    &lt;/code&gt;&lt;/li&gt;

  &lt;li&gt;If the vagrant box download stops around 4G, check that you have a NTFS filesystem (rather than FAT) and deactivate any &amp;quot;network&amp;quot; scanning capabilities of installed security software (I had problems with NOD32 particularly)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTH&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=FKnvIm9tV_o:c2v07-9QZOE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=FKnvIm9tV_o:c2v07-9QZOE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=FKnvIm9tV_o:c2v07-9QZOE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=FKnvIm9tV_o:c2v07-9QZOE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=FKnvIm9tV_o:c2v07-9QZOE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-8421625943848937955</guid>
         <pubDate>Thu, 20 Oct 2011 15:27:00 +0000</pubDate>
      </item>
      <item>
         <title>Another friend blogging</title>
         <link>http://hype-free.blogspot.com/2011/10/another-friend-blogging.html</link>
         <description>&lt;p&gt;Another friend &lt;strike&gt;bit the dust&lt;/strike&gt; started blogging: &lt;a rel="nofollow" target="_blank" href="http://cleonte.github.com/"&gt;Cleonte's GitHub blog&lt;/a&gt; - bookmarks at the moment but looking forward to more involved posts :-).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=v65yn6s5O14:s_2XjjMN0UI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=v65yn6s5O14:s_2XjjMN0UI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=v65yn6s5O14:s_2XjjMN0UI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=v65yn6s5O14:s_2XjjMN0UI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=v65yn6s5O14:s_2XjjMN0UI:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-5536018271772784303</guid>
         <pubDate>Thu, 13 Oct 2011 18:20:00 +0000</pubDate>
      </item>
      <item>
         <title>Using Jython from Maven</title>
         <link>http://hype-free.blogspot.com/2011/10/using-jython-from-maven.html</link>
         <description>&lt;p&gt;&lt;em&gt;This blogpost was originally posted to &lt;/em&gt;&lt;a rel="nofollow" target="_blank" href="http://www.transylvania-jug.org/archives/303"&gt;&lt;em&gt;the Transylvania JUG blog&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;On the surface it looks simple: just add the dependency and you can run &lt;a rel="nofollow" target="_blank" href="http://www.jython.org/archive/21/docs/embedding.html"&gt;the example code&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;However what the &lt;code&gt;jython&lt;/code&gt; artifact doesn’t get you are the standard python libraries like &lt;code&gt;re&lt;/code&gt;. This means that as soon as you try to do something like the code below, it will error out:&lt;/p&gt;  &lt;pre&gt;PythonInterpreter interp = new PythonInterpreter();
try {
  interp.exec(&amp;quot;import re&amp;quot;);
} 
catch (PyException ex) {
  ex.printStackTrace();
}&lt;/pre&gt;

&lt;p&gt;The solution? Use the &lt;code&gt;jython-standalone&lt;/code&gt; artifact which includes the standard libraries. An other advantage is that it has the latest release (2.5.2) while &lt;code&gt;jython&lt;/code&gt; lags two minor revisions behind (2.5.0) in Maven Central. A possible downside is the larger size of the jar.&lt;/p&gt;

&lt;pre&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.python&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jython-standalone&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.5.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=cdPIvh2Aj6g:iw5xKi1FFso:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=cdPIvh2Aj6g:iw5xKi1FFso:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=cdPIvh2Aj6g:iw5xKi1FFso:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?i=cdPIvh2Aj6g:iw5xKi1FFso:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Hype-free?a=cdPIvh2Aj6g:iw5xKi1FFso:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Hype-free?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
         <author>Attila-Mihaly Balazs</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-35005627.post-4135628696788373182</guid>
         <pubDate>Thu, 13 Oct 2011 18:16:00 +0000</pubDate>
      </item>
   </channel>
</rss><!-- fe4.yql.bf1.yahoo.com compressed/chunked Wed Jun 19 13:02:15 UTC 2013 -->
