<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Radu Cotescu's professional blog]]></title>
  <link href="https://radu.cotescu.com/atom.xml" rel="self"/>
  <link href="https://radu.cotescu.com/"/>
  <updated>2016-02-04T14:39:31+01:00</updated>
  <id>https://radu.cotescu.com/</id>
  <author>
    <name><![CDATA[Radu Cotescu]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Remapping Keys in Ubuntu 14.04]]></title>
    <link href="https://radu.cotescu.com/remapping-keys-in-ubuntu-14.04/"/>
    <updated>2014-09-07T18:30:00+02:00</updated>
    <id>https://radu.cotescu.com/remapping-keys-in-ubuntu-14.04</id>
    <content type="html"><![CDATA[<p>Ever since I&#8217;ve switched to Mac OS X I liked its shortcut modifiers more than the ones available on Windows / Linux. While I do agree that sometimes
you lose count of the number of modifier keys that you have to press in order to get something done, most of the cases that claim is just FUD.</p>

<p>The ergonomy of the Mac has also made its way into how shortcuts are defined. The <code>Command</code> key, positioned where <code>Alt</code> is on PC keyboards, is
definitely better positioned when it comes to using that key as your main modifier for shortcuts. Call it the power of habit, but every time I
switch to a PC I find myself pressing the <code>Alt</code> key instead of <code>Control</code>. And that&#8217;s because <code>Alt</code> is in a handier position.</p>

<!--more-->


<p>A few weeks ago I bought a <a href="http://www.wasdkeyboards.com/index.php/products/code-keyboard/code-87-key-mechanical-keyboard.html" title="CODE 87-Key Mechanical Keyboard ">CODE ten-keyless mechanical keyboard</a>.
One of the nifty features (and there are plenty) is the ability to change the layout of your keyboard with a combination of DIP switches located on
the back. Obviously, it can be configured to a Mac layout. But what do you do when you want to use the same keyboard on your Linux box, from time to
time? I mean you&#8217;re mostly using <code>Command</code> for your shortcuts. Remapping the shortcuts in your head to <code>Control</code> is not that easy at first.</p>

<p><img src="https://radu.cotescu.com/uploads/2014/09/07/code.jpg" title="CODE 87-Key Mechanical Keyboard with Mac layout" alt="&quot;CODE 87-Key Mechanical Keyboard with Mac layout&quot;" /></p>

<h2>XKB</h2>

<p>Luckily Ubuntu, like many other Linux distros, comes with <code>xkb</code> - the X KeyBoard extension. This extension is responsible for mapping the physical
keys of your keyboard to their designed function. <code>xkb</code> symbol files can be found in <code>/usr/share/X11/xkb/symbols</code> and it&#8217;s good to know that they&#8217;re
localised, in case you need to add some language-specific mappings. However, in my case, I need to remap some of the modifier keys.</p>

<p>The modifier keys are mapped in <code>/usr/share/X11/xkb/symbols/pc</code>, a file which is inherited by all other configurations. Since I just want to replace
<code>Super</code> with <code>Control</code>, the changes are minimal:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>key &lt;LCTL&gt; <span class="o">{</span>    <span class="o">[</span> Super_L       <span class="o">]</span>   <span class="o">}</span>;
</span><span class='line'>key &lt;LWIN&gt; <span class="o">{</span>    <span class="o">[</span> Control_L     <span class="o">]</span>   <span class="o">}</span>;
</span><span class='line'>key &lt;RCTL&gt; <span class="o">{</span>    <span class="o">[</span> Super_R       <span class="o">]</span>   <span class="o">}</span>;
</span><span class='line'>key &lt;RWIN&gt; <span class="o">{</span>    <span class="o">[</span> Control_R     <span class="o">]</span>   <span class="o">}</span>;
</span></code></pre></td></tr></table></div></figure>


<p>In order to apply the new mappings you need to clear out <code>xkb</code>&#8217;s cache from <code>/var/lib/xkb</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>rm -rf /var/lib/xkb/*
</span></code></pre></td></tr></table></div></figure>


<p>Afterwards just restart your X session and you&#8217;re good to go. Even though this small change doesn&#8217;t make all shortcuts to work like on a Mac it&#8217;s still
a lot better than without it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Coloured log outputs on Unix/Linux]]></title>
    <link href="https://radu.cotescu.com/coloured-log-outputs/"/>
    <updated>2012-10-29T21:36:00+01:00</updated>
    <id>https://radu.cotescu.com/coloured-log-outputs</id>
    <content type="html"><![CDATA[<p>There are various times when a software engineer needs to closely monitor log output in real-time. More often than not the engineer is
actually interested in the output of multiple logs at the same time. Given the amount of information that an application can output to log
files at any one time, filtering the important information from bogus entries becomes frustrating and tedious.</p>

<p>One of the solutions I&#8217;ve come across recently is to colorize the log output according to the log entries&#8217; severity.</p>

<!--more-->


<h2>GUI half-baked options</h2>

<p>On GNOME-based Linux distributions there&#8217;s <em>GNOME System Log Viewer</em>, a GUI application that can be used to monitor logs in real-time.
One nice functionality that it provides are filters which can be configured to match an expression or a regular expression; the filters
allow colorizing the output according to what they match. +1 for Linux.</p>

<p>On Mac OS X <em>Console.app</em>, although is able to filter information faster and easier than <em>GNOME System Log Viewer</em>, is not able to highlight
the lines of interest using colours. Which is a shame, given the fact that more and more developers are migrating to Macs.</p>

<h2><code>tail</code> and the power of Bash</h2>

<p>Every Unix/Linux user has used <a href="http://linux.die.net/man/1/tail" title="tail's man page"><code>tail</code></a> at least once (though I have my doubts regarding
some of the Mac users :P). The advantage of <code>tail</code> is that it allows piping its output to whatever program able to consume information from
<code>stdin</code>.</p>

<h3>Enter <code>awk</code></h3>

<p><a href="http://en.wikipedia.org/wiki/Awk" title="AWK on Wikipedia"><code>awk</code></a> is an interpreted programming language perfect for extracting data from text
files. Given the fact that <code>awk</code> can read from <code>stdin</code>, it&#8217;s quite trivial to pipe data to it from which to extract more meaningful
information. Combine this with a little Bash scripting (needs Bash 4 due to associative arrays) and we have a nice and easy way to analyze
logs in real-time using colour-coded output.</p>

<figure class='code'><figcaption><span>ctail with awk</span><a href='https://github.com/raducotescu/ctail'>Clone on GitHub </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/usr/local/bin/bash</span>
</span><span class='line'><span class="nv">TAIL</span><span class="o">=</span><span class="sb">`</span>which tail<span class="sb">`</span>
</span><span class='line'><span class="nv">AWK</span><span class="o">=</span><span class="sb">`</span>which awk<span class="sb">`</span>
</span><span class='line'><span class="k">if</span> <span class="o">[[</span> -z <span class="nv">$TAIL</span> <span class="o">]]</span>; <span class="k">then</span>
</span><span class='line'><span class="k">    </span><span class="nb">echo</span> -e <span class="s2">&quot;Cannot find tail executable.\n&quot;</span>
</span><span class='line'>    <span class="nb">exit </span>1
</span><span class='line'><span class="k">fi</span>
</span><span class='line'><span class="k">if</span> <span class="o">[[</span> -z <span class="nv">$AWK</span> <span class="o">]]</span>; <span class="k">then</span>
</span><span class='line'><span class="k">    </span><span class="nb">echo</span> -e <span class="s2">&quot;Cannot find awk executable.\n&quot;</span>
</span><span class='line'>    <span class="nb">exit </span>1
</span><span class='line'><span class="k">fi</span>
</span><span class='line'>
</span><span class='line'><span class="nv">CWD</span><span class="o">=</span><span class="sb">`</span>dirname <span class="nv">$0</span><span class="sb">`</span>
</span><span class='line'>
</span><span class='line'><span class="nb">declare</span> -A log
</span><span class='line'>log<span class="o">[</span><span class="s2">&quot;INFO&quot;</span><span class="o">]=</span><span class="s2">&quot;BWhite&quot;</span>
</span><span class='line'>log<span class="o">[</span><span class="s2">&quot;ERROR&quot;</span><span class="o">]=</span><span class="s2">&quot;BRed&quot;</span>
</span><span class='line'>log<span class="o">[</span><span class="s2">&quot;WARN&quot;</span><span class="o">]=</span><span class="s2">&quot;BYellow&quot;</span>
</span><span class='line'>log<span class="o">[</span><span class="s2">&quot;DEBUG&quot;</span><span class="o">]=</span><span class="s2">&quot;BGreen&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="o">[[</span> -f <span class="s2">&quot;$CWD/ctail.config&quot;</span> <span class="o">]]</span>; <span class="k">then</span>
</span><span class='line'><span class="k">    </span><span class="nb">source</span> <span class="s2">&quot;$CWD/ctail.config&quot;</span>
</span><span class='line'><span class="k">fi</span>
</span><span class='line'>
</span><span class='line'><span class="nb">declare</span> -A colours
</span><span class='line'><span class="c"># Regular</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Black&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;30m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Red&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;31m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Green&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;32m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Yellow&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;33m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Blue&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;34m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Purple&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;35m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;Cyan&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;36m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;White&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;37m&quot;</span>
</span><span class='line'><span class="c">#Bold</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BBlack&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;30m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BRed&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;31m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BGreen&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;32m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BYellow&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;33m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BBlue&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;34m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BPurple&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;35m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BCyan&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;36m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BWhite&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;37m&quot;</span>
</span><span class='line'><span class="c"># High Intensity</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IBlack&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;90m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IRed&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;91m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IGreen&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;92m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IYellow&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;93m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IBlue&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;94m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IPurple&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;95m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;ICyan&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;96m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;IWhite&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[0;97m&quot;</span>
</span><span class='line'><span class="c"># Bold High Intensity</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIBlack&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;90m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIRed&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;91m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIGreen&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;92m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIYellow&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;93m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIBlue&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;94m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIPurple&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;95m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BICyan&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;96m&quot;</span>
</span><span class='line'>colours<span class="o">[</span><span class="s2">&quot;BIWhite&quot;</span><span class="o">]=</span><span class="s2">&quot;\033[1;97m&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="nv">AWK_EXPRESSION</span><span class="o">=</span><span class="s2">&quot;&quot;</span>
</span><span class='line'><span class="k">for </span>i in <span class="s2">&quot;${!log[@]}&quot;</span>; <span class="k">do</span>
</span><span class='line'><span class="k">    </span><span class="nv">AWK_EXPRESSION</span><span class="o">=</span><span class="s2">&quot;/$i/ {print \&quot;${colours[${log[$i]}]}\&quot; \$0 \&quot;\033[39m\&quot;} $AWK_EXPRESSION&quot;</span>
</span><span class='line'><span class="k">done</span>
</span><span class='line'>
</span><span class='line'><span class="nv">$TAIL</span> <span class="s2">&quot;$@&quot;</span> | <span class="nv">$AWK</span> <span class="s2">&quot;$AWK_EXPRESSION&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>A <code>ctail.config</code> file can be created in the same folder with <code>ctail</code> to override the default colours and log levels associations.</p>

<p>The advantage of using <code>awk</code> is that it&#8217;s present on most of the available Linux distributions and UNIX flavours and that it&#8217;s reasonably
fast.</p>

<h3>Option no. 2: <code>ack</code></h3>

<p>Another tool used for filtering information is <a href="http://linux.die.net/man/1/ack" title="ack's man page"><code>ack</code></a>, a tool &#8220;designed as a replacement
for 99% of the uses of <code>grep</code>&#8221;. A similar colorized <code>tail</code> script can be written like:</p>

<figure class='code'><figcaption><span>ctail with ack </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'>
</span><span class='line'>tail <span class="s2">&quot;$@&quot;</span> <span class="se">\</span>
</span><span class='line'>| ack --flush --passthru --color --color-match<span class="o">=</span>red    <span class="s2">&quot;^.*\*ERROR\*.*&quot;</span> <span class="se">\</span>
</span><span class='line'>| ack --flush --passthru --color --color-match<span class="o">=</span>yellow <span class="s2">&quot;^.*\*WARN\*.*&quot;</span> <span class="se">\</span>
</span><span class='line'>| ack --flush --passthru --color --color-match<span class="o">=</span>green  <span class="s2">&quot;^.*\*INFO\*.*&quot;</span> <span class="se">\</span>
</span><span class='line'>| ack --flush --passthru --color --color-match<span class="o">=</span>white  <span class="s2">&quot;^.*\*DEBUG\*.*&quot;</span> <span class="se">\</span>
</span><span class='line'>| ack --flush --passthru --color --color-match<span class="o">=</span>white  <span class="s2">&quot;^.*\*TRACE\*.*&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Credits for this solution go to <a href="https://twitter.com/alexkli">Alex Klimetschek</a>, one of my colleagues from Adobe. <code>ack</code> does not come
standard on most Linux distributions, nor on Mac OS X; however, installing it is usually a few commands away with your favourite package
manager.</p>

<h2>In the end</h2>

<p>Being an avid terminal user, I find the <code>ctail</code> script (in any of its variations) a better tool than its half-baked GUI alternatives.
Furthermore, <code>ctail</code> can also be used on servers with very little setup.</p>

<p>Do you know of any other interesting ways for highlighting log messages?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A useful rant on how people write Java code]]></title>
    <link href="https://radu.cotescu.com/java-common-sense/"/>
    <updated>2012-10-21T20:49:00+02:00</updated>
    <id>https://radu.cotescu.com/java-common-sense</id>
    <content type="html"><![CDATA[<p>During the last months I&#8217;ve had the chance to see a lot of code written by different types of developers. Some of it has definitely made me
proud of the word &#8220;engineering&#8221; being associated with my profession; the other, not. There are a few basic unwritten rules that more or less
have become software engineering common sense.</p>

<!-- more -->


<h3>Input handling</h3>

<p>99.9% of the code written on this planet deals in some way or the other with user input. <em>The User</em> is not necessary a good person. A paranoid
engineer (all engineers should be paranoid; if you&#8217;re an engineer but don&#8217;t feel paranoid just quit your job!) would actually say that <em>The
User</em> is a terrible person whose only role is to create problems that the engineer has to solve. Since <em>The User</em> is such a terrible person
nothing coming from them should be trusted. This is why everything that doesn&#8217;t come from a safe source (are there any safe sources for data
input?!) must be validated.</p>

<p>For example:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="n">String</span> <span class="nf">reverse</span><span class="o">(</span><span class="n">String</span> <span class="n">input</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>    <span class="kd">final</span> <span class="n">StringBuilder</span> <span class="n">sb</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringBuilder</span><span class="o">();</span>
</span><span class='line'>    <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">input</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span><span class="o">--)</span> <span class="o">{</span>
</span><span class='line'>        <span class="n">sb</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">input</span><span class="o">.</span><span class="na">charAt</span><span class="o">(</span><span class="n">i</span><span class="o">));</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">sb</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>What would happen on line 3 if <em>The User</em> submitted null for the <code>input</code> string? That&#8217;s right. The assumption that your user is a nice person
just earned you a <code>NullPointerException</code>. Now assume that your unvalidated code was delivered as part of some bigger project which accidentally
calls your wonderful method. Oh yeah, the <code>NPE</code> now hogs in their code&#8230;</p>

<p>This could have easily been avoided by:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="n">String</span> <span class="nf">reverse</span><span class="o">(</span><span class="n">String</span> <span class="n">input</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">String</span> <span class="n">result</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="o">(</span><span class="n">input</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>        <span class="kd">final</span> <span class="n">StringBuilder</span> <span class="n">sb</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringBuilder</span><span class="o">();</span>
</span><span class='line'>        <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">input</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">-</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span><span class="o">--)</span> <span class="o">{</span>
</span><span class='line'>            <span class="n">sb</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">input</span><span class="o">.</span><span class="na">charAt</span><span class="o">(</span><span class="n">i</span><span class="o">));</span>
</span><span class='line'>        <span class="o">}</span>
</span><span class='line'>        <span class="n">result</span> <span class="o">=</span> <span class="n">sb</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">result</span><span class="o">;</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>However, if the logic in your method is not as simple as that, always inform the caller of the consequences of calling your code with invalid
parameters - whether you explicitly throw an <code>Exception</code> (which is <em>documented</em>), or you just provide a default return value.</p>

<h3>Useful logging</h3>

<p>Every engineer should use a logging mechanism through which meaningful and important information is&#8230; Well, logged. Probably the most useful
information is the one which is logged in the case of an error. Assuming your logger supports a <code>Throwable</code> object as a parameter in its
<code>error</code> method, <strong>never ever</strong> do this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="k">try</span> <span class="o">{</span>
</span><span class='line'>    <span class="c1">// code that throws a random exception</span>
</span><span class='line'><span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">log</span><span class="o">.</span><span class="na">error</span><span class="o">(</span><span class="s">&quot;Bla bla bla&quot;</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>It&#8217;s not gonna help anyone. Moreover it&#8217;s going to annoy the person who encounters the error because they won&#8217;t know the exact cause.
<strong>Always</strong> log your errors like:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="n">log</span><span class="o">.</span><span class="na">error</span><span class="o">(</span><span class="s">&quot;Meaningful error message&quot;</span><span class="o">,</span> <span class="n">e</span><span class="o">);</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Java is not <strike>C++</strike> C89/ANSI C</h3>

<p>Seriously! Repeat after me: <em>&#8220;Java is not <strike>C++</strike> C89/ANSI C!&#8221;</em> You don&#8217;t need to declare your loop variable outside of the loop, like you used to do back in the old C. Nor do you have to declare
and initialise a variable at the beginning of a method and then change its value on the next line. What&#8217;s the point?!</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="c1">// int i = 0; BAD!</span>
</span><span class='line'><span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span> <span class="cm">/* GOOD! */</span>
</span><span class='line'>    <span class="c1">//do something here</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// hilarious</span>
</span><span class='line'><span class="kt">int</span> <span class="n">index</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="o">;</span>
</span><span class='line'><span class="n">index</span> <span class="o">=</span> <span class="s">&quot;random_not_null_string&quot;</span><span class="o">.</span><span class="na">indexOf</span><span class="o">(</span><span class="s">&quot;!&quot;</span><span class="o">);</span>
</span><span class='line'><span class="k">if</span> <span class="o">(</span><span class="n">index</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>
</span><span class='line'><span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
</span><span class='line'>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Learn how to correctly concatenate Strings</h3>

<p>Strings are immutable! Stop concatenating more than two of them with <code>+</code> if they are not constants. Every time you use <code>+</code> for something like</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="c1">// assume we&#39;re in a loop</span>
</span><span class='line'><span class="n">result</span> <span class="o">+=</span> <span class="n">a</span> <span class="o">+</span> <span class="s">&quot; bla bla &quot;</span> <span class="o">+</span> <span class="n">b</span> <span class="o">+</span> <span class="s">&quot; bla bla&quot;</span><span class="o">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>a kitten dies in terrible pain. Not only that your code is slow, it&#8217;s also occupying more memory than it should. Use one of the convenient classes
for building strings, like <code>StringBuilder</code> or <code>StringBuffer</code>, the latter one being thread safe.</p>

<h3>In case you need to write JSON</h3>

<p>Don&#8217;t! Seriously. Just don&#8217;t. And not because I don&#8217;t like JSON, but because you&#8217;re probably going to do something wrong. Always use a class that
can write JSON for you. Yes, it&#8217;s another dependency to your project. However the chances are that it&#8217;s been tested by more developers than just one.
Code is one of those things where &#8220;the more, the merrier&#8221; expression just fits in without sounding awkward. Whether you use
<a href="http://code.google.com/p/json-simple/" title="Json.simple">Json.simple</a> or <a href="http://code.google.com/p/google-gson/" title="Gson">Gson</a>, it&#8217;s up to you.</p>

<h2>As a conclusion</h2>

<p>Don&#8217;t be ashamed to ask for a code review from one of your colleagues. Nobody&#8217;s perfect, but the code you deliver should work no matter what data it&#8217;s
fed through it. Write your application as if you&#8217;re building a tank. Make it handle abuse and misuse. And don&#8217;t forget to be paranoid. It helps.</p>

<p>(Many thanks to fellow Redditers who provided me with valuable feedback for two things that I haven&#8217;t double checked: the String concatenation example
didn&#8217;t specify that <code>+</code> should be avoided in loops, although that was the intended case; the C++ standard allows variable declarations anywhere.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Tools required for opening a MacBook Pro]]></title>
    <link href="https://radu.cotescu.com/tools-required-for-opening-a-macbook-pro/"/>
    <updated>2012-06-04T01:45:00+02:00</updated>
    <id>https://radu.cotescu.com/tools-required-for-opening-a-macbook-pro</id>
    <content type="html"><![CDATA[<p>Last week my final MacBook Pro arrived. Since at Adobe we are forced to encrypt our hard-drives in order to protect our work (in case our machines get stolen) the IT team decided to provide us with SSD drives for our portable computers. The advantages are numerous:</p>

<ul>
<li><p>improved IO performance (encryption comes with a cost - I really wouldn&#8217;t like to use it on a mechanical drive)</p></li>
<li><p>reduced power consumption</p></li>
<li><p>reduced operation noise (only the fans and the optical unit contain moving parts)</p></li>
<li><p>less dissipated heat</p></li>
</ul>


<p>Because I was in hurry to get the new machine set-up I decided to install the new SSD by myself. After all, it wasn&#8217;t the first time I tore a computer apart. Big mistake&#8230;</p>

<!--more-->


<p>Apparently Apple uses the tiniest screws available. Most of the guides and forum posts on the subject mention that the only tools you need to access the user-replaceable components (the hard-drive and the RAM DIMMs) are a PH#00 and a T6 screwdriver. For n00bs, that&#8217;s a Phillips 00 screwdriver (<strong>+</strong> shaped) and a Torx 0.6 (<strong>*</strong> shaped). Wrong!</p>

<p>It seems that the recommended PH#00 screwdriver is too big to safely remove the screws that keep the back lid attached to the body. Using a bigger screwdriver might end up in deforming the screws&#8217; heads. However the Phillips PH#000 is a perfect match. If you&#8217;re looking to buy these two screwdrivers - the PH#000 and the T6 - I suggest you visit your local DIY store and look for precision screwdrivers. Try to buy a set that&#8217;s made from high carbon steel if you want to use them for a longer time.</p>

<p>A very good guide for changing your Mac&#8217;s hard-drive can be found <a href="http://www.ifixit.com/Guide/Installing-MacBook-Pro-15-Inch-Unibody-Late-2011-Hard-Drive-Replacement/7513/" title="Installing MacBook Pro 15&quot; Unibody Late 2011 Hard Drive Replacement">here</a>. Keep in mind, though, that you need a PH#000 screwdriver.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Switching to Mac from Ubuntu]]></title>
    <link href="https://radu.cotescu.com/the-switch-to-mac-from-ubuntu/"/>
    <updated>2012-05-20T23:39:00+02:00</updated>
    <id>https://radu.cotescu.com/the-switch-to-mac-from-ubuntu</id>
    <content type="html"><![CDATA[<p>When I joined Adobe I was given the chance of choosing between using a Lenovo ThinkPad or a MacBook Pro as my
development machine. Since I really dislike the design of the ThinkPads and also because I really wanted to try a Mac
for a longer period of time I accepted the challenge. My previous experiences with a Mac were limited to only a few
occasions when I had to perform some specific tasks - mostly while dishing Apple and Mac because it took me at least
twice the time I needed to complete the same tasks on a machine running Ubuntu.</p>

<p>After 10 days of using only the MacBook as my main computer (even at home), I can&#8217;t say that I really miss using Ubuntu.</p>

<!-- more -->


<p>Sure, there are some things that aren&#8217;t as nice on a Mac:</p>

<ul>
<li><p>the lack of a decent package manager - <strong>MacPorts</strong>, although usable, can&#8217;t compare with <strong><code>apt-get</code></strong>;</p></li>
<li><p>the lack of a good default text editing application - <strong>TextEdit</strong> sucks compared to <strong>gedit</strong>; however I have
discovered <a href="http://www.sublimetext.com/" title="Sublime Text 2"><strong>Sublime Text 2</strong></a> aka <code>vim</code> on steroids with a GUI;</p></li>
<li><p>the window management system - although I&#8217;ve come to understand why there&#8217;s no need to maximize a window (hence why
the third window management button is called &#8220;zoom&#8221;), I really don&#8217;t like the fact that if you &#8220;hide&#8221; a window
(minimize it in plain English), you have to right-click on its icon from the dock to restore it;</p></li>
<li><p><strong>Terminal</strong> is not that smart by default - more info <a href="http://blog.macromates.com/2006/word-movement-in-terminal/" title="Word Movement in Terminal">here</a>; also, because I often perform tasks from the terminal I needed a way to make the app on
the Mac behave more like <a href="http://en.wikipedia.org/wiki/Yakuake" title="Yakuake"><strong>Yakuake</strong></a> and that&#8217;s how I found out about
<a href="http://totalterminal.binaryage.com/" title="TotalTerminal"><strong>TotalTerminal</strong></a>;</p></li>
<li><p><strong>Finder</strong>, the file browser on the Mac, is not really worthy of &#8220;the world&#8217;s most advanced desktop operating system&#8221;;
it lacks tabs, the <code>cut</code> function is not enabled (although it is available) and if you enable it anything you &#8220;cut&#8221; will
make it to <strong>Trash</strong>.</p></li>
</ul>


<p>I had no problems configuring the system and this was probably helped by the changes that were made in Ubuntu in this
direction over the previous years. An Ubuntu user would have no problems at all adjusting to the Mac; and the other way
around. This was a bold decision - to use the Mac as the source of inspiration for Ubuntu - and I really appreciate Mark
Shuttleworth&#8217;s leadership in the project. Although I really like the idea of freedom that the Linux ecosystem promotes,
I do agree that having some restrictions in place - some would call it direction - helps in delivering a product with a
superior quality.</p>

<p>There are a lot of things that I like about the Mac:</p>

<ul>
<li><p>the hardware is superior to everything else on the market and by superior I don&#8217;t mean necessarily performance-wise;
everything fits together so good that nothing seems out of place; the attention to details was paramount; the fact
that the body is made from Aluminum helps a lot for the overall system cooling - the fan rarely can be heard and that&#8217;s
only when the CPU is very busy;</p></li>
<li><p>having an illuminated keyboard is really useful when using the laptop in dim light or when you want to work during the
night - such a simple and efficient idea;</p></li>
<li><p>the battery life is very good - if you don&#8217;t use <strong>Skype</strong> or the <strong>GoogleVoiceAndVideo</strong> plug-in; you can easily
squeeze 4 - 5 hours if you&#8217;re not performing rocket science; I managed to reach 3.5 hours while coding with Java on top
of a web application that ran continuously in a Servlets container;</p></li>
<li><p>the gestures and the track-pad really increase productivity;</p></li>
<li><p>the GUI - this is where the Mac was, is and will be ahead of the other OSs;</p></li>
<li><p>using a secondary display is as easy as connecting it to the Mini DisplayPort; no other settings have to be made;</p></li>
<li><p>it&#8217;s a widely (?!) supported Unix or it has better support than any Linux distribution anyway;</p></li>
<li><p>the display (even the one with the 1440x900 resolution) looks sharp from any angle without any colour bleeding.</p></li>
</ul>


<p>If I&#8217;d run Mac OS X on any other hardware probably I wouldn&#8217;t be so amazed (yes, I know about the license). But combine
the OS with the hardware and you get a killer combination that&#8217;s easy to accept as the norm. It slowly gets you and it
becomes harder and harder to go back to what you were using before. Yes, I have become a
&#8221;<a href="http://www.google.com/search?&amp;q=define%3Amactard">mactard</a>&#8221;.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Migrating your Ubuntu machine to a SSD drive]]></title>
    <link href="https://radu.cotescu.com/migrating-your-ubuntu-machine-to-a-ssd-drive/"/>
    <updated>2012-05-11T23:10:00+02:00</updated>
    <id>https://radu.cotescu.com/migrating-your-ubuntu-machine-to-a-ssd-drive</id>
    <content type="html"><![CDATA[<p>SSD drives have finally become affordable and more reliable than they used to be. Partly this was sure helped by the price boost of the traditional hard-disks manufactured in Thailand (I think everybody still reminds the <a href="http://en.wikipedia.org/wiki/2011_Thailand_flood" title="2011 Thailand flood">floods</a> from the summer of 2011). The competition helped the development of innovative solutions and after 4 years since their mass-consumption breakthrough they have managed to become a standard on ultrabooks and premium laptops.</p>

<p>Because the price / GB of the classic mechanical hard-disk was so low (as low as US$0.05 per GB for 3.5 inch drives and US$0.10 per GB for 2.5 inch drives), producers started to offer larger drives for the same money. Unfortunately SSD technologies cannot and probably will not evolve the same way due to memory degradations once the chip size decreases. In particular this led to higher prices for the same disk size, making SSDs more attractive for boot / OS drives instead of plain storage ones.</p>

<p>Migrating a current OS installation usually has to take into consideration that the SSD destination disk might not be able to fully accommodate the previously stored data. The following paragraphs will describe what solutions can be employed in order to successfully migrate an Ubuntu installation (or any other Linux distribution) to a SSD drive.</p>

<!-- more -->


<h1>How To</h1>

<p>Depending on the available storage space of the SSD, there are two available solutions:</p>

<ol>
<li><p>the destination drive is just as big as the source drive, or larger &ndash; <code>ddrescue</code></p></li>
<li><p>the destination drive is smaller than the source drive &ndash; <code>rsync</code>, <code>gparted</code>, <code>boot-repair</code></p></li>
</ol>


<p>Tools needed for both solutions:</p>

<ol>
<li><p>an Ubuntu live CD / live USB stick from which to boot and perform the migration;</p></li>
<li><p>at least two SATA drives, one for the source and one for the destination disk;</p></li>
<li><p>at least two SATA data cables and two SATA power cables if you&#8217;re using a desktop machine to perform the migration, or a SATA to USB adaptor if you&#8217;re using a laptop;</p></li>
<li><p>a Philips screwdriver to mount / un-mount the hard drives and possibly the 3.5&#8221; adaptor.</p></li>
</ol>


<p>It&#8217;s time to connect the hard drives to your machine.</p>

<h2>1. Same size or larger SSD</h2>

<p>If the SSD you have installed on your machine is the same size or larger than your current mechanical drive it means that you&#8217;re rich. Furthermore, the work you have to do to migrate your system to the new drive does not require too much effort. <code>ddrescue</code> is a great tool for restoring information from failing drives but it can also be used to perform bitwise clones.</p>

<p>To start migrating your system from one drive to the other, perform the following steps:</p>

<ol>
<li><p>boot your machine using the live CD / USB stick;</p></li>
<li><p>enable the &#8220;universe&#8221; repositories on Ubuntu and install <code>gddrescue</code>:</p>

<pre><code> sudo apt-get update &amp;&amp; sudo apt-get install gddrescue
</code></pre></li>
<li><p>use <code>gddrescue</code> to clone your drive:</p>

<pre><code> sudo ddrescue -v --force /dev/sda /dev/sdb
</code></pre>

<p> where <code>/dev/sda</code> is your source drive and <code>/dev/sdb</code> is your destination drive</p></li>
<li><p>have patience; depending on your disk size and your machine&#8217;s performance this might take a while.</p></li>
</ol>


<p>At the end you should be able to seamlessly replace the old spinning drive with the SSD and just enjoy the snappiness of your system.</p>

<h2>2. Smaller SSD - the usual compromise</h2>

<p>Trying to clone a larger disk to a smaller one using <code>ddrescue</code> is not trivial, even if the total used storage space would be less than the SSD&#8217;s storage capacity. In this case three software tools of the *nix Swiss Army knife have to be used:</p>

<ol>
<li><p><code>gparted</code> &ndash; for setting out the partitioning layout;</p></li>
<li><p><code>rsync</code> &ndash; for selectively synchronising the needed data (you can easily decide what to exclude using patterns);</p></li>
<li><p><code>boot-repair</code> &ndash; to fix your Grub2 setup.</p></li>
</ol>


<h3>Partitioning with <code>gparted</code></h3>

<p>Boot your system using your live Ubuntu image. Using <code>gparted</code> (it is included on the live image) create the desired partitions on your SSD. Currently only 2 Linux file systems properly support SSDs (making use of native TRIM): <code>btrfs</code> and <code>ext4</code>. Out of these two, only <code>ext4</code> is considered mature enough to be used on production-ready systems, due to its mass-adoption in the Linux world.</p>

<p>In order to align your partitions with the drive&#8217;s sectors (for optimal performance and longevity) make sure to leave the first MiB of storage unallocated and to align your partitions to MiB, not cylinders. This is fairly intuitive with <code>gparted</code>.</p>

<p>Remember to add the <code>boot</code> flag to the partition where your <code>/boot</code> folder will be stored.</p>

<h3>Syncing with <code>rsync</code></h3>

<p>Once your SSD drive is partitioned, mount the source and destination partitions. This can easily be done from Nautilus, the default file browser from Ubuntu. Just open the home folder and on the left sidebar you can see the unmounted file systems. Click on them to let the system mount them automatically. I strongly recommend to mount them two by two (1 source, 1 destination) in order to avoid any complications. Using <code>rsync</code> selectively sync your partitions:</p>

<pre><code>    sudo rsync -a -v --exclude "excluded_folder_name_or_pattern" /media/&lt;source_uuid&gt;/ /media/&lt;destination_uuid&gt;
</code></pre>

<h3>Restoring <code>grub</code></h3>

<p>Unfortunately <code>rsync</code> will not be able to handle <code>grub</code>, thus you will not be able to boot your system. Restoring <code>grub</code> is very straight-forward. Again you will need the live CD / live USB stick to boot up your machine. After Ubuntu is up and running from the installation medium, you just need to install and use Boot-Repair. A very good guide is available <a href="https://help.ubuntu.com/community/Boot-Repair" title="Boot-Repair - Ubuntu Community Documentation">here</a>.</p>

<h2>Specific mount options for SSD</h2>

<p>Because of the way SSD drives work, some mount options need to be specified in your <code>/etc/fstab</code> file:</p>

<ul>
<li><code>discard</code> &ndash; this enables <a href="http://en.wikipedia.org/wiki/TRIM" title="TRIM explained on Wikipedia">TRIM</a>;</li>
<li><code>noatime</code> &ndash; this disables pointless writes to disk to store the last accessed time for a read file</li>
</ul>


<p>Your <code>fstab</code> file should look more or less like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># /etc/fstab: static file system information.</span>
</span><span class='line'><span class="c">#</span>
</span><span class='line'><span class="c"># Use &#39;blkid -o value -s UUID&#39; to print the universally unique identifier</span>
</span><span class='line'><span class="c"># for a device; this may be used with UUID= as a more robust way to name</span>
</span><span class='line'><span class="c"># devices that works even if disks are added and removed. See fstab(5).</span>
</span><span class='line'><span class="c">#</span>
</span><span class='line'><span class="c"># &lt;file system&gt; &lt;mount point&gt;   &lt;type&gt;  &lt;options&gt;       &lt;dump&gt;  &lt;pass&gt;</span>
</span><span class='line'>proc            /proc           proc    nodev,noexec,nosuid 0       0
</span><span class='line'><span class="nv">UUID</span><span class="o">=</span>0765430a-83ae-4530-b1b1-a976cd72ce16 /               ext4    discard,noatime,errors<span class="o">=</span>remount-ro             0 1
</span><span class='line'><span class="nv">UUID</span><span class="o">=</span>263bba00-32f4-4bea-966b-ab7ae1fc3e8b /home           ext4    discard,noatime,errors<span class="o">=</span>remount-ro,user_xattr  0 2
</span></code></pre></td></tr></table></div></figure>


<h1>Conclusions</h1>

<p>Migrating from your slow mechanical hard drive was easy. I am pretty sure that  if you have not used a SSD drive until now you will definitely question yourself why it took you so long to switch - I know I do. Sometimes we fail to remember that the hard-disk is still the slowest component in a computing system. A SSD might be the solution to speed up your machine instead of buying the newest and coolest CPU and it&#8217;s definitely cheaper as long as you can accommodate with less storage space for the drive that should store your OS and applications (and <em>maybe</em> your media workspace).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why awk is better than cut]]></title>
    <link href="https://radu.cotescu.com/why-awk-is-better-than-cut/"/>
    <updated>2011-08-01T12:45:40+02:00</updated>
    <id>https://radu.cotescu.com/why-awk-is-better-than-cut</id>
    <content type="html"><![CDATA[<p>I am currently working with some text files from which I have to extract some data. Generally, when you have to do this kind of work on a *nix machine, you use <code>cut</code> or <code>awk</code>. However, even for simple tasks <code>cut</code> is superseded by the mighty <code>awk</code>. Let&#8217;s look at the following examples which are closely related to the data that I&#8217;m working with. Assume we have the following text file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>radu@riker:~<span class="nv">$ </span>cat testFile
</span><span class='line'>a
</span><span class='line'>b c
</span><span class='line'>d
</span><span class='line'>e f
</span></code></pre></td></tr></table></div></figure>


<p>What I&#8217;d like to do is to extract the strings from each line and assign them to some parameters; obviously the second parameter can be null. To do this with <code>cut</code> you&#8217;d have to use two different call types, one for each parameter:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>radu@riker:~<span class="nv">$ </span>cat testFile | cut -d<span class="s2">&quot; &quot;</span> -f1
</span><span class='line'>a
</span><span class='line'>b
</span><span class='line'>d
</span><span class='line'>e
</span><span class='line'>radu@riker:~<span class="nv">$ </span>cat testFile | cut -d<span class="s2">&quot; &quot;</span> -f2 -s
</span><span class='line'>c
</span><span class='line'>f
</span></code></pre></td></tr></table></div></figure>


<p>Notice the <code>-s</code> option in the second call. This tells <code>cut</code> not to print lines not containing delimiters. If by mistake you&#8217;d forget to add that flag to the options list, the output would be this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>radu@riker:~<span class="nv">$ </span>cat testFile | cut -d<span class="s2">&quot; &quot;</span> -f2
</span><span class='line'>a
</span><span class='line'>c
</span><span class='line'>d
</span><span class='line'>f
</span></code></pre></td></tr></table></div></figure>


<p>which includes the values for the first parameter too. Not good.</p>

<p>Now let&#8217;s share some <code>awk</code> love:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>radu@riker:~<span class="nv">$ </span>cat testFile | awk <span class="s1">&#39;{print $1}&#39;</span>
</span><span class='line'>a
</span><span class='line'>b
</span><span class='line'>d
</span><span class='line'>e
</span><span class='line'>radu@riker:~<span class="nv">$ </span>cat testFile | awk <span class="s1">&#39;{print $2}&#39;</span>
</span><span class='line'>
</span><span class='line'>c
</span><span class='line'>
</span><span class='line'>f
</span></code></pre></td></tr></table></div></figure>


<p>Of course, if your restrictions aren&#8217;t like mine you can as well use <code>cut</code>. However, you&#8217;d be safer with <code>awk</code>.</p>

<p>Happy Bash parsing!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bash one-liner for removing old kernel artefacts]]></title>
    <link href="https://radu.cotescu.com/bash-old-kernel-artefacts/"/>
    <updated>2011-07-29T14:13:57+02:00</updated>
    <id>https://radu.cotescu.com/bash-old-kernel-artefacts</id>
    <content type="html"><![CDATA[<p>Since now I have 4 virtual machines to administer for my dissertation project, I have to find ways to do sysadmin stuff as quickly as possible and to concentrate my efforts on software development. If you ever did a kernel update you would know that a kernel upgrade will not remove the old kernel artefacts, specifically the old headers and the Linux image. While this is a good technique for avoiding incompatibilities of some binaries with the new kernel versions, therefore allowing you to test that everything is working as expected, old kernel images occupy an important amount of space (around 256 MB / release). When your system has a limited amount of storage allocated to it, this might become a problem.</p>

<p>The process of removing the unused images requires a few keystrokes and some user input, needing a great deal of attention not to remove the currently running kernel or - in case you are extremely inattentive - all the kernel images from your system. To semi-automate this task, you can use the following Bash one-liner:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>sudo apt-get purge <span class="k">$(</span>dpkg -l | grep <span class="s2">&quot;^ii&quot;</span> | awk <span class="s1">&#39;{print $2}&#39;</span> | egrep -e <span class="s2">&quot;^linux-headers-[0-9]|^linux-image-[0-9]&quot;</span> | egrep -v <span class="sb">`</span>uname -r | cut -d<span class="s2">&quot;-&quot;</span> -f1,2<span class="sb">`</span><span class="k">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Run this line only after you have booted into your new kernel, otherwise you&#8217;ll remove the upgrade.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Facebook, Pidgin and the "Not authorised" error message]]></title>
    <link href="https://radu.cotescu.com/facebook-pidgin-not-authorised/"/>
    <updated>2011-06-15T13:46:58+02:00</updated>
    <id>https://radu.cotescu.com/facebook-pidgin-not-authorised</id>
    <content type="html"><![CDATA[<p>I noticed a few days ago that my Facebook XMPP chat account from Pidgin had stopped working, popping up a weird error message: &#8220;Not authorised&#8221;. This happened even though I did not change any of the account&#8217;s settings.</p>

<p>The resolution is pretty Voodoo or, how <a href="http://web.nastasiu.com">Vlad</a> described it, the error needs a Microsoft-type fix. Apparently if you are logged in on Facebook using your email address instead of the user name, the XMPP protocol might not authenticate you. Therefore, if you&#8217;d like to use Facebook&#8217;s chat on third-party clients while you&#8217;re still logged on in a browser, make sure you always log in using your user name instead of your email address on Facebook&#8217;s site. Trying to use your email address in Pidgin for the user name field results in an error, as email addresses are not valid XMPP user names.</p>

<p>Weird!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Help needed]]></title>
    <link href="https://radu.cotescu.com/ubuntu-automated-configuration-tool/"/>
    <updated>2011-06-02T20:39:28+02:00</updated>
    <id>https://radu.cotescu.com/ubuntu-automated-configuration-tool</id>
    <content type="html"><![CDATA[<p>Dear all,</p>

<p>I am running <a href="http://goo.gl/RW4s0">a survey</a> for my dissertation project to collect some useful data that might help me shape the application that I am going to build. If you have previously used <a href="http://www.ubuntu.com/">Ubuntu</a> your input will be much appreciated. It shouldn&#8217;t take you more than 5 - 10 minutes to complete the form.</p>

<p>Thank you very much for your kind help!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to install VMware Server on kernel version 2.6.38]]></title>
    <link href="https://radu.cotescu.com/vmware-server-kernel-2-6-38/"/>
    <updated>2011-05-05T12:18:56+02:00</updated>
    <id>https://radu.cotescu.com/vmware-server-kernel-2-6-38</id>
    <content type="html"><![CDATA[<h2>Notices:</h2>

<ul>
<li><p>VMware has declared VMware Server End Of Availability on January 2010 with the actual support ending on June 30th, 2011. More details can be read <a href="http://www.vmware.com/support/policies/lifecycle/general/index.html#policy_server">here</a>. Furthermore, VMware Server is not officially supported on Ubuntu releases greater than 8.04.</p></li>
<li><p>The VMware Server console plug-in won&#8217;t work on Firefox versions older than 3.6 (I have found no viable solution for this problem).</p></li>
</ul>


<p>The needed instructions for the installation can be found <a href="http://radu.cotescu.com/how-to-install-vmware-server-ubuntu-fedora-opensuse/">here</a>. For comments related to the installation on machines running the 2.6.38 kernel version please post here.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ubuntu 64-bit and Flash videos in fullscreen]]></title>
    <link href="https://radu.cotescu.com/ubuntu-flash-videos-fullscreen/"/>
    <updated>2011-03-25T00:00:13+01:00</updated>
    <id>https://radu.cotescu.com/ubuntu-flash-videos-fullscreen</id>
    <content type="html"><![CDATA[<p>I have never been an Adobe fan and something tells me that I won&#8217;t change my mind soon. One of the main reasons for which Linux had problems being a &#8220;normal&#8221; operating system for a quite long period of time (although there were other issues as well, but not as visible at this one) was that the Flash Player never really worked very well on this platform. Time passed and things began slowly to advance, however users of the 64-bit version of the Linux kernel had to use various hacks to run a 32-bit browser because of Flash.</p>

<h2>A little bit of history (and personal experience)</h2>

<p>Only when it reached version 10 Adobe managed to issue a native 64-bit version of their Flash plug-in for Linux, but it was a Labs attempt and therefore not considered a stable release. Still, it was the best way to enjoy Flash content on a 64-bit platform, even though there wasn&#8217;t a nice and easy way to install it (get an archive from Adobe, extract the <code>.so</code> file from it, and then using <code>sudo</code> move it to the proper location using the terminal). Nevertheless, everything worked smoothly, even 1080p videos in full screen, as long as you had a decent machine. Yeah, Flash is power hungry (not quite news&#8230;).</p>

<p>It didn&#8217;t last long until Adobe found out that version 10.0 had a major security bug, which led to the release of version 10.1. But because Linux users were (and probably still are) a negligible quantity, version 10.1 didn&#8217;t contain a 64-bit release for this platform. The &#8220;official&#8221; reasons were that Adobe wanted to work on version 10.2 which unified several technologies and therefore did not have to time to work on a Linux release. And then again, in order to avoid the security bugs, Linux users had to use the 32-bit Flash player wrapped with 32-bit compatible libraries on their 64-bit systems. And hell broke loose ever since because running Flash videos in fullscreen was a matter of luck, randomness and Adobe&#8217;s willingness to test video cards drivers.</p>

<p>Although <a href="http://radu.cotescu.com/geeks-and-their-computers/">Riker</a> has pretty powerful hardware components, a Flash video in fullscreen made it look ridiculous. Flash 10.2 (this time a native 64-bit release) didn&#8217;t seem to handle the problem better. Annoyed by such a trivial thing, I have started to look for a fix. It was weird that things were working with 10.0 and then degraded with newer releases. I know that my video driver hasn&#8217;t been updated since then, which clearly meant that the problem was on Adobe&#8217;s side.</p>

<h2>The fix</h2>

<p>Apparently, on UNIX (and consequently Linux) machines, the Flash player can read settings from two files:</p>

<ul>
<li><p><code>mm.cfg</code> - a file residing in each user&#8217;s home directory with per user settings</p></li>
<li><p><code>mms.cfg</code> - a file residing in <code>/etc/adobe</code> which sets things for the whole machine</p></li>
</ul>


<p>Because Flash uses its own mechanism to check for video card compatibility and then runs animations according to it, on some drivers it might fail to read properly the OpenGL specs of the card, which in turn leads to crappy performance in fullscreen (lags, unresponsiveness, browser crashes, etc.). To override the internal compatibility check (which Adobe says that might lead to crashes; ironic, isn&#8217;t it?!), one has to add a setting in the mms.cfg file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">OverrideGPUValidation</span><span class="o">=</span><span class="nb">true</span>
</span></code></pre></td></tr></table></div></figure>


<p>Once this is done, simply restart your browser and check how things are working. You might have a nice surprise. It&#8217;s amazing though how until 10.1 things were working as they should have without this override.</p>

<p>If by any chance that file, or even the <code>adobe</code> folder, is missing, use these commands:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>sudo mkdir /etc/adobe <span class="c">#in case the folder is missing</span>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;OverrideGPUValidation=true&quot;</span> | sudo tee /etc/adobe/mms.cfg
</span></code></pre></td></tr></table></div></figure>


<p>Let&#8217;s hope though that 10.3 won&#8217;t require something more esoteric.</p>

<p>Source: <a href="http://blogs.adobe.com/penguinswf/2008/08/secrets_of_the_mmscfg_file_1.html">Secrets of The mms.cfg File</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to secure your SSH server from brute-force attacks]]></title>
    <link href="https://radu.cotescu.com/ssh-brute-force-attacks/"/>
    <updated>2011-02-18T20:13:52+01:00</updated>
    <id>https://radu.cotescu.com/ssh-brute-force-attacks</id>
    <content type="html"><![CDATA[<p>There are a lot of tutorials online that will tell you how to secure your SSH server. Most of them will tell you not to allow the <code>root</code> account to login, to use only keys for authentication and possibly to change the port on which your server listens from 22 to any other. Although this is valid advice, there are times when due to zealous system administrators you <em>have</em> to use port 22 (because along with 21 and 80 it&#8217;s not blocked and you <em>do</em> like to check your server from time to time). Also, you might still want to use password authentication together with public and private keys just because there are chances that you might lose your keys (it happens to the best of us). Combine these two and you are exposing your server to a lot of brute-force attacks from various script kiddies.</p>

<p>If your SSH server (generally OpenSSH) is compiled to use <a href="http://en.wikipedia.org/wiki/TCP_Wrapper">TCP Wrapper</a> you can use <a href="http://denyhosts.sourceforge.net/">DenyHosts</a> to protect yourself against the annoying attempts to hack the server. However, if you don&#8217;t have the option to use a TCP Wrapper aware SSH server (which happens to be the case on almost all Linux distributions made to operate home-class routers), you&#8217;re pretty much on your own. Unless you&#8217;d like to use another script I wrote while I was bored.</p>

<p>The script analyses your SSH daemon&#8217;s log, identifies IPs from which there are unauthorized access attempts (the attackers usually try to login using a multitude of user/password combinations - brute-force attacks) and then denies all traffic from those IPs. Also it keeps a list of all those pesky &#8220;hackers&#8221; for times when you reboot (the part where you re-add those IPs to your <code>iptables</code> configuration is left as an exercise to you). The cherry on top of the cake is that for every bad IP the script tries to mail the ISP with the relevant parts from your log (in case you have configured <code>sendmail</code> or another MTA with a <code>sendmail</code> interface).</p>

<p>As usual, you can find the script in one of my GitHUB <a href="https://github.com/raducotescu/SSHBruteForceLogger">repos</a> with a nice README file giving you all the juicy configuration details.</p>

<p>If you can improve the script to do even more, please fork the repo. Also, if you find any bugs please let me know.</p>

<p><strong>TIP</strong>: if your kernel can use the recent module, you can add some rules like these:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
</span><span class='line'>iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j LOG --log-prefix <span class="s2">&quot;SSH_brute_force &quot;</span>
</span><span class='line'>iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
</span></code></pre></td></tr></table></div></figure>


<p>This would assure that a user cannot open more than 8 connections in 60 seconds to your server on port 22. Of course, if the user tries to open a ninth connection, <code>iptables</code> will block the access for 60 seconds. This is just an extra measure to protect your server in addition to the script.</p>

<p>Don&#8217;t let the &#8220;hackers&#8221; win!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Java, HTTPS and REST web services using Apache CXF]]></title>
    <link href="https://radu.cotescu.com/java-https-rest-services-apache-cxf/"/>
    <updated>2010-12-16T23:39:23+01:00</updated>
    <id>https://radu.cotescu.com/java-https-rest-services-apache-cxf</id>
    <content type="html"><![CDATA[<p><strong>Securing REST web services</strong> is a very debated topic on the Internet. Because REST represents an architecture, and not a protocol - like SOAP -, there aren&#8217;t any specifications dealing with security, leaving this aspect as a design decision for the software engineers / developers. Still, if you search the web to find out what are the approaches, you&#8217;ll see that most of the results suggest you use <strong><a href="http://en.wikipedia.org/wiki/Basic_access_authentication">basic authentication</a> over <a href="http://en.wikipedia.org/wiki/HTTP_Secure">HTTPS</a></strong>.</p>

<p>The basic authentication is a trivial way of authenticating HTTP requests directly by the web server, without any added effort for the developer. Since REST isn&#8217;t very pretentious (it uses the well known HTTP methods for accessing resources), leaving the authentication to the web server is a natural thing to do. Still, this doesn&#8217;t mean that your REST API is secure. You merely separate users that should have access to your API from users that should be denied access. Enabling HTTPS on the server is the next step that needs to be followed, so that all the requests are secured. This avoids the classical man-in-the-middle attack and also assures that the credentials sent by the users aren&#8217;t visible to the whole world (although they are BASE64 encoded by the basic authentication mechanism, decoding them is a child&#8217;s play).</p>

<h2>A practical example</h2>

<p>For the next paragraphs, I will be very specific (the title should have already told you this). To add something more, let&#8217;s assume you use <strong>Maven</strong> (because you&#8217;re a real developer) and <strong>Jetty</strong> (only for testing - I assume that for production you use a proper server, like Tomcat). Enabling HTTPS on any other server shouldn&#8217;t be much different.</p>

<h3><code>pom.xml</code></h3>

<p>To enable HTTPS and basic user authentication on Jetty by using Maven, you would have to use an additional plug-in for generating keystores, unless you already have a keystore that you would like to use, in which case you should not keep it in the <code>target</code> folder of your project. The following section of <code>pom.xml</code> should do the trick:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;plugin&gt;</span>
</span><span class='line'>  <span class="nt">&lt;groupId&gt;</span>org.codehaus.mojo<span class="nt">&lt;/groupId&gt;</span>
</span><span class='line'>  <span class="nt">&lt;artifactId&gt;</span>keytool-maven-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span><span class='line'>  <span class="nt">&lt;executions&gt;</span>
</span><span class='line'>      <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>          <span class="nt">&lt;phase&gt;</span>generate-resources<span class="nt">&lt;/phase&gt;</span>
</span><span class='line'>          <span class="nt">&lt;id&gt;</span>clean<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>          <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>              <span class="nt">&lt;goal&gt;</span>clean<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>      <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>          <span class="nt">&lt;phase&gt;</span>generate-resources<span class="nt">&lt;/phase&gt;</span>
</span><span class='line'>          <span class="nt">&lt;id&gt;</span>genkey<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>          <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>              <span class="nt">&lt;goal&gt;</span>genkey<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/executions&gt;</span>
</span><span class='line'>  <span class="nt">&lt;configuration&gt;</span>
</span><span class='line'>      <span class="nt">&lt;keystore&gt;</span>${project.build.directory}/jetty-ssl.keystore<span class="nt">&lt;/keystore&gt;</span>
</span><span class='line'>      <span class="nt">&lt;dname&gt;</span>cn=server_host_name<span class="nt">&lt;/dname&gt;</span>
</span><span class='line'>      <span class="nt">&lt;keypass&gt;</span>jetty6<span class="nt">&lt;/keypass&gt;</span>
</span><span class='line'>      <span class="nt">&lt;storepass&gt;</span>jetty6<span class="nt">&lt;/storepass&gt;</span>
</span><span class='line'>      <span class="nt">&lt;alias&gt;</span>jetty6<span class="nt">&lt;/alias&gt;</span>
</span><span class='line'>      <span class="nt">&lt;keyalg&gt;</span>RSA<span class="nt">&lt;/keyalg&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/configuration&gt;</span>
</span><span class='line'><span class="nt">&lt;/plugin&gt;</span>
</span><span class='line'>  <span class="c">&lt;!-- Jetty support for testing --&gt;</span>
</span><span class='line'><span class="nt">&lt;plugin&gt;</span>
</span><span class='line'>  <span class="nt">&lt;groupId&gt;</span>org.mortbay.jetty<span class="nt">&lt;/groupId&gt;</span>
</span><span class='line'>  <span class="nt">&lt;artifactId&gt;</span>maven-jetty-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span><span class='line'>  <span class="nt">&lt;executions&gt;</span>
</span><span class='line'>      <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>          <span class="nt">&lt;id&gt;</span>start-jetty<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>          <span class="nt">&lt;phase&gt;</span>pre-integration-test<span class="nt">&lt;/phase&gt;</span>
</span><span class='line'>          <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>              <span class="nt">&lt;goal&gt;</span>run<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>          <span class="nt">&lt;configuration&gt;</span>
</span><span class='line'>              <span class="nt">&lt;scanIntervalSeconds&gt;</span>0<span class="nt">&lt;/scanIntervalSeconds&gt;</span>
</span><span class='line'>              <span class="nt">&lt;daemon&gt;</span>true<span class="nt">&lt;/daemon&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/configuration&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>      <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>          <span class="nt">&lt;id&gt;</span>stop-jetty<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>          <span class="nt">&lt;phase&gt;</span>post-integration-test<span class="nt">&lt;/phase&gt;</span>
</span><span class='line'>          <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>              <span class="nt">&lt;goal&gt;</span>stop<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/executions&gt;</span>
</span><span class='line'>  <span class="nt">&lt;configuration&gt;</span>
</span><span class='line'>      <span class="nt">&lt;stopKey&gt;</span>foo<span class="nt">&lt;/stopKey&gt;</span>
</span><span class='line'>      <span class="nt">&lt;stopPort&gt;</span>9999<span class="nt">&lt;/stopPort&gt;</span>
</span><span class='line'>      <span class="nt">&lt;scanIntervalSeconds&gt;</span>2<span class="nt">&lt;/scanIntervalSeconds&gt;</span>
</span><span class='line'>      <span class="nt">&lt;contextPath&gt;</span>/restws<span class="nt">&lt;/contextPath&gt;</span>
</span><span class='line'>      <span class="nt">&lt;userRealms&gt;</span>
</span><span class='line'>          <span class="nt">&lt;userRealm</span> <span class="na">implementation=</span><span class="s">&quot;org.mortbay.jetty.security.HashUserRealm&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>              <span class="nt">&lt;name&gt;</span>name_of_realm<span class="nt">&lt;/name&gt;</span>
</span><span class='line'>              <span class="nt">&lt;config&gt;</span>src/main/resources/sec.properties<span class="nt">&lt;/config&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/userRealm&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/userRealms&gt;</span>
</span><span class='line'>      <span class="nt">&lt;connectors&gt;</span>
</span><span class='line'>          <span class="nt">&lt;connector</span> <span class="na">implementation=</span><span class="s">&quot;org.mortbay.jetty.nio.SelectChannelConnector&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>              <span class="nt">&lt;port&gt;</span>8080<span class="nt">&lt;/port&gt;</span>
</span><span class='line'>              <span class="nt">&lt;maxIdleTime&gt;</span>60000<span class="nt">&lt;/maxIdleTime&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/connector&gt;</span>
</span><span class='line'>          <span class="nt">&lt;connector</span> <span class="na">implementation=</span><span class="s">&quot;org.mortbay.jetty.security.SslSocketConnector&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>              <span class="nt">&lt;port&gt;</span>8443<span class="nt">&lt;/port&gt;</span>
</span><span class='line'>              <span class="nt">&lt;maxIdleTime&gt;</span>60000<span class="nt">&lt;/maxIdleTime&gt;</span>
</span><span class='line'>              <span class="nt">&lt;keystore&gt;</span>${project.build.directory}/jetty-ssl.keystore<span class="nt">&lt;/keystore&gt;</span>
</span><span class='line'>              <span class="nt">&lt;password&gt;</span>jetty6<span class="nt">&lt;/password&gt;</span>
</span><span class='line'>              <span class="nt">&lt;keyPassword&gt;</span>jetty6<span class="nt">&lt;/keyPassword&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/connector&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/connectors&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/configuration&gt;</span>
</span><span class='line'><span class="nt">&lt;/plugin&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The highlighted lines indicate the user <strong>realm</strong>. This is a file which describes to the server who are your users and what roles are they assigned. The specified file contains records of this form:</p>

<p><code>
user: password,role
</code></p>

<h3><code>web.xml</code></h3>

<p>Now you must configure your web application to accept HTTPS encrypted content. This is done in the <strong>web.xml</strong> file, by adding the following lines of code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;security-constraint&gt;</span>
</span><span class='line'>  <span class="nt">&lt;web-resource-collection&gt;</span>
</span><span class='line'>      <span class="nt">&lt;web-resource-name&gt;</span>application_name<span class="nt">&lt;/web-resource-name&gt;</span>
</span><span class='line'>  <span class="c">&lt;!-- all URLs are protected --&gt;</span>
</span><span class='line'>      <span class="nt">&lt;url-pattern&gt;</span>/*<span class="nt">&lt;/url-pattern&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/web-resource-collection&gt;</span>
</span><span class='line'>  <span class="nt">&lt;auth-constraint&gt;</span>
</span><span class='line'>      <span class="nt">&lt;role-name&gt;</span>user<span class="nt">&lt;/role-name&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/auth-constraint&gt;</span>
</span><span class='line'>  <span class="nt">&lt;user-data-constraint&gt;</span>
</span><span class='line'>      <span class="c">&lt;!-- redirect all requests to HTTPS --&gt;</span>
</span><span class='line'>      <span class="nt">&lt;transport-guarantee&gt;</span>CONFIDENTIAL<span class="nt">&lt;/transport-guarantee&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/user-data-constraint&gt;</span>
</span><span class='line'><span class="nt">&lt;/security-constraint&gt;</span>
</span><span class='line'><span class="nt">&lt;login-config&gt;</span>
</span><span class='line'>  <span class="nt">&lt;auth-method&gt;</span>BASIC<span class="nt">&lt;/auth-method&gt;</span>
</span><span class='line'>  <span class="nt">&lt;realm-name&gt;</span>name_of_realm<span class="nt">&lt;/realm-name&gt;</span>
</span><span class='line'><span class="nt">&lt;/login-config&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>REST web services and Apache CXF</h3>

<p>So, everything is set up and working. Well, almost. If your REST web services also include some client code, you might encounter an exception with the following message:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="n">javax</span><span class="o">.</span><span class="na">net</span><span class="o">.</span><span class="na">ssl</span><span class="o">.</span><span class="na">SSLHandshakeException</span><span class="o">:</span> <span class="n">sun</span><span class="o">.</span><span class="na">security</span><span class="o">.</span><span class="na">validator</span><span class="o">.</span><span class="na">ValidatorException</span><span class="o">:</span> <span class="n">PKIX</span> <span class="n">path</span> <span class="n">building</span> <span class="nl">failed:</span> <span class="n">sun</span><span class="o">.</span><span class="na">security</span><span class="o">.</span><span class="na">provider</span><span class="o">.</span><span class="na">certpath</span><span class="o">.</span><span class="na">SunCertPathBuilderException</span><span class="o">:</span> <span class="n">unable</span> <span class="n">to</span> <span class="n">find</span> <span class="n">valid</span> <span class="n">certification</span> <span class="n">path</span> <span class="n">to</span> <span class="n">requested</span> <span class="n">target</span>
</span></code></pre></td></tr></table></div></figure>


<p>The exception is thrown because the certificate your server uses is not from a known <strong>Certificate Authority</strong>. If you have studied the POM example, you&#8217;d see that the certificate is generated at every execution of the <code>install</code> goal. Moreover, the certificate is self-signed. From here we have two solutions:</p>

<ol>
<li><p>try to create a single key store and save it in the <code>src</code> folder, configuring the server to use the file from this location; then start the server and use the program written by Andreas Sterbenz which you can find <a href="http://blogs.sun.com/andreas/entry/no_more_unable_to_find">here</a>; grab the certificate and move the resulted file into the security folder of your JRE (on Linux this should be <code>/usr/lib/jvm/java-6-sun/jre/lib/security/</code>); although this will work okay on your machine, if your project should be accessed by multiple developers, each member of the team has to add that certificate to his/hers JVM (which is not quite nice);</p></li>
<li><p>create an<strong> alternative <code>TrustStore</code></strong> used only by your application; this is by far the most elegant solution, which adds some more code to the application but doesn&#8217;t force your team members to add dummy certificates to their JVM.</p></li>
</ol>


<h4>Implementing the <code>TrustStore</code></h4>

<p>The class implementing the <code>X509TrustManager</code> is trivial:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">FakeTrustManager</span> <span class="kd">implements</span> <span class="n">javax</span><span class="o">.</span><span class="na">net</span><span class="o">.</span><span class="na">ssl</span><span class="o">.</span><span class="na">X509TrustManager</span> <span class="o">{</span>
</span><span class='line'>  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">security</span><span class="o">.</span><span class="na">cert</span><span class="o">.</span><span class="na">X509Certificate</span><span class="o">[]</span> <span class="nf">getAcceptedIssuers</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">checkClientTrusted</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">security</span><span class="o">.</span><span class="na">cert</span><span class="o">.</span><span class="na">X509Certificate</span><span class="o">[]</span> <span class="n">certs</span><span class="o">,</span>
</span><span class='line'>          <span class="n">String</span> <span class="n">authType</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">checkServerTrusted</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">security</span><span class="o">.</span><span class="na">cert</span><span class="o">.</span><span class="na">X509Certificate</span><span class="o">[]</span> <span class="n">certs</span><span class="o">,</span>
</span><span class='line'>          <span class="n">String</span> <span class="n">authType</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>To make all your <strong>Apache CXF REST</strong> <strong>clients</strong> use the new trust store, it is necessary to create a static method in an utility class that sets everything up for the clients:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">setClientAuthentication</span><span class="o">(</span><span class="n">Object</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>  <span class="n">Properties</span> <span class="n">p</span> <span class="o">=</span> <span class="n">PropertiesLoader</span>
</span><span class='line'>          <span class="o">.</span><span class="na">getPropertiesFromFile</span><span class="o">(</span><span class="s">&quot;config.properties&quot;</span><span class="o">);</span>
</span><span class='line'>  <span class="n">ClientConfiguration</span> <span class="n">config</span> <span class="o">=</span> <span class="n">WebClient</span><span class="o">.</span><span class="na">getConfig</span><span class="o">(</span><span class="n">client</span><span class="o">);</span>
</span><span class='line'>  <span class="n">HTTPConduit</span> <span class="n">httpConduit</span> <span class="o">=</span> <span class="o">(</span><span class="n">HTTPConduit</span><span class="o">)</span> <span class="n">config</span><span class="o">.</span><span class="na">getConduit</span><span class="o">();</span>
</span><span class='line'>  <span class="k">if</span> <span class="o">(</span><span class="n">p</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">&quot;user.name&quot;</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span>
</span><span class='line'>          <span class="o">&amp;&amp;</span> <span class="n">p</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">&quot;user.password&quot;</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>      <span class="n">AuthorizationPolicy</span> <span class="n">authorization</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AuthorizationPolicy</span><span class="o">();</span>
</span><span class='line'>      <span class="n">authorization</span><span class="o">.</span><span class="na">setUserName</span><span class="o">(</span><span class="n">p</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">&quot;user.name&quot;</span><span class="o">));</span>
</span><span class='line'>      <span class="n">authorization</span><span class="o">.</span><span class="na">setPassword</span><span class="o">(</span><span class="n">p</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">&quot;user.password&quot;</span><span class="o">));</span>
</span><span class='line'>      <span class="n">httpConduit</span><span class="o">.</span><span class="na">setAuthorization</span><span class="o">(</span><span class="n">authorization</span><span class="o">);</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>  <span class="n">TLSClientParameters</span> <span class="n">tlsParams</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TLSClientParameters</span><span class="o">();</span>
</span><span class='line'>  <span class="n">TrustManager</span><span class="o">[]</span> <span class="n">trustAllCerts</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TrustManager</span><span class="o">[]</span> <span class="o">{</span> <span class="k">new</span> <span class="n">FakeTrustManager</span><span class="o">()</span> <span class="o">};</span>
</span><span class='line'>  <span class="n">tlsParams</span><span class="o">.</span><span class="na">setTrustManagers</span><span class="o">(</span><span class="n">trustAllCerts</span><span class="o">);</span>
</span><span class='line'>  <span class="c1">// disables verification of the common name (the host for which the certificate has been issued)</span>
</span><span class='line'>  <span class="n">tlsParams</span><span class="o">.</span><span class="na">setDisableCNCheck</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>
</span><span class='line'>  <span class="n">httpConduit</span><span class="o">.</span><span class="na">setTlsClientParameters</span><span class="o">(</span><span class="n">tlsParams</span><span class="o">);</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The properties file you see loaded in the previous code output contains the username and password for authentication, but it&#8217;s different from the realm. This is because the realm would be harder to parse, although the information is still plain text. Although it might seem redundant to have the username and password in two files, the realm can actually hold users belonging to different roles - therefore the parsing effort.</p>

<p>The <code>PropertiesLoader</code> class is not standard, but again it&#8217;s something trivial:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">java.util.Properties</span><span class="o">;</span>
</span><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PropertiesLoader</span> <span class="o">{</span>
</span><span class='line'>  <span class="kd">public</span> <span class="kd">static</span> <span class="n">Properties</span> <span class="nf">getPropertiesFromFile</span><span class="o">(</span><span class="n">String</span> <span class="n">propertiesFile</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>      <span class="n">Properties</span> <span class="n">p</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Properties</span><span class="o">();</span>
</span><span class='line'>      <span class="n">ClassLoader</span> <span class="n">loader</span> <span class="o">=</span> <span class="n">PropertiesLoader</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getClassLoader</span><span class="o">();</span>
</span><span class='line'>      <span class="k">if</span> <span class="o">(</span><span class="n">loader</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>          <span class="n">loader</span> <span class="o">=</span> <span class="n">ClassLoader</span><span class="o">.</span><span class="na">getSystemClassLoader</span><span class="o">();</span>
</span><span class='line'>      <span class="o">}</span>
</span><span class='line'>      <span class="n">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="n">propertiesFile</span><span class="o">);</span>
</span><span class='line'>      <span class="k">try</span> <span class="o">{</span>
</span><span class='line'>          <span class="n">p</span><span class="o">.</span><span class="na">load</span><span class="o">(</span><span class="n">url</span><span class="o">.</span><span class="na">openStream</span><span class="o">());</span>
</span><span class='line'>      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>          <span class="n">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&quot;Could not load configuration file: &quot;</span>
</span><span class='line'>                  <span class="o">+</span> <span class="n">propertiesFile</span><span class="o">);</span>
</span><span class='line'>      <span class="o">}</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">p</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Having done all this, your clients should now work as expected. Just remember that the <code>FakeTrustStore</code> is to be used <em>only</em> for testing purposes.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ubuntu and Internet Connection Sharing via a wireless card]]></title>
    <link href="https://radu.cotescu.com/ubuntu-internet-connection-sharing-wireless/"/>
    <updated>2010-11-27T18:37:46+01:00</updated>
    <id>https://radu.cotescu.com/ubuntu-internet-connection-sharing-wireless</id>
    <content type="html"><![CDATA[<p>Sharing your Internet connection is the poor man&#8217;s way of creating an access point using one of your PCs as the gateway. This implies that the PC (gateway) that you want to use for this has two network cards:</p>

<ul>
<li><p>an Ethernet card (<a href="http://en.wikipedia.org/wiki/Network_interface_controller">NIC</a>) connected to a network (LAN) with Internet access</p></li>
<li><p>a wireless network interface card (<a href="http://en.wikipedia.org/wiki/Wireless_network_interface_card">WNIC</a>) used to share the Internet connection</p></li>
</ul>


<p>Setting up ICS on an Ubuntu machine is a very straight-forward process:</p>

<ol>
<li><p>Click on the <em>Network Manager</em> icon and select the <em>Create New Wireless Network&#8230;</em> menu entry
<a href="https://radu.cotescu.com/uploads/wpuploads/2010/11/wifi-1.png"><img src="https://radu.cotescu.com/uploads/wpuploads/2010/11/wifi-1-300x199.png" alt="Step 1. Create New Wireless Network" /></a></p></li>
<li><p>Enter the details you want for this new &#8220;ad-hoc&#8221; network. WPA is not supported, so your only options for &#8220;Wireless Security&#8221; are &#8220;None&#8221; (although I wouldn&#8217;t call this security) or the WEP settings (not a secure algorithm, but hopefully your neighbours don&#8217;t use WireShark to crack your network). For the WEP 40/128-bit Key option, you key has to be exactly 5/10/13 characters long. If you want to be able to connect <strong><em>Windows clients</em></strong> to your network, the only option that worked for me is <em><strong>WEP 40/128-bit Key with a 13 characters key</strong></em>. <em><strong>An Ubuntu machine won&#8217;t have any problems with either options</strong></em>. Click on <em>Create</em>. <em>Network Manager</em> will automatically connect to this new network you have just created.
<a href="https://radu.cotescu.com/uploads/wpuploads/2010/11/wifi-2.png"><img src="https://radu.cotescu.com/uploads/wpuploads/2010/11/wifi-2-300x200.png" alt="Step 2. New wireless network" /></a></p></li>
<li><p>After your PC has connected (self-connected) to the &#8220;ad-hoc&#8221; network, you have to make sure that this connection is shared to other computers and devices (clients). Right click on the <em>Network Manager</em> icon and select <em>Edit Connections&#8230;</em> Select the <em>Wireless</em> tab, select your recently created connection and click on <em>Edit</em>. Make sure that the <em>Connect automatically</em> check-box is selected and on the <em>IPv4 Settings</em> tab male sure that the <em>Method</em> option is set to <em>Shared to other computers</em>.
<a href="https://radu.cotescu.com/uploads/wpuploads/2010/11/wifi-3.png"><img src="https://radu.cotescu.com/uploads/wpuploads/2010/11/wifi-3-300x263.png" alt="Step 3. Ad-Hoc network settings" /></a></p></li>
<li><p>Ensure that you do have the <code>dnsmasq-base</code> package installed (you can check usiny <em>Synaptic</em>). This is a DNS / DHCP server which will not run as a daemon, but as a background program, launched by the <em>Network Manager</em>.</p></li>
<li><p>To be sure that your clients will receive an IP check that your firewall allows connections from and to the new network you have just created. Given the following command, you should see a similar output:</p></li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>radu@riker:~<span class="nv">$ </span>sudo iptables -L
</span><span class='line'><span class="o">[</span>sudo<span class="o">]</span> password <span class="k">for </span>radu:
</span><span class='line'>Chain FORWARD <span class="o">(</span>policy ACCEPT<span class="o">)</span>
</span><span class='line'>target     prot opt <span class="nb">source               </span>destination
</span><span class='line'>ACCEPT     all  --  anywhere             10.42.43.0/24       state RELATED,ESTABLISHED
</span><span class='line'>ACCEPT     all  --  10.42.43.0/24        anywhere
</span></code></pre></td></tr></table></div></figure>


<p>Enjoy browsing! I told you this was simple.</p>

<p>P.S. I would like to thank <a href="http://vlad.nastasiu.com/">Vlad</a> for helping me correct the information provided about clients&#8217; IPs and the fact that the gateway will provide the necessary data through DHCP.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to install VMware Server on 2.6.35 kernels]]></title>
    <link href="https://radu.cotescu.com/how-to-install-vmware-server-kernel-2-6-35/"/>
    <updated>2010-11-01T22:37:59+01:00</updated>
    <id>https://radu.cotescu.com/how-to-install-vmware-server-kernel-2-6-35</id>
    <content type="html"><![CDATA[<p>Continuing the tradition of my blog this is going to be another post about VMware Server on the latest kernels provided by the most popular distributions. This is actually an example of a paradox because I don&#8217;t use this hypervisor any more, exactly due to the patching that has to be done. Still, there are quite a few people who like the product and it&#8217;s never too late to make another good deed.</p>

<p>The (now famous) script I wrote a year ago (when Ubuntu 9.10 was released) had to be modified just a bit in order to support the 2.6.35 kernel. The change that affected the compilation of the VMware kernel modules was the change of location for two header files which were expected to be in a certain folder. Thanks to symbolic links, this is now handled without any major efforts. All the needed instructions can be found <a href="http://radu.cotescu.com/how-to-install-vmware-server-ubuntu-fedora-opensuse/">here</a>. For comments related to the way VMware works on the 2.6.35 kernels please use the comment form from this post.</p>

<p>A thing to know before installing VMware Server on your machines is that VMware has declared the product End Of Availability on January 2010 with the actual support ending on June 30th, 2011. More details can be read <a href="http://www.vmware.com/support/policies/lifecycle/general/index.html#policy_server">here</a>. Furthermore, VMware Server is not officially supported on Ubuntu releases greater than 8.04.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using two JVMs in Ubuntu]]></title>
    <link href="https://radu.cotescu.com/using-two-jvm-in-ubuntu/"/>
    <updated>2010-10-19T22:15:49+02:00</updated>
    <id>https://radu.cotescu.com/using-two-jvm-in-ubuntu</id>
    <content type="html"><![CDATA[<p>Today I was faced with the challenge of using two JVMs on the same machine. And let me tell you that whenever you have to do this, things get dirty. Basically I was forced to install an additional 32-bit JVM for <a href="http://www.event-b.org/platform.html">Rodin</a>, the IDE we use at faculty for Event-B modelling, because the developers of the platform (which is actually a modified Eclipse) decided not to support the 64-bit architectures (LAME!).</p>

<p>Installing a 32-bit JVM on a machine that already has a 64-bit JVM installed will change the default JVM to be the last one installed. Since all of my Java programs and application were made for 64-bit, it was a mayhem on my machine. The solution is rather simple (but, oh, so uncomfortable). You would have to change the default JVM back to the 64-bit one and build some wrapper scripts for all the 32-bit apps to use the correct JVM for them.</p>

<p>Changing the defaults is done in this way:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>sudo update-alternatives --install <span class="s2">&quot;/usr/bin/java&quot;</span> <span class="s2">&quot;java&quot;</span> <span class="s2">&quot;/usr/lib/jvm/java-6-sun/bin/java&quot;</span> 1
</span><span class='line'>sudo update-alternatives --set java /usr/lib/jvm/java-6-sun/bin/java
</span></code></pre></td></tr></table></div></figure>


<p>The first line will instruct your system that there&#8217;s another Java version available (the old one) while the second line will make it the default version of JVM.</p>

<p>For Rodin, the wrapper script is pretty trivial, since it&#8217;s nothing more than a modified Eclipse IDE:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'><span class="nv">WHERE</span><span class="o">=</span><span class="sb">`</span>dirname <span class="nv">$0</span><span class="sb">`</span>
</span><span class='line'><span class="nv">$WHERE</span>/rodin -vm /usr/lib/jvm/ia32-java-6-sun/bin/java
</span></code></pre></td></tr></table></div></figure>


<p>Everything should be working okay now but don&#8217;t forget to instruct the 32-bit apps to use their dedicated JVM. Anyway, keep in mind that this is an ugly hack. If you&#8217;re a developer you should better package your apps for all the available architectures and not force your user-base to do this kind of hacks. Don&#8217;t forget though that this happens only when some system dependent libraries are used (as is the case for Rodin).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ubuntu 10.10 and VirtualBox Guest Additions]]></title>
    <link href="https://radu.cotescu.com/ubuntu-virtualbox-additions/"/>
    <updated>2010-10-12T12:00:06+02:00</updated>
    <id>https://radu.cotescu.com/ubuntu-virtualbox-additions</id>
    <content type="html"><![CDATA[<p>Two days ago Ubuntu 10.10 was released. Since I don&#8217;t want to upgrade yet to the new release - I am currently running 10.04 - I decided to try Maverick (the code name for the latest release) in a VirtualBox virtual machine.</p>

<p>The installation process went fine (it&#8217;s just point and click) and I do like the new wizard&#8217;s screens. Usually the next step for any virtual machine would be to install VirtualBox Guest Additions in order to be able to use higher resolutions, mouse integration, seamless integration and all the other geeky goodies. From my previous experiences, to install the Guest Additions into a virtual guest, one was supposed to click on <em>Devices » Install Guest Additions&#8230;</em> in VirtualBox&#8217;s guest window and then to launch the autorun script from the virtual CD. Well, that used to work until now.</p>

<p>For Ubuntu 10.10 the process has to be slightly altered for a successful installation of the additions. This means that once you install Ubuntu in your VM you have to make sure that two other packages are installed in your guest before you use the instructions provided in the previous paragraph. The packages are <code>build-essential</code> and the linux headers for your running kernel. To install these two packages the quickest way would be to open a terminal (the GUI alternatives would be Ubuntu Software Centre and Synaptic Package Manager, but it will take you longer) and issue the following commands:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>sudo apt-get update
</span><span class='line'>sudo apt-get install build-essential linux-headers-<span class="sb">`</span>uname -r<span class="sb">`</span>
</span></code></pre></td></tr></table></div></figure>


<p>Remember that <em><strong>these two packages have to be installed in your guest</strong></em>. Afterwards you proceed with the usual way of installing the additions.</p>

<p>Have fun!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[jQuery .click() and the double submit of a form]]></title>
    <link href="https://radu.cotescu.com/jquery-click-double-submit/"/>
    <updated>2010-09-07T14:21:41+02:00</updated>
    <id>https://radu.cotescu.com/jquery-click-double-submit</id>
    <content type="html"><![CDATA[<p>jQuery is one of the greatest JavaScript frameworks with plenty of documentation for just about everything one can do with it. In my latest project I have used jQuery extensively for any UX aspect: form validations, dialogs, error messages, AJAX, UI, etc.</p>

<p>A feature that I would really like to see implemented on all HTML forms is the ability to submit the form by using the Return key as well. I am sure that there are a lot of users who really like to keep their hands on the keyboard as much as possible, without using the mouse just to click a button or without hitting the TAB key in order to focus on the submit button after which to press Return. Some of the particularities of my project are the fact that it uses Struts2 and the <a href="http://code.google.com/p/struts2-jquery/">Struts2 jQuery plugin</a>. This plugin allows developers either to use the <code>.jar</code> embedded JavaScript libraries or to automatically get the required files from Google&#8217;s servers (CDN). In July, when my project was using Oracle 11G and TopLink everything worked okay. Now, after I have migrated the project to open-source solutions (MySQL and EclipseLink) I have noticed that whenever I tried to create a new account into the application I would get 2 submits for one action. At first I thought that this had something to do with EclipseLink. After some debugging I actually found out that it was a JavaScript issue (it is possible that now I&#8217;m using another jQuery UI release).</p>

<h2>The problem</h2>

<p>The code responsible for the issue is the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#newProfileForm input:submit&#39;</span><span class="p">).</span><span class="nx">button</span><span class="p">().</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nx">checkInputs</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#newProfileForm form&#39;</span><span class="p">).</span><span class="nx">submit</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#newProfileForm input&#39;</span><span class="p">).</span><span class="nx">keyup</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">code</span> <span class="o">=</span> <span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">?</span> <span class="nx">e</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">which</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nx">code</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span><span class="p">(</span><span class="nx">checkInputs</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#newProfileForm&#39;</span><span class="p">).</span><span class="nx">submit</span><span class="p">();</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>   <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>What I have discovered is that the <code>.click()</code> handler actually binds itself to keyboard events too, not only mouse events. This means that if the user presses the Return button the event will be identified with a click event.</p>

<h2>The solution</h2>

<p>Even though if the behaviour mentioned previously is unexpected (who would have thought that a click event would be triggered by the keyboard even if the focus is not set on the submit button?!), there are two ways of avoiding it in the code above:</p>

<ol>
<li><p>eliminate the <code>.keyup()</code> handler because pressing on the Return button will be considered a click event;</p></li>
<li><p>alter the first bind for the <code>.click()</code> handler like this:</p></li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#newProfileForm input:submit&#39;</span><span class="p">).</span><span class="nx">button</span><span class="p">().</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span> <span class="c1">// stop the browser&#39;s default behaviour</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nx">checkInputs</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#newProfileForm form&#39;</span><span class="p">).</span><span class="nx">submit</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Have you ever had similar problems?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The art of web feeds]]></title>
    <link href="https://radu.cotescu.com/the-art-of-web-feeds/"/>
    <updated>2010-08-31T17:05:31+02:00</updated>
    <id>https://radu.cotescu.com/the-art-of-web-feeds</id>
    <content type="html"><![CDATA[<p>Web feeds, as many of you surely know by now, represent a data format under which frequently updated content from various sources is provided to readers (the humans reading the content). The purpose of the web feed is therefore to inform the user of new or updated content originating from a source. Generally speaking web feeds contain HMTL mark-up for the content, on top of an XML document which is parsed by feed readers (the programs used to read web feeds).</p>

<p>Since a web feed is usually a standard feature for any web site that displays articles (by which we understand blog posts, news, press releases, etc.), the number of clients (software programmes) for this job has experienced a constant growth. From web applications, such as Google Reader, to desktop dedicated programs, such as Liferea, or Internet browsers, we have a multitude of ways for accessing web feeds. Because the primary function of the feed is to inform of the new content, the important attributes (sections) of the feed should be the title of the article in question, the author, date of publishing and the full text or the summarized one.</p>

<h2>&#8220;To summarize or not to summarize? That is the question.&#8221;</h2>

<p>What is more important for you and your readers: to serve them the full content (with the risk of them not being necessarily interested) or to give them just a hint of what you&#8217;ve published and let them to decide if they want to read it or not?</p>

<p>The advantage of offering the full content in the web feed is given by the fact that from a user&#8217;s standpoint the only action that he (or she) should perform is to open the reader and select your feed. Unfortunately this is also a disadvantage. Why? Because some of the content might be extending on a number of pages and some of the readers (the people) might not be interested in it, although the article&#8217;s category might be of interest. This leads to a cancelling of the benefits a feed might offer. I am sure that there are a lot of users who only read a small portion of the syndicated articles, which means that they have to get past the articles which are of no interest. This usually means scrolling over various amounts of content to select only the articles which are to be read in full.</p>

<p>Summarized feeds though offer only an introductory paragraph from the content itself. Sure, if the user needs to read more he (or she) has to access the source directly. But since the act of subscribing and receiving a feed&#8217;s content implies having access to the bid bag Internet, one more click for an interesting topic is just a small price to pay (both in effort and in time lost with the action). After all, your website has a nice theme for attracting readers (and probably you have invested time, money and energy on the user interface aspect of your site - web designers, CSS code, JS for user interaction, etc.). By not inviting the user to browse your website you loose not only traffic (although in recent times feeds are counted as an important communication channel with easy to follow traffic indicators), but the purpose of the shiny user interface. If all of your content is available through a web feed, why should we mind to visit it?</p>

<h2>Personal experience</h2>

<p>After several months of using a dedicated desktop application for syndicating the feeds I read I&#8217;ve switched to Google Reader. I won&#8217;t discuss here the advantages or disadvantages of one over the other. The end result in my case are 14 feeds under 5 categories (from geek stuff to more down to earth information). Out of the hundreds of articles which are published on a daily basis, I probably read about a quarter (maximum). This means that about 75% of the content to which I have access to I choose to skip over: either I am not interested (in which case I skip the content almost without retaining the title for more than 2 seconds) or I don&#8217;t think that the topic deserves more attention that what a short glimpse at one of its paragraphs might offer me. Imagine now the time lost with scrolling over full content from 75% of about 300 articles. Is it nice? NO! Is it reader-friendly? NO! This is why I prefer summarized feeds: I read the title to decide if the content is relevant and if so I don&#8217;t mind browsing to the source to read it all. I mean if I have the time to check what&#8217;s been published I am sure that I will make some time to read what&#8217;s interesting.</p>

<h2>In conclusion&#8230;</h2>

<p>Think of your users before putting the full content of your next article in the feed. There are chances that not all of your articles really hit the spot. By using summarized feeds you&#8217;ll more often than not win loyal and constant readers. Let them choose what they like from you instead of filling their screens with nonsense. Sure, they still have to click on the title to reach to your website. However, if your content is good, the readers will come by themselves.</p>

<p><em>SUMMARIZE YOUR FEEDS, PLEASE!</em></p>
]]></content>
  </entry>
  
</feed>
