Jeff Mesnil 2012-05-21T18:55:40+02:00 http://www.jmesnil.net/weblog Jeff Mesnil jmesnil@gmail.com ☛ Tesla & Edison 2012-05-21T18:40:49+02:00 2012-05-21T18:40:49+02:00 http://www.jmesnil.net/weblog/2012/05/21/tesla-edison <p>Interesting back and forth about the relative merits of <a href="http://en.wikipedia.org/wiki/Nikola_Tesla">Nikola Tesla</a> and <a href="http://en.wikipedia.org/wiki/Thomas_Edison">Thomas Edison</a></p> <ol> <li><a href="http://theoatmeal.com/comics/tesla">the original comics from the Oatmeal</a></li> <li><a href="http://www.forbes.com/sites/alexknapp/2012/05/18/nikola-tesla-wasnt-god-and-thomas-edison-wasnt-the-devil/">the critics from Forbes</a></li> <li><a href="http://theoatmeal.com/blog/tesla_response">the response from the Oatmeal</a></li> </ol> <p>The Oatmeal draws cartoons; exaggeration comes with the territory.</p> <p>I don't know a lot about Tesla and it's hard to separate the myths from the facts but this debate made me eager to learn more about him and make my own opinion about these two great engineers.</p> <p><a href="http://www.jmesnil.net/weblog/2012/05/21/tesla-edison" title="Permanent link to Tesla & Edison">⚑</a></p> ☛ How Yahoo Killed Flickr and Lost the Internet 2012-05-16T08:56:23+02:00 2012-05-16T08:56:23+02:00 http://www.jmesnil.net/weblog/2012/05/16/how-yahoo-killed-flickr-and-lost-the-internet <blockquote><p>This is the story of a wonderful idea. Something that had never been done before, a moment of change that shaped the Internet we know today. This is the story of Flickr. And how Yahoo bought it and murdered it and screwed itself out of relevance along the way.</p></blockquote> <p>I had a sweet spot for <a href="http://www.flickr.com/">Flickr</a> when I started to shoot. I had a pro account for a few years but its site has lingered on without any innovation for a long time and I left it.</p> <p>Flickr could have been YouTube, Facebook or Instagram. Once a thriving Web site with a enthusiastic community, it is now slowly fading into irrelevance. Sad story...</p> <p><a href="http://www.jmesnil.net/weblog/2012/05/16/how-yahoo-killed-flickr-and-lost-the-internet" title="Permanent link to How Yahoo Killed Flickr and Lost the Internet">⚑</a></p> Φ Another Rose 2012-05-15T19:07:00+02:00 2012-05-15T19:07:00+02:00 http://www.jmesnil.net/weblog/2012/05/15/another-rose <p><figure> <a href="https://s3.amazonaws.com/www.jmesnil.net/images/2012-05-15-another-rose.jpg" rel="lightbox" title="Another Rose"> <img src="https://s3.amazonaws.com/www.jmesnil.net/images/2012-05-15-another-rose.jpg" alt="Rose" /> </a> <figcaption>Another Rose</figcaption> </figure></p> <p>I continue to work my technique to shoot flowers with my Nikon D7000, 70-300mm f/4.5-5.6G and Hoya close up lens. Unsurprisingly, using my trusted <a href="http://www.giottos-tripods.co.uk/index.php?page=productpage&amp;product=4b83be9116e5c">Giotto's Vitruvian</a> tripod helps...</p> <p>The hidden goal of this post is to check that the photo appears correctly in overlay thanks to <a href="http://lokeshdhakar.com/projects/lightbox2/">Lightbox</a>.</p> ⚑ STOMP Over WebSockets With Multiple Frames 2012-05-15T18:27:34+02:00 2012-05-15T18:27:34+02:00 http://www.jmesnil.net/weblog/2012/05/15/stomp-over-websockets-with-multi-frames <p>I updated <a href="http://jmesnil.net/stomp-websocket/doc/">stomp-websocket</a> JavaScript library to fix a critical bug.</p> <p>When it receives a WebSocket <em>message</em>, I was parsing it to unmarshall a <em>single STOMP frame</em>. However it is valid to send <em>many STOMP frames in a single WebSocket message</em> (<a href="http://activemq.apache.org/apollo/">ActiveMQ Apollo</a> does this). I updated the code to take this into account (and check for <code>content-length</code> header too).</p> <p>This should considerably improve the performance when consuming STOMP messages from the Web browsers.</p> <p>Thanks to <a href="https://github.com/rfox90">rfox90</a> which proposed a solution to this fix and Jeff Robbins which tested it on many STOMP brokers to validate it.</p> <p>The latest version of the library is available on <a href="https://github.com/jmesnil/stomp-websocket/blob/master/dist/stomp.js">GitHub</a>.</p> ☛ RabbitMQ + STOMP + WebSockets 2012-05-15T18:06:13+02:00 2012-05-15T18:06:13+02:00 http://www.jmesnil.net/weblog/2012/05/15/rabbitmq-stomp-websockets <p>RabbitMQ is now providing messages to Web browsers with STOMP over Web Sockets.</p> <p>Interestingly, in their examples, they use my <a href="http://www.jmesnil.net/stomp-websocket/doc/">stomp-websocket library</a> library with <a href="https://github.com/sockjs/sockjs-client">SockJS</a> instead of the native <code>WebSocket</code> object:</p> <div class="highlight"><pre><code class="js"><span class="nx">WebSocketStompMock</span> <span class="o">=</span> <span class="nx">SockJS</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">client</span> <span class="o">=</span> <span class="nx">Stomp</span><span class="p">.</span><span class="nx">client</span><span class="p">(</span><span class="s1">&#39;http://127.0.0.1:55674/stomp&#39;</span><span class="p">);</span> <span class="p">...</span> </code></pre> </div> <p><a href="http://www.jmesnil.net/weblog/2012/05/15/rabbitmq-stomp-websockets" title="Permanent link to RabbitMQ + STOMP + WebSockets">⚑</a></p> ☛ JBoss Admin for iPhone 2012-05-15T16:38:54+02:00 2012-05-15T16:38:54+02:00 http://www.jmesnil.net/weblog/2012/05/15/jboss-admin-for-iphone <p>Chistos Vasilakis <a href="https://community.jboss.org/thread/199446">announced</a> last week this iPhone app to manage JBoss AS 7 instances.</p> <iframe src="http://player.vimeo.com/video/40247548" width="800" height="450" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe> <p>The code is Open Source and hosted on <a href="https://github.com/cvasilak/JBoss-Admin">Github</a>.</p> <p>It screams for an iPad version... I need to find an extra 25<sup>th</sup> hour in the day to contribute to it.</p> <p><a href="http://www.jmesnil.net/weblog/2012/05/15/jboss-admin-for-iphone" title="Permanent link to JBoss Admin for iPhone">⚑</a></p> Φ Rose 2012-05-09T09:47:53+02:00 2012-05-09T09:47:53+02:00 http://www.jmesnil.net/weblog/2012/05/09/rose <p><figure> <img src="https://s3.amazonaws.com/www.jmesnil.net/images/2012-05-09-rose.jpg" alt="Rose" /> <figcaption>Rose</figcaption> </figure></p> <p>Taken with a Nikon D7000, 70-300mm f/4.5-5.6G and Hoya close up lens.</p> <p>I am struggling to get sharp images using Hoya close up lens. Macrophotography does not like approximation.</p> ⚑ How To Enable STOMP Messaging Protocol in JBoss AS7 2012-05-03T14:30:16+02:00 2012-05-03T14:30:16+02:00 http://www.jmesnil.net/weblog/2012/05/03/how-to-enable-stomp-messaging-protocol-in-as7 <p>Since I have started working on <a href="http://jboss.org/jbossas">AS7</a>, I have been pleasantly surprised by its ease of configuration. My favorite thing about AS7 (after its fast boot time) is that its configuration is located into a single file.</p> <p>If you need messaging with AS7, you can use its <code>standalone/configuration/standalone-full.xml</code> configuration file which contains a messaging stack built on top of <a href="http://jboss.org/hornetq/">HornetQ</a>. The whole messaging stack is configured in its messaging <code>&lt;subsystem&gt;</code>:</p> <div class="highlight"><pre><code class="xml"><span class="nt">&lt;subsystem</span> <span class="na">xmlns=</span><span class="s">&quot;urn:jboss:domain:messaging:1.2&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;hornetq-server&gt;</span> ... <span class="nt">&lt;hornetq-server&gt;</span> <span class="nt">&lt;/subsystem&gt;</span> </code></pre> </div> <p>By default, AS7 only supports JMS as its messaging protocol. If your applications needs to send and receive messages from other platforms or languages than Java, JMS is not an option and you need to enable <a href="http://stomp.github.com/index.html">STOMP</a> too.</p> <p>Fortunately, adding STOMP support to AS7 is dead easy:</p> <ol> <li>add an HornetQ acceptor to let AS7 accept STOMP frames on a dedicated socket</li> <li>configure this socket to bind to default STOMP port</li> </ol> <p>To add an HornetQ acceptor for STOMP, edit the <code>standalone/configuration/standalone-full.xml</code> file and add these lines in the <code>&lt;acceptors&gt;</code> section of <code>&lt;hornetq-server&gt;</code>:</p> <div class="highlight"><pre><code class="xml"><span class="nt">&lt;netty-acceptor</span> <span class="na">name=</span><span class="s">&quot;stomp-acceptor&quot;</span> <span class="na">socket-binding=</span><span class="s">&quot;messaging-stomp&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;param</span> <span class="na">key=</span><span class="s">&quot;protocol&quot;</span> <span class="na">value=</span><span class="s">&quot;stomp&quot;</span><span class="nt">/&gt;</span> <span class="nt">&lt;/netty-acceptor&gt;</span> </code></pre> </div> <p>The <code>stomp-acceptor</code> is expected to receive STOMP frames on the socket binding named <code>messaging-stomp</code>.</p> <p>At the end of the same <code>standalone/configuration/standalone-full.xml</code> file, add a <code>&lt;socket-binding&gt;</code> to the <code>&lt;socket-binding-group name="standard-sockets&gt;</code> section:</p> <div class="highlight"><pre><code class="xml"><span class="nt">&lt;socket-binding</span> <span class="na">name=</span><span class="s">&quot;messaging-stomp&quot;</span> <span class="na">port=</span><span class="s">&quot;61613&quot;</span><span class="nt">/&gt;</span> </code></pre> </div> <p><code>61613</code> is the default port for Stomp brokers.</p> <p>With these 2 changes, we can now start JBoss AS7 with STOMP enabled:</p> <div class="highlight"> <pre> <code class="bash">$ <kbd>./bin/standalone.sh -c standalone-full.xml</kbd> ... 14:14:38,027 INFO [org.hornetq.core.remoting.impl.netty.NettyAcceptor] (MSC service thread 1-2) Started Netty Acceptor version 3.2.5.Final-a96d88c 127.0.0.1:61613 for STOMP protocol ... 14:14:38,263 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.1.2.Final-SNAPSHOT "Brontes" started in 2749ms - Started 163 of 251 services (87 services are passive or on-demand)</code> </pre> </div> <p>Before sending and receiving messages from a STOM client, we also need to configure 2 things for the AS7:</p> <ol> <li>add an user (AS7 is secured by default and we must explicitely add an application user to connect to it)</li> <li>add a JMS queue to send and receive messages on it</li> </ol> <p>To add an user, we use the <code>add-user.sh</code> tool:</p> <div class="highlight"> <pre> <code class="bash">$ <kbd>./bin/add-user.sh</kbd> What type of user do you wish to add? a) Management User (mgmt-users.properties) b) Application User (application-users.properties) (a): <kbd>b</kbd> Enter the details of the new user to add. Realm (ApplicationRealm) : <kbd>[type enter]</kbd> Username : <kbd>myuser</kbd> Password : <kbd>mypassword</kbd> Re-enter Password : <kbd>mypassword</kbd> What roles do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[ ]: <kbd>guest</kbd> About to add user 'myuser' for realm 'ApplicationRealm' Is this correct yes/no? <kbd>yes</kbd> Added user 'myuser' to file '[...]/standalone/configuration/application-users.properties' Added user 'myuser' to file '[...]/domain/configuration/application-users.properties' Added user 'myuser' with roles guest to file '[...]/standalone/configuration/application-roles.properties' Added user 'myuser' with roles guest to file '[...]/domain/configuration/application-roles.properties'</code> </pre> </div> <p>Finally, to add a JMS queue, we will use JBoss CLI tool:</p> <div class="highlight"> <pre> <code class="bash">$ <kbd>./bin/jboss-cli.sh</kbd> You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands. [disconnected /] <kbd>connect</kbd> [standalone@localhost:9999 /] <kbd>/subsystem=messaging/hornetq-server=default/jms-queue=test/:add(entries=["/java:jboss:exported/queue/test"])</kbd> {"outcome" => "success"}</code> </pre> </div> <p>We now have configured an user and a JMS queue. Let's send and receive STOMP messages using Ruby and its <code>stomp</code> gem (installed with <code>sudo gem install stomp</code>):</p> <div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span> <span class="nb">require</span> <span class="s1">&#39;stomp&#39;</span> <span class="n">client</span> <span class="o">=</span> <span class="no">Stomp</span><span class="o">::</span><span class="no">Client</span><span class="o">.</span><span class="n">new</span> <span class="s2">&quot;myuser&quot;</span><span class="p">,</span> <span class="s2">&quot;mypassword&quot;</span><span class="p">,</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span> <span class="mi">61613</span> <span class="n">client</span><span class="o">.</span><span class="n">publish</span> <span class="s1">&#39;jms.queue.test&#39;</span><span class="p">,</span> <span class="s1">&#39;Hello, STOMP on AS7!&#39;</span> <span class="n">client</span><span class="o">.</span><span class="n">subscribe</span> <span class="s2">&quot;jms.queue.test&quot;</span> <span class="k">do</span> <span class="o">|</span><span class="n">msg</span><span class="o">|</span> <span class="nb">p</span> <span class="s2">&quot;received: </span><span class="si">#{</span><span class="n">msg</span><span class="o">.</span><span class="n">body</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">end</span> </code></pre> </div> <p>And it will output the expected message:</p> <div class="highlight"><pre><code class="bash">received: Hello, STOMP on AS7! </code></pre> </div> <h2>Conclusion</h2> <ol> <li>add a <code>&lt;netty-acceptor&gt;</code> with a <code>stomp</code> protocol param</li> <li>add a <code>&lt;socket-binding&gt;</code> for default 61613 STOMP port</li> <li>configure users and JMS queues by following <a href="https://docs.jboss.org/author/display/AS71/Messaging+configuration">AS7 messaging documentation</a></li> </ol> <p>Using STOMP with AS7 is simple to setup (4 lines to add to its configuration file) and allow any languages and platforms to send and receive messages to your application hosted in AS7.</p> ⚑ Node.js + Redis on OpenShift 2012-05-02T10:56:23+02:00 2012-05-02T10:56:23+02:00 http://www.jmesnil.net/weblog/2012/05/02/nodejs-redis-on-openshift <p>I have a pet project that uses a Web application running on <a href="http://nodejs.org">node.js</a> with its data stored in <a href="http://redis.io">Redis</a>.<br/> Since I joined <a href="http://www.redhat.com">Red Hat</a>, I took the opportunity to eat our own dog food and port this application from <a href="http://www.heroku.com/">Heroku</a> to <a href="https://openshift.redhat.com">OpenShift</a>.</p> <p>OpenShift does not support (yet) Redis in its list of database cartridges but it is straighforward to build a Redis server from scratch directly in OpenShift by following <a href="https://github.com/razorinc/redis-openshift-example">these instructions</a>.</p> <p>The next step is to add redis module to the list of dependencies in <code>deplist.txt</code>:</p> <div class="highlight"><pre><code class="bash"><span class="nv">$ </span>cat deplist.txt ... redis ... </code></pre> </div> <p>Redis node.js module does not expose a method to create a client from a Unix socket. We need to add our own function to do that and pass the path to the socket located in a temporary directory inside <code>OPENSHIFT_GEAR_DIR</code> directory (I found the code snippet on <a href="http://stackoverflow.com/questions/4191019/direct-non-tcp-connection-to-redis-from-nodejs">stackoverflow</a>):</p> <div class="highlight"><pre><code class="js"><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">net</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;net&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">__redis__</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;redis&#39;</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">createSocketClient</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">__redis__</span><span class="p">.</span><span class="nx">RedisClient</span><span class="p">(</span><span class="nx">net</span><span class="p">.</span><span class="nx">createConnection</span><span class="p">(</span><span class="nx">path</span><span class="p">),</span> <span class="nx">options</span><span class="p">);</span> <span class="nx">client</span><span class="p">.</span><span class="nx">path</span> <span class="o">=</span> <span class="nx">path</span><span class="p">;</span> <span class="k">return</span> <span class="nx">client</span><span class="p">;</span> <span class="p">};</span> <span class="kd">var</span> <span class="nx">redis</span> <span class="o">=</span> <span class="nx">createSocketClient</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">OPENSHIFT_GEAR_DIR</span> <span class="o">+</span> <span class="s1">&#39;tmp/redis.sock&#39;</span><span class="p">);</span> </code></pre> </div> <p>The rest of the code was not changed at all:</p> <div class="highlight"><pre><code class="js"><span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">.</span><span class="nx">createServer</span><span class="p">();</span> <span class="c1">// Handler for POST /test</span> <span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/test&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">){</span> <span class="nx">redis</span><span class="p">.</span><span class="nx">incr</span><span class="p">(</span><span class="s1">&#39;val&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nx">writeHead</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">();</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nx">res</span><span class="p">.</span><span class="nx">writeHead</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;Content-Type&#39;</span><span class="o">:</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">});</span> <span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">(</span><span class="s1">&#39;val=&#39;</span> <span class="o">+</span> <span class="nx">value</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> <span class="p">})</span> <span class="p">...</span> </code></pre> </div> <p>Once the code is committed and pushed to OpenShift Git repository, the hook will build and start Redis (only the first time) and the Web application is ready to serve any data from Redis:</p> <div class="highlight"><pre><code class="bash"><span class="nv">$ </span>curl -X POST http://<span class="k">${</span><span class="nv">appname</span><span class="k">}</span>-jmesnil.rhcloud.com/test/ <span class="nv">val</span><span class="o">=</span>1 <span class="nv">$ </span>curl -X POST http://<span class="k">${</span><span class="nv">appname</span><span class="k">}</span>-jmesnil.rhcloud.com/test/ <span class="nv">val</span><span class="o">=</span>2 </code></pre> </div> <p>Even though Redis is not officially supported by OpenShift yet, it is still possible to use it now and it is very simple to deploy and run it.</p> ☛ OpenShift Origin - The Open Source Platform-as-a-Service 2012-05-02T09:29:04+02:00 2012-05-02T09:29:04+02:00 http://www.jmesnil.net/weblog/2012/05/02/openshift-origin-the-open-source-platform-as-a-service <div class="alignleft"> <a href="http://openshift.redhat.com"><img src="https://openshift.redhat.com/app/images/logo-medium.png" alt="Open Shift"></a> </div> <p>While I was offline, Red Hat announced the Open Source release of its Platform as a service (PaaS). <a href="https://openshift.redhat.com/community/open-source">Open Shift Origin</a> will be the Open Source upstream project for <a href="https://openshift.redhat.com">Open Shift</a> in the same way that <a href="http://fedoraproject.org/">Fedora</a> and <a href="http://www.jboss.org/as7">JBoss AS7</a> are the upstream projects for <a href="http://www.redhat.com/products/enterprise-linux/">Red Hat Enterprise Linux</a> and <a href="http://www.redhat.com/products/jbossenterprisemiddleware/application-platform/">JBoss EAP6</a>.</p> <p>I have played a little with OpenShift and it is very easy to use and deploy. I ported a small application using <a href="http://nodejs.org/">node.js</a> and <a href="http://redis.io/">Redis</a> to it in a matter of minutes (I will write about it in my next post).</p> <p><a href="http://www.jmesnil.net/weblog/2012/05/02/openshift-origin-the-open-source-platform-as-a-service" title="Permanent link to OpenShift Origin - The Open Source Platform-as-a-Service">⚑</a></p> ☛ A Year With MongoDB at Kiip 2012-04-18T12:11:08+02:00 2012-04-18T12:11:08+02:00 http://www.jmesnil.net/weblog/2012/04/18/a-year-with-mongodb-at-kiip <blockquote><p>Over the past 6 months, we’ve “scaled” MongoDB by moving data off of it. [...] For key-value data, we switched to Riak, which provides predictable read/write latencies and is completely horizontally scalable. For smaller sets of relational data where we wanted a rich query layer, we moved to PostgreSQL.</p></blockquote> <p>As usual, take this with a grain of salt (performance varies with data size, use cases, read/write ratio, etc).</p> <p>I had a short experience developing with <a href="http://www.mongodb.org/">MongoDB</a> and I like it. Unfortunately, I had not the opportunity to see how it behave in production use.</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/18/a-year-with-mongodb-at-kiip" title="Permanent link to A Year With MongoDB at Kiip">⚑</a></p> ☛ Dropbox Founder Interview 2012-04-17T10:28:54+02:00 2012-04-17T10:28:54+02:00 http://www.jmesnil.net/weblog/2012/04/17/dropbox-founder-interview <blockquote><p> What we're really trying to build is the Internet's file system.<br/> &mdash;<cite>Drew Houston</cite></p></blockquote> <p>As a follow up to my previous post, this is an interesting interview from <a href="https://www.dropbox.com/">Dropbox</a> founder, Drew Houston.</p> <p>I use heavily Dropbox to synchronize contents and share documents between my iDevices and home/corporate laptop and it works without any problem.</p> <p>I have not used their <a href="https://www.dropbox.com/developers/reference/api">APIs</a> but I hear it is great. Given the number of apps installed on my iPhone and iPad which uses it to share content, it is likely true.</p> <p>(via <a href="http://shawnblanc.net/">Shawn Blanc</a>)</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/17/dropbox-founder-interview" title="Permanent link to Dropbox Founder Interview">⚑</a></p> ☛ iCloud's First Six Months 2012-04-16T15:11:20+02:00 2012-04-16T15:11:20+02:00 http://www.jmesnil.net/weblog/2012/04/16/iclouds-first-six-months <blockquote><p>The past six months have also shown that, without proper developer tools and a clear explanation of how things work in backend, things don’t “just work” — in fact, quite the opposite: some developers have given up entirely on building iCloud apps for now, others are wishing for new APIs that would make the platform suitable to their needs, while the ones who did implement iCloud in their apps are torn better the positive feedback of “it just works” users, and the frustration of those struggling to keep their data in sync on a daily basis.</p></blockquote> <p>I played a little bit with <a href="https://developer.apple.com/icloud/index.php">iCloud</a> on a iOS personal project. Unsurprisingly, it is <em>hard</em> to get syncing right.</p> <p>It was obvious from the start that supporting iCloud would not been easy. There are many <a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">fallacies</a> to avoid once an application depends on the network (especially when it is as unreliable and spotty as a cellular network) and version conflict resolution works best with a deep knowledge of your domain.</p> <p>Apple documentation for iCloud is too high-level to be helpful. The best resources I found about iCloud development are lectures 17 &amp; 18 of <a href="http://itunes.apple.com/us/itunes-u/ipad-iphone-application-development/id473757255">Stanford's iPad and iPhone Application Development by Paul Hegarty</a>. These lectures give the correct mindset to comprehend and work with iCloud.</p> <p>Supporting iCloud is not an easy task and it requires to <em>really</em> think about it. It is not just about dropping files in a directory. However when it works seamlessly, it improves and simplifies the user experience. The user benefit is worth the developer pain. With the release of <a href="http://www.apple.com/macosx/mountain-lion/features.html#icloud">Mountain Lion</a> I expect Apple to continue to improve iCloud API and features and make more developer resources available as they learn from adding iCloud to their own apps.</p> <p>(via <a href="http://www.loopinsight.com/">The Loop</a>)</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/16/iclouds-first-six-months" title="Permanent link to iCloud's First Six Months">⚑</a></p> ☛ "Understanding ISO/F-Stop/Depth of Field" Videos 2012-04-16T10:13:31+02:00 2012-04-16T10:13:31+02:00 http://www.jmesnil.net/weblog/2012/04/16/understanding-isof-stopdepth-of-field-videos <p>Three videos with simple explanation to photography concepts: ISO, F-Stop and Depth of Field</p> <iframe width="853" height="480" src="http://www.youtube.com/embed/WEApLA-YNko" frameborder="0" allowfullscreen></iframe> <iframe width="853" height="480" src="http://www.youtube.com/embed/KmNIouLByJQ" frameborder="0" allowfullscreen></iframe> <iframe width="853" height="480" src="http://www.youtube.com/embed/34jkJoN8qOI" frameborder="0" allowfullscreen></iframe> <p>(via <a href="http://blog.snapsort.com/">snapsort</a>)</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/16/understanding-isof-stopdepth-of-field-videos" title="Permanent link to "Understanding ISO/F-Stop/Depth of Field" Videos">⚑</a></p> ☛ Zack Arias Reviews The Fuji X-Pro 1 2012-04-12T14:36:39+02:00 2012-04-12T14:36:39+02:00 http://www.jmesnil.net/weblog/2012/04/12/zack-arias-fuji-x-pro-1-review <blockquote><p>The X was growing on me. I was walking the streets of a new place with two cameras and three lenses and never once tired of carrying this gear. It was hanging on my side or in a pocket. The weight of all of it was distributed around my person and I never felt it. No tired neck. No sore shoulder. Kick ass image quality. Lens choices. As long as I was methodical in my shooting the camera, and all of its quirks and laggy issues, were beginning to fade away.</p></blockquote> <p>I am searching for a camera with good image quality that I can bring with me anywhere (my DSLR is too big for that). I like the X-Pro 1's retro look, its size seems adequate and the IQ is outstanding:</p> <p><figure> <img src="http://zackarias.com/wp-content/uploads/2012/04/gabby02.jpg" alt="" /> <figcaption><a href="http://zackarias.com/">Photography By Zack Arias</a></figcaption> </figure></p> <p>The Fuji X-Pro 1 is a tempting camera...</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/12/zack-arias-fuji-x-pro-1-review" title="Permanent link to Zack Arias Reviews The Fuji X-Pro 1">⚑</a></p> ☛ Redis Persistence Demystified 2012-04-11T17:24:12+02:00 2012-04-11T17:24:12+02:00 http://www.jmesnil.net/weblog/2012/04/11/redis-persistence-demystified <blockquote><p>And my feeling is that there is no Redis feature that is as misunderstood as its persistence.<br/> &mdash; <cite><a href="http://antirez.com/">antirez</a></cite></p></blockquote> <p>Talking about Redis, this is a very interesting article dissecting Redis persistence (with a light comparison to PostgreSQL).</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/11/redis-persistence-demystified" title="Permanent link to Redis Persistence Demystified">⚑</a></p> ☛ Redis Storage Strategies Benchmark 2012-04-11T15:46:19+02:00 2012-04-11T15:46:19+02:00 http://www.jmesnil.net/weblog/2012/04/11/redis-storage-strategies-benchmark <p>An analysis of using Redis to store data by my former colleague <a href="https://twitter.com/brisssou">Brice Laurencin</a>:</p> <blockquote><p>Do not over think your data schema when storing to Redis, it is faster than you may think, and a simple software compression may help you contain your data growth.</p></blockquote> <p>I have used a little <a href="http://redis.io/">Redis</a> for a pet project and it is a great key/value store. Its <a href="http://redis.io/commands#sorted_set">sorted set</a> data structure is invaluable to store time-based data.</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/11/redis-storage-strategies-benchmark" title="Permanent link to Redis Storage Strategies Benchmark">⚑</a></p> ☛ Arquillian 1.0 Is Released 2012-04-11T11:15:24+02:00 2012-04-11T11:15:24+02:00 http://www.jmesnil.net/weblog/2012/04/11/arquillian-10-is-released <p>Integration testing is hard but <em>essential</em>. It is hard to track down integration issues (due to a misunderstanding between the callee and the caller's contract/API/service) but that's where <em>most</em> of bugs are located from my own experience.<br/> Unit tests with mocking does not help. Who cares about <em>my</em> expectations about what a contrat/API/service provides <em>if it does not match the actual implementation.</em> Testing <em>in situ</em> is the best way to check the actual behavior.</p> <p><a href="http://arquillian.org/">Arquillian</a> is a fantastic tool to help <strong>write, execute and maintain integration tests</strong>.</p> <p>Congratulations to the Arquillian team!</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/11/arquillian-10-is-released" title="Permanent link to Arquillian 1.0 Is Released">⚑</a></p> ⚑ Joe McNally's "Sketching Light" 2012-04-10T14:20:06+02:00 2012-04-10T14:20:06+02:00 http://www.jmesnil.net/weblog/2012/04/10/joe-mcnally-sketching-light <p>I received <a href="http://portfolio.joemcnally.com/">Joe McNally</a>'s <a href="http://www.amazon.com/dp/B006ZYUN5W/ref=rdr_ext_sb_ti_hist_1">Sketching Light</a>. It is a gorgeous book full of nuggets to learn more about lighting a scene.</p> <p><figure> <img src="https://s3.amazonaws.com/www.jmesnil.net/images/2012-04-10-sketching-light.png" alt="Sketching Light" /> <figcaption><a href="http://www.amazon.com/dp/B006ZYUN5W/ref=rdr_ext_sb_ti_hist_1">Sketching Light</a></figcaption> </figure></p> <p>I prefer to take pictures with available light as I find the flash too intrusive. However this book makes me eager to experiment more: the possibilities offered by flashes open a whole new world of images.</p> ☛ Facebook Buys Instagram for $1 Billion 2012-04-10T09:01:07+02:00 2012-04-10T09:01:07+02:00 http://www.jmesnil.net/weblog/2012/04/10/facebook-buys-instagram-for-b <p>This is a huge shift for Web startups: their exit strategy changes from <em>being bought by Google</em> to <em>being bought by Facebook</em>.</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/10/facebook-buys-instagram-for-b" title="Permanent link to Facebook Buys Instagram for $1 Billion">⚑</a></p> ⚑ "Free-to-play is a Scam" 2012-04-05T17:17:37+02:00 2012-04-05T17:17:37+02:00 http://www.jmesnil.net/weblog/2012/04/05/free-to-playis-a-scam <p><a href="http://notch.tumblr.com/">Notch</a> (of <a href="http://www.minecraft.net/">Minecraft</a> fame) talking about its next game <a href="http://0x10c.com/">Ox10c</a>:</p> <blockquote class="twitter-tweet tw-align-center" data-in-reply-to="187297762914734082"><p>@<a href="https://twitter.com/KiiLLBOT">KiiLLBOT</a> f2p is a scam.</p>&mdash; Markus Persson (@notch) <a href="https://twitter.com/notch/status/187298042087604224" data-datetime="2012-04-03T21:58:27+00:00">April 3, 2012</a></blockquote> <script src="//platform.twitter.com/widgets.js" charset="utf-8"></script> <p>I don't understand the economics behind <a href="http://en.wikipedia.org/wiki/Free-to-play">Free-to-play</a>. I don't want to play games that cost even more through in-app purchases or which display ads.</p> <p>I have not warmed up to Minecraft but I am looking forward to this game. Hard science fiction and duct tape: what's not to love!</p> ☛ Example of a JMS Queue Hosted in JBoss AS7 2012-04-03T11:22:16+02:00 2012-04-03T11:22:16+02:00 http://www.jmesnil.net/weblog/2012/04/03/example-jms-queue-hosted-in-jboss-as7 <p>To familiarize myself with running tests in <a href="http://www.jboss.org/jbossas">JBoss AS7</a>, I have created the smallest Maven project which uses <a href="http://www.jboss.org/arquillian">Arquillian</a> to manage an instance of JBoss AS7 with <a href="http://www.jboss.org/hornetq">HornetQ</a> enabled, deploy a JMS queue in it and run a test.</p> <p>Works from the shell or Eclipse.</p> <p><a href="http://www.jmesnil.net/weblog/2012/04/03/example-jms-queue-hosted-in-jboss-as7" title="Permanent link to Example of a JMS Queue Hosted in JBoss AS7">⚑</a></p> ☛ WebSockets in IE10 2012-03-30T17:12:18+02:00 2012-03-30T17:12:18+02:00 http://www.jmesnil.net/weblog/2012/03/30/web-sockets-in-ie10 <p>Talking about <a href="http://dev.w3.org/html5/websockets/">WebSockets</a>, it is nice to see that Internet Explorer will support them. This post provides a good and up-to-date explanation of <a href="http://www.rfc-editor.org/rfc/rfc6455.txt">WebSocket protocol</a>.</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/30/web-sockets-in-ie10" title="Permanent link to WebSockets in IE10">⚑</a></p> ⚑ Infinispan, Distributed Execution, and Messaging 2012-03-30T15:05:54+02:00 2012-03-30T15:05:54+02:00 http://www.jmesnil.net/weblog/2012/03/30/infinispan-distributed-execution-and-messaging <p><a href="http://galder.zamarreno.com/">Galder Zamarreño</a>, a colleague from Red Hat, presented <a href="http://www.jboss.org/infinispan">Infinispan</a> yesterday at <a href="http://www.alpesjug.org/">AlpesJUG</a>.</p> <p>Watching his presentation reminded me of a conversation I had with an ex-colleague about messaging and distributed execution frameworks.</p> <p>I have contributed to several messaging servers over the years, mainly on <a href="http://hornetq.org/">HornetQ</a>. During my previous job in a Web media company, I also used <a href="http://hadoop.apache.org/mapreduce/">Hadoop Map/Reduce</a> for <em>Big Data</em> processing.</p> <p>With Big Data, the amount of data is so important that you can not process everything sequentially. Instead you parallelize the execution on several nodes. In practice, this implies to <em>distribute the execution</em>: the execution code (the mapper and reducer tasks) <em>moves</em> to the data nodes - where the data to process is stored - and runs locally.</p> <p>With Messaging, you can achieve the opposite: to <em>distribute the data</em>. Messages containing the data are sent to consumers that will process them. In many cases, the data transported inside the messages is not the data to process; it can be an event or contains the location of the data to process. Nonetheless, the result is the same: the execution code will not moved, it will fetch the data and process it on its own node.</p> <ul> <li><em>Messaging <strong>moves the data</strong> close to the execution code.</em></li> <li><em>Distributed Execution <strong>moves the execution code</strong> close to the data.</em></li> </ul> <p>If I understood Galder correctly, Infinispan proposes the two approaches:</p> <ul> <li>a <a href="https://docs.jboss.org/author/display/ISPN/Infinispan+Distributed+Execution+Framework#InfinispanDistributedExecutionFramework-MapReducemodel">Map/Reduce model</a> where the mapper and reducer tasks are sent on the cluster nodes to distribute the code execution.</li> <li><a href="https://docs.jboss.org/author/display/ISPN/Listeners+and+Notifications">Listeners and Notifications</a> that can be used as a <strong>kind of</strong> messaging bus.</li> </ul> <p>Messaging is a model that is widely used in entreprise applications and may become mainstream on the Web with the support of <a href="http://dev.w3.org/html5/websockets/">WebSockets</a> by all Web browsers.<br/> Distributed execution framework like Hadoop Map/Reduce or Twitter <a href="http://engineering.twitter.com/2011/08/storm-is-coming-more-details-and-plans.html">Storm</a> <em>will</em> become mainstream as the amount of generated data to process and analyze (on the Web or behind firewalls for entreprise softwares) will continue to grow.</p> <p>Infinispan seems to hit a sweet spot by providing the two models and the ability to mix and match them. I am looking forward to seeing what's next for Infinispan and the best ways to leverage it...</p> ☛ Red Hat Hits $1 Billion In Revenue 2012-03-29T10:09:00+02:00 2012-03-29T10:09:00+02:00 http://www.jmesnil.net/weblog/2012/03/29/red-hat-hits--billion-in-revenue <blockquote><p>For the full fiscal year 2012, total revenue was $1.13 billion, an increase of 25% over the prior year, and subscription revenue was $965.6 million, up 25% year-over-year.</p></blockquote> <p>It is possible to make money with Open Source.</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/29/red-hat-hits--billion-in-revenue" title="Permanent link to Red Hat Hits $1 Billion In Revenue">⚑</a></p> ☛ A New Computer (For Lightroom) 2012-03-28T10:25:00+02:00 2012-03-28T10:25:00+02:00 http://www.jmesnil.net/weblog/2012/03/28/a-new-computer-for-lightroom <p><a href="http://www.tbray.org/ongoing/">Tim Bray</a> want to buy a new laptop that can run <a href="http://www.adobe.com/products/photoshop-lightroom.html">Lightroom</a>:</p> <blockquote><p>I take pictures. I use Lightroom to process them. I like it. The current camera emits DNGs that average between 20-25M, and I take them dozens or hundreds at a time. Lightroom 4 is, um, not faster than Lightroom 3 and I see no evidence that Adobe knows how to make any future version faster. Lightroom on the current machine is just barely fast enough, where “just barely” means “not really”.</p></blockquote> <p>I have the same problem: my old MacBook is slowly dying and can no longer run Lightroom 3 (or Xcode for that matter) in an usable fashion. I download the trial version of Lightroom 4 and it is worse.</p> <p>I am looking to upgrade to a new Apple laptop. My ideal machine would be a 13-Inch MacBook with Retina Display, SSD (+ external HDD), at least 8Go and the latest Intel processors. I am waiting for the next generation of MacBook Air and Pro to be released to check if one of their models matches my expectations. However, I will monitor comments on Tim's post in case the next Apple laptops do not change that much.</p> <p>In the mean time, I am stacking up photos until I can post process them...</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/28/a-new-computer-for-lightroom" title="Permanent link to A New Computer (For Lightroom)">⚑</a></p> ☛ Joe Armstrong On Defensive Programming 2012-03-27T14:49:35+02:00 2012-03-27T14:49:35+02:00 http://www.jmesnil.net/weblog/2012/03/27/joe-armstrong-on-defensive-programming <blockquote><p>Note this method of structuring cannot be done in a sequential language - since there is only one thread of control - thus in a sequential language all error handling MUST be done <em>within</em> the process itself.<br/> That's why you have to program defensively in a sequential language - you get one thread of control and one chance to fix your error.</p> <p>&mdash; <cite>Joe Armstrong</cite></p></blockquote> <p>I can not warm up to <a href="http://www.erlang.org/">Erlang</a> language and syntax but there is no denying that the Erlang worker/observer model is much more simpler and simple to figure out that code which mixes business logic and error handling.</p> <p>(via <a href="https://twitter.com/debasishg/statuses/184323422787092480">@debasishg</a>)</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/27/joe-armstrong-on-defensive-programming" title="Permanent link to Joe Armstrong On Defensive Programming">⚑</a></p> ☛ Infinispan At AlpesJUG On March 29th 2012-03-27T10:28:43+02:00 2012-03-27T10:28:43+02:00 http://www.jmesnil.net/weblog/2012/03/27/infinispan-at-alpesjug-on-march-29th <p><a href="http://galder.zamarreno.com/">Galder Zamarreño</a>, from JBoss / Red Hat, is coming to the AlpesJug this Thursday to talk about <a href="http://www.jboss.org/infinispan">Infinispan</a>, DataGrid &amp; Distributed Cache.</p> <p>Count me in.</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/27/infinispan-at-alpesjug-on-march-29th" title="Permanent link to Infinispan At AlpesJUG On March 29th">⚑</a></p> Φ Fragile Things 2012-03-26T17:47:53+02:00 2012-03-26T17:47:53+02:00 http://www.jmesnil.net/weblog/2012/03/26/fragile-things <p><figure> <img src="https://s3.amazonaws.com/www.jmesnil.net/images/2012-03-26-fragile-things.jpg" alt="Fragile Things" /> <figcaption>Fragile Things</figcaption> </figure></p> ☛ Mindmap of JVM Tuning Parameters 2012-03-26T13:47:48+02:00 2012-03-26T13:47:48+02:00 http://www.jmesnil.net/weblog/2012/03/26/mindmap-of-jvm-tuning-parameters <p>Nice visual representation and summary of the <code>-X</code> and <code>-XX</code> parameters to tune a JVM.</p> <p>(via <a href="https://twitter.com/#!/glaforge/status/184203287933878273">@glaforge</a>)</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/26/mindmap-of-jvm-tuning-parameters" title="Permanent link to Mindmap of JVM Tuning Parameters">⚑</a></p> ☛ Tom's Hardware Reviews Fedora 16 and GNOME Shell 2012-03-20T00:00:00+01:00 2012-03-20T00:00:00+01:00 http://www.jmesnil.net/weblog/2012/03/20/toms-hardware-reviews-fedora-16-and-gnome-shell <p><a href="http://fedoraproject.org/">Fedora 16</a> is appropriate for my developer job but still not recommendable to friends and family.</p> <p>I have installed Fedora 16 on my corporate laptop and like it better that the latest Ubuntu with Unity. However, I still feel that both environments have regressed and are further away from Mac OS X for the user experience.</p> <p>The foundations of Fedora 16 are solid, let's hope the next version will build on top of it to provide a useful and enjoyable UX.</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/20/toms-hardware-reviews-fedora-16-and-gnome-shell" title="Permanent link to Tom's Hardware Reviews Fedora 16 and GNOME Shell">⚑</a></p> ☛ Introduction to Objective C Literals By Big Nerd Ranch 2012-03-19T00:00:00+01:00 2012-03-19T00:00:00+01:00 http://www.jmesnil.net/weblog/2012/03/19/objective-c-literals <p>In <a href="http://weblog.bignerdranch.com/?p=398">Part 1</a>:</p> <blockquote><p>What is an “Objective-C Literal”? It’s a chunk of code that references a specific Cocoa object, creating it if necessary. Objective-C has had literals for NSStrings since the beginning of time [...].<br/> The new literals for NSNumbers, NSArrays, and NSDictionaries take a similar approach</p></blockquote> <p>In <a href="http://weblog.bignerdranch.com/?p=407">Part 2</a>:</p> <blockquote><p>The new collection-access syntax is a welcome change, making it very convenient to dig into collections. What’s even better is that our own classes can play in this world.<br/> There are two flavors of convenient collection access: scalar indexing which is used by NSArray, and object indexing which is used by NSDictionary.</p></blockquote> <p>With these features, Objective-C becomes more expressive and takes the best syntactic sugars from dynamic languages like Ruby and Python. More expressiveness with less syntax noise.</p> <p><a href="http://www.jmesnil.net/weblog/2012/03/19/objective-c-literals" title="Permanent link to Introduction to Objective C Literals By Big Nerd Ranch">⚑</a></p> Φ Balade Dans Le Vercors 2012-03-18T12:55:00+01:00 2012-03-18T12:55:00+01:00 http://www.jmesnil.net/weblog/2012/03/18/balade-dans-le-vercors <p><figure> <img src="https://s3.amazonaws.com/www.jmesnil.net/images/2012-03-18-vercors.jpg" alt="Balade Dans Le Vercors" /> <figcaption>Balade Dans Le Vercors</figcaption> </figure></p> ⚑ Web Site Update 2012-03-16T00:00:00+01:00 2012-03-16T00:00:00+01:00 http://www.jmesnil.net/weblog/2012/03/16/web-site-update <p>If you read this post from my Atom feed, it means I migrated successfully my blog from <a href="http://wordpress.org/">Wordpress</a> to <a href="http://jekyllrb.com">Jekyll</a>.<br/> If you read this from your Web browser, you are seeing the new design for my <a href="http://jmesnil.net/">Web site</a>.</p> <p>For some time, I wanted to simplify my blog, both its design and the process to write on it. Wordpress is a great tool to publish on the Web but I wanted something simpler to understand and develop new features for.</p> <p>For example, I want to distinguish between blog posts (prefixing by a &#9873; in the title) and links (suffixed by a &#9755;) which mainly redirect to interesting content. There is a Wordpress plug-in for that but I had problems with it every time I upgraded Wordpress. I replaced this plug-in by writing a few lines using <a href="https://github.com/shopify/liquid/wiki/liquid-for-designers">Liquid</a> in Jekyll templates.<br/> Using static pages only also means that I no longer have any cache issues, Web servers are pretty good at serving static content these days :)</p> <p>This considerably simplify writing content and updating the web site:</p> <ul> <li>write a post in a text editor using markdown syntax</li> <li>generate static files using <a href="http://jekyllrb.com">Jekyll</a></li> <li>upload the files to <a href="http://aws.amazon.com/s3/">Amazon S3</a> using <a href="http://s3tools.org/s3cmd-sync">S3 tools sync command</a>.</li> </ul> <p>I also took the opportunity to update the design and layout of the Web pages and I owe much to <a href="http://mark.reid.name/">Mark Reid</a> and <a href="http://duncandavidson.com/">James Duncan Davidson</a> Web sites. Everything that looks great on my site is thanks to them, the rest is my own little contribution.</p> <p>I also migrated the <a href="http://jmesnil.net/stomp-websocket/doc/">documentation of stomp-websocket</a> to S3.</p> <p>As far as I can tell, all my contents has been migrated and I kept all URLs compatible with their previous forms. If you ever find a page wich is not available anymore, please le me know on <a href="https://twitter.com/jmesnil">Twitter (@jmesnil)</a>.</p> ⚑ I Am a Red Hatter (Again!) 2012-03-12T00:00:00+01:00 2012-03-12T00:00:00+01:00 http://www.jmesnil.net/weblog/2012/03/12/i-am-a-red-hatter-again <div class="alignleft" style="font-size: 4em; padding: 10px;"> <img src='https://s3.amazonaws.com/www.jmesnil.net/images/2012-03-12-redhat.png' alt="Red Hat" style="vertical-align:middle;" height="64"/> + <img src='https://s3.amazonaws.com/www.jmesnil.net/images/2012-03-12-jbossas7.png' alt="JBoss AS 7" style ="vertical-align:middle;" height="64" /> </div> <p>Starting today, I am working for <a href="http://redhat.com">Red Hat</a> as a member of the <a href="http://www.jboss.org/jbossas">JBoss AS/EAP</a> team.</p> <p>I already worked once for Red Hat as a member of <a href="http://www.jboss.org/hornetq/">HornetQ</a> team, helping to write the <a href="http://planet.jboss.org/post/8_2_million_messages_second_with_specjms">fastest Open Source Messaging system</a> and had a blast doing that. However, in 2010, I had a very interesting proposition to join a Web media company to develop <em>Big Data</em> code using <a href="http://hadoop.apache.org/">Hadoop</a>-related technologies. The job was technically interesting, the team great (I made a bunch of good friends there) but some things were amiss...</p> <p>Every time I was talking about HornetQ or Red Hat in general, I kept saying "<em>we</em>" as I am proud of my time with the HornetQ team, <em>a sense of achievement</em> that I was not feeling in my new company. I also realized that I was missing contributing to Open Source projects. Having developed both closed and open source projects, I found out that <em>Open Source development is the most satisfying way to write good code and deliver quality features</em>. More generally, I also realized that I want to <em>work for a company whose values I share and embrace</em>. Red Hat has proven many times its dedication to Open Source and its community, its ability to innovate at multiple levels from the operating system to the applications and, of course, the middleware with JBoss. This is a company I was proud to work for and I continued to present HornetQ in various JUGs in France during my spare time (Lyon, Nice, Marseille, Grenoble... Any other French JUG is interested for me to come?).</p> <p>When I put everything together, it was clear that I wanted to join back Red Hat. And today is the day.</p> <p>I am changing teams, moving from HornetQ team to AS/EAP team. My job will be to help integrate HornetQ in the Application Server, removing some load from the HornetQ guys and being the man in the middle to smooth out integration issues to make the best messaging system and the best application server work even better together.</p> <p>I am eager to work on the Application Server code. With AS7, there is a solid foundation which lays the ground for interesting opportunities with a personal interest in entreprise-level services for JVM-based languages, with <a href="http://torquebox.org/">Torquebox</a> (Ruby) and <a href="http://immutant.org/">Immutant</a> (Clojure), and to the Cloud with <a href="https://openshift.redhat.com/app/">OpenShift</a>.</p> <p>Let's put my red Fedora, I am ready to tackle great challenges at Red Hat with my team.</p> Φ La Sioule 2012-02-28T08:59:14+01:00 2012-02-28T08:59:14+01:00 http://www.jmesnil.net/weblog/2012/02/28/la-sioule <p><figure> <img src="http://farm8.staticflickr.com/7202/6789055202_ddba37913b_z.jpg" alt="La Sioule" /> <figcaption><a href="http://www.flickr.com/photos/jmesnil/6789055202/">La Sioule</a></figcaption> </figure></p> ⚑ Apple Profits and Humanity Losses 2012-01-25T11:23:13+01:00 2012-01-25T11:23:13+01:00 http://www.jmesnil.net/weblog/2012/01/25/apple-profits-and-humanity-losses <p>During the last quarter of 2011, Apple <a href="http://money.cnn.com/2012/01/24/technology/apple_earnings/index.htm?on.cnn=1">generated sales of $46.3 billion</a>. 37 millions of iPhone were sold during that period.</p> <p>From a <a href="http://www.nytimes.com/2012/01/22/business/apple-america-and-a-squeezed-middle-class.html?_r=3&amp;pagewanted;=all">New York Times article</a>, we learn how Apple was able to build its devices:</p> <blockquote><p>Apple executives say that going overseas, at this point, is their only option. One former executive described how the company relied upon a Chinese factory to revamp iPhone manufacturing just weeks before the device was due on shelves. Apple had redesigned the iPhone’s screen at the last minute, forcing an assembly line overhaul. New screens began arriving at the plant near midnight.<br/> A foreman immediately roused 8,000 workers inside the company’s dormitories, according to the executive. Each employee was given a biscuit and a cup of tea, guided to a workstation and within half an hour started a 12-hour shift fitting glass screens into beveled frames. Within 96 hours, the plant was producing over 10,000 iPhones a day.</p></blockquote> <p>In a related news, the <a href="http://www.nytimes.com/2012/01/25/us/politics/state-of-the-union-2012-transcript.html?_r=1&amp;pagewanted;=all">President of United States want to get manufacturing jobs back in the USA</a>:</p> <blockquote><p>No, we will not go back to an economy weakened by outsourcing, bad debt, and phony financial profits. Tonight, I want to speak about how we move forward, and lay out a blueprint for an economy that’s built to last -– an economy built on American manufacturing, American energy, skills for American workers, and a renewal of American values.</p></blockquote> <p>Apple is far from being the only one to profit from outsourcing its production but with its stunning profits, it is emblematic of the failure of capitalism to balance profit with humanity <em>bien-être</em>.</p> <p>Apple success is well deserved, they have an outstanding line of products and I own many of them. I bought an iPhone 4S during this quarter and it is the best phone (and pocket camera) I ever had. However, I can not accept that someone is woken up in the middle of a night, given a biscuit and a cup of tea and has to work 12-hour to build a device I use sitting in my couch.</p> <p>We would live in a better world if the companies profits (from Apple and all the others) could be used to create new jobs or at least provide decent working conditions when they outsource their production.</p> ☛ Brent Simmons on Web Publishing 2011-11-28T13:02:21+01:00 2011-11-28T13:02:21+01:00 http://www.jmesnil.net/weblog/2011/11/28/brent-simmons-on-web-publishing <p>Very interesting triptych from <a href="http://inessential.com/">Brent Simmons</a> about Web publishing:</p> <ul> <li><a href="http://inessential.com/2011/11/22/the_pummeling_pages">The Pummeling Pages</a></li> <li><a href="http://inessential.com/2011/11/23/pub_rules">Pub Rules</a></li> <li><a href="http://inessential.com/2011/11/25/the_readable_future">Readable Future</a></li> </ul> <p>In other words, <strong>content! content! content!</strong> (as in quality, not quantity).</p> <p>It's a sad state for Web publishing when I need to use a mix of <a href="http://www.instapaper.com/">Instapaper</a>, <a href="http://www.readability.com/">Readability</a>, <a href="http://www.apple.com/safari/whats-new.html#read">Safari Reader</a> to have a sane reading experience without advertisement overload (and unfortunately, I know what an <em>interstitial</em> is...).</p> <p><a href="http://www.jmesnil.net/weblog/2011/11/28/brent-simmons-on-web-publishing" title="Permanent link to Brent Simmons on Web Publishing">⚑</a></p> ⚑ stomp-websocket converted to CoffeeScript 2011-11-03T23:06:06+01:00 2011-11-03T23:06:06+01:00 http://www.jmesnil.net/weblog/2011/11/03/stomp-websocket-converted-to-coffeescript <p>One of the joy of working with Open Source projects is when you get an awesome contribution coming out of nowhere.</p> <p><a href="https://github.com/progrium">Jeff Lindsay</a> requested to pull one of his branch of <a href="http://jmesnil.net/stomp-websocket/doc/">stomp-websocket</a> where he converted all the code to CoffeeScript, added unit tests with a mock implementation of a WebSocket server. This work is a preliminary for more features (including a much-needed support for STOMP 1.1).</p> <p>When he offered to pull its branch, he wonders if the move to CoffeeScript was controversial and if I would accept it.</p> <p><a href="http://jmesnil.net/stomp-websocket/doc/">stomp-websocket</a> is meant to run inside Web browsers and leverage the Web Sockets API. When I wrote it, JavaScript was a no-brainer.</p> <p>However I have started to question this choice recently.</p> <p>I have a pet project where I use <a href="http://nodejs.org">node.js</a> and I am making countless JavaScript code mistakes (I was bitten by <a href="http://blog.meloncard.com/post/12175941935/how-one-missing-var-ruined-our-launch">this one</a> last week, thankfully I have not released my project yet).</p> <p>As much as I like JavaScript and its related HTML5 APIs, I must admint I am not a good JavaScript programmer and I want a language that helps me instead of trapping me. I started to read about <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> as a replacement of JavaScript. I find the language more pleasing to read even though some syntax conventions makes it more cryptic than concise.</p> <p>I am quite pleased with the new code of stomp-websocket in <a href="https://github.com/jmesnil/stomp-websocket/blob/master/src/stomp.coffee">stomp.coffee</a>. It reads much better than the <a href="https://github.com/jmesnil/stomp-websocket/blob/master/src/stomp.orig.js">original stomp.js</a>, there are no longer noisy <code>this</code>, <code>that</code> or <code>var</code>s (when they are not missing by errors!).</p> <p>However, the <a href="https://github.com/jmesnil/stomp-websocket/blob/master/dist/stomp.js">JavaScript code compiled by CoffeeScript</a> does not look good. I suppose I must stop to look at the compiled JavaScript and instead consider it as <a href="http://www.hanselman.com/blog/JavaScriptIsAssemblyLanguageForTheWebSematicMarkupIsDeadCleanVsMachinecodedHTML.aspx">the assembly language of the Web</a>.</p> <p>In any case, the transition should be transparent for developers using stomp.js: the new generated <a href="https://github.com/jmesnil/stomp-websocket/blob/master/dist/stomp.js">stomp.js</a> offers the same <a href="http://jmesnil.net/stomp-websocket/doc/#api">API</a> than the previous one.</p> <p>If that is not the case, please report any regression or bug on <a href="https://github.com/jmesnil/stomp-websocket/issues">GitHub issue tracker</a>.</p> <p>As usual, do not hesitate to contribute:</p> <pre><code>git clone git://github.com/jmesnil/stomp-websocket.git </code></pre> <p>As Jeff Lindsay can attest, I welcome good contributions :)</p> ⚑ Qui Veut Aller Loin Ménage Sa Monture 2011-10-21T10:25:48+02:00 2011-10-21T10:25:48+02:00 http://www.jmesnil.net/weblog/2011/10/21/qui-veut-aller-loin-menage-sa-monture <p>That's the French proverb for "Slow and steady wins the race".</p> <p><a href="http://blog.8thlight.com/uncle-bob/2011/10/20/Simple-Hickey.html">Uncle Bob</a>:</p> <blockquote><p>Rich [Hickey] makes the point that sprinters run fast, but not long. Then he says that Agile “solved” this problem by just firing the starting gun over and over again in quick succession. He grins, and the audience laughs. Then he goes on to say that continuous sprinting does not necessarily makes systems simple, and simplicity is the real key to speed.</p></blockquote> <p>That is exactly the issue I have with Scrum and other so-called "agile" methods. It sacrifices long-term design and overall quality for fast short-term hacks. Sometimes there are no shortcuts for long hard work to end up with something simple.</p> <p>Simple and easy are not interchangeable concepts...</p> <p>As a bonus fo French readers, a post with a different perspective on the different meanings of simplicity by a colleague, <a href="http://martinsson-johan.blogspot.com/">Johan Martinsonn</a>: <a href="http://martinsson-johan.blogspot.com/2011/10/pas-si-simple-de-faire-simple.html">Pas si simple de faire simple</a>.</p> ☛ Matias Duarte on the philosophy of Android, and an in-depth look at Ice Cream Sandwich 2011-10-19T16:17:44+02:00 2011-10-19T16:17:44+02:00 http://www.jmesnil.net/weblog/2011/10/19/matias-duarte-on-the-philosophy-of-android-and-an-in-depth-look-at-ice-cream-sandwich <blockquote><p>The concept of an address book or contacts feels so lame and dated, it’s like ‘an address book is this little thing with this faux leather cover!<br/> -- Matias Duarte</p></blockquote> <p><em>Touche</em>! The Address Book app is a sore point in the iOS (and Mac OS X) experience.</p> <p><figure> <img src="http://www.apple.com/iphone/built-in-apps/images/contacts_everywhere.jpg" alt="Address Book on iOS" /> <figcaption>Address Book on iOS</figcaption> </figure></p> <p>It is a chore to use this application to update contacts information and the "real life" user interface makes it even more frustrating.</p> <p><a href="http://www.jmesnil.net/weblog/2011/10/19/matias-duarte-on-the-philosophy-of-android-and-an-in-depth-look-at-ice-cream-sandwich" title="Permanent link to Matias Duarte on the philosophy of Android, and an in-depth look at Ice Cream Sandwich">⚑</a></p> ☛ New Sensor and Lens in iPhone 4S Camera 2011-10-06T09:03:11+02:00 2011-10-06T09:03:11+02:00 http://www.jmesnil.net/weblog/2011/10/06/new-sensor-and-lens-in-iphone-4s-camera <p>The improved camera is the single reason I will replace my iPhone 3GS by an iPhone 4S as soon as it is available.</p> <p>It's too bad that <a href="http://duncandavidson.com/blog/2011/10/dailyshoot_retired">James Duncan Davidson announced they shut down the Daily Shoot</a> when I finally have a good camera in my pocket all the time everyday.</p> <p><a href="http://www.jmesnil.net/weblog/2011/10/06/new-sensor-and-lens-in-iphone-4s-camera" title="Permanent link to New Sensor and Lens in iPhone 4S Camera">⚑</a></p> ⚑ Steve Jobs: 1955 - 2011 2011-10-06T07:53:10+02:00 2011-10-06T07:53:10+02:00 http://www.jmesnil.net/weblog/2011/10/06/steve-jobs-1955-2011 <p><figure> <img src="https://s3.amazonaws.com/www.jmesnil.net/images/2011-10-06-SteveJobs1955-2011.jpg" alt="Steve Jobs" /> <figcaption>Steve Jobs 1955-2011</figcaption> </figure></p> <p><a href="http://news.stanford.edu/news/2005/june15/jobs-061505.html">Steve Jobs</a>:</p> <blockquote><p>Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma — which is living with the results of other people's thinking. Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.</p></blockquote> <p>For all the products and ideas that Steve Jobs delivered during his life, nothing from him has inspired me more than when he talked about life, love and death and what we can do from our life in his Stanford commencement speech:</p> <iframe class="aligncenter" width="640" height="480" src="http://www.youtube.com/embed/UF8uR6Z6KLc" frameborder="0" allowfullscreen=""></iframe> <p>All my thoughts go to his family, friends and coworkers at Pixar &amp; Apple.</p> Φ Brumes Matinales 2011-10-03T17:57:15+02:00 2011-10-03T17:57:15+02:00 http://www.jmesnil.net/weblog/2011/10/03/brumes-matinales <p><figure> <img src="http://farm7.static.flickr.com/6173/6176013346_3f2e30a802_z_d.jpg" alt="Brumes Matinales" /> <figcaption><a href="http://www.flickr.com/photos/jmesnil/6176013346">Brumes Matinales</a></figcaption> </figure></p> Φ Creative Commons licenses for photographs on the Web 2011-10-03T16:48:19+02:00 2011-10-03T16:48:19+02:00 http://www.jmesnil.net/weblog/2011/10/03/creative-commons-licenses-for-photographs-on-the-web <p>Interesting conversation between <a href="http://duncandavidson.com/">James Duncan Davidson</a> and <a href="http://www.tbray.org/ongoing/">Tim Bray</a> about photos and licenses on the web.</p> <ul> <li>James wrote about its <a href="http://duncandavidson.com/blog/2011/09/not_against_creative_commons">reluctance</a> to use creative commons licenses for his professional photographs</li> <li>Tim then <a href="http://www.tbray.org/ongoing/When/201x/2011/10/01/Architecture-of-Theology">explained</a> how one of his photographs that he uploaded on Wikipedia (in a compressed size) under Creative Commons licenses was chosen to be a book cover and that he got paid for the full size version</li> <li>James then replied with additional <a href="http://duncandavidson.com/blog/2011/10/wikipedia_photography">food for thought</a></li> </ul> <p>At the moment, I upload <a href="http://www.flickr.com/photos/jmesnil/">my photos on Flickr</a> under an <a href="http://creativecommons.org/licenses/by-sa/2.0/">"Attribution, Share Alike" Creative Commons license</a>. I do not take photos professionally but if people would be interested to use them in commercial products, I would like to get paid for their use.</p> <p>Tim's proposal to use different licenses depding on the resolution is a good idea:</p> <ul> <li>use a creative commons licenses for low-to-moderate resolution and make them available liberally (on Wikipedia, Flickr, etc.)</li> <li>keep a more restrictive licenses on the full resolution</li> </ul> ☛ How Browsers Work 2011-08-19T16:52:20+02:00 2011-08-19T16:52:20+02:00 http://www.jmesnil.net/weblog/2011/08/19/how-browsers-work <blockquote><p>As a web developer, learning the internals of browser operations helps you make better decisions and know the justifications behind development best practices. While this is a rather lengthy document, we recommend you spend some time digging in; we guarantee you'll be glad you did.</p></blockquote> <p>All you have ever wanted to know about the internals of Web browsers and more...</p> <p>I link to the document on <a href="http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/">HTML5 rocks</a> which is nicely presented but the original is available on <a href="http://taligarsiel.com/Projects/howbrowserswork1.htm">Tali Garsiel web site</a>.</p> <p>(via <a href="http://functionsource.com/post/how-browsers-work">FunctionSource</a>)</p> <p><a href="http://www.jmesnil.net/weblog/2011/08/19/how-browsers-work" title="Permanent link to How Browsers Work">⚑</a></p> Φ Jaguar XK 120 Roadster 2011-07-12T11:54:42+02:00 2011-07-12T11:54:42+02:00 http://www.jmesnil.net/weblog/2011/07/12/jaguar-xk-120-roadster <p>I don't care much about cars but when I see a beauty, I know it.</p> <p>A friend's father owns the <a href="http://www.classicetsportautos.fr/">Classic &amp; Sports Auto</a> garage and kindly invited me to shoot a Jaguar XK 120 roadster that he is renovating:</p> <p><figure> <img src="http://farm7.static.flickr.com/6148/5927230855_a206015beb_z.jpg" alt="Jaguar XK 120" /> <figcaption><a href="http://www.flickr.com/photos/jmesnil/5927230855/">Jaguar XK 120 Roadster</a></figcaption> </figure></p> <p><figure> <img src="http://farm7.static.flickr.com/6015/5927785456_6a8635292c_z.jpg" alt="Jaguar XK 120" /> <figcaption><a href="http://www.flickr.com/photos/jmesnil/5927785456/">Jaguar XK 120 Roadster</a></figcaption> </figure></p> <p>It was a great opportunity to shoot such a beautiful car with enough time and freedom to compose the shots. I waited for the late afternoon and the sun was starting to be low enough to reveal the curves of the car.<br/> I shot on top of a stool to remove the noisy background behind the car and put the emphasis on the car's front. A 3/4 view was the best way to show the length and curves of both the car's hood and left side.</p> <p>I used my Nikon 16-85mm at f/11 to shoot it. At first, I tried to shoot at 16-18mm but I found it made the car's hood too much proeminent at the expense of the rest of the car. I stepped back a little bit, zoom to 35mm and shoot it on top of the stool to get a more realistic perspective which still highlights the long and curvy hood.</p> <p>If you like this car, you are lucky: you can <a href="http://www.classicetsportautos.fr/achatsventes.html">buy it</a> once it is renovated.</p> <p>I really enjoy the experience and I am looking forward to the next opportunity to shoot such a beauty again. I may even start to care about (beautiful) cars a bit more!</p> ☛ node.x, a Asynchronous Event Framework for the JVM 2011-07-11T13:08:57+02:00 2011-07-11T13:08:57+02:00 http://www.jmesnil.net/weblog/2011/07/11/node-x-a-asynchronous-event-framework-for-the-jvm <p><a href="https://github.com/purplefox/node.x">Tim Fox</a>:</p> <blockquote><p>What is Node.x?</p> <ul> <li>A general purpose framework that uses an asynchronous event based style for building highly scalable network or file system aware applications</li> <li>Runs on the JVM.</li> <li>Everything is asynchronous.</li> <li>Embraces the style of node.js and extends it to the JVM. Think node.js on steroids. Plus some.</li> <li>Polyglot. The same (or similar) API will be available in multiple languages: Ruby, Java, Groovy, (Python?, JS?, Clojure?), etc</li> <li>Goes with the recent developments with InvokeDynamic in Java 7 and bets on the JVM being the future premier runtime for dynamic languages.</li> <li>Enables you to create network servers or clients incredibly easily.</li> <li>True threading. Unlike node.js, Python Twisted or Ruby EventMachine, it has true multi-threaded scalability. No more spinning up 32 instances just to utilise the cores on your server.</li> <li>Understands multiple protocols out of the box including: TCP, SSL, UDP, HTTP, HTTPS, Websockets, AMQP, STOMP, Redis etc</li> <li>Provides an elegant api for composing asynchronous actions together. Glue together HTTP, AMQP, Redis or whatever in a few lines of code.</li> </ul> </blockquote> <p>A framework a la <a href="http://nodejs.org">node.js</a> (and some more) in a multithreaded environment on the JVM is an intriguing idea with a lot of potential and the examples look both simple and powerful.</p> <p>This project is based on <a href="http://www.jboss.org/netty">Netty</a>, an asynchronous event-driven network application framework, that I can't stop to praise. We use it in <a href="http://www.jboss.org/hornetq">HornetQ</a> and is a big reason why <a href="http://www.spec.org/jms2007/results/jms2007.html">HornetQ is so fast</a>.</p> <p>Tim is an ex-colleague from <a href="http://www.redhat.com/">Red Hat</a> and the previous lead of HornetQ. He knows his stuff about performance, concurrent and asynchronous code and I am intrigued to see where he will go with <a href="https://github.com/purplefox/node.x">node.x</a> (esp. if he adds a <a href="http://clojure.org/">Clojure</a> layer on top of it, functional programming is a good match for an asynchronous event framework).</p> <p><a href="http://www.jmesnil.net/weblog/2011/07/11/node-x-a-asynchronous-event-framework-for-the-jvm" title="Permanent link to node.x, a Asynchronous Event Framework for the JVM">⚑</a></p> Φ Kodak Junior 620 2011-07-10T15:30:56+02:00 2011-07-10T15:30:56+02:00 http://www.jmesnil.net/weblog/2011/07/10/kodak-junior-620 <p>While talking about photography with my father, he told me that he still had an "old" camera from my grandfather and, lo and behold!, he showed me a folding camera: the <a href="http://vieilalbum.com/KodakJuniorsix20US.htm">Kodak Junior 620</a>.</p> <p><figure> <img src="http://farm7.static.flickr.com/6126/5921672819_8fe893bb36_z.jpg" alt="Kodak Junior 620" /> <figcaption><a href="http://www.flickr.com/photos/jmesnil/5921672819/">My grandfather's Kodak Junior 620</a></figcaption> </figure></p> <p>I have not found a serial number and I don't know exactly which series it is but Kodak Junior 620 cameras were manufactured between 1935 and 1939 (depending on the series).</p> <p>My grandfather's model has a Kodak Anastigmat f/7.7 lens and the shutter speeds are 1/25, 1/75, T, and B. The camera is in pretty good shape (except for a bit of leather skin that I need to glue) and if I buy a 620 film roll, I could shoot like my grandfather did when he got it.<br/> I even found its <a href="http://www.cameramanuals.org/kodak_pdf/kodak_junior_six-20_six-16_iii.pdf">user manual</a> to use it properly (I have never owned a camera with roll film).</p> <p>What a family treasure to discover!</p> ☛ Clojure on Heroku 2011-07-05T19:33:50+02:00 2011-07-05T19:33:50+02:00 http://www.jmesnil.net/weblog/2011/07/05/clojure-on-heroku <p><a href="http://www.heroku.com/">Heroku</a> explains why they have added <a href="http://clojure.org/">Clojure</a> support in addition to <a href="http://www.ruby-lang.org/">Ruby</a> and <a href="http://nodejs.org/">node.js</a>:</p> <blockquote><p>Ruby, Javascript, and Clojure are all general-purpose languages, but they each excel at certain use cases. Ruby's highly dynamic nature and emphasis on beauty makes it a natural fit for user-facing web apps. Node.js's evented concurrency makes it a great fit for the realtime web. Clojure covers a new use case on the Heroku platform: components which demand correctness, performance, composability; and optionally, access to the Java ecosystem.</p></blockquote> <p>The right tool for the right job.<br/> More choice for the tool helps get the job done simpler and faster.</p> <p><a href="http://www.jmesnil.net/weblog/2011/07/05/clojure-on-heroku" title="Permanent link to Clojure on Heroku">⚑</a></p>