<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5022667766051686813</id><updated>2012-01-27T09:23:05.601Z</updated><category term='logging'/><category term='sgae'/><category term='computadora'/><category term='aptitude ubuntu server mail upgrade'/><category term='appleseed'/><category term='tools'/><category term='educacion'/><category term='live'/><category term='favoritos'/><category term='bugs'/><category term='bash stderr stdout'/><category term='vi vim syntax ubuntu'/><category term='night vision'/><category term='pygtk'/><category term='jk'/><category term='new'/><category term='42'/><category term='permgen'/><category term='mencoder'/><category term='ssh error buffer_get'/><category term='yql'/><category term='memoria'/><category term='sala'/><category term='put'/><category term='licencias open source gpl lgpl mit bsd apache mozilla epl'/><category term='suse'/><category term='practice'/><category term='64'/><category term='git'/><category term='rdp'/><category term='libglade'/><category term='yap'/><category term='jongo'/><category term='video'/><category term='ofertas'/><category term='virtual'/><category term='distros'/><category term='java log4j log trazas PropertyResourceBundle properties debugging'/><category term='rant'/><category term='1234567890'/><category term='facebook'/><category term='proceedure'/><category term='host'/><category term='java'/><category term='wifi'/><category term='lock'/><category term='commit'/><category term='effect'/><category term='store'/><category term='tecnológica'/><category term='resolve'/><category term='django'/><category term='slf4j'/><category term='estafa'/><category term='beta'/><category term='webservice'/><category term='mvc'/><category term='rest'/><category term='java blogger syntax highlight'/><category term='ubuntu screen capture zona imagemagick import'/><category term='groovy'/><category term='varios'/><category term='puttycm'/><category term='ordenador'/><category term='stock'/><category term='persistencia'/><category term='ubuntu'/><category term='criticas'/><category term='coffescript'/><category term='j2ee'/><category term='extjs'/><category term='brillo'/><category term='json'/><category term='yakuake'/><category term='svn'/><category term='koala'/><category term='vino'/><category term='trabajo'/><category term='gnuplot'/><category term='mail'/><category term='helios'/><category term='red'/><category term='8.10'/><category term='software libre soporte desarrollo criticas'/><category term='españa'/><category term='ubuntu linux pconsole multiples consolas'/><category term='tomcat'/><category term='tag'/><category term='template'/><category term='directorios'/><category term='ebook'/><category term='stored'/><category term='outlet'/><category term='mp4'/><category term='interface'/><category term='hup'/><category term='mencode'/><category term='guice'/><category term='frameworks'/><category term='terminos'/><category term='jetty'/><category term='zope'/><category term='llorar'/><category term='gimp'/><category term='canvas'/><category term='lubuntu'/><category term='minor'/><category term='image'/><category term='inkscape'/><category term='instalar'/><category term='linux reciclar ordenadores'/><category term='touch'/><category term='screen'/><category term='grafico'/><category term='lengua'/><category term='windows ubuntu installer'/><category term='revision'/><category term='nav erp microsoft'/><category term='vision nocturna'/><category term='p2p'/><category term='usb'/><category term='highlight'/><category term='dba'/><category term='remote'/><category term='jtds'/><category term='gtk'/><category term='world'/><category term='diaspora'/><category term='ssh'/><category term='iconos'/><category term='efecto'/><category term='version'/><category term='lynx'/><category term='post'/><category term='vnc'/><category term='button'/><category term='glade'/><category term='sql'/><category term='wireless'/><category term='seguridad virus tontos'/><category term='ipod'/><category term='code2blog'/><category term='unix'/><category term='xubuntu'/><category term='twitter'/><category term='netbook'/><category term='closure'/><category term='thoggen'/><category term='ftp'/><category term='wubi'/><category term='boton'/><category term='differo'/><category term='html5'/><category term='ibex'/><category term='web'/><category term='rsync'/><category term='restart'/><category term='seguridad'/><category term='treeview'/><category term='syntax'/><category term='plasma'/><category term='editores estupidez pantalla completa linux windows mac'/><category term='bazaar'/><category term='grails'/><category term='conflictos'/><category term='ejb'/><category term='ejb3'/><category term='frustracion'/><category term='bash linux stdin stdout'/><category term='ubuntu screen capture zona imagemagick import bash script gnome key bindings'/><category term='sts'/><category term='vim'/><category term='eclipse'/><category term='xbox'/><category term='poderosa'/><category term='review'/><category term='get'/><category term='carnicas'/><category term='brecha'/><category term='ubuntu particion disco duro linux'/><category term='xml'/><category term='virtualbox'/><category term='ext3'/><category term='turbo'/><category term='productividad'/><category term='squirrel'/><category term='bzr'/><category term='local'/><category term='chorradas'/><category term='informatica'/><category term='comandos'/><category term='terminator'/><category term='bash'/><category term='temas'/><category term='multiples'/><category term='oracle'/><category term='intrepid'/><category term='bash linux sustitucion parametros'/><category term='monocaffe'/><category term='sense'/><category term='gears'/><category term='instalacion'/><category term='zenburn ubuntu colores temas'/><category term='ha'/><category term='software'/><category term='5'/><category term='mcm'/><category term='persistence'/><category term='estructura'/><category term='session'/><category term='pconsole'/><category term='gnote'/><category term='grooy'/><category term='release'/><category term='lib'/><category term='manifiesto'/><category term='vcs'/><category term='karmic'/><category term='vista'/><category term='telefonica'/><category term='bugzilla perl xls excel'/><category term='nacar'/><category term='yahoo'/><category term='proxy'/><category term='multiples consolas'/><category term='jdbc'/><category term='javascript'/><category term='hello'/><category term='apple'/><category term='panasonic'/><category term='ipad'/><category term='7'/><category term='lucid'/><category term='social'/><category term='fedora'/><category term='varargs'/><category term='manager'/><category term='monitores'/><category term='curl'/><category term='gorm'/><category term='http'/><category term='kill'/><category term='vimrc'/><category term='gnome'/><category term='daemon'/><category term='trucos'/><category term='yast2'/><category term='pixelqi'/><category term='caps'/><category term='delete'/><category term='netboot'/><category term='python'/><category term='telnet'/><category term='internet'/><category term='script'/><category term='logback'/><category term='open'/><category term='windows'/><category term='tomboy'/><category term='corrupcion'/><category term='estupidez'/><category term='video juegos wish estadisticas camper'/><category term='mint'/><category term='microsoft fud linux patentes'/><category term='mremote'/><category term='deploy'/><category term='camello'/><category term='vimdiff'/><category term='apache'/><category term='linux'/><category term='debug'/><category term='comparacion'/><category term='bash linux script'/><category term='java log properties enum exception excepcion'/><category term='hibernate'/><category term='traduccion'/><category term='enum'/><category term='cvs'/><category term='fud'/><category term='vi'/><category term='stress'/><category term='opensuse'/><category term='translation'/><category term='connections'/><category term='10.04'/><category term='oscon'/><category term='kubuntu'/><category term='pirateria'/><category term='tutorial'/><category term='tarjeta personal java friki'/><category term='monocaffe desarrollo'/><category term='politicos'/><category term='servidor'/><category term='jvm'/><category term='gtkbuilder'/><category term='tilda'/><category term='television'/><category term='time'/><category term='log4j'/><category term='source'/><category term='colores'/><category term='mode'/><category term='day'/><category term='blogger'/><category term='terminal'/><category term='modulo'/><category term='guake'/><category term='hasMany'/><category term='3.0'/><category term='jboss'/><category term='house'/><category term='ror'/><category term='microsoft'/><category term='mono'/><category term='cocaina'/><category term='failure'/><category term='jconsole'/><category term='glossy'/><title type='text'>monocaffe</title><subtitle type='html'>Where monkeys drink coffee and code.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default?start-index=101&amp;max-results=100'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>150</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7104862522754017499</id><published>2012-01-17T23:30:00.000Z</published><updated>2012-01-25T20:05:32.975Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ha'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual'/><category scheme='http://www.blogger.com/atom/ns#' term='jongo'/><category scheme='http://www.blogger.com/atom/ns#' term='jk'/><category scheme='http://www.blogger.com/atom/ns#' term='host'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Sharing Apache Tomcat and Apache Web Server</title><content type='html'>&lt;div&gt;Today's problem is sharing one single virtual host with different Tomcat instances. For example, say you have your Apache (the web server) with a virtual host for &lt;b&gt;intranet&lt;/b&gt; and you have in different Tomcat instances different applications like: &lt;b&gt;monitoring&lt;/b&gt;, &lt;b&gt;dashboard&lt;/b&gt;&amp;nbsp;and&amp;nbsp;&lt;b&gt;hradmin&lt;/b&gt;. You want your users to be directed to the correct application if they access the URL &lt;i&gt;http://intranet/dashboard&lt;/i&gt; or &lt;i&gt;http://intranet/hradmin&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;In this example I'm using three Tomcat servers and this applications:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;server1:8080/monitoring/&lt;/li&gt;&lt;li&gt;server1:8080/dashboard/&lt;/li&gt;&lt;li&gt;hr1:8080/hradmin/&lt;/li&gt;&lt;li&gt;hr2:8080/hradmin/&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The &lt;i&gt;server1&lt;/i&gt; Tomcat is running two different applications and the &lt;i&gt;hr1&lt;/i&gt; and &lt;i&gt;hr2&lt;/i&gt; are running the &lt;b&gt;hradmin&lt;/b&gt; application which we want to be load balanced and since it's critical, to be always available.&lt;br /&gt;&lt;br /&gt;The first thing to do is create the&amp;nbsp;&lt;i&gt;&lt;a href="http://tomcat.apache.org/connectors-doc/reference/workers.html" target="_blank"&gt;jkworkers.properties&lt;/a&gt;&lt;/i&gt; file:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #f1f0f0; color: black;"&gt;&lt;span style="color: #c34e00;"&gt;# This names are the ones defined bellow&lt;/span&gt;&lt;br /&gt;worker.list=server1&lt;span style="color: #806030;"&gt;,&lt;/span&gt;hrlb&lt;br /&gt;worker.lock=P&lt;br /&gt;worker.status.type=status&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #c34e00;"&gt;# Single server running monitoring and dashboard&lt;/span&gt;&lt;br /&gt;worker.server1.type=ajp13&lt;br /&gt;worker.server1.host=&lt;span style="color: #8c0000;"&gt;192&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;168&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;1&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;2&lt;/span&gt;&lt;br /&gt;worker.server1.port=&lt;span style="color: #8c0000;"&gt;8080&lt;/span&gt;&lt;br /&gt;worker.server1.disabled=false&lt;br /&gt;worker.server1.socket_timeout=&lt;span style="color: #8c0000;"&gt;60000&lt;/span&gt;&lt;br /&gt;worker.server1.connect_timeout=&lt;span style="color: #8c0000;"&gt;60000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #c34e00;"&gt;# Two workers for two servers running a critical application&lt;/span&gt;&lt;br /&gt;worker.hr1.type=ajp13&lt;br /&gt;worker.hr1.host=&lt;span style="color: #8c0000;"&gt;192&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;168&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;1&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;3&lt;/span&gt;&lt;br /&gt;worker.hr1.port=&lt;span style="color: #8c0000;"&gt;8080&lt;/span&gt;&lt;br /&gt;worker.hr1.disabled=false&lt;br /&gt;worker.hr1.socket_timeout=&lt;span style="color: #8c0000;"&gt;60000&lt;/span&gt;&lt;br /&gt;worker.hr1.connect_timeout=&lt;span style="color: #8c0000;"&gt;60000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;worker.hr2.type=ajp13&lt;br /&gt;worker.hr2.host=&lt;span style="color: #8c0000;"&gt;192&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;168&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;1&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;4&lt;/span&gt;&lt;br /&gt;worker.hr2.port=&lt;span style="color: #8c0000;"&gt;8080&lt;/span&gt;&lt;br /&gt;worker.hr2.disabled=false&lt;br /&gt;worker.hr2.socket_timeout=&lt;span style="color: #8c0000;"&gt;60000&lt;/span&gt;&lt;br /&gt;worker.hr2.connect_timeout=&lt;span style="color: #8c0000;"&gt;60000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #c34e00;"&gt;# Loadbalancer configuration for the critical application&lt;/span&gt;&lt;br /&gt;worker.hrlb.type=lb&lt;br /&gt;worker.hrlb.balance_workers=hr1&lt;span style="color: #806030;"&gt;,&lt;/span&gt;hr2&lt;br /&gt;worker.hrlb.sticky_session=true&lt;br /&gt;worker.hrlb.sticky_session_force=false&lt;br /&gt;worker.hrlb.method=R&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Of course, you should use the DNS names instead of the IP addresses. Also, there are many more options to be set here, but this should give you a good start.&lt;br /&gt;&lt;br /&gt;Second, you need your &lt;i&gt;&lt;a href="http://tomcat.apache.org/connectors-doc/reference/apache.html"&gt;jk.conf&lt;/a&gt;&lt;/i&gt; file:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #f1f0f0; color: black;"&gt;JkWorkersFile /etc/apache2/conf.d/jkworkers.properties&lt;br /&gt;JkLogFile /var/log/apache2/mod_jk.log&lt;br /&gt;JkLogLevel &lt;span style="color: #074726;"&gt;info&lt;/span&gt;&lt;br /&gt;JkLogStampFormat &lt;span style="color: #e60000;"&gt;"[%a %b %d %H:%M:%S %Y]"&lt;/span&gt;&lt;br /&gt;JkOptions &lt;span style="color: #806030;"&gt;+&lt;/span&gt;ForwardKeySize &lt;span style="color: #806030;"&gt;+&lt;/span&gt;ForwardURICompatUnparsed &lt;span style="color: #806030;"&gt;-&lt;/span&gt;ForwardDirectories&lt;br /&gt;JkRequestLogFormat &lt;span style="color: #e60000;"&gt;"%w %V %T"&lt;/span&gt;&lt;br /&gt;JkShmFile /var/log/httpd/jk.shm&lt;br /&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;Location&lt;/span&gt; &lt;span style="color: #e60000;"&gt;/jkstatus&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    JkMount status&lt;br /&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Order &lt;/span&gt;&lt;span style="color: #074726;"&gt;deny&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt;&lt;span style="color: #074726;"&gt;allow&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000; font-weight: bold;"&gt;Deny from&lt;/span&gt; &lt;span style="color: #074726;"&gt;all&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000; font-weight: bold;"&gt;Allow from&lt;/span&gt; &lt;span style="color: #8c0000;"&gt;127&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;0&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;0&lt;/span&gt;.&lt;span style="color: #8c0000;"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;Location&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And finally, you can set up your virtual host in the, for example, &lt;i&gt;intranet.conf&lt;/i&gt; file:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #f1f0f0; color: black;"&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;VirtualHost&lt;/span&gt; &lt;span style="color: #e60000;"&gt;*:80&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;ServerName&lt;/span&gt; intranet&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;RewriteEngine&lt;/span&gt; &lt;span style="color: #074726;"&gt;on&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #c34e00;"&gt;&amp;nbsp;&amp;nbsp;# Here we set where we want the url http://intranet/ to go&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;RedirectMatch&lt;/span&gt; ^/$ /dashboard/&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;DocumentRoot&lt;/span&gt; /srv/www/htdocs/docroot&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;CustomLog&lt;/span&gt;  /var/log/apache2/access_reports combined&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;ErrorLog&lt;/span&gt;  /var/log/apache2/error_reports&lt;br /&gt;  &lt;br /&gt;&lt;span style="color: #c34e00;"&gt;&amp;nbsp;&amp;nbsp;# You can even setup a jongo proxy&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;ProxyPass&lt;/span&gt; /jongo/ &lt;span style="color: #5555dd;"&gt;http://192.168.1.5:8080/jongo/&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #400000; font-weight: bold;"&gt;ProxyPassReverse&lt;/span&gt; /jongo/ &lt;span style="color: #5555dd;"&gt;http://192.168.1.5:8080/jongo/&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;&lt;span style="color: #c34e00;"&gt;&amp;nbsp;&amp;nbsp;# It's important that this names are the same used in your Tomcat&lt;/span&gt;&lt;br /&gt;  JkMount /dashboard/* server1&lt;br /&gt;  JkMount /monitoring/* server1&lt;br /&gt;  JkMount /hradmin/* hrlb&lt;br /&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;VirtualHost&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What we're doing here is telling the Apache server to listen on port 80 for all requests to the intranet host and to forward this requests to their corresponding applications:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;http://intranet/&lt;/i&gt; goes to &lt;i&gt;http://server1/dashboard/&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;http://intranet/dashboard/&lt;/i&gt;&amp;nbsp;goes to &lt;i&gt;http://&lt;i&gt;server1&lt;/i&gt;/dashboard/&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;http://intranet/monitoring/&lt;/i&gt;&amp;nbsp;goes to &lt;i&gt;http://&lt;i&gt;server1&lt;/i&gt;/monitoring/&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;http://intranet/hradmin/&lt;/i&gt;&amp;nbsp;goes to &lt;i&gt;http://hr1/hradmin/ &lt;/i&gt;or to&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;i&gt;http://hr2/hradmin/&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Where you put this files depends on your httpd.conf configuration.&lt;br /&gt;&lt;br /&gt;This example will allow a vanilla Apache to serve three different applications (one load balanced) from three Tomcat servers (server1, hr1 and hr2)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7104862522754017499?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7104862522754017499/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2012/01/sharing-apache-tomcat-and-apache-web.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7104862522754017499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7104862522754017499'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2012/01/sharing-apache-tomcat-and-apache-web.html' title='Sharing Apache Tomcat and Apache Web Server'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3524147004022010973</id><published>2012-01-14T10:32:00.000Z</published><updated>2012-01-14T10:37:16.150Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='jongo'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Python and Jongo</title><content type='html'>For some reason or another, I've always found Python support for RDBMS lacking behind Java, specially in the ORM area. Just imagine, there are no officially supported Python drivers to connect to an Oracle database and you must install the Oracle client... ugh!&lt;br /&gt;&lt;br /&gt;Anyway, by having a Jongo server connected to your database you don't have to worry about installing any Python modules, you'll only need a standard Python 2.4+ installation with simplejson or Python 2.5+ which already support JSON.&lt;br /&gt;&lt;br /&gt;Let's see, for example, an application which accesses the &lt;b&gt;CIDB&lt;/b&gt; database and the &lt;b&gt;Car&lt;/b&gt; table:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #f1f0f0; color: black;"&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;import&lt;/span&gt; jongo&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;class&lt;/span&gt; Car&lt;span style="color: #806030;"&gt;(&lt;/span&gt;jongo&lt;span style="color: #806030;"&gt;.&lt;/span&gt;JongoModel&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;span style="color: #806030;"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;__init__&lt;/span&gt;&lt;span style="color: #806030;"&gt;(&lt;/span&gt;self&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;id&lt;/span&gt;&lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; model&lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; maker&lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; fuel&lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; transmission&lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; year&lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;span style="color: #806030;"&gt;:&lt;/span&gt;&lt;br /&gt;        jongo&lt;span style="color: #806030;"&gt;.&lt;/span&gt;JongoModel&lt;span style="color: #806030;"&gt;.&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;__init__&lt;/span&gt;&lt;span style="color: #806030;"&gt;(&lt;/span&gt;self&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;id&lt;/span&gt; &lt;span style="color: #806030;"&gt;=&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;id&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;idCol &lt;span style="color: #806030;"&gt;=&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"cid"&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;model &lt;span style="color: #806030;"&gt;=&lt;/span&gt; model&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;maker &lt;span style="color: #806030;"&gt;=&lt;/span&gt; maker&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;fuel &lt;span style="color: #806030;"&gt;=&lt;/span&gt; fuel&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;transmission &lt;span style="color: #806030;"&gt;=&lt;/span&gt; transmission&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;year &lt;span style="color: #806030;"&gt;=&lt;/span&gt; year&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;class&lt;/span&gt; CarStore&lt;span style="color: #806030;"&gt;(&lt;/span&gt;jongo&lt;span style="color: #806030;"&gt;.&lt;/span&gt;JongoStore&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;span style="color: #806030;"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;__init__&lt;/span&gt;&lt;span style="color: #806030;"&gt;(&lt;/span&gt;self&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;span style="color: #806030;"&gt;:&lt;/span&gt;&lt;br /&gt;        jongo&lt;span style="color: #806030;"&gt;.&lt;/span&gt;JongoStore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;__init__&lt;/span&gt;&lt;span style="color: #806030;"&gt;(&lt;/span&gt;self&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;model &lt;span style="color: #806030;"&gt;=&lt;/span&gt; Car&lt;br /&gt;        self&lt;span style="color: #806030;"&gt;.&lt;/span&gt;proxy &lt;span style="color: #806030;"&gt;=&lt;/span&gt; jongo&lt;span style="color: #806030;"&gt;.&lt;/span&gt;Proxy&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #e60000;"&gt;"localhost:8080"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt;&lt;span style="color: #e60000;"&gt;"cidb"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt;&lt;span style="color: #e60000;"&gt;"car"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; Car&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #400000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #e34adc;"&gt;__name__&lt;/span&gt; &lt;span style="color: #806030;"&gt;=&lt;/span&gt;&lt;span style="color: #806030;"&gt;=&lt;/span&gt; &lt;span style="color: #e60000;"&gt;'__main__'&lt;/span&gt;&lt;span style="color: #806030;"&gt;:&lt;/span&gt;&lt;br /&gt;    carstore &lt;span style="color: #806030;"&gt;=&lt;/span&gt; CarStore&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;load&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000; font-weight: bold;"&gt;for&lt;/span&gt; car &lt;span style="color: #400000; font-weight: bold;"&gt;in&lt;/span&gt; carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;data&lt;span style="color: #806030;"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #400000; font-weight: bold;"&gt;print&lt;/span&gt; car&lt;br /&gt;&lt;br /&gt;    c1 &lt;span style="color: #806030;"&gt;=&lt;/span&gt; Car&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #e34adc;"&gt;None&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"206cc"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"Peugeot"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"Gasoline"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"Manual"&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #c00000;"&gt;2008&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;add&lt;span style="color: #806030;"&gt;(&lt;/span&gt;c1&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;sync&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    c1 &lt;span style="color: #806030;"&gt;=&lt;/span&gt; carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;getAt&lt;span style="color: #806030;"&gt;(&lt;/span&gt;carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;count&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt; &lt;span style="color: #806030;"&gt;-&lt;/span&gt; &lt;span style="color: #c00000;"&gt;1&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    c1&lt;span style="color: #806030;"&gt;.&lt;/span&gt;set&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #e60000;"&gt;'model'&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"206"&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    c1&lt;span style="color: #806030;"&gt;.&lt;/span&gt;set&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #e60000;"&gt;'maker'&lt;/span&gt;&lt;span style="color: #806030;"&gt;,&lt;/span&gt; &lt;span style="color: #e60000;"&gt;"PPegoushn"&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;update&lt;span style="color: #806030;"&gt;(&lt;/span&gt;c1&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;sync&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #c34e00;"&gt;# We need to refresh the object since it has changed after the sync&lt;/span&gt;&lt;br /&gt;    c1 &lt;span style="color: #806030;"&gt;=&lt;/span&gt; carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;getAt&lt;span style="color: #806030;"&gt;(&lt;/span&gt;carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;count&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt; &lt;span style="color: #806030;"&gt;-&lt;/span&gt; &lt;span style="color: #c00000;"&gt;1&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;remove&lt;span style="color: #806030;"&gt;(&lt;/span&gt;c1&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;    carstore&lt;span style="color: #806030;"&gt;.&lt;/span&gt;sync&lt;span style="color: #806030;"&gt;(&lt;/span&gt;&lt;span style="color: #806030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Since this is Python, the code is pretty straightforward and self documented, right? For more information and examples on working with Python and Jongo check this &lt;a href="http://code.google.com/p/jongo/wiki/JongoPythonAPI" target="_blank"&gt;page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3524147004022010973?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3524147004022010973/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2012/01/python-and-jongo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3524147004022010973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3524147004022010973'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2012/01/python-and-jongo.html' title='Python and Jongo'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7182325284942142921</id><published>2011-12-16T23:00:00.000Z</published><updated>2011-12-16T23:00:03.040Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jongo'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='beta'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Jongo Beta 0.1</title><content type='html'>Last night I uploaded the first version of &lt;a href="http://code.google.com/p/jongo/" target="_blank"&gt;Jongo&lt;/a&gt;. This is a beta version and all of the projected&amp;nbsp;functionality&amp;nbsp;is provided.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;All REST to CRUD operations are implemented (PUT, POST, GET, DELETE).&lt;/li&gt;&lt;li&gt;JDBC errors mapping to HTTP errors.&lt;/li&gt;&lt;li&gt;POST requests accept form and JSON data.&lt;/li&gt;&lt;li&gt;Full HTTP response with JSON or XML&lt;/li&gt;&lt;li&gt;Grails style dynamic finders.&lt;/li&gt;&lt;li&gt;Complex Queries.&lt;/li&gt;&lt;li&gt;Deploy-able&amp;nbsp;web applications in the apps directory.&lt;/li&gt;&lt;li&gt;Administration Console with jQuery.&lt;/li&gt;&lt;li&gt;Demo mode which creates a in-memory database with demo data and deploys a demo application called cidb (made using ExtJS)&lt;/li&gt;&lt;li&gt;Support for MySQL, Oracle and Hypersonic.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;In future versions support for more RDBMS will be added, like Microsoft SQL Server and Sybase using the jTDS JDBC Driver. Also support for PostgreSQL and SQLite is projected.&lt;br /&gt;&lt;br /&gt;A couple of screenshots:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-4jj4mh8yLu8/Tus3Pzx0uYI/AAAAAAAAA48/QmnpS2NsyBs/s1600/screenshot_233.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="175" src="http://2.bp.blogspot.com/-4jj4mh8yLu8/Tus3Pzx0uYI/AAAAAAAAA48/QmnpS2NsyBs/s320/screenshot_233.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This is the administration console, from where you can control the tables Jongo will provide access to. It's completely made with jQuery and is a good example of how to work with jQuery.Ajax() and Jongo.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-T2zpbTAKxNo/Tus3RxPuDOI/AAAAAAAAA5E/8Rdy2gJDrJA/s1600/screenshot_232.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://2.bp.blogspot.com/-T2zpbTAKxNo/Tus3RxPuDOI/AAAAAAAAA5E/8Rdy2gJDrJA/s320/screenshot_232.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;cidb&lt;/i&gt; application is a&amp;nbsp;demonstration&amp;nbsp;of how to use &lt;a href="http://sencha.com/products/extjs/" target="_blank"&gt;ExtJS&lt;/a&gt; rest stores without any server side coding.&lt;br /&gt;&lt;br /&gt;If you find Jongo useful please leave your &lt;a href="http://code.google.com/p/jongo/wiki/JongoFeedback" target="_blank"&gt;feedback&lt;/a&gt;. Find any bugs, errors or have a cool idea? &lt;a href="http://code.google.com/p/jongo/issues/list" target="_blank"&gt;Open a ticket&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7182325284942142921?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7182325284942142921/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/12/jongo-beta-01.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7182325284942142921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7182325284942142921'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/12/jongo-beta-01.html' title='Jongo Beta 0.1'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-4jj4mh8yLu8/Tus3Pzx0uYI/AAAAAAAAA48/QmnpS2NsyBs/s72-c/screenshot_233.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2460179394917913035</id><published>2011-12-05T20:52:00.001Z</published><updated>2011-12-05T21:10:43.482Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='deploy'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='jongo'/><title type='text'>Jongo as a JavaScript Application Server</title><content type='html'>&lt;a href="http://code.google.com/p/jongo/"&gt;Jongo&lt;/a&gt; is built on top of the &lt;a href="http://www.eclipse.org/jetty/"&gt;Jetty&lt;/a&gt;&amp;nbsp;webserver, allowing a developer to use only one server to build a full application using static content (html, css, images) and JavaScript. For Jongo to be able to deploy your application, you need to activate the&amp;nbsp;&lt;i&gt;jongo.allow.apps&lt;/i&gt; option in the &lt;i&gt;jongo.properties&lt;/i&gt; file.&lt;br /&gt;&lt;br /&gt;Continue and create a folder in your JONGO_HOME named &lt;i&gt;apps/myapp &lt;/i&gt;and develop you application there, something like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-_80Jsx14sRI/Tt0ydBZQFYI/AAAAAAAAA40/_N0an5-Iezs/s1600/jongo_app.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-_80Jsx14sRI/Tt0ydBZQFYI/AAAAAAAAA40/_N0an5-Iezs/s320/jongo_app.png" width="188" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;An example of a MVC ExtJS Application&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;If everything went fine, the next time you run jongo, you'll see this in your logs (if debug mode is enabled):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: xx-small;"&gt;2011-12-05 22:02:04 o.j.JongoJetty [DEBUG] Loading apps&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: xx-small;"&gt;2011-12-05 22:02:04 o.j.JongoJetty [DEBUG] Creating Servlet for myapp&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now navigate to &lt;span class="Apple-style-span" style="color: #93c47d;"&gt;http://jongo-server:port/myapp/&lt;/span&gt; and your application should work.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2460179394917913035?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2460179394917913035/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/12/jongo-as-javascript-application-server.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2460179394917913035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2460179394917913035'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/12/jongo-as-javascript-application-server.html' title='Jongo as a JavaScript Application Server'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-_80Jsx14sRI/Tt0ydBZQFYI/AAAAAAAAA40/_N0an5-Iezs/s72-c/jongo_app.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-388280277803466360</id><published>2011-12-05T20:23:00.001Z</published><updated>2011-12-05T20:44:05.526Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='jongo'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><category scheme='http://www.blogger.com/atom/ns#' term='store'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>Jongo and ExtJS</title><content type='html'>To work out some issues other developers might have when working with Jongo, I've started to develop a &amp;nbsp;JavaScript only application (pretty much like the Administration Console) and get some insights into using &amp;nbsp;a great JavaScript framework named &lt;a href="http://www.sencha.com/products/extjs/"&gt;ExtJS&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;ExtJS provides a clean MVC framework which fits perfectly with a Jongo back-end.&lt;br /&gt;&lt;br /&gt;By using a &lt;a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Rest"&gt;rest proxy&lt;/a&gt;&amp;nbsp;like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Ext&lt;span style="color: blue;"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;define&lt;span style="color: blue;"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;'User'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt; &lt;span style="color: blue;"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    extend&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'Ext.data.Model'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    fields&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;&lt;b&gt;[&lt;/b&gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;'id'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt; &lt;span style="color: purple;"&gt;'name'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt; &lt;span style="color: purple;"&gt;'email'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;]&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ext&lt;span style="color: blue;"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;define&lt;span style="color: blue;"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;'Users'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt; &lt;span style="color: blue;"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    extend&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'Ext.data.Store'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    model&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'User'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    proxy&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;        type&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'rest'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;        url &lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'/jongo/user'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;        reader&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: blue;"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;            type&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'json'&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;            success&lt;span style="color: blue;"&gt;:&lt;/span&gt; true&lt;span style="color: blue;"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;            root&lt;span style="color: blue;"&gt;:&lt;/span&gt; &lt;span style="color: purple;"&gt;'response'&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: blue;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;;&lt;/b&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Our application is ready to perform all rest operations on the database without doing any server-side coding. Give it a try, you'll be pleased.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-388280277803466360?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/388280277803466360/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/12/jongo-and-extjs.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/388280277803466360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/388280277803466360'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/12/jongo-and-extjs.html' title='Jongo and ExtJS'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1855834427536851111</id><published>2011-12-02T11:58:00.001Z</published><updated>2011-12-02T12:07:09.125Z</updated><title type='text'>Un gobierno en funciones no puede aprobar la ley Sinde</title><content type='html'>&lt;i&gt;Hoy verás este texto en decenas de blogs. Si estás de acuerdo con él, reprodúcelo donde consideres oportuno.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ante la previsible aprobación de la polémica “Ley Sinde”, los periodistas, bloggers, usuarios, profesionales y creadores de Internet seguimos manifestando –como hicimos en el Manifiesto de 2 de Diciembre de 2009- nuestra firme oposición a una norma que incluye modificaciones legislativas que &lt;b&gt;afectan al libre ejercicio de las libertades de expresión&lt;/b&gt;, información y el derecho de acceso a la cultura a través de Internet.&lt;br /&gt;&lt;br /&gt;En principio no parece de recibo que un Gobierno en funciones adopte esta decisión en su último o uno de sus últimos Consejos de Ministros. &lt;b&gt;Sería doblemente grave que se confirmaran las presiones ejercidas por EEUU&lt;/b&gt;, a través de su embajada en Madrid, como revelaron los cables de Wikileaks.&lt;br /&gt;&lt;br /&gt;En todo caso insistimos en estos razonamientos:&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión.&amp;nbsp;&lt;/li&gt;&lt;li&gt;La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.&amp;nbsp;&lt;/li&gt;&lt;li&gt;La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.&amp;nbsp;&lt;/li&gt;&lt;li&gt;La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.&lt;/li&gt;&lt;li&gt;Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.&lt;/li&gt;&lt;li&gt;Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.&amp;nbsp;&lt;/li&gt;&lt;li&gt;En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1855834427536851111?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1855834427536851111/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/12/hoy-veras-este-texto-en-decenas-de.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1855834427536851111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1855834427536851111'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/12/hoy-veras-este-texto-en-decenas-de.html' title='Un gobierno en funciones no puede aprobar la ley Sinde'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3307155102524577373</id><published>2011-10-19T15:51:00.002+01:00</published><updated>2011-10-19T16:26:44.438+01:00</updated><title type='text'>Java's Ghost JVMs</title><content type='html'>It's a nice day when you end up digging through some of the JDK source code to find out what is broken with one of the JDK tools like JPS or JConsole. Today was one of those days.&lt;br /&gt;&lt;br /&gt;The problem was with our JBoss monitoring tool which depends on jconsoles&amp;nbsp;LocalVirtualMachine.getAllVirtualMachines() method. For some reason, after a controlled restart of the farm, a couple of servers were being reported as offline. Looking at the log files, I was able to see that the PID for this servers was wrong and the process couldn't connect to retrieve the data (this is done using JMX).&lt;br /&gt;&lt;br /&gt;The solution was to see what this method was doing with the source code from &lt;a href="http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/jvmstat/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java.htm"&gt;LocalVmManager.java&lt;/a&gt; and &lt;a href="http://javasourcecode.org/html/open-source/jdk/jdk-5.0/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java.html"&gt;PerfDataFile.java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So how does tools like JPS, JConsole or VisualVM know the JVMs running in a system? They simply look in the folder &lt;b&gt;/tmp/hsperfdata_foo&lt;/b&gt; where a 32KB data file with the PID as name is created for each JVM.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-sqYv5tN6wVM/Tp7r41S922I/AAAAAAAAA2E/POue1T6fXiw/s1600/screenshot_215.png" imageanchor="1"&gt;&lt;img border="0" height="221" src="http://1.bp.blogspot.com/-sqYv5tN6wVM/Tp7r41S922I/AAAAAAAAA2E/POue1T6fXiw/s320/screenshot_215.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Back to our problem. After the restart, some of the files that should have been removed when the JVM was killed were still there, so this was giving the monitoring process a wrong PID and it couldn't connect to the JVM and do its magic.&lt;br /&gt;&lt;br /&gt;Solution: remove the unused files and everything works as expected.&lt;br /&gt;&lt;br /&gt;So, the next time you need to know all the JVM running on your system, remember this: &lt;i&gt;$ls /tmp/hsperfdata_*/&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3307155102524577373?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3307155102524577373/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/10/javas-ghost-jvms.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3307155102524577373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3307155102524577373'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/10/javas-ghost-jvms.html' title='Java&apos;s Ghost JVMs'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-sqYv5tN6wVM/Tp7r41S922I/AAAAAAAAA2E/POue1T6fXiw/s72-c/screenshot_215.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-4089777140034034548</id><published>2011-10-08T18:35:00.000+01:00</published><updated>2011-12-05T20:23:03.546Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='curl'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='put'/><category scheme='http://www.blogger.com/atom/ns#' term='post'/><category scheme='http://www.blogger.com/atom/ns#' term='jongo'/><category scheme='http://www.blogger.com/atom/ns#' term='get'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='delete'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><title type='text'>RESTing with Jongo</title><content type='html'>For the last few weekends and as part of a week of holidays where I had to stay at home taking care of my convalescent wife I started a project called &lt;a href="http://code.google.com/p/jongo/"&gt;Jongo&lt;/a&gt; which is a RESTful interface for JDBC that allows any application to directly access a RDBMS using the different HTTP methods. The idea came from working with &lt;a href="http://couchdb.apache.org/"&gt;CouchDB's&lt;/a&gt;&amp;nbsp;RESTful JSON API but using the ability of Java's JDBC to be database independent.&lt;br /&gt;&lt;br /&gt;So what does all this gibberish means? To put it in a simple way, you can, for example, develop JavaScript only applications with a database&amp;nbsp;back-end&amp;nbsp;without doing any server side development.&lt;br /&gt;&lt;br /&gt;For example, say you have a table with some users and you want to GET the first one:&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="pln" style="color: black;"&gt;$ curl &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;-&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;X GET &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"http://localhost:8080/jongo/user/1"&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #666600;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="str" style="color: #008800;"&gt;&lt;span class="Apple-style-span" style="background-color: white; color: black; font-family: arial, sans-serif; font-size: 13px; white-space: normal;"&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="pun" style="color: #666600;"&gt;{&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"success"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;true&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"count"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="lit" style="color: #006666;"&gt;1&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"resource"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"user"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"response"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:[{&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"birthday"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"null"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"credit"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"45.00"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"lastupdate"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"null"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"name"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"foo user"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"age"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="lit" style="color: #006666;"&gt;30&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"id"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="lit" style="color: #006666;"&gt;4&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;}]}&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;If you want to INSERT a new user, you would POST it with:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px; white-space: normal;"&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="pln" style="color: black;"&gt;$curl &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;-&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;X POST &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;-&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;d &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;'{"name":"foo user", "age":30, "credit":45.0}'&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"http://localhost:8080/jongo/user"&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;{&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"success"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;true&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"response"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:[{}]}&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Since the default format is JSON, we provide a JSON object or an array of JSON objects. This will be formatted to native SQL values and inserted in the database as new user.&lt;br /&gt;&lt;br /&gt;To UPDATE an user, you would perform a PUT request with the new values:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="pln" style="color: black;"&gt;$ curl &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;-&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;X PUT &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;-&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;d &amp;nbsp;&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;'{"name":"user change", "age":34}'&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"http://localhost:8080/jongo/user/4"&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;{&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"success"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;true&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"response"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:[{}]}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And finally, the DELETE:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"&gt;&lt;span class="pln" style="color: black;"&gt;$ curl &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;-&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;X DELETE &lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"http://localhost:8080/jongo/user/4"&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;{&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"success"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;true&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;"response"&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:[{}]}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I hope this explains a little what a RESTful webservice is and how Jongo helps on publishing your RDBMS without any server-side development.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-4089777140034034548?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/4089777140034034548/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/10/resting-with-curl.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4089777140034034548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4089777140034034548'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/10/resting-with-curl.html' title='RESTing with Jongo'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-697274119661773334</id><published>2011-10-05T11:40:00.000+01:00</published><updated>2011-10-05T14:49:21.372+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='slf4j'/><category scheme='http://www.blogger.com/atom/ns#' term='template'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='logback'/><title type='text'>My Logback.xml template</title><content type='html'>This is a simple working XML configuration to start using &lt;a href="http://logback.qos.ch/"&gt;Logback&lt;/a&gt; on your Java projects as fast as possible:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: navy;"&gt;&amp;lt;?xml&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;version&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"1.0"&lt;/span&gt; &lt;span style="color: #009900;"&gt;encoding&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"UTF-8"&lt;/span&gt;&lt;b&gt;&lt;span style="color: navy;"&gt;?&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;configuration&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;debug&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"false"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;br /&gt;  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;&amp;lt;!-- Console --&amp;gt;&lt;/span&gt;&lt;/i&gt;  &lt;br /&gt;    &lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;appender&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"S"&lt;/span&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.ConsoleAppender"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;encoder&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;pattern&amp;gt;&lt;/span&gt;&lt;/b&gt;%d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/pattern&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/encoder&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;&amp;lt;!-- HTML Rolling Appender --&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;appender&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"H"&lt;/span&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.rolling.RollingFileAppender"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;file&amp;gt;&lt;/span&gt;&lt;/b&gt;logs/jongo.html&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/file&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;encoder&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.encoder.LayoutWrappingEncoder"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;layout&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.classic.html.HTMLLayout"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;            &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;pattern&amp;gt;&lt;/span&gt;&lt;/b&gt;%msg%n&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/pattern&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/encoder&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rollingPolicy&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.rolling.FixedWindowRollingPolicy"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;fileNamePattern&amp;gt;&lt;/span&gt;&lt;/b&gt;logs/jongo.html.%i&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/fileNamePattern&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;minIndex&amp;gt;&lt;/span&gt;&lt;/b&gt;1&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/minIndex&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;maxIndex&amp;gt;&lt;/span&gt;&lt;/b&gt;3&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/maxIndex&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/rollingPolicy&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;triggeringPolicy&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;MaxFileSize&amp;gt;&lt;/span&gt;&lt;/b&gt;1024KB&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/MaxFileSize&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/triggeringPolicy&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;i&gt;&lt;span style="color: #9a1900;"&gt;&amp;lt;!-- Plain Text Rolling Appender --&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;appender&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"R"&lt;/span&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.rolling.RollingFileAppender"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;Append&amp;gt;&lt;/span&gt;&lt;/b&gt;true&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/Append&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;File&amp;gt;&lt;/span&gt;&lt;/b&gt;logs/jongo.log&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/File&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;encoder&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;pattern&amp;gt;&lt;/span&gt;&lt;/b&gt;%d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/pattern&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/encoder&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rollingPolicy&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;class&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;fileNamePattern&amp;gt;&lt;/span&gt;&lt;/b&gt;logs/jongo.log.%d{yyyy-MM-dd}&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/fileNamePattern&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;      &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;maxHistory&amp;gt;&lt;/span&gt;&lt;/b&gt;30&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/maxHistory&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/rollingPolicy&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/appender&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;logger&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"org.w3c.tidy"&lt;/span&gt; &lt;span style="color: #009900;"&gt;level&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"OFF"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;logger&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"ch.qos"&lt;/span&gt; &lt;span style="color: #009900;"&gt;level&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"OFF"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;logger&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"org.slf4j"&lt;/span&gt; &lt;span style="color: #009900;"&gt;level&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"OFF"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;root&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;level&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"DEBUG"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;appender-ref&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;ref&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"S"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;&amp;lt;!--    &amp;lt;appender-ref ref="H"/&amp;gt;--&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;&amp;lt;!--    &amp;lt;appender-ref ref="R"/&amp;gt;--&amp;gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Simply copy/paste this to your logback.xml file and it should work but you should modify it to make it work as you please.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-697274119661773334?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/697274119661773334/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/10/my-logbackxml-template.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/697274119661773334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/697274119661773334'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/10/my-logbackxml-template.html' title='My Logback.xml template'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6357025020654810825</id><published>2011-09-12T11:30:00.003+01:00</published><updated>2011-09-12T11:30:44.709+01:00</updated><title type='text'>Grails and Tomcat 7 Datasource</title><content type='html'>This should be fast and easy. You want a shared datasource on your Tomcat 7 server, which you can change without deploying a new Grails war and that is shared between all your Grails applications on this same Tomcat server.&lt;br /&gt;&lt;br /&gt;You have to configure your &lt;b&gt;&lt;span style="color: #38761d;"&gt;DataSource.groovy&lt;/span&gt;&lt;/b&gt; file with this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="background-color: white; color: #134f5c; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;production{&lt;br /&gt;&amp;nbsp; &amp;nbsp; pooled = false&lt;br /&gt;&amp;nbsp; &amp;nbsp; dbCreate = "update"&lt;br /&gt;&amp;nbsp; &amp;nbsp; jndiName = "java:comp/env/&lt;/span&gt;&lt;span style="background-color: white; color: #b45f06; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;jdbc/MyGrailsDS&lt;/span&gt;&lt;span style="background-color: white; color: #134f5c; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;"&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Generate your war, place it for deployment and go configure the &lt;span style="color: #38761d;"&gt;&lt;b&gt;conf/context.xml&lt;/b&gt;&lt;/span&gt; file on your Tomcat server.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;Resource name="&lt;span style="background-color: white;"&gt;&lt;span style="color: #e69138;"&gt;jdbc/MyGrailsDS&lt;/span&gt;&lt;/span&gt;" auth="Container" type="javax.sql.DataSource"&amp;nbsp;username="abc" password="abc" driverClassName="com.mysql.jdbc.Driver"&amp;nbsp;url="jdbc:mysql://localhost:3306/my_grails_schema"/&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Start your Tomcat 7 server and enjoy. Now you can change the database your applications point at by simply changing the configuration on the context.xml file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6357025020654810825?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6357025020654810825/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/09/grails-and-tomcat-7-datasource.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6357025020654810825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6357025020654810825'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/09/grails-and-tomcat-7-datasource.html' title='Grails and Tomcat 7 Datasource'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2048903964816387852</id><published>2011-06-09T15:49:00.000+01:00</published><updated>2011-06-09T15:49:09.144+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vino'/><category scheme='http://www.blogger.com/atom/ns#' term='vnc'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu Black Screen over VNC</title><content type='html'>Trying to share your desktop with Ubuntu and when you connect to it a black screen is shown but you can see control taken over it?&lt;br /&gt;&lt;br /&gt;Disable visual effects in System-&gt; Preferences-&gt; Appearance-&gt; Visual Effects-&gt; None&lt;br /&gt;&lt;br /&gt;Easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2048903964816387852?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2048903964816387852/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/06/ubuntu-black-screen-over-vnc.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2048903964816387852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2048903964816387852'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/06/ubuntu-black-screen-over-vnc.html' title='Ubuntu Black Screen over VNC'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7892402906572854484</id><published>2011-05-12T16:24:00.000+01:00</published><updated>2011-05-13T21:27:21.061+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='jconsole'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Monitor Tomcat/JBoss served connections</title><content type='html'>Say you want to monitor how many connections each of your JBoss/Tomcat servers are serving, because, you might want to make sure load balancing is working correctly. This can be accomplished by reading this information from an MBean, in this case the GlobalRequestProcessor.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-C1Rc3PT9At4/Tcv8uts89iI/AAAAAAAAAzg/bWTQk216TUA/s1600/screenshot_179.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="260" src="http://4.bp.blogspot.com/-C1Rc3PT9At4/Tcv8uts89iI/AAAAAAAAAzg/bWTQk216TUA/s400/screenshot_179.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;jconsole screenshot of a jboss jvm&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The image speaks by itself. So, depending on how your Tomcat server is being accessed, you can count the number of served requests it has processed and many more data which could become useful someday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7892402906572854484?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7892402906572854484/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/05/monitor-tomcatjboss-served-connections.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7892402906572854484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7892402906572854484'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/05/monitor-tomcatjboss-served-connections.html' title='Monitor Tomcat/JBoss served connections'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-C1Rc3PT9At4/Tcv8uts89iI/AAAAAAAAAzg/bWTQk216TUA/s72-c/screenshot_179.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1561835630668497774</id><published>2011-04-13T13:10:00.001+01:00</published><updated>2011-04-13T13:11:14.360+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='daemon'/><title type='text'>Java Daemon</title><content type='html'>Here's a little Bash script to run any Java application as a daemon. The only change you'll have to implement in your Java application is a handler for UNIX kill signals. Something like this:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;    Signal&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;handle&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Signal&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"INT"&lt;/span&gt;&lt;span style="color: #990000;"&gt;),&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;SignalHandler&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;handle&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;Signal&lt;/span&gt; sig&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;exit&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;10&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;That's an example, handle exceptions and other signals properly.&lt;br /&gt;Now that your application is ready to handle a signal, be sure to be very special with the signal 10 and exit with code 10. Why 10? Read the kill manual page and you'll see there are no standard signals with this value.&lt;br /&gt;&lt;br /&gt;Here's the Bash code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;#!/bin/bash&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;#&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Startup Script&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;JAVA_HOME&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"/opt/jre1.6.0_18/"&lt;/span&gt;&lt;br /&gt;runnable&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"com.test.TestApplication"&lt;/span&gt;&lt;br /&gt;pid&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;""&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: black;"&gt;do_start&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; &lt;span style="color: #990000;"&gt;!&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;d &lt;span style="color: red;"&gt;"${JAVA_HOME}"&lt;/span&gt; &lt;span style="color: #990000;"&gt;]&lt;/span&gt; &lt;span style="color: #990000;"&gt;;&lt;/span&gt; then&lt;br /&gt;        echo &lt;span style="color: red;"&gt;"${JAVA_HOME} Directory doesn't exist."&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;exit&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; &lt;span style="color: #990000;"&gt;!&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;x&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;"${JAVA_HOME}/bin/java"&lt;/span&gt; &lt;span style="color: #990000;"&gt;]&lt;/span&gt; &lt;span style="color: #990000;"&gt;;&lt;/span&gt; then&lt;br /&gt;            echo &lt;span style="color: red;"&gt;"Java binary error: not found or not executable"&lt;/span&gt;&lt;br /&gt;            &lt;b&gt;&lt;span style="color: blue;"&gt;exit&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;br /&gt;        fi&lt;br /&gt;    fi&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;local&lt;/span&gt;&lt;/b&gt; path&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"lib/*"&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;local&lt;/span&gt;&lt;/b&gt; opts&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"-Ddebug.level=INFO"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Launch the process&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;local&lt;/span&gt;&lt;/b&gt; exit_code&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: #993399;"&gt;10&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; &lt;span style="color: #009900;"&gt;$exit_code&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;eq&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #993399;"&gt;10&lt;/span&gt; &lt;span style="color: #990000;"&gt;];&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;"${JAVA_HOME}/bin/java"&lt;/span&gt; $&lt;span style="color: red;"&gt;{&lt;/span&gt;opts&lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;cp &lt;span style="color: red;"&gt;"${path}"&lt;/span&gt; $&lt;span style="color: red;"&gt;{&lt;/span&gt;runnable&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;        exit_code&lt;span style="color: #990000;"&gt;=&lt;/span&gt;$&lt;span style="color: #990000;"&gt;?&lt;/span&gt;&lt;br /&gt;    done&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: black;"&gt;do_stop&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;    &lt;/span&gt;&lt;/tt&gt;&lt;tt style="color: blue;"&gt;&lt;tt&gt;&lt;b&gt;getPID&lt;/b&gt;&lt;/tt&gt;&lt;/tt&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;kill&lt;/span&gt;&lt;/b&gt; $&lt;span style="color: red;"&gt;{&lt;/span&gt;pid&lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;/dev/&lt;/span&gt;null &lt;span style="color: #993399;"&gt;2&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; echo &lt;span style="color: red;"&gt;"Stoping process ${pid}"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: black;"&gt;do_status&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;    &lt;/span&gt;&lt;/tt&gt;&lt;tt style="color: blue;"&gt;&lt;tt&gt;&lt;b&gt;getPID&lt;/b&gt;&lt;/tt&gt;&lt;/tt&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;kill&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;&lt;span style="color: #993399;"&gt;0&lt;/span&gt; $&lt;span style="color: red;"&gt;{&lt;/span&gt;pid&lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;/dev/&lt;/span&gt;null &lt;span style="color: #993399;"&gt;2&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; echo &lt;span style="color: red;"&gt;"Process is running"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: black;"&gt;do_restart&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;    &lt;/span&gt;&lt;/tt&gt;&lt;tt style="color: blue;"&gt;&lt;tt&gt;&lt;b&gt;getPID&lt;/b&gt;&lt;/tt&gt;&lt;/tt&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;kill&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;&lt;span style="color: #993399;"&gt;10&lt;/span&gt; $&lt;span style="color: red;"&gt;{&lt;/span&gt;pid&lt;span style="color: red;"&gt;}&lt;/span&gt;  &lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;/dev/&lt;/span&gt;null &lt;span style="color: #993399;"&gt;2&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; echo &lt;span style="color: red;"&gt;"Restarting"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: black;"&gt;getPID&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# not the best, but works on most linux&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;    pid&lt;span style="color: #990000;"&gt;=&lt;/span&gt;$&lt;span style="color: #990000;"&gt;(&lt;/span&gt; ps &lt;span style="color: #990000;"&gt;-&lt;/span&gt;ef &lt;span style="color: #990000;"&gt;|&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;grep&lt;/span&gt;&lt;/b&gt;  $&lt;span style="color: red;"&gt;{&lt;/span&gt;runnable&lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;grep&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;v &lt;b&gt;&lt;span style="color: blue;"&gt;grep&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;|&lt;/span&gt; awk &lt;span style="color: red;"&gt;'{ print $2 }'&lt;/span&gt; &lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;case $&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt; in&lt;br /&gt;    start&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        do_start&lt;br /&gt;    &lt;span style="color: #990000;"&gt;;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    stop&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        do_stop&lt;br /&gt;    &lt;span style="color: #990000;"&gt;;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    status&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        do_status&lt;br /&gt;    &lt;span style="color: #990000;"&gt;;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    nohup&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #990000;"&gt;        # I really like this hack&amp;nbsp;&lt;/span&gt;&lt;br /&gt;        nohup &lt;span style="color: #009900;"&gt;$0&lt;/span&gt; start &lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: red;"&gt;/dev/&lt;/span&gt;null &lt;span style="color: #993399;"&gt;2&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;amp;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;;;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    restart&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        do_restart&lt;br /&gt;    &lt;span style="color: #990000;"&gt;;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;*)&lt;/span&gt;&lt;br /&gt;        echo &lt;span style="color: red;"&gt;"Usage: $0 start|nohup|restart|stop|status"&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;exit&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;;;&lt;/span&gt;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;exit&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #993399;"&gt;0&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;I believe the script is pretty straight forward. Cool thing is that if you use &lt;b&gt;start&lt;/b&gt;, you will run your application normally, but using the &lt;b&gt;nohup&lt;/b&gt; option, it will call &lt;b&gt;nohup&lt;/b&gt; on the script and run itself in daemon mode. Now, the only way to stop this process is to call the &lt;b&gt;stop&lt;/b&gt; option or directly kill it. Also, if your process somehow listens for any event, you can implement a special one which allows the process to restart itself. For example, if your application is a web service, you can call &lt;i&gt;curl http://localhost/restart&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1561835630668497774?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1561835630668497774/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/04/java-daemon.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1561835630668497774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1561835630668497774'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/04/java-daemon.html' title='Java Daemon'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2962969639601065037</id><published>2011-03-02T15:54:00.000Z</published><updated>2011-03-02T15:54:53.547Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='sts'/><category scheme='http://www.blogger.com/atom/ns#' term='grooy'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Groovy Conflicts with Grails</title><content type='html'>If you get this error:&lt;br /&gt;&lt;blockquote&gt;Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.codehaus.groovy.control.SourceUnit.getSource()Lorg/codehaus/groovy/control/io/ReaderSource;&lt;/blockquote&gt;Check your WEB-INF/lib folder for older version of Groovy. In my case, this happened after installing some plugins using the STS plugin manager.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2962969639601065037?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2962969639601065037/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/03/groovy-conflicts-with-grails.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2962969639601065037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2962969639601065037'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/03/groovy-conflicts-with-grails.html' title='Groovy Conflicts with Grails'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1252017271008949374</id><published>2011-02-16T16:31:00.001Z</published><updated>2011-02-16T16:37:25.239Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='hasMany'/><category scheme='http://www.blogger.com/atom/ns#' term='delete'/><category scheme='http://www.blogger.com/atom/ns#' term='gorm'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails hasMany Delete</title><content type='html'>Suppose the following:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;Group{&lt;/span&gt;&lt;br /&gt;    String name&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&lt;/b&gt; hasMany &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt;users:User]&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;User{&lt;/span&gt;&lt;br /&gt;    String name&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;This means, you have lots of Users for some Group, but also a User might have other Groups, so can't use a "belongsTo". To delete a Group is really easy:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: teal;"&gt;def&lt;/span&gt; b &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;Group.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;0&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;b&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;delete&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;flush&lt;span style="color: #990000;"&gt;:&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;On the other hand, you might want to delete a User, but not the Group:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: teal;"&gt;def&lt;/span&gt; b &lt;span style="color: #990000;"&gt;=&lt;/span&gt; User&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;0&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;b&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;delete&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;flush&lt;span style="color: #990000;"&gt;:&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;This will throw a lot of exceptions from Hibernate and JDBC. How are you supposed to do it? Well, first of all, you'll need a way to get a Group for a given User, but since "users" is transitive, you can't do something like &lt;b&gt;Group.findByUser(user)&lt;/b&gt; so go ahead and add the following code to your Group class:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Group&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;findByUser&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;User&lt;/span&gt; user&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;def&lt;/span&gt; criteria &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Group&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;createCriteria&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;def&lt;/span&gt; result &lt;span style="color: #990000;"&gt;=&lt;/span&gt; criteria&lt;span style="color: #990000;"&gt;.&lt;/span&gt;get &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        users &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;b&gt;&lt;span style="color: black;"&gt;idEq&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;user&lt;span style="color: #990000;"&gt;.&lt;/span&gt;id&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; result&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;Now, go to your &lt;i&gt;UserController delete&lt;/i&gt; method and add the following&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;userInstance&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: teal;"&gt;AlertGroup&lt;/span&gt; g &lt;span style="color: #990000;"&gt;=&lt;/span&gt; Group&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;findByUser&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;userInstance&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;g&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            g&lt;span style="color: #990000;"&gt;.&lt;/span&gt;users&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;remove&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(userInstance)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;        userInstance&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;delete&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;flush&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #990000;"&gt;...&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;The clear call will empty the references in the current object so you don't get any trouble.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1252017271008949374?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1252017271008949374/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/02/grails-hasmany-delete.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1252017271008949374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1252017271008949374'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/02/grails-hasmany-delete.html' title='Grails hasMany Delete'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6994126514680081720</id><published>2011-02-10T18:37:00.000Z</published><updated>2011-02-10T18:37:40.257Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='coffescript'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><title type='text'>CoffeScript and Canvas</title><content type='html'>I keep playing with CoffeeScript, and what better way than using canvas!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;/b&gt;CoffeScript Canvas&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;script&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;src&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"coffee-script.js"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;script&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;type&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"text/coffeescript"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;            draw &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt; &lt;br /&gt;                canvas &lt;span style="color: #990000;"&gt;=&lt;/span&gt; document&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;getElementById&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'coffee'&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; canvas&lt;span style="color: #990000;"&gt;.&lt;/span&gt;getContext&lt;br /&gt;                    ctx &lt;span style="color: #990000;"&gt;=&lt;/span&gt; canvas&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;getContext&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'2d'&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;                    ctx&lt;span style="color: #990000;"&gt;.&lt;/span&gt;fillStyle &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: red;"&gt;"rgb(200,0,0)"&lt;/span&gt;&lt;br /&gt;                    ctx&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;fillRect&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;10&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;10&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;55&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;50&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                    ctx&lt;span style="color: #990000;"&gt;.&lt;/span&gt;fillStyle &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: red;"&gt;"rgba(0, 0, 200, 0.5)"&lt;/span&gt;&lt;br /&gt;                    ctx&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;fillRect&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;30&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;30&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;55&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;50&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            &lt;b&gt;&lt;span style="color: black;"&gt;draw&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;style&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;type&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"text/css"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;            canvas &lt;span style="color: red;"&gt;{&lt;/span&gt; &lt;span style="color: blue;"&gt;border:&lt;/span&gt; &lt;i&gt;&lt;span style="color: #009900;"&gt;1px&lt;/span&gt;&lt;/i&gt; &lt;i&gt;&lt;span style="color: #009900;"&gt;solid&lt;/span&gt;&lt;/i&gt; &lt;i&gt;&lt;span style="color: #009900;"&gt;black&lt;/span&gt;&lt;/i&gt;; &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;canvas&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;id&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"coffee"&lt;/span&gt; &lt;span style="color: #009900;"&gt;width&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"150"&lt;/span&gt; &lt;span style="color: #009900;"&gt;height&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"150"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Well, it's basically the same as with JavaScript.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6994126514680081720?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6994126514680081720/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/02/coffescript-and-canvas.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6994126514680081720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6994126514680081720'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/02/coffescript-and-canvas.html' title='CoffeScript and Canvas'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2516366197058993881</id><published>2011-02-03T19:52:00.000Z</published><updated>2011-02-03T19:52:09.884Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='coffescript'/><title type='text'>CoffeeScript in 1, 2, 3...</title><content type='html'>Ok, this is very easy, but nowhere to be found on the &lt;a href="http://jashkenas.github.com/coffee-script/"&gt;CoffeeScript&lt;/a&gt; site and shows how easy it's to get started.&lt;br /&gt;I mean, really, why? If you're going to develop on Javascript, you don't want to "build" your code.&lt;br /&gt;So, all you need is some simple HTML and the following:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #3d85c6;"&gt;&amp;lt;script src="coffee-script.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br style="color: #3d85c6;" /&gt;&lt;span style="color: #3d85c6;"&gt;&amp;lt;script type="text/coffeescript"&amp;gt;&lt;/span&gt;&lt;br style="color: #3d85c6;" /&gt;&lt;span style="color: #3d85c6;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert "Hello CoffeeScript!"&lt;/span&gt;&lt;br style="color: #3d85c6;" /&gt;&lt;span style="color: #3d85c6;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;Now add the "coffee-script.js" file in your path, and open it with your browser. No servers, no compilers, no NodeJS and nothing to install.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2516366197058993881?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2516366197058993881/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/02/coffeescript-in-1-2-3.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2516366197058993881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2516366197058993881'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/02/coffeescript-in-1-2-3.html' title='CoffeeScript in 1, 2, 3...'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-9045633852941506409</id><published>2011-01-20T23:36:00.008Z</published><updated>2011-01-21T09:16:43.193Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='screen'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><title type='text'>Central GNU Screen/SSH Server</title><content type='html'>I'm not going to explain why screen is such a great tool because it's and there are many blogs who will tell you so. What I'm going to explain is how you can use screen to setup a central server to manage and monitor who connects to your servers and what do they do.&lt;br /&gt;Screen has the special ability that allows us to log and connect to running sessions. This becomes handy in our current objective: setting up a central server where all users must connect so they can connect to other servers.&lt;br /&gt;The idea is pretty basic and has lots of advantages:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No user management for each server&lt;/li&gt;&lt;li&gt;Users know only one, easily changed password for all servers&lt;/li&gt;&lt;li&gt;Greater control of user actions&lt;/li&gt;&lt;li&gt;Monitor unscheduled access&lt;/li&gt;&lt;li&gt;Log user activity&lt;/li&gt;&lt;/ul&gt;Of course, there are some disadvantages:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Single point of failure&lt;/li&gt;&lt;li&gt;Single point of entrance&lt;/li&gt;&lt;li&gt;Can become a pain when transfering files&lt;/li&gt;&lt;/ul&gt;First, we need to setup a single server with the following:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;SSH Client&lt;/li&gt;&lt;li&gt;GNU Screen&lt;/li&gt;&lt;li&gt;User account for each user (limit the user's group using quotas)&lt;/li&gt;&lt;li&gt;Common user account on each server you wish to connect to (i.e. foo)&lt;/li&gt;&lt;/ol&gt;You have your &lt;i&gt;screen server&lt;/i&gt;, and on each server you have a user (i.e. foo) with the same password (i.e. bar123). Now secure you SSH configuration by allowing access only from the &lt;i&gt;screen server&lt;/i&gt; to the &lt;b&gt;foo&lt;/b&gt; user (and &lt;i&gt;admin&lt;/i&gt; just in case):&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# /etc/hosts.allow&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;sshd&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;span style="color: #993399;"&gt;192.168&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;span style="color: #993399;"&gt;0.2&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&lt;/span&gt;&lt;span style="color: #993399;"&gt;255.255&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;span style="color: #993399;"&gt;255.0&lt;/span&gt;&lt;br /&gt;sshd&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;span style="color: #993399;"&gt;192.168&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;span style="color: #993399;"&gt;0.3&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&lt;/span&gt;&lt;span style="color: #993399;"&gt;255.255&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;span style="color: #993399;"&gt;255.0&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# /etc/hosts.deny&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;sshd&lt;span style="color: #990000;"&gt;:&lt;/span&gt; ALL&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# /etc/ssh/sshd_config&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;AllowUsers foo admin&lt;br /&gt;PermitRootLogin no&lt;/tt&gt;&lt;/pre&gt;Your users should be able now to:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Connect to the &lt;i&gt;screen server&lt;/i&gt; using &lt;tt&gt;someuser@screenserver&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;Connect to your servers only from the new &lt;i&gt;screen server&lt;/i&gt; using &lt;tt&gt;foo@webserver&lt;/tt&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Use some &lt;tt&gt;screen&lt;/tt&gt; magic&lt;/h2&gt;If you include &lt;tt&gt;screen&lt;/tt&gt; in this whole setup, you'll be able to log user activity in the servers by correctly configuring &lt;tt&gt;screen&lt;/tt&gt;. First, add the following configuration to /etc/screenrc:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Scrolling&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;defscrollback &lt;span style="color: #993399;"&gt;1500&lt;/span&gt;&lt;br /&gt;termcapinfo xterm&lt;span style="color: #990000;"&gt;*&lt;/span&gt; ti@&lt;span style="color: #990000;"&gt;:&lt;/span&gt;te@&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Detach on close&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;autodetach on&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Disable key binds&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind H echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow the user to disable logging&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind d echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow to detach&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind &lt;span style="color: #990000;"&gt;^&lt;/span&gt;d echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow to detach&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind c echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow to create&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind &lt;span style="color: #990000;"&gt;^&lt;/span&gt;c echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow to create&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind S echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow to split&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;bind &lt;span style="color: #990000;"&gt;:&lt;/span&gt; echo &lt;span style="color: red;"&gt;"Disabled"&lt;/span&gt; &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Don't allow to issue commands&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# no startup msg&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;startup_message off&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Logging&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;deflog on&lt;br /&gt;logtstamp on&lt;br /&gt;logfile &lt;span style="color: red;"&gt;/tmp/screen-logs/&lt;/span&gt;&lt;span style="color: #009900;"&gt;%t&lt;/span&gt;&lt;span style="color: #990000;"&gt;-&lt;/span&gt;&lt;span style="color: #009900;"&gt;%Y%m%d&lt;/span&gt;&lt;span style="color: #990000;"&gt;-&lt;/span&gt;&lt;span style="color: #009900;"&gt;%n&lt;/span&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;log&lt;/span&gt;&lt;/b&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;On each user's home folder, create an empty &lt;tt&gt;.screenrc&lt;/tt&gt; file. This file should be owned by root with read only permits (since you don't want the users to modify it). This way, no user will be able to override the general configuration.&lt;br /&gt;&lt;br /&gt;Next, download the &lt;a href="http://sites.google.com/site/monocaffe/home/mcm/manager.sh"&gt;manager.sh&lt;/a&gt; script and add your servers:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;servers&lt;span style="color: #990000;"&gt;=(&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;"foo@bar1"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;"foo@bar2"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;"foo@bar3"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;This script allows a user to select a server from the given list and launchs a ssh session inside a &lt;tt&gt;screen&lt;/tt&gt; session:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt; /usr/bin/screen -S user.bar1 -t user.bar1 /usr/bin/ssh foo@bar1 &lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Since you're controlling and monitoring all the &lt;tt&gt;screen&lt;/tt&gt; sessions, you can easily know what the users are doing on each server by watching the log files: &lt;tt&gt;user-20110116-0.log&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Well, I hope this is useful for someone else. Leave a comment for any suggestions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-9045633852941506409?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/9045633852941506409/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/01/im-not-going-to-explain-why-screen-is.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/9045633852941506409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/9045633852941506409'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/01/im-not-going-to-explain-why-screen-is.html' title='Central GNU Screen/SSH Server'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6090410636043049096</id><published>2011-01-18T17:51:00.003Z</published><updated>2011-01-18T17:52:53.812Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='tag'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='lib'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Adding Tags to your Tags</title><content type='html'>I'm working on a Plugin to allow for Grails to easily draw HTML5 Graphs using the &lt;a href="http://www.rgraph.net/"&gt;RGraph library&lt;/a&gt;. The problem with this plugin is that we have to provide a lot of attributes for any given tag to work, for example, the Rose Chart:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:rose&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"rosetest"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;title&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"Rose Chart Test"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;values&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"[1, 2, 3]"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;tooltips&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"['Fred', 'Rich', 'Alex']"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;zoom&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"true"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;width&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"500"&lt;/span&gt; &lt;span style="color: #009900;"&gt;height&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"500"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;The code for this tag was the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; rose &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;{&lt;/span&gt; attrs &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: black;"&gt;draw&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;new &lt;b&gt;&lt;span style="color: black;"&gt;Rose&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;attrs&lt;span style="color: #990000;"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;But this is what I wanted:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:rose&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;title&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"Rose Chart Test"&lt;/span&gt; &lt;span style="color: #009900;"&gt;zoom&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"true"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:attribute&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"rosetest2"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:attribute&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;values&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"[1, 2, 3,]"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:attribute&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;tooltips&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"['Fred', 'Rich', 'Alex']"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:attribute&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;width&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"500"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:attribute&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;height&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"500"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:rose&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;My objective is to be able to use a map given by the controller to draw the whole thing in three lines of code. But first, to acomplish this, we need to create a new tag named &lt;tt&gt;attribute&lt;/tt&gt; which saves the given attribute to the page scope:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; attribute &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;{&lt;/span&gt; attrs &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    this&lt;span style="color: #990000;"&gt;.&lt;/span&gt;pageScope&lt;span style="color: #990000;"&gt;.&lt;/span&gt;attrs &lt;span style="color: #990000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt; attrs&lt;br /&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Now we modify our tags to look like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; rose &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;{&lt;/span&gt; attrs&lt;span style="color: #990000;"&gt;,&lt;/span&gt; body &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    attrs &lt;span style="color: #990000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;initTag&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;body&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: black;"&gt;draw&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;new &lt;b&gt;&lt;span style="color: black;"&gt;Rose&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;attrs&lt;span style="color: #990000;"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;This new method &lt;tt&gt;initTag&lt;/tt&gt; is for DRY:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;initTag&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; body&lt;span style="color: #990000;"&gt;){&lt;/span&gt;&lt;br /&gt;    this&lt;span style="color: #990000;"&gt;.&lt;/span&gt;pageScope&lt;span style="color: #990000;"&gt;.&lt;/span&gt;attrs &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;[:]&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: black;"&gt;body&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; this&lt;span style="color: #990000;"&gt;.&lt;/span&gt;pageScope&lt;span style="color: #990000;"&gt;.&lt;/span&gt;attrs&lt;br /&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Here &lt;tt&gt;initTag&lt;/tt&gt; instantiates a new map in the &lt;i&gt;attrs&lt;/i&gt; key in the page scope. Then, the &lt;tt&gt;body&lt;/tt&gt; is executed, which continues processing the tags inside the &lt;i&gt;rose&lt;/i&gt; tag and reads all the &lt;i&gt;attribute&lt;/i&gt; tags. Each &lt;i&gt;attribute&lt;/i&gt; tag simply saves the given attributes to the scope. Finally, when all &lt;i&gt;attribute&lt;/i&gt; tags are read, &lt;tt&gt;initTag&lt;/tt&gt; method returns all the attributes to the tags &lt;i&gt;attrs&lt;/i&gt; variable, which is used to instantiate a new Rose object used to paint the JavaScript code.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;rosetestRGraphDraw&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt;&lt;/b&gt; rosetest &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; RGraph&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Rose&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'rosetest'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;2&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;3&lt;/span&gt;&lt;span style="color: #990000;"&gt;]);&lt;/span&gt;&lt;br /&gt;    rosetest&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Set&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'chart.zoom'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    rosetest&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Set&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'chart.width'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;500&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    rosetest&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Set&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'chart.tooltips'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"Fred"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: red;"&gt;"Rich"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: red;"&gt;"Alex"&lt;/span&gt;&lt;span style="color: #990000;"&gt;]);&lt;/span&gt;&lt;br /&gt;    rosetest&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Set&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'chart.title'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: red;"&gt;"Rose Chart Test"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    rosetest&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Set&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'chart.height'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;500&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    rosetest&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;Draw&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Now, this works, but what if I wanted to, instead of putting each attribute by it's own, to have the controller return a map with all the data I need and use the &lt;tt&gt;g:each&lt;/tt&gt; tag. Then, we need to modify the &lt;tt&gt;attribute&lt;/tt&gt; tag like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; attribute &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;{&lt;/span&gt; attrs &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; m &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;[:]&lt;/span&gt;&lt;br /&gt;    m&lt;span style="color: #990000;"&gt;.&lt;/span&gt;put attrs&lt;span style="color: #990000;"&gt;.&lt;/span&gt;name&lt;span style="color: #990000;"&gt;,&lt;/span&gt; attrs&lt;span style="color: #990000;"&gt;.&lt;/span&gt;value&lt;br /&gt;    this&lt;span style="color: #990000;"&gt;.&lt;/span&gt;pageScope&lt;span style="color: #990000;"&gt;.&lt;/span&gt;attrs &lt;span style="color: #990000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt; m&lt;br /&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;rose title&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"Rose Chart Test 2"&lt;/span&gt; zoom&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"true"&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;attribute name&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"name"&lt;/span&gt; value&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"rosetest2"&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;attribute name&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"values"&lt;/span&gt; value&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"[1, 2, 3]"&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;attribute name&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"tooltips"&lt;/span&gt; value&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"['Fred', 'Rich', 'Alex']"&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;attribute name&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"width"&lt;/span&gt; value&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"500"&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;attribute name&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"height"&lt;/span&gt; value&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"500"&lt;/span&gt;&lt;span style="color: #990000;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #990000;"&gt;&amp;lt;/&lt;/span&gt;rgraph&lt;span style="color: #990000;"&gt;:&lt;/span&gt;rose&lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;The HTML might not be so nice this way, but now we can do this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:rose&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;title&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"Rose Chart Test 2"&lt;/span&gt; &lt;span style="color: #009900;"&gt;zoom&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"true"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;g:each&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;in&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"${someMap}"&lt;/span&gt; &lt;span style="color: #009900;"&gt;var&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"${entry}"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;rgraph:attribute&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;name&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"${entry.key}"&lt;/span&gt; &lt;span style="color: #009900;"&gt;value&lt;/span&gt;&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: red;"&gt;"${entry.value}"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/g:each&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;lt;/rgraph:rose&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6090410636043049096?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6090410636043049096/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2011/01/adding-tags-to-your-tags.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6090410636043049096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6090410636043049096'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2011/01/adding-tags-to-your-tags.html' title='Adding Tags to your Tags'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-302368558808116062</id><published>2010-12-03T15:03:00.000Z</published><updated>2010-12-03T15:03:18.063Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails debug logging</title><content type='html'>There are two things about logging in Grails which can be a little pain. The first one is to activate debug logging in some domain or controller class during testing. To make this work, use the following with each class under testing:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mockLogging Foo, &lt;span style="color: #0b5394;"&gt;true&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Now, all the debug messages in you class Foo will be generated.&lt;br /&gt;&lt;br /&gt;The other thing which can be a pain, is enabling debug in general, and Hibernate debugging in particular. Well, not this time, since you have to only add the following to your Config.groovy file:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;log4j= {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; debug 'com.foo.app',&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'org.hibernate'&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;Yes, Grails is that easy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-302368558808116062?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/302368558808116062/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/12/grails-debug-logging.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/302368558808116062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/302368558808116062'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/12/grails-debug-logging.html' title='Grails debug logging'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-138698498417176896</id><published>2010-12-01T20:05:00.001Z</published><updated>2010-12-01T20:10:23.172Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><title type='text'>Video Streaming Linux/iPad</title><content type='html'>People like to complicate things a lot. I've been reading of ways to stream video to my iPad. When a solution starts with "Install Wine" I give up. Is not that I don't like Wine, it just feels dirty.&lt;br /&gt;Anyway, the problem is that Apple likes to do stupid stuff to put some crazy locks on hardware and software. I really like the iPad so I'm putting up with some of its problems, but this video streaming thing was getting on my nerves until I found &lt;a href="http://itunes.apple.com/us/app/oplayer-hd/id373236724?mt=8"&gt;OPlayer HD&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So, go to your computer and run a simple HTTP server with some Python magic:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$python -c "import SimpleHTTPServer;SimpleHTTPServer.test()"&lt;/div&gt;&lt;br /&gt;BTW, you should do this on a folder where you keep your movies.&lt;br /&gt;&lt;br /&gt;Now, install OPLayer and go to the web browser it has. Point it to your server: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;http://192.168.0.2:8000&lt;/span&gt; for example, and watch/download your movies.&lt;br /&gt;&lt;br /&gt;Cool!&lt;br /&gt;&lt;br /&gt;OPlayer also has a feature in which runs an HTTP server on the iPad. With this, you can upload your movies to the device from your computer, any computer.&lt;br /&gt;&lt;br /&gt;Very cool! &lt;br /&gt;&lt;br /&gt;On a final note, I was hoping this would be something VLC would bring, but what a disappointment. There's yxplayer, or something of the like, that is supposed to do the same thing. I've not tested it, I liked OPlayer, so I won't bother.&lt;br /&gt;&lt;br /&gt;Another thing, the battery drains like crazy when playing a video over the network, so&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-138698498417176896?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/138698498417176896/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/12/video-streaming-linuxipad.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/138698498417176896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/138698498417176896'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/12/video-streaming-linuxipad.html' title='Video Streaming Linux/iPad'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7721458232091374868</id><published>2010-11-20T12:25:00.000Z</published><updated>2010-11-20T12:25:52.267Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='enum'/><category scheme='http://www.blogger.com/atom/ns#' term='gorm'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails Enum</title><content type='html'>¿Soporta Groovy enums?&lt;br /&gt;&lt;br /&gt;Sí, como con cualquier objeto de Java, podemos acceder a ellos desde Groovy. Hacer que estos funcionen con Grails ya es un poco más complicado ya que tenemos que tener en cuenta el comportamiento de Hibernate al encontrarse un enum.&lt;br /&gt;&lt;br /&gt;Después de un poco de trial &amp;amp; error, finalmente logre una solución que se ajusta a lo que quería.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #7f0055; font-weight: bold;"&gt;public&lt;/span&gt; enum BookType{&lt;br /&gt;  EBOOK(&lt;span style="color: #2a00ff;"&gt;"eBook"&lt;/span&gt;),&lt;br /&gt;  PAPERBACK(&lt;span style="color: #2a00ff;"&gt;"PaperBack"&lt;/span&gt;),&lt;br /&gt;  HARD(&lt;span style="color: #2a00ff;"&gt;"Hard Cover"&lt;/span&gt;),&lt;br /&gt;  AUDIO(&lt;span style="color: #2a00ff;"&gt;"Audio Book"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #7f0055; font-weight: bold;"&gt;String&lt;/span&gt; type&lt;br /&gt;&lt;br /&gt;  BookType(&lt;span style="color: #7f0055; font-weight: bold;"&gt;String&lt;/span&gt; type){&lt;br /&gt;    &lt;span style="color: #7f0055; font-weight: bold;"&gt;this&lt;/span&gt;.type = type&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #7f0055; font-weight: bold;"&gt;static&lt;/span&gt; list() {&lt;br /&gt;    [EBOOK, PAPERBACK, HARD, AUDIO]&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Luego utilizamos este enum en nuestro modelo:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #7f0055; font-weight: bold;"&gt;class&lt;/span&gt; Book{&lt;br /&gt;  &lt;span style="color: #7f0055; font-weight: bold;"&gt;String&lt;/span&gt; name&lt;br /&gt;  BookType type&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #7f0055; font-weight: bold;"&gt;static&lt;/span&gt; constraints = {&lt;br /&gt;     type(nullable:&lt;span style="color: #7f0055; font-weight: bold;"&gt;false&lt;/span&gt;)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Lo mejor de esto es el comportamiento de Hibernate, que crea la tabla &lt;b&gt;book_type&lt;/b&gt; con la columna &lt;b&gt;type&lt;/b&gt; y enlaza los valores del enum con nuestro modelo. A continuación, podemos utilizar los valores de nuestro enum al crear un libro:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #7f0055;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #7f0055;"&gt;g:&lt;/span&gt;&lt;span style="color: #7f0055; font-weight: bold;"&gt;select&lt;/span&gt; name=&lt;span style="color: #2a00ff;"&gt;"bookType"&lt;/span&gt; id=&lt;span style="color: #2a00ff;"&gt;"bookType"&lt;/span&gt;&lt;br /&gt;from=&lt;span style="color: #2a00ff;"&gt;"${BookType.list()}"&lt;/span&gt; &lt;br /&gt;value=&lt;span style="color: #2a00ff;"&gt;"${fieldValue(bean: bookInstance, field: 'bookType')}"&lt;/span&gt; &lt;br /&gt;optionValue=&lt;span style="color: #2a00ff;"&gt;"type"&lt;/span&gt;&lt;span style="color: #7f0055;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7721458232091374868?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7721458232091374868/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/11/grails-enum.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7721458232091374868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7721458232091374868'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/11/grails-enum.html' title='Grails Enum'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-9198205905287217637</id><published>2010-10-06T22:33:00.000+01:00</published><updated>2010-10-06T22:33:56.105+01:00</updated><title type='text'>GUI vs CLI</title><content type='html'>Yesterday I was with a colleague who sadly, runs Windows 7. I was really trying to help him on setting up his development environment and at the end I was getting pretty frustrated by all the clicking and moving windows around. Anyway, this is not a rant against Windows. My colleague asked me why I felt more comfortable on the CLI. Easy to answer, it's faster... if you know what you're doing.&lt;br /&gt;&lt;br /&gt;To put some numbers behind my assertion, I started timing some tasks which I do daily:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Copying files and folders.&lt;/li&gt;&lt;li&gt;Moving files and folders.&lt;/li&gt;&lt;li&gt;Create symbolic links.&lt;/li&gt;&lt;li&gt;Edit text files.&lt;/li&gt;&lt;li&gt;Create folders&lt;/li&gt;&lt;/ul&gt;Pretty standard stuff everyone does daily on a computer.&lt;br /&gt;After I started timing some of this tasks and thinking about new ones, I came into the conclusion that this wasn't a fair contest, for the GUI. Some basic tasks can be easily done and quite fast (not as fast as in the CLI) but others are impossible. Any task which involved more than 3 iterations are mind numbing, like:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Finding a file in a list of compressed files.&lt;/li&gt;&lt;li&gt;Renaming a list of files.&lt;/li&gt;&lt;li&gt;Editing a bunch of image files.&lt;/li&gt;&lt;li&gt;And many more. &lt;/li&gt;&lt;/ul&gt;On the other hand, I've spent the last ten years working from a CLI pretty much all the time, so I've got some experience which makes me feel comfortable and productive. &lt;br /&gt;Anyway, &lt;a href="https://spreadsheets.google.com/ccc?key=0Ap3IHeZltVF-dDlsdS1hWDZRS1E2blB4UTVLVGt5VUE&amp;amp;hl=en&amp;amp;authkey=CNjFh7AL"&gt;here are my results&lt;/a&gt; which were timed, of course, on the CLI ($time read x)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-9198205905287217637?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/9198205905287217637/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/10/gui-vs-cli.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/9198205905287217637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/9198205905287217637'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/10/gui-vs-cli.html' title='GUI vs CLI'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1246214678354671825</id><published>2010-09-24T21:00:00.000+01:00</published><updated>2010-09-24T21:00:02.401+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='appleseed'/><category scheme='http://www.blogger.com/atom/ns#' term='social'/><category scheme='http://www.blogger.com/atom/ns#' term='diaspora'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='red'/><title type='text'>No más Facebook</title><content type='html'>Cuando un servicio como Facebook deja de funcionar durante un par de horas, mucha gente se pregunta ¿por qué? La respuesta sólo la saben ellos, pero queda clara una de las mayores debilidades de Facebook: centralizado.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Centralizado&lt;/span&gt;&lt;br /&gt;Esto significa que sólo existe en un sitio, una sola empresa lo controla y sólo una empresa se beneficia. Por lo que todas las decisiones son unilaterales por parte de una empresa, y las empresas tienen un único objetivo, ganar dinero. ¿Cómo gana dinero Facebook? No sólo con los pequeños anuncios que aparecen en la página, ya que en realidad, no hay muchos. El negocio está en vender los datos que poseen. Os recomiendo el documental "Revolución virtual: El precio de lo gratuito":&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"En este nuevo negocio de la información la moneda de cambio, no es tanto  el dinero físico como los datos y características del usuario potencial  del entorno web. Así vemos como nuestra privacidad se diluye, se  trafica con ella, en favor de los intereses económicos de las grandes  empresas virtuales."&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Diaspora&lt;/span&gt;&lt;br /&gt;Hace unos meses se hizo mucha publicidad sobre "&lt;a href="http://www.joindiaspora.com/"&gt;Diaspora&lt;/a&gt;" donde la idea principal, es conseguir crear un clon de Facebook que no este controlado por ninguna empresa. Para lograr este cometido, la única solución es utilizar un sistema distribuido.&lt;br /&gt;El código de Diaspora fue liberado hace poco, lo cual significa que todo el mundo se ha puesto a revisarlo y las conclusiones en principio no parecen nada prometedoras tanto por el lenguaje (Ruby) como por la arquitectura de servidores distribuidos y por muchos fallos de diseño y seguridad.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Appleseed, GNUSocial y Status.Net&lt;/span&gt;&lt;br /&gt;Sí, Diaspora no es la primera ni será la última competencia que va a intentar quitar el reinato de las redes sociales a Facebook, de hecho, el proyecto Appleseed, lleva funcionando y liberando versiones desde el año 2005. Status.Net es un clon de Twitter que funciona mucho mejor y Drumbeat es usado a diario por muchas personas detrás de Firefox asi que ¿por qué se ha hecho tanta publicidad a Diaspora habiendo tantos otros proyectos iguales y con más evolución? Supongo que será porque siempre que se escribe de Diaspora se trata de 4 chavales universitarios de NY contra la gigante Facebook, y esto vende muchas portadas.&lt;br /&gt;Aquí os dejo una lista de otros proyectos de redes sociales distribuidas y abiertas:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://zeldab.com/" target="_blank"&gt;zeldab&lt;/a&gt;&lt;br /&gt;&lt;a href="http://movim.eu/" target="_blank"&gt;movim&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ucentric.org/" target="_blank"&gt;ucentric&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ods.openlinksw.com/wiki/ODS" target="_blank"&gt;openlink data spaces&lt;/a&gt;&lt;br /&gt;&lt;a href="http://socialriver.org/" target="_blank"&gt;socialriver&lt;/a&gt;&lt;br /&gt;&lt;a href="https://wiki.mozilla.org/Drumbeat" target="_blank"&gt;mozilla's drumbeat&lt;/a&gt;&lt;br /&gt;&lt;a href="http://diso-project.org/" target="_blank"&gt;diso project&lt;/a&gt;&lt;br /&gt;&lt;a href="http://opensource.appleseedproject.org/" target="_blank"&gt;appleseed&lt;/a&gt;&lt;br /&gt;&lt;a href="http://openid.net/" target="_blank"&gt;higgin's project&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gnu.org/software/social/" target="_blank"&gt;gnusocial&lt;/a&gt;&lt;br /&gt;&lt;a href="http://smob.me/" target="_blank"&gt;smob&lt;/a&gt;&lt;br /&gt;&lt;a href="http://onesocialweb.org/" target="_blank"&gt;onesocialweb&lt;/a&gt;&lt;br /&gt;&lt;a href="http://status.net/" target="_blank"&gt;status.net&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Por último y para quienes deseen profundizar más en el tema, os dejo &lt;a href="http://www.w3.org/2005/Incubator/socialweb/wiki/FinalReport"&gt;éste reporte&lt;/a&gt; hecho para la W3C sobre las redes sociales y las posibles soluciones al problema que es Facebook para la privacidad. Ahora sólo falta que el FarmVille funcione sin Faceboo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1246214678354671825?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1246214678354671825/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/09/no-mas-facebook.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1246214678354671825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1246214678354671825'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/09/no-mas-facebook.html' title='No más Facebook'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5915141014165320099</id><published>2010-09-03T11:12:00.002+01:00</published><updated>2010-09-03T15:10:07.713+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='j2ee'/><category scheme='http://www.blogger.com/atom/ns#' term='permgen'/><category scheme='http://www.blogger.com/atom/ns#' term='jconsole'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><category scheme='http://www.blogger.com/atom/ns#' term='jvm'/><title type='text'>PermGen Out of Memory</title><content type='html'>Si te encuentras con este error es porque probablemente estés trabajando en una aplicación enterprise bastante grande. El principal problema de este error es que la JVM no muere, por lo que es cuestión de suerte saber que algún nodo de nuestro sistema ha dejado de funcionar.&lt;br /&gt;&lt;br /&gt;Intentemos entender lo que es el espacio PermGen. Primero debemos entender sobre los tres mecanismos de recolección del GC de Java:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Young&lt;/li&gt;&lt;li&gt;Tenured&lt;/li&gt;&lt;li&gt;Perm&lt;/li&gt;&lt;/ul&gt;Podéis leer más sobre estos mecanismos &lt;a href="http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#1.1.%20Generations%7Coutline"&gt;aquí&lt;/a&gt;. El Perm(anent) se caracteriza por responsabilizarse del código binario de clases y métodos. De esta forma se separan las instancias de los objetos, del código que los describe. Por lo que si la JVM llena este espacio por completo, no podremos crear instancias nuevas de objetos que no lo hayan sido anteriormente ya que sus firmas no podrán ser metidas en el PermGen.&lt;br /&gt;&lt;br /&gt;Dado que cualquier aplicación utiliza hoy en día Spring, Hibernate y cuarenta librerías más, el espacio para PermGen se puede llenar bastante rápido sino tenemos cuidado. Antes de solucionar este problema, vamos a intentar reproducirlo.&lt;br /&gt;&lt;br /&gt;Si nuestra aplicación se ejecuta en algún servidor de aplicaciones, lo más sencillo será reducir el tamaño máximo del PermGen al mínimo, tal que el servidor funcione, despliegue nuestra aplicación pero falle con la primera petición. Esto lo logramos variando los valores del argumento para la JVM MaxPermSize.&lt;br /&gt;&lt;br /&gt;A continuación vamos a medir esto utilizando &lt;i&gt;jconsole&lt;/i&gt; ya que es bastante gráfico. Lo primero será activar el servicio JMX de la JVM añadiendo los siguientes argumentos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;com.sun.management.jmxremote.port=12346"&lt;/li&gt;&lt;li&gt;com.sun.management.jmxremote.authenticate=false"&lt;/li&gt;&lt;li&gt;com.sun.management.jmxremote.ssl=false"&lt;/li&gt;&lt;/ul&gt;Arrancamos el servidor de aplicaciones y jconsole.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/TH_RzUaNK_I/AAAAAAAAAyM/CQv4O8GF1Qk/s1600/screenshot_088.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/TH_RzUaNK_I/AAAAAAAAAyM/CQv4O8GF1Qk/s320/screenshot_088.png" /&gt;&lt;/a&gt;&lt;/div&gt;A continuación realizamos una petición a nuestra aplicación y podemos ver como aumenta el uso del PermGen:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/TH_RiPdk-AI/AAAAAAAAAyE/-DdMskBhgV0/s1600/screenshot_089.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/TH_RiPdk-AI/AAAAAAAAAyE/-DdMskBhgV0/s320/screenshot_089.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Y continuamos hasta que alcanzamos el límite dado (64m):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/TH_SM-vdYhI/AAAAAAAAAyU/7SjqnIoSlhM/s1600/screenshot_090.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/TH_SM-vdYhI/AAAAAAAAAyU/7SjqnIoSlhM/s320/screenshot_090.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Después de esto, jconsole se desconecta y no podremos seguir analizando, aunque nuestra aplicación sigue funcionando y es posible que no se pierda funcionalidad, pero es inestable y en el momento en el que se intente crear una instancia de un objeto cuya "firma" no se encuentra en el PermGen, fallará.&lt;br /&gt;&lt;br /&gt;La solución inmediata a este problema es claramente aumentar la cantidad de memoria disponible para el PermGen y por ende, de la JVM o seguir analizando el problema. Volvamos a arrancar el servidor de aplicaciones y nos conectamos con jconsole. Hacemos una petición:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/TH_Sbb1KZVI/AAAAAAAAAyc/ND6sS6uOFrI/s1600/screenshot_091.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/TH_Sbb1KZVI/AAAAAAAAAyc/ND6sS6uOFrI/s320/screenshot_091.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;¡Casí! Vamos a pulsar el botón "Perform GC" a ver qué sucede:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/TH_SinYgCKI/AAAAAAAAAyk/hzrJ9U2c3xg/s1600/screenshot_092.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/TH_SinYgCKI/AAAAAAAAAyk/hzrJ9U2c3xg/s320/screenshot_092.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;¿Nada? ¿No se limpia el PermGen? Dado el nombre de este espacio de memoria era bastante obvio el resultado. Otra solución que encontramos en Internet es añadir la siguiente opción a la JVM &lt;b&gt;-XX:+CMSClassUnloadingEnabled&lt;/b&gt; veamos qué sucede:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/TH_TMdDodgI/AAAAAAAAAys/sB1h4bmhje0/s1600/screenshot_093.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/TH_TMdDodgI/AAAAAAAAAys/sB1h4bmhje0/s320/screenshot_093.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Nada, seguimos igual. Probemos con otra de las soluciones&lt;code style="font-family: inherit;"&gt; &lt;/code&gt;&lt;b&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="pun"&gt;-&lt;/span&gt;&lt;span class="pln"&gt;XX&lt;/span&gt;&lt;span class="pun"&gt;:+&lt;/span&gt;&lt;span class="typ"&gt;CMSPermGenSweepingEnabled&lt;/span&gt;&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/TH_TRZJX2OI/AAAAAAAAAy0/-2CuA30bFjc/s1600/screenshot_094.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/TH_TRZJX2OI/AAAAAAAAAy0/-2CuA30bFjc/s320/screenshot_094.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;De igual manera parece que no ha habido ningún cambio &lt;/span&gt;&lt;/code&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;favorable&lt;/span&gt;&lt;/code&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt; y el rendimiento se ha visto impactado negativamente y la misma petición ha tomado el triple de tiempo en ser procesada.&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Puede que sencillamente, nuestra aplicación en realidad necesita tal cantidad de memoria ya que utilizamos una cantidad ingente de librerías. Como se puede ver en el siguiente gráfico, después de una larga sesión de stress, la memoria PermGen se mantiene estable:&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/TICzuSKGSiI/AAAAAAAAAy8/eaUdqOof0GM/s1600/screenshot_100.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/TICzuSKGSiI/AAAAAAAAAy8/eaUdqOof0GM/s320/screenshot_100.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Esto es un servidor de aplicaciones el cual utiliza gran cantidad de librerías, contextos y distintas complejidades que pueden hacer que ciertas referencias se mantengan y eviten que el GC haga su trabajo, por lo que vamos a intentarlo con una aplicación J2SE. Esta es sencillamente un servicio REST que nos permite hacer búsquedas contra unos EJB's. Para hacer pruebas es muy útil y como podemos ver, su funcionamiento es similar al servidor de aplicaciones:&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/TIC5CCcegXI/AAAAAAAAAzE/l54VLCkOlC4/s1600/screenshot_101.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/TIC5CCcegXI/AAAAAAAAAzE/l54VLCkOlC4/s320/screenshot_101.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Se utiliza cierta cantidad de memoria del PermGen y después de varias peticiones, esta se mantiene estable, incluso después de añadir las posibles soluciones indicadas más arriba no hay ningún cambio.&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Dado que no hay un crecimiento continuo y que éste se detiene una vez hayamos pasado por todas las posibles combinaciones y usos de nuestra aplicación, es posible indicar un valor máximo para el PermGen que sea lo bastante como para sostener nuestras aplicaciones y justo en el consumo de memoria.&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Redesplespliegues&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Ahora hablemos de nuestro amigo el ClassLoader. Un servidor de aplicaciones como Tomcat o JBoss utilizan un artilugio que se encarga de cargar los ficheros .class de los JARs que componen nuestra aplicación.&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://docs.jboss.org/jbossas/jboss4guide/r2/html/images/Chap2-26.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://docs.jboss.org/jbossas/jboss4guide/r2/html/images/Chap2-26.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Los ClassLoader tienen una jerarquia, donde el servidor de aplicaciones tiene uno o varios "propios" y por debajo de estos tenemos a los que se crean para cada una de nuestras aplicaciones. Dentro de ésta jerarquía las clases de nuestro ClassLoader pueden utilizar las de arriba, pero no al revés. Por lo tanto, al crear un nuevo objeto, sucede lo siquiente:&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Cada objeto mantiene una referencia a su objeto .class.&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt; Cada objeto .class mantiene una referencia con su ClassLoader.&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Cada ClassLoader mantiene una referencia para cada clase que ha cargado.&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Dado que cada una de nuestras aplicaciones tiene su ClassLoader, al volver a desplegar se destruyen todas las referencias al anterior para crear uno nuevo. Pues va a ser que no:&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/TIC-kppuxPI/AAAAAAAAAzM/Q0MY7kiP9zY/s1600/screenshot_102.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/TIC-kppuxPI/AAAAAAAAAzM/Q0MY7kiP9zY/s320/screenshot_102.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;El ClassLoader vuelve a ser creado y por ende todas las referencias a clases antiguas se pierden y se crean nuevamente, pero no se realiza ninguna limpieza del PermGen... ever! Si continuamos redesplegando nuestra aplicación y haciendo peticiones, volveremos a quedarnos sin Perm.&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Incluso si eliminamos el despliegue, el Perm no es liberado.&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Soluciones&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Podemos concluir que el PermGen nunca se libera de forma significativa y que debemos controlar su uso siguiendo estos consejos:&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;La solución más rápida es aumentar su tamaño máximo.&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Ordenar y desarrollar nuestras aplicaciones de tal forma que se maximice el uso de las librerías provistas por el servidor de aplicaciones.&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Utilizar librerías comunes entre distintos proyectos y añadir dichas librerías al ClassLoader del servidor de aplicaciones. Un buen ejemplo son los conectores JDBC.&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Evitar referencias externas a nuestra aplicación a objetos internos de la misma (ClassLoader Leak).&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;span style="font-size: large;"&gt;Solución JRockit&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;JRockit, la máquina virtual de Oracle que era de BEA y utilizada por defecto por WebLogic no implementa un PermGen, por lo que este problema no existe y el GC recolecta de forma normal siempre que se eliminen las referencias, por lo que si la aplicación contiene un leak de este tipo, tendremos un Out of Memory del HEAP que son más fáciles de ver y monitorizar.&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Nota final&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;Mientras he estado realizando las distintas pruebas, he podido comprobar que al añadir la opción &lt;/span&gt;&lt;/code&gt;&lt;b&gt;&lt;code style="font-family: inherit;"&gt;&lt;span class="typ"&gt;CMSPermGenSweepingEnabled&lt;/span&gt;&lt;/code&gt;&lt;/b&gt; el rendimiento baja significativamente, incluso en una aplicacion J2SE por lo que no lo recomiendo para nada.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;Más información&lt;br /&gt;&lt;a href="http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang"&gt;http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html"&gt;http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.alessandroribeiro.com/?q=en/node/39"&gt;http://www.alessandroribeiro.com/?q=en/node/39&lt;/a&gt;&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/88235/how-to-deal-with-java-lang-outofmemoryerror-permgen-space-error"&gt;http://stackoverflow.com/questions/88235/how-to-deal-with-java-lang-outofmemoryerror-permgen-space-error&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java"&gt;http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://docs.jboss.org/jbossas/jboss4guide/r2/html/ch2.chapter.html%20"&gt;http://docs.jboss.org/jbossas/jboss4guide/r2/html/ch2.chapter.html &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-5915141014165320099?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/5915141014165320099/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/09/permgen-out-of-memory.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5915141014165320099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5915141014165320099'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/09/permgen-out-of-memory.html' title='PermGen Out of Memory'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/TH_RzUaNK_I/AAAAAAAAAyM/CQv4O8GF1Qk/s72-c/screenshot_088.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3361741575411012954</id><published>2010-08-05T13:13:00.000+01:00</published><updated>2010-08-05T13:13:34.808+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coffescript'/><category scheme='http://www.blogger.com/atom/ns#' term='oscon'/><title type='text'>No más JavaScript!</title><content type='html'>&lt;h2&gt;Bienvenido CoffeScript&lt;/h2&gt;Hace poco tuvo lugar OSCON y uno de los eventos más populares fue el &lt;a href="http://emerginglangs.com/"&gt;Emerging Languages Camp&lt;/a&gt; donde muchas personas muy inteligentes dieron distintas presentaciones sobre nuevos lenguajes de programación, buenas practicas, patrones, etc. Por lo que después de ver las distintas presentaciones obvias como la de PyPy y Clojure me llamo la atención &lt;a href="http://jashkenas.github.com/coffee-script/"&gt;CoffeScript&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;CoffeScript permite, utilizando una sintaxis muy parecida a la de Python, generar código JavaScript. Por ejemplo, una de las cosas que odio a muerte de JavaScript es su supuesto soporte de objetos. Veamos como se hace con CoffeScript:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; Animal&lt;br /&gt;  constructor&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;@name&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  move&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;meters&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    alert @name &lt;span style="color: #990000;"&gt;+&lt;/span&gt; &lt;span style="color: red;"&gt;" moved "&lt;/span&gt; &lt;span style="color: #990000;"&gt;+&lt;/span&gt; meters &lt;span style="color: #990000;"&gt;+&lt;/span&gt; &lt;span style="color: red;"&gt;" meters"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; Person extends Animal&lt;br /&gt;  move&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;meters&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: black;"&gt;super&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;meters&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  walk&lt;span style="color: #990000;"&gt;:&lt;/span&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;steps&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&amp;gt;&lt;/span&gt;&lt;br /&gt;    this&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;move&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;0.6&lt;/span&gt; &lt;span style="color: #990000;"&gt;*&lt;/span&gt; steps&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;me &lt;span style="color: #990000;"&gt;=&lt;/span&gt; new Person &lt;span style="color: red;"&gt;"Ale"&lt;/span&gt;&lt;br /&gt;me&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;walk&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;10&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;El código JavaScript generado es el siguiente:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt;&lt;/b&gt; Animal&lt;span style="color: #990000;"&gt;,&lt;/span&gt; Person&lt;span style="color: #990000;"&gt;,&lt;/span&gt; me&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt;&lt;/b&gt; __extends &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;child&lt;span style="color: #990000;"&gt;,&lt;/span&gt; parent&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt;&lt;/b&gt; ctor &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;span style="color: red;"&gt;{}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    ctor&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; parent&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    child&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;ctor&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;    child&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;constructor &lt;span style="color: #990000;"&gt;=&lt;/span&gt; child&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;&lt;/b&gt; parent&lt;span style="color: #990000;"&gt;.&lt;/span&gt;extended &lt;span style="color: #990000;"&gt;===&lt;/span&gt; &lt;span style="color: red;"&gt;"function"&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt; parent&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;extended&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;child&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    child&lt;span style="color: #990000;"&gt;.&lt;/span&gt;__superClass__ &lt;span style="color: #990000;"&gt;=&lt;/span&gt; parent&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;Animal &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;_a&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;name &lt;span style="color: #990000;"&gt;=&lt;/span&gt; _a&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;Animal&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;move &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;meters&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;alert&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;name &lt;span style="color: #990000;"&gt;+&lt;/span&gt; &lt;span style="color: red;"&gt;" moved "&lt;/span&gt; &lt;span style="color: #990000;"&gt;+&lt;/span&gt; meters &lt;span style="color: #990000;"&gt;+&lt;/span&gt; &lt;span style="color: red;"&gt;" meters"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;Person &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; Animal&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;apply&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; arguments&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: black;"&gt;__extends&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;Person&lt;span style="color: #990000;"&gt;,&lt;/span&gt; Animal&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;Person&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;move &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;meters&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; Person&lt;span style="color: #990000;"&gt;.&lt;/span&gt;__superClass__&lt;span style="color: #990000;"&gt;.&lt;/span&gt;move&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;call&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; meters&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;Person&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;prototype&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;walk &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;steps&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;move&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;0.6&lt;/span&gt; &lt;span style="color: #990000;"&gt;*&lt;/span&gt; steps&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;me &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Person&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Alex"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;me&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;walk&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: #993399;"&gt;10&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Ugh!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3361741575411012954?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3361741575411012954/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/08/no-mas-javascript.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3361741575411012954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3361741575411012954'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/08/no-mas-javascript.html' title='No más JavaScript!'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1309971514685992395</id><published>2010-07-03T18:19:00.000+01:00</published><updated>2010-07-03T18:19:00.959+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='cvs'/><category scheme='http://www.blogger.com/atom/ns#' term='vcs'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Sistemas de control de versiones (VCS)</title><content type='html'>Sistemas de control de Versiones&lt;br /&gt;&lt;br /&gt;No es posible llevar a buen puerto ningún proyecto sin &lt;br /&gt;la utilización de un sistema de control de versiones. &lt;br /&gt;Es mi opinión que todo desarrollador debe &lt;br /&gt;tener amplios conocimientos de al menos dos sistemas &lt;br /&gt;de control de versiones: funcionamiento, características &lt;br /&gt;y comandos más usados. No digo que todos deban ser expertos&lt;br /&gt;pero sí conocer el funcionamiento básico de estos, cosas como:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;checkout&lt;/li&gt;&lt;li&gt;commit&lt;/li&gt;&lt;li&gt;merge&lt;/li&gt;&lt;li&gt;update&lt;/li&gt;&lt;/ul&gt;Ahora mismo estamos en proceso de definir una nueva arquitectura&lt;br /&gt;para nuestro SCV y al ahondar en el estudio de los mismos, nos damos&lt;br /&gt;cuenta de la gran cantidad de opciones y sistemas que existen.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Existen ciertas características que diferencian a estos sistemas y que es&lt;br /&gt;conveniente explicar:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Atomic Commits&lt;/h2&gt;&lt;p&gt;Una de las características más importantes (y principal razón para&lt;br /&gt;eliminar CVS de todo sistema). Significa que al realizar un commit&lt;br /&gt;cada fichero es tratado de forma individual, por lo que si el proceso&lt;br /&gt;es interrumpido en cualquier momento, nuestro código no quedará en un&lt;br /&gt;estado inconsistente.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Renombrar o mover ficheros o directorios&lt;/h2&gt;&lt;p&gt;Al mover o renombrar un fichero o directorio se &lt;br /&gt;mantiene su historial de cambios.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Merge inteligente&lt;/h2&gt;&lt;p&gt;El sistema es capaz de realizar un merge inteligente de los cambios que sufre&lt;br /&gt;un fichero incluso después de que este haya sido renombrado.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: no&lt;/li&gt;&lt;li&gt;Git: no&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Copia de ficheros&lt;/h2&gt;&lt;p&gt;Al copiar un fichero, se mantiene la historia en ambas copias.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: no&lt;/li&gt;&lt;li&gt;Bazaar: no&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Clonado del repositorio&lt;/h2&gt;&lt;p&gt;Podemos clonar el repositorio a una copia local manteniendo&lt;br /&gt;la misma funcionalidad sin necesidad de permisos especiales&lt;br /&gt;en el servidor central.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no (CVSup)&lt;/li&gt;&lt;li&gt;Subversion: no (SVN::Mirror)&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Propagación de cambios&lt;/h2&gt;&lt;p&gt;Los cambios entre repositorios son posibles.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Permisos del repositorio&lt;/h2&gt;&lt;p&gt;Se permiten definir permisos de acceso a distintas partes del repositorio.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: limitado&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Conjuntos de cambios&lt;/h2&gt;&lt;p&gt;Podemos crear conjuntos de cambios que son relevantes entre sí en un&lt;br /&gt;único paquete atómico que puede ser cancelado o propagado como sea&lt;br /&gt;necesario.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: implicitos&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Historial de ficheros linea a linea (annotate, blame)&lt;/h2&gt;&lt;p&gt;Deseamos revisar los cambios realizados sobre cada línea de un fichero&lt;br /&gt;y quien lo ha realizado&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: sí&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: sí&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Trabajo en un directorio&lt;/h2&gt;&lt;p&gt;El sistema permite realizar checkouts y restringir commits&lt;br /&gt;de un único directorio.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: sí&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: no&lt;/li&gt;&lt;li&gt;Bazaar: no y sí&lt;/li&gt;&lt;li&gt;Mercurial: más o menos&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Mensajes de commit por fichero&lt;/h2&gt;&lt;p&gt;Se pueden asignar distintos mensajes de commit a cada fichero o conjunto.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: no&lt;/li&gt;&lt;li&gt;Subversion: no&lt;/li&gt;&lt;li&gt;Git: no&lt;/li&gt;&lt;li&gt;Bazaar: no (bzr-gtk sí)&lt;/li&gt;&lt;li&gt;Mercurial: no&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Integración con Eclipse&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;CVS: sí&lt;/li&gt;&lt;li&gt;Subversion: sí&lt;/li&gt;&lt;li&gt;Git: sí&lt;/li&gt;&lt;li&gt;Bazaar: en desarrollo&lt;/li&gt;&lt;li&gt;Mercurial: sí&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Estado de desarrollo&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;CVS: en mantenimiento. Nada nuevo&lt;/li&gt;&lt;li&gt;Subversion: desarrollo activo&lt;/li&gt;&lt;li&gt;Git: desarrollo activo&lt;/li&gt;&lt;li&gt;Bazaar: desarrollo activo&lt;/li&gt;&lt;li&gt;Mercurial: desarrollo activo&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Quienes usan cada uno&lt;/h2&gt;&lt;h3&gt;CVS&lt;/h3&gt;&lt;p&gt;SourceForge, GNU Emacs, SQLite, FreeBSD.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Subversion&lt;/h3&gt;&lt;p&gt;SourceForge, Google Code, Apache, KDE, GNOME, gcc, Python, Ruby, Samba, &lt;br /&gt;MPlayer, Mono, Django, Zope, vim y un largo etc.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Git&lt;/h3&gt;&lt;p&gt;GitHub, Linux kernel, VLC, Perl, RoR, Android, Wine, Xorg, Fedora, etc.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Bazaar&lt;/h3&gt;&lt;p&gt;Launchpad (Ubuntu y todos los proyectos en Launchpad), Apt, &lt;br /&gt;Squid, Mailman, MySQL, Monocaffe Connections Manager.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Mercurial&lt;/h3&gt;&lt;p&gt;BitBucket, Google Code, OpenJDK, MoinMoin, Aptitude, Xine, Xen, Mozilla, OpenSolaris, etc.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Claro que existen muchos otros VCS que los mostrados aquí, pero estos&lt;br /&gt;son los más populares, los mejor documentados y son software libre.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1309971514685992395?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1309971514685992395/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/07/sistemas-de-control-de-versiones-vcs.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1309971514685992395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1309971514685992395'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/07/sistemas-de-control-de-versiones-vcs.html' title='Sistemas de control de versiones (VCS)'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1357071386736758854</id><published>2010-06-23T22:29:00.000+01:00</published><updated>2010-06-23T22:29:12.139+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='helios'/><title type='text'>Eclipse Helios for Linux Developers</title><content type='html'>Hoy ha salido Eclipse Helios (3.6) incluyendo una serie de mejoras y ciertamente en mi caso no podía haber salido en mejor momento ya que llevo unas semanas retomando la programación con C utilizando Eclipse. Lo más llamativo en ésta ocasión es -aparte del desarrollo para J2EE6- es la versión para desarrolladores de Linux.&lt;br /&gt;&lt;br /&gt;En estos momentos se está descargando -sobre conexión 3G va algo lento- por lo que en algunos días habrá post con los detalles e intentar explicar un poco cómo puede Helios ayudar a facilitar -aun más- el desarrollo de aplicaciones para Linux.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1357071386736758854?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1357071386736758854/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/06/eclipse-helios-for-linux-developers.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1357071386736758854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1357071386736758854'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/06/eclipse-helios-for-linux-developers.html' title='Eclipse Helios for Linux Developers'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5517205961810908298</id><published>2010-06-16T21:53:00.000+01:00</published><updated>2010-06-16T21:53:00.090+01:00</updated><title type='text'>Java Template Engines, fight!</title><content type='html'>One of the greatest features Java provides for enterprise applications, are the many&lt;br /&gt;frameworks, libraries and tools provided by many third-party developers. In the web development&lt;br /&gt;front, we find many useful resources and today I'm gonna compare the most popular template&lt;br /&gt;systems a Java developer will find.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Basically, instead of using several HTML pages, you produce some templates which allows you&lt;br /&gt;to easily maintain most of the static content of a site without having to touch 40 different files. This&lt;br /&gt;way, if we want to modify the header of any site, simply by editing our header template, all the headers&lt;br /&gt;on our site will change.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A template system is comprimised of three main components:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Template Engine&lt;/li&gt;&lt;li&gt;Content Resource&lt;/li&gt;&lt;li&gt;Template Resource&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;You can find more information about the theory behind template systems in the &lt;a href="http://en.wikipedia.org/wiki/Web_template_system"&gt;Wikipedia Entry&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;J2EE Templates&lt;/h2&gt;Our candidates are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Freemarker&lt;/li&gt;&lt;li&gt;Velocity&lt;/li&gt;&lt;li&gt;StringTemplate&lt;/li&gt;&lt;li&gt;MVEL&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Freemarker&lt;/h3&gt;&lt;dl&gt;&lt;dt&gt;License:&lt;/dt&gt;&lt;dd&gt;BSD-style&lt;/dd&gt;&lt;dt&gt;Tested Version:&lt;/dt&gt;&lt;dd&gt;2.3.16&lt;/dd&gt;&lt;dt&gt;Dependencies:&lt;/dt&gt;&lt;dd&gt;None&lt;/dd&gt;&lt;dt&gt;Advantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;XML/HTML Templates (no need to learn a new language).&lt;/li&gt;&lt;li&gt;Very simple and straight to the point.&lt;/li&gt;&lt;li&gt;Plugins for lots of IDEs.&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt;&lt;dt&gt;Disadvantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;Latest version is almost 8 months old.&lt;/li&gt;&lt;li&gt;Simplicity comes at a price: not as powerful as the others.&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt; &lt;/dl&gt;As stated on the projects' site "It simply generates text" and it does it greatly. It was very easy to get to work with it and appart from the example below, I was able to generate&lt;br /&gt;SQL queries, HTML pages and Configuration files without a problem, from a file or from in-code templates. Also, having the ability to provide a &lt;b&gt;OutputWriter&lt;/b&gt; was great.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;FreemarkerExample&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; TemplateExample&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;Configuration&lt;/span&gt; config &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Configuration&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;Template&lt;/span&gt; freemarkerTemplate&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;OutputStreamWriter&lt;/span&gt; output &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;OutputStreamWriter&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: teal;"&gt;Map&amp;lt;String,String&amp;gt;&lt;/span&gt; dataModel &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; HashMap&lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #990000;"&gt;,&lt;/span&gt;String&lt;span style="color: #990000;"&gt;&amp;gt;();&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;FreemarkerExample&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;String&lt;/span&gt; user&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user &lt;span style="color: #990000;"&gt;=&lt;/span&gt; user&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;        dataModel&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;put&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"user"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;print&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            freemarkerTemplate &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;Template&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Template"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringReader&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Hello Freemarker, I'm ${user}&lt;/span&gt;&lt;span style="color: #cc33cc;"&gt;\n&lt;/span&gt;&lt;span style="color: red;"&gt;"&lt;/span&gt;&lt;span style="color: #990000;"&gt;),&lt;/span&gt; config&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;            freemarkerTemplate&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;process&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;dataModel&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;output&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;TemplateException&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;IOException&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;printFromFile&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            freemarkerTemplate &lt;span style="color: #990000;"&gt;=&lt;/span&gt; config&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;getTemplate&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"templates/freemarker.xml"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;            freemarkerTemplate&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;process&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;dataModel&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;output&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;TemplateException&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;IOException&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Velocity Engine&lt;/h3&gt;&lt;dl&gt;&lt;dt&gt;License:&lt;/dt&gt;&lt;dd&gt;Apache&lt;/dd&gt;&lt;dt&gt;Tested Version:&lt;/dt&gt;&lt;dd&gt;1.6.4&lt;/dd&gt;&lt;dt&gt;Dependencies:&lt;/dt&gt;&lt;dd&gt;None&lt;/dd&gt;&lt;dt&gt;Advantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;Very alive. This version is from a few weeks back.&lt;/li&gt;&lt;li&gt;The most powerful.&lt;/li&gt;&lt;li&gt;Most popular.&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt;&lt;dt&gt;Disadvantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;Ugly syntax.&lt;/li&gt;&lt;li&gt;Complex.&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt; &lt;/dl&gt;Without a doubt, the most powerful and complex project. If you take into account all the parts that conform Velocity (Engine, Tools, DVSL, Texen, Anakia, etc.) you have almost&lt;br /&gt;all of your needs covered. If you take only the Velocity Engine, you'll want to rip your eyes off because of the syntax. Also, the variable names are very easy to&lt;br /&gt;get lost inside complex pieces of code, and when we're talking about velocity, they will.&lt;br /&gt;&lt;br /&gt;I really wish they followed Python's way with the syntax. Instead of using all those counter intuitive pound signs. I mean, for any Unix/Linux user, those are comments&lt;br /&gt;and believe me, your mind won't get used to them, &lt;b&gt;ever!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;It was the hardest to get running and creating a new context can be a mess in big systems when developers start putting data in there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;VelocityExample&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; TemplateExample &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;VelocityEngine&lt;/span&gt; engine &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;VelocityEngine&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: teal;"&gt;VelocityContext&lt;/span&gt; context &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;VelocityContext&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;VelocityExample&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;String&lt;/span&gt; user&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user &lt;span style="color: #990000;"&gt;=&lt;/span&gt; user&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;        context&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;put&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"user"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;print&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: teal;"&gt;StringWriter&lt;/span&gt; writer &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringWriter&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: teal;"&gt;StringReader&lt;/span&gt; reader &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringReader&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"&lt;/span&gt;&lt;span style="color: #cc33cc;"&gt;\n&lt;/span&gt;&lt;span style="color: red;"&gt;Hello Velocity, I'm $user&lt;/span&gt;&lt;span style="color: #cc33cc;"&gt;\n&lt;/span&gt;&lt;span style="color: red;"&gt;"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            Velocity&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;evaluate&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;context&lt;span style="color: #990000;"&gt;,&lt;/span&gt; writer&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user&lt;span style="color: #990000;"&gt;,&lt;/span&gt; reader&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;            System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;println&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt; writer&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;toString&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: #990000;"&gt;);&lt;/span&gt; &lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;Exception&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;printFromFile&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: teal;"&gt;StringWriter&lt;/span&gt; writer &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringWriter&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: teal;"&gt;Template&lt;/span&gt; template &lt;span style="color: #990000;"&gt;=&lt;/span&gt; engine&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;getTemplate&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"templates/velocity.vm"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;            template&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;merge&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt; context&lt;span style="color: #990000;"&gt;,&lt;/span&gt; writer &lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;            System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;println&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt; writer&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;toString&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: #990000;"&gt;);&lt;/span&gt; &lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;Exception&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;StringTemplate&lt;/h3&gt;&lt;dl&gt;&lt;dt&gt;License:&lt;/dt&gt;&lt;dd&gt;BSD&lt;/dd&gt;&lt;dt&gt;Tested Version:&lt;/dt&gt;&lt;dd&gt;3.2.1&lt;/dd&gt;&lt;dt&gt;Dependencies:&lt;/dt&gt;&lt;dd&gt;ANTLR&lt;/dd&gt;&lt;dt&gt;Advantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;Powerful and simple&lt;/li&gt;&lt;li&gt;Not limited to Web.&lt;/li&gt;&lt;li&gt;Not a Java only project.&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt;&lt;dt&gt;Disadvantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;Counter-intuitive usage of the dollar sign.&lt;/li&gt;&lt;li&gt;Single person project. Not much activity.&lt;/li&gt;&lt;li&gt;Not much documentation.&lt;/li&gt;&lt;li&gt;No IDE plugins&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt; &lt;/dl&gt;Watching an article about StringTemplate is what drove me into writing this post. I thought: "finally someone is implementing a StringBuilder that behaves like it should". But no, it was another template engine, but I wanted to see how it works. And it was fast and easy to learn, but the way the the dollar sign is used kept me head banging on the table. You only have to take a look at this to cry: $if(title)$&amp;lt;title&amp;gt;$title$&amp;lt;/title&amp;gt;$endif$. Now imagine a thousand lines of it.&lt;br /&gt;&lt;br /&gt;If you get used to this syntax, having a template engine that works in several programming languages is a very good thing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;StringTemplateExample&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; TemplateExample&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: teal;"&gt;StringTemplate&lt;/span&gt; template &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringTemplate&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Hello StringTemplate, I'm $user$"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringTemplateExample&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;String&lt;/span&gt; user&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user &lt;span style="color: #990000;"&gt;=&lt;/span&gt; user&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;        template&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;setAttribute&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"user"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;print&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;println&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;template&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;printFromFile&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: teal;"&gt;StringTemplateGroup&lt;/span&gt; templateGroup &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;StringTemplateGroup&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"xml group"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: red;"&gt;"templates"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: teal;"&gt;StringTemplate&lt;/span&gt; xmlTemplate &lt;span style="color: #990000;"&gt;=&lt;/span&gt; templateGroup&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;getInstanceOf&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"xml"&lt;/span&gt;&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        xmlTemplate&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;setAttribute&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"user"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;println&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;xmlTemplate&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;toString&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;());&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;MVEL2&lt;/h3&gt;&lt;dl&gt;&lt;dt&gt;License:&lt;/dt&gt;&lt;dd&gt;Apache 2.0&lt;/dd&gt;&lt;dt&gt;Tested Version:&lt;/dt&gt;&lt;dd&gt;2.0.17&lt;/dd&gt;&lt;dt&gt;Dependencies:&lt;/dt&gt;&lt;dd&gt;None&lt;/dd&gt;&lt;dt&gt;Advantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;Easiest to use of all&lt;/li&gt;&lt;li&gt;Nice syntax&lt;/li&gt;&lt;li&gt;Very alive. Latest version is from March 2010&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt;&lt;dt&gt;Disadvantages:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;&lt;li&gt;The &lt;i&gt;eval&lt;/i&gt; method should accept a File object directly.&lt;/li&gt;&lt;li&gt;No IDE plugins&lt;/li&gt;&lt;/ul&gt;&lt;/dd&gt; &lt;/dl&gt;I really liked MVEL2 for its simplicity and power. You get a very nice template engine and a very nice expression language which will look very familiar to Java programmers. No weird syntax and the usage of @{var} was a good decision since it's not something you see in any other place, allowing the programmer to easily adjust to the engine.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;MVELExample&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; TemplateExample&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: teal;"&gt;Map&amp;lt;String,String&amp;gt;&lt;/span&gt; map &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; HashMap&lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;String&lt;span style="color: #990000;"&gt;,&lt;/span&gt;String&lt;span style="color: #990000;"&gt;&amp;gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;MVELExample&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;String&lt;/span&gt; user&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;.&lt;/span&gt;user &lt;span style="color: #990000;"&gt;=&lt;/span&gt; user&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;        map&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;put&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"user"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; user&lt;span style="color: #990000;"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;print&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;println&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;((&lt;/span&gt;String&lt;span style="color: #990000;"&gt;)&lt;/span&gt;TemplateRuntime&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;eval&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"Hello MVEL, I'm @{user}&lt;/span&gt;&lt;span style="color: #cc33cc;"&gt;\n&lt;/span&gt;&lt;span style="color: red;"&gt;"&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; map&lt;span style="color: #990000;"&gt;));&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #009900;"&gt;void&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;printFromFile&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/b&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            System&lt;span style="color: #990000;"&gt;.&lt;/span&gt;out&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;println&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;TemplateRuntime&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;eval&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;FileInputStream&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;File&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"templates/mvel.xml"&lt;/span&gt;&lt;span style="color: #990000;"&gt;)),&lt;/span&gt; map&lt;span style="color: #990000;"&gt;));&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;FileNotFoundException&lt;/span&gt; e&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;            e&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;printStackTrace&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;For an enterprise system the decision is clear: Velocity. It's the most known and powerful tool of them all. It might also have the ugliest syntax but if you get your mind around it and install your IDE plugin, things start looking better. If Velocity wasn't the most known of them all, I would definitely go with MVEL2 for everything, from complex systems to simple ones. From Web apps, to Swing apps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-5517205961810908298?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/5517205961810908298/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/06/java-template-engines-fight.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5517205961810908298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5517205961810908298'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/06/java-template-engines-fight.html' title='Java Template Engines, fight!'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-4837872541520050996</id><published>2010-05-30T13:42:00.000+01:00</published><updated>2010-05-30T13:42:19.770+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbook'/><category scheme='http://www.blogger.com/atom/ns#' term='temas'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu Baja Resolución</title><content type='html'>Ubuntu Netbook es la versión de Ubuntu para netbooks, los cuales traen unas pantallas en las que cada pixel debe ser aprovechado. Al instalar éste sabor de Ubuntu en una maquina virtual, me gusto como se distribuian los diferentes elementos básicos como el menú, la barra de tareas y la barra de título de las ventanas, así que decidí hacer lo mismo para mi portatil, el cual, con una resolución máxima de 1024x768 y una pantalla de 14'' necesita cada pixel.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/TAJXQsON1ZI/AAAAAAAAAxc/tEG_svu1ly0/s1600/screenshot_015.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/TAJXQsON1ZI/AAAAAAAAAxc/tEG_svu1ly0/s320/screenshot_015.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Partiendo de una instalación base de Ubuntu, instalamos el Applet para GNOME "window-picker-applet" y descargamos el tema "&lt;a href="http://gnome-look.org/content/show.php/dust+metacity+mod+-+no+title+bar+on+max?content=93631"&gt;Dust Metacity Mod&lt;/a&gt;". Se descomprime el tarball e instalamos con el administrador de temas los dos temas que obtenemos (aparecen como Dust Fedora).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/TAJY6iQiPoI/AAAAAAAAAxk/etJGa8reMsE/s1600/screenshot_016.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/TAJY6iQiPoI/AAAAAAAAAxk/etJGa8reMsE/s320/screenshot_016.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Por otro lado, podemos incorporar sólo el efecto de eliminar las barras de título utilizando ésta parte del tema.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/TAJZZstylbI/AAAAAAAAAxs/UIxeLyCO87E/s1600/screenshot_017.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/TAJZZstylbI/AAAAAAAAAxs/UIxeLyCO87E/s320/screenshot_017.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Ya tenemos todo lo que hace falta, por lo que vamos a eliminar la barra de abajo quitando primero todos los widgets que estén allí (barra de tareas, botón de mostrar escritorio y el workspace switcher)&lt;br /&gt;&lt;br /&gt;Luego, movemos la barra superior a la parte inferior utilizando el dialogo de preferencias de dicha barra y eliminamos el Menú por defecto de Ubuntu. A continuación añadimos los Applets "Main Menu" y "Window Picker".&lt;br /&gt;&lt;br /&gt;Con esto se han ganado unos 35 pixeles de espacio vertical y si utilizamos Chromium en lugar de Firefox, ganamos otros 35 pixeles&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/TAJdGZWhA2I/AAAAAAAAAx0/b5sS42ywoN8/s1600/screenshot_018.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/TAJdGZWhA2I/AAAAAAAAAx0/b5sS42ywoN8/s320/screenshot_018.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-4837872541520050996?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/4837872541520050996/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/05/ubuntu-baja-resolucion.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4837872541520050996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4837872541520050996'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/05/ubuntu-baja-resolucion.html' title='Ubuntu Baja Resolución'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/TAJXQsON1ZI/AAAAAAAAAxc/tEG_svu1ly0/s72-c/screenshot_015.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-1206376069348110463</id><published>2010-05-19T21:53:00.001+01:00</published><updated>2010-05-19T21:53:01.028+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stock'/><category scheme='http://www.blogger.com/atom/ns#' term='image'/><category scheme='http://www.blogger.com/atom/ns#' term='pygtk'/><category scheme='http://www.blogger.com/atom/ns#' term='treeview'/><category scheme='http://www.blogger.com/atom/ns#' term='button'/><title type='text'>Botones en un TreeView</title><content type='html'>Esto ha sido algo complicado de conseguir, pero después de algo de trial&amp;amp;error, he logrado añadir unos botones a un TreeView en MCM. En Internet es algo complicado encontrar información sobre esto y de hecho, no encontré nada por lo que ha tocado investigar distintas aproximaciones y al final estoy bastante contento con el resultado.&lt;br /&gt;&lt;br /&gt;Así que, veamos como añadir un botón con imagen a un TreeView en PyGTK. Dado que no existe un CellRenderer para los botones -¿grave fallo?- hay que buscar otras soluciones como utilizar un &lt;b&gt;&lt;span style="color: #6fa8dc;"&gt;CellRedererPixbuf&lt;/span&gt;&lt;/b&gt; o lo que es lo mismo, una imagen. En este caso voy a utilizar una del stock.&lt;br /&gt;&lt;br /&gt;El primer método que nos interesa es para obtener la selección actual del TreeView para saber contra cual registro debemos actuar:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;get_selection&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;self&lt;span style="color: #990000;"&gt;):&lt;/span&gt;&lt;br /&gt;    cursor &lt;span style="color: #990000;"&gt;=&lt;/span&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;view&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_selection&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;    model &lt;span style="color: #990000;"&gt;=&lt;/span&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;view&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_model&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #990000;"&gt;(&lt;/span&gt;model&lt;span style="color: #990000;"&gt;,&lt;/span&gt; iter&lt;span style="color: #990000;"&gt;)&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; cursor&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_selected&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; iter &lt;span style="color: #990000;"&gt;==&lt;/span&gt; None&lt;span style="color: #990000;"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; None&lt;br /&gt;    alias &lt;span style="color: #990000;"&gt;=&lt;/span&gt; model&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_value&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;iter&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;0&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; alias&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Es fácil ver lo que se hace aquí que es obtener a partir de la selección del TreeView los campos del registro. En este caso (MCM) el primer campo contiene el alias de la conexión el cual es único (podría haber sido un UID numérico) y es esto lo que el método va a devolver. Se puede escoger la columna deseada cambiando el valor de ese cero.&lt;br /&gt;&lt;br /&gt;A continuación, añadimos a nuestro ListStore o TreeStore, una columna para contener imágenes, creamos la imagen que deseamos utilizar y la añadimos al ListStore junto con los demás campos del registro:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;connections_model&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;self&lt;span style="color: #990000;"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;    """Creates a ListStore with the Connections data"""&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;    store &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;ListStore&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; str&lt;span style="color: #990000;"&gt;,&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Pixbuf&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;    img &lt;span style="color: #990000;"&gt;=&lt;/span&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;dialog&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;render_icon&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;STOCK_CLEAR&lt;span style="color: #990000;"&gt;,&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;ICON_SIZE_BUTTON&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt;&lt;/b&gt; cx &lt;b&gt;&lt;span style="color: blue;"&gt;in&lt;/span&gt;&lt;/b&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;connections&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;values&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;():&lt;/span&gt;&lt;br /&gt;        cx_list &lt;span style="color: #990000;"&gt;=&lt;/span&gt; cx&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;to_list&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;        cx_list&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;append&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;img&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        store&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;append&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;cx_list&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; store&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;El ultimo argumento del ListStore es &lt;b style="color: #6fa8dc;"&gt;gtk.gdk.Pixbuf&lt;/b&gt; lo cual indica al nuevo objeto que debe contener objetos de éste tipo. En MCM cada objeto Connection, tiene un método llamado &lt;b&gt;&lt;span style="color: #6fa8dc;"&gt;to_list()&lt;/span&gt;&lt;/b&gt; que devuelve las propiedades del objeto como una lista, añadimos la imagen a dicha lista y ésta al ListStore.&lt;br /&gt;&lt;br /&gt;Con esto ya obtendríamos un TreeView con una imagen de stock al final de cada registro, pero ahora tenemos que hacer que dicha imagen haga algo al hacer doble-click en ella.&lt;br /&gt;&lt;br /&gt;Para lograr esto -y aquí empieza lo complicado- vamos a utilizar el evento &lt;b&gt;&lt;span style="color: #6fa8dc;"&gt;button-press-event&lt;/span&gt;&lt;/b&gt; del TreeView, por lo que debemos crear un método para el callback de éste evento y conectarlo con el TreeView al crearlo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;i&gt;&lt;span style="color: #9a1900;"&gt;# Configure Tree Properties&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;view&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;set_headers_clickable&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;True&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;view&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;connect&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;'button-press-event'&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;cell_click_event&lt;span style="color: #990000;"&gt;,&lt;/span&gt; store &lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;El callback de button-press-event debe recibir al widget, el evento y vamos además a añadir nuestro store ya que -aunque éste no sea el caso- nos puede ser útil:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;cell_click_event&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;self&lt;span style="color: #990000;"&gt;,&lt;/span&gt; widget&lt;span style="color: #990000;"&gt;,&lt;/span&gt; event&lt;span style="color: #990000;"&gt;,&lt;/span&gt; store&lt;span style="color: #990000;"&gt;):&lt;/span&gt;&lt;br /&gt;    path &lt;span style="color: #990000;"&gt;=&lt;/span&gt; widget&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_path_at_pos&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;int&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;event&lt;span style="color: #990000;"&gt;.&lt;/span&gt;x&lt;span style="color: #990000;"&gt;),&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;int&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;event&lt;span style="color: #990000;"&gt;.&lt;/span&gt;y&lt;span style="color: #990000;"&gt;))&lt;/span&gt;&lt;br /&gt;    &lt;i&gt;&lt;span style="color: #9a1900;"&gt;#row = int(path[0][0])&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;    column &lt;span style="color: #990000;"&gt;=&lt;/span&gt; path&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: #990000;"&gt;]&lt;/span&gt;&lt;br /&gt;    col_title &lt;span style="color: #990000;"&gt;=&lt;/span&gt; column&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_title&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; col_title &lt;span style="color: #990000;"&gt;==&lt;/span&gt; &lt;span style="color: red;"&gt;'Delete'&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;and&lt;/span&gt;&lt;/b&gt; event&lt;span style="color: #990000;"&gt;.&lt;/span&gt;type &lt;span style="color: #990000;"&gt;==&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;_2BUTTON_PRESS&lt;span style="color: #990000;"&gt;:&lt;/span&gt;&lt;br /&gt;        alias &lt;span style="color: #990000;"&gt;=&lt;/span&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_selection&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;        dlg &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;b&gt;&lt;span style="color: black;"&gt;UtilityDialogs&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;        response &lt;span style="color: #990000;"&gt;=&lt;/span&gt; dlg&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;show_question_dialog&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;constants&lt;span style="color: #990000;"&gt;.&lt;/span&gt;deleting_connection_warning &lt;span style="color: #990000;"&gt;%&lt;/span&gt; alias&lt;span style="color: #990000;"&gt;,&lt;/span&gt; constants&lt;span style="color: #990000;"&gt;.&lt;/span&gt;are_you_sure&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; response &lt;span style="color: #990000;"&gt;==&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;RESPONSE_OK&lt;span style="color: #990000;"&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;b&gt;&lt;span style="color: blue;"&gt;del&lt;/span&gt;&lt;/b&gt; self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;connections&lt;span style="color: #990000;"&gt;[&lt;/span&gt;alias&lt;span style="color: #990000;"&gt;]&lt;/span&gt;&lt;br /&gt;            self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;redraw_tree&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;El elemento más útil aquí es el objeto &lt;b&gt;&lt;span style="color: #6fa8dc;"&gt;event&lt;/span&gt;&lt;/b&gt; del tipo &lt;b&gt;&lt;span style="color: #6fa8dc;"&gt;gtk.gdk.Event&lt;/span&gt;&lt;/b&gt; con el cual vamos a obtener algo como esto:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;Event at &lt;span style="color: #993399;"&gt;0x1ed9b20&lt;/span&gt;&lt;span style="color: #990000;"&gt;:&lt;/span&gt; GDK_BUTTON_PRESS x&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: #993399;"&gt;1000.00&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; y&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: #993399;"&gt;31.00&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; button&lt;span style="color: #990000;"&gt;=&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Eso dos campos (x,y) son las coordenadas donde se ha hecho el click y  con esto podemos obtener un path con el cual obtener la columna y el registro sobre el que se está actuando. Dicho path contiene la siguiente información:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: #990000;"&gt;((&lt;/span&gt;&lt;span style="color: #993399;"&gt;3&lt;/span&gt;&lt;span style="color: #990000;"&gt;,),&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;lt;&lt;/span&gt;gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;TreeViewColumn object at &lt;span style="color: #993399;"&gt;0x2684af0&lt;/span&gt; &lt;span style="color: #990000;"&gt;(&lt;/span&gt;GtkTreeViewColumn at &lt;span style="color: #993399;"&gt;0x27d09b0&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&amp;gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;27&lt;/span&gt;&lt;span style="color: #990000;"&gt;,&lt;/span&gt; &lt;span style="color: #993399;"&gt;13&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;El primer valor de la tupla path es una tupla en la que el primer valor es el indice del registro sobre el que nos encontramos. Está comentado ya que gracias al metodo "get_selection()" no nos hace falta, pero sabemos que hemos actuado sobre el cuarto registro del TreeView. Lo que nos interesa de aquí es el TreeViewColumn del que vamos a obtener su titulo y si se cumplen las condiciones: doble-click sobre la columna con titulo Delete, actuamos, en este caso mostrando un dialogo de confirmación, borrando el registro y dibujando el TreeView.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-1206376069348110463?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/1206376069348110463/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/05/botones-en-un-treeview.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1206376069348110463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/1206376069348110463'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/05/botones-en-un-treeview.html' title='Botones en un TreeView'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8090544018621444944</id><published>2010-05-11T19:11:00.000+01:00</published><updated>2010-05-11T19:11:26.292+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='vnc'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Monocaffe Connections Manager 0.9.3</title><content type='html'>Nueva versión disponible de Monocaffe Connections Manager: 0.9.3&lt;br /&gt;&lt;br /&gt;&lt;a href="http://launchpad.net/mcm/%20"&gt;http://launchpad.net/mcm/ &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Se han añadido las siguientes carácteristicas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cliente VNC integrado&lt;/li&gt;&lt;li&gt;Edición de conexiones&lt;/li&gt;&lt;li&gt;Formulario para reportar fallos, ideas o spamearme.&lt;/li&gt;&lt;li&gt;Mensaje de error al fallar un cliente&lt;/li&gt;&lt;li&gt;Traducciones al francés, alemán y castellano.&lt;/li&gt;&lt;/ul&gt;Se han resuelto algunos fallos gracias a los reportes de algunos usuarios.&lt;br /&gt;&lt;br /&gt;Finalmente, screenshot!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S-mdlWhX-MI/AAAAAAAAAw4/xEzV_-FGVlU/s1600/f24a4046e07cf8aaaafad2f14202d167_medium.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S-mdlWhX-MI/AAAAAAAAAw4/xEzV_-FGVlU/s320/f24a4046e07cf8aaaafad2f14202d167_medium.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8090544018621444944?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8090544018621444944/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/05/monocaffe-connections-manager-093.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8090544018621444944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8090544018621444944'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/05/monocaffe-connections-manager-093.html' title='Monocaffe Connections Manager 0.9.3'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/S-mdlWhX-MI/AAAAAAAAAw4/xEzV_-FGVlU/s72-c/f24a4046e07cf8aaaafad2f14202d167_medium.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-734428512329183837</id><published>2010-05-04T00:59:00.000+01:00</published><updated>2010-05-04T00:59:54.412+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='temas'/><category scheme='http://www.blogger.com/atom/ns#' term='pygtk'/><category scheme='http://www.blogger.com/atom/ns#' term='colores'/><title type='text'>PyGTK Colores por defecto</title><content type='html'>Me he encontrado con un pequeño problema al intentar modificar los colores de los campos de MCM ya que es bastante complicado encontrar los colores por defecto utilizados por el tema. El problema se acentuaba al utilizar temas oscuros ya que se modificaban los colores de la aplicación para pintar los campos con fondo blanco.&lt;br /&gt;&lt;br /&gt;Un poco de trial &amp;amp; error y esto es lo obtenido:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;DefaultColorSettings&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;object&lt;span style="color: #990000;"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt;&lt;/b&gt; &lt;b&gt;&lt;span style="color: black;"&gt;__init__&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;self&lt;span style="color: #990000;"&gt;):&lt;/span&gt;&lt;br /&gt;        def_settings &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;settings_get_default&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;        color_scheme &lt;span style="color: #990000;"&gt;=&lt;/span&gt; def_settings&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;get_property&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"gtk-color-scheme"&lt;/span&gt;&lt;span style="color: #990000;"&gt;).&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;strip&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;()&lt;/span&gt;&lt;br /&gt;        color_scheme &lt;span style="color: #990000;"&gt;=&lt;/span&gt; color_scheme&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;split&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;"\n"&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        settings &lt;span style="color: #990000;"&gt;=&lt;/span&gt; &lt;span style="color: #990000;"&gt;{}&lt;/span&gt;&lt;br /&gt;        &lt;b&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt;&lt;/b&gt; property &lt;b&gt;&lt;span style="color: blue;"&gt;in&lt;/span&gt;&lt;/b&gt; color_scheme&lt;span style="color: #990000;"&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;i&gt;&lt;span style="color: #9a1900;"&gt;# property is of the type key: value&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;            property &lt;span style="color: #990000;"&gt;=&lt;/span&gt; property&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;split&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;&lt;span style="color: red;"&gt;": "&lt;/span&gt;&lt;span style="color: #990000;"&gt;)&lt;/span&gt;&lt;br /&gt;            settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;property&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: #993399;"&gt;0&lt;/span&gt;&lt;span style="color: #990000;"&gt;]]&lt;/span&gt; &lt;span style="color: #990000;"&gt;=&lt;/span&gt; property&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: #990000;"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;tooltip_fg_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"tooltip_fg_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;selected_bg_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"selected_bg_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;tooltip_bg_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"tooltip_bg_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;base_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"base_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;fg_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"fg_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;text_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"text_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;selected_fg_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"selected_fg_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;])&lt;/span&gt;&lt;br /&gt;        self&lt;span style="color: #990000;"&gt;.&lt;/span&gt;bg_color &lt;span style="color: #990000;"&gt;=&lt;/span&gt; gtk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;gdk&lt;span style="color: #990000;"&gt;.&lt;/span&gt;&lt;b&gt;&lt;span style="color: black;"&gt;color_parse&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #990000;"&gt;(&lt;/span&gt;settings&lt;span style="color: #990000;"&gt;[&lt;/span&gt;&lt;span style="color: red;"&gt;"bg_color"&lt;/span&gt;&lt;span style="color: #990000;"&gt;]) &lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Básicamente, todos los componentes que se configuran con los temas de GNOME llegan a nuestras aplicaciones a través de &lt;b&gt;&lt;span style="color: #274e13;"&gt;gtk.gdk.Screen&lt;/span&gt;&lt;/b&gt;. Con "&lt;b&gt;&lt;span style="color: #274e13;"&gt;settings_get_default&lt;/span&gt;&lt;/b&gt;" obtenemos distintos aspectos de la configuración del tema: colores, tamaños de iconos, sonidos, etc.&lt;br /&gt;&lt;br /&gt;Para lo que nos incumbe ahora, obtenemos "&lt;b&gt;&lt;span style="color: #274e13;"&gt;gtk-color-scheme&lt;/span&gt;&lt;/b&gt;" el cual es un &lt;b&gt;&lt;span style="color: #274e13;"&gt;str&lt;/span&gt;&lt;/b&gt; con los distintos colores. En MCM mi solución fue la de crear una clase &lt;b&gt;&lt;span style="color: #274e13;"&gt;DefaultColorSettings&lt;/span&gt;&lt;/b&gt; y luego utilizar &lt;b&gt;&lt;span style="color: #274e13;"&gt;DefaultColorSettings.base_color&lt;/span&gt;&lt;/b&gt; para redibujar los campos a su estado original cada vez que cambiaba los colores de los mismos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-734428512329183837?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/734428512329183837/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/05/pygtk-colores-por-defecto.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/734428512329183837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/734428512329183837'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/05/pygtk-colores-por-defecto.html' title='PyGTK Colores por defecto'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-493084284286795569</id><published>2010-04-27T15:52:00.001+01:00</published><updated>2010-04-27T15:53:39.943+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='lynx'/><category scheme='http://www.blogger.com/atom/ns#' term='opensuse'/><category scheme='http://www.blogger.com/atom/ns#' term='distros'/><category scheme='http://www.blogger.com/atom/ns#' term='mint'/><category scheme='http://www.blogger.com/atom/ns#' term='fedora'/><category scheme='http://www.blogger.com/atom/ns#' term='lucid'/><category scheme='http://www.blogger.com/atom/ns#' term='kubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>MCM en Varias Distros</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Ubuntu Lucid Lynx 10.04 RC&lt;/span&gt;&lt;br /&gt;Funciona, aunque da problemas el nuevo tema "Ambience" &lt;a href="http://bugs.launchpad.net/mcm/+bug/570600"&gt;http://bugs.launchpad.net/mcm/+bug/570600&lt;/a&gt;&amp;nbsp;y la verdad es que el tema de los colores y los nuevos botones no me gusta nada.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S9bY6aL-80I/AAAAAAAAAv4/bDSoAiGZOtg/s1600/screenshot_041.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S9bY6aL-80I/AAAAAAAAAv4/bDSoAiGZOtg/s320/screenshot_041.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Fedora 12&lt;/span&gt;&lt;br /&gt;Hay un pequeño problema en el script de instalación ya que el directorio /usr/share/apps no existe. Sólo fue añadir la opción "-p" al mkdir y todo perfecto.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S9bY8lcYJvI/AAAAAAAAAwA/guSAJBMxIvk/s1600/screenshot_044.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S9bY8lcYJvI/AAAAAAAAAwA/guSAJBMxIvk/s320/screenshot_044.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;OpenSUSE 11&lt;/span&gt;&lt;br /&gt;Destacar que el LiveCD de OpenSUSE es el único con soporte para ratón integrado de VirtualBox y que además, arranca con una buena resolución. Sólo hará falta instalar el paquete "python-xdg" o algo por el estilo. Buscad xdg y os aparece.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S9b4aWmNrcI/AAAAAAAAAwI/4UWSzoy78ns/s1600/screenshot_045.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S9b4aWmNrcI/AAAAAAAAAwI/4UWSzoy78ns/s320/screenshot_045.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Kubuntu Karmic Koala 9.10&lt;/span&gt;&lt;br /&gt;No había usado Kubuntu en mucho tiempo y sólo puedo decir: WOW! Es un espectaculo, pero demasiado cargado para mi gusto. Ha sido el más complicado ya que hay que instalar dos paquetes: python-glade2 y python-vte. Ya estan añadidas esas dependencias al paquete .deb&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S9b5EkRxH2I/AAAAAAAAAwQ/a-LBb1_uZO0/s1600/screenshot_046.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S9b5EkRxH2I/AAAAAAAAAwQ/a-LBb1_uZO0/s320/screenshot_046.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Linux Mint 8&lt;/span&gt;&lt;br /&gt;Ha sido la más sencilla ya que viene con todos los repositorios añadidos al apt. La verdad, me ha encantado la tematica y el cuidado que se le da a los diferentes aspectos estéticos.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/S9b5lawwaXI/AAAAAAAAAwY/wCGtv3WoxHY/s1600/screenshot_047.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/S9b5lawwaXI/AAAAAAAAAwY/wCGtv3WoxHY/s320/screenshot_047.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;No he podido probar con las siguientes distros con las que lo he intentado: Arch (hay que instalar), Slax (no parece tener un buen soporte para PyGTK ya que no encontre los "modulos").&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-493084284286795569?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/493084284286795569/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/04/mcm-en-varias-distros.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/493084284286795569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/493084284286795569'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/04/mcm-en-varias-distros.html' title='MCM en Varias Distros'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/S9bY6aL-80I/AAAAAAAAAv4/bDSoAiGZOtg/s72-c/screenshot_041.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5872847882248565516</id><published>2010-04-20T00:54:00.000+01:00</published><updated>2010-04-20T00:54:36.134+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='memoria'/><title type='text'>Estructura de la memoria de Objetos Java</title><content type='html'>Un poco de teoría bajo nivel sobre el funcionamiento de Java y como maneja la memoria. Esto es un repaso sencillo de cómo Java maneja la memoria, cuanta memoria utiliza un objeto y como mejorar la utilización de memoria de nuestros objetos.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Shallow Copy Size vs Deep Size&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Shallow Copy Size es la cantidad de memoria ocupada por un sólo POJO al crearlo. Deep Size por otra lado, es la cantidad de memoria que ocupa un POJO sumado a la memoria utilizada por todos los POJOs que referencia.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Los 8 bytes&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Todos los objetos en Java deben tener un tamaño que sea múltiplo de 8 bytes, es decir, una granularidad de 8 bytes. La razón de esto es la facilidad de los distintos sistemas operativos y procesadores de convertir direcciones de memoria a registros de cuatro en cuatro (o de ocho en ocho para sistemas de 64bits). Esto es así para todas las plataformas a diferencia de C o C++ que utilizan distintos tamaños de memoria para tipos primitivos.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Todos los objetos -menos los arreglos ( String [] array )- tienen una cabecera de dos direcciones, donde la primera es un código Hash de identificación y la segunda contiene una referencia a la clase del objeto. De esta forma, al instanciar un nuevo objeto Object() se utilizarán 8 bytes de la memoria heap (no entremos en las demás posibilidades ahora) para mantener el uid y la referencia ya que Object() no tiene ningún campo o variable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Despues de estos 8 bytes de la cabecera, siguen los bytes necesarios para los atributos de la clase, los cuales siempre son alineados en la memoria según su tamaño:&lt;br /&gt;&lt;br /&gt;- double y long&lt;br /&gt;- float e int&lt;br /&gt;- char y short&lt;br /&gt;- boolean y byte&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Reestructuración de nuestras clases.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La JVM es capaz de ordenar los atributos de nuestras clases de tal manera que los nuevos objetos no ocupen más memoria de la que necesitan.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;span style="color: teal;"&gt;Class&lt;/span&gt; DespilfarradorDeMemoria &lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;    byte&lt;/span&gt; a&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;    int&lt;/span&gt; b&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;    boolean&lt;/span&gt; c&lt;span style="color: #990000;"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #009900;"&gt;    long&lt;/span&gt; d&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: teal;"&gt;    Object&lt;/span&gt; e&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;Si la JVM no fuera capaz de reordenar los atributos de esta clase al instanciarla, nuestro nuevo objeto desperdiciaría unos 14 bytes de memoria:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S8zhBBraxVI/AAAAAAAAAvA/W7eHeLO2cwI/s1600/dia1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="86" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S8zhBBraxVI/AAAAAAAAAvA/W7eHeLO2cwI/s400/dia1.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Se puede ver en la imagen como se va reservando memoria para mantener al objeto dentro de un múltiplo de 8 bytes por lo que se desperdicia mucha memoria. Para esto la JVM es capaz de ordenar los atributos de tal manera que sólo se utilice la cantidad de memoria necesaria y se reduzca al mínimo la consumida para relleno. La imagen del objeto instanciado sería la siguiente:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S8zhDfBF00I/AAAAAAAAAvI/iNWGL9AWUBY/s1600/dia2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="96" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S8zhDfBF00I/AAAAAAAAAvI/iNWGL9AWUBY/s400/dia2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Gracias a esto, se reduce el consumo innecesario a 6 bytes y en total 32 para dicho objeto.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Calcular el consumo de memoria&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ahora podemos calcular el consumo de memoria de cualquier objeto que extiende de Object() directamente. Probemos con un boolean:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S8zhEwz1cKI/AAAAAAAAAvQ/k_RIUmWTbTs/s1600/dia3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S8zhEwz1cKI/AAAAAAAAAvQ/k_RIUmWTbTs/s320/dia3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Por increíble que parezca, una instancia de un objeto boolean consume ¡16 bytes! De estos 16, 7 son usados como relleno para mantener la granularidad. Este es el coste de que todo en Java sea un objeto.&lt;br /&gt;&lt;div class="post-body entry-content"&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Las mezclas son malas&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Whisky, cerveza y tequila: malo. Mezclar atributos entre clases de la hierarquía: muy malo. La primera regla es: primero los atributos de las clases padres seguidas por los atributos de las clases instanciadas.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S8zhGAZBgiI/AAAAAAAAAvY/a-en4trnppI/s1600/dia4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="112" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S8zhGAZBgiI/AAAAAAAAAvY/a-en4trnppI/s400/dia4.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;La imagen describe la asignación de memoria para los objetos "Hija":&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Padre&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;long&lt;/span&gt; a&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;int&lt;/span&gt; b&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;int&lt;/span&gt; c&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Hija&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; Padre&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;long&lt;/span&gt; d&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;La segunda regla es que se utilizará un relleno entre las asignaciones de dos objetos para separarlos y lograr la granuralidad de 4 bytes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Padre&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;byte&lt;/span&gt; a&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Hija&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; Padre&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;byte&lt;/span&gt; c&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S8zky6ChuAI/AAAAAAAAAvg/SD91jJ9In_8/s1600/dia5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S8zky6ChuAI/AAAAAAAAAvg/SD91jJ9In_8/s320/dia5.png" /&gt;&lt;/a&gt;&lt;/div&gt;Como se puede ver, se utiliza un relleno de 3 bytes para obtener 12 bytes, los cuales no pueden ser utilizados para los atributos del objeto siguiente.&lt;br /&gt;&lt;br /&gt;La tercera y ultima regla viene a establecerse para casos concretos en los que la segunda regla no puede ser aplicada, como cuando el primer elemento de la clase hija es un "long" o un "double" y la clase padre no termina con un limite de 8 bytes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Padre&lt;/span&gt;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;byte&lt;/span&gt; a&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&lt;/b&gt; &lt;span style="color: teal;"&gt;Hija&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;extends&lt;/span&gt;&lt;/b&gt; Padre&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;long&lt;/span&gt; b&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;short&lt;/span&gt; c&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #009900;"&gt;byte&lt;/span&gt; d&lt;span style="color: #990000;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;}&lt;/span&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/S8znaMv3cgI/AAAAAAAAAvo/W2Fqet-Arnw/s1600/dia6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="132" src="http://2.bp.blogspot.com/_GKVx1yC7np0/S8znaMv3cgI/AAAAAAAAAvo/W2Fqet-Arnw/s400/dia6.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Cuando el primer campo de una sub-clase es un double o un long y la super-clase no se alinea a los 8 bytes, la JVM romperá la segunda regla e intentará colocar los campos int, short, byte y referencias al principio del espacio reservado para la sub-clase hasta que se rellene por completo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;En la imagen se puede ver que en el byte 12 cuando la clase Padre ha terminado, se comienza con un short de 2 bytes y un byte de 1 byte antes del long para ahorrar 3 o 4 bytes que de otra forma se habrían desperdiciado:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/S8zqn0CcX0I/AAAAAAAAAvw/ZeIKBMy8tGo/s1600/dia7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="116" src="http://2.bp.blogspot.com/_GKVx1yC7np0/S8zqn0CcX0I/AAAAAAAAAvw/ZeIKBMy8tGo/s400/dia7.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Como siempre tenemos otro caso especial con las clases internas no estáticas, la cuales tienen un campo escondido que mantiene la referencia a la clase a la que pertenece. Esta es una referencia regular que sigue los mismos principios anteriores. Por esto, las clases interntas tienen un coste extra de 4 bytes.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-5872847882248565516?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/5872847882248565516/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/04/estructura-de-la-memoria-de-objetos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5872847882248565516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5872847882248565516'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/04/estructura-de-la-memoria-de-objetos.html' title='Estructura de la memoria de Objetos Java'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GKVx1yC7np0/S8zhBBraxVI/AAAAAAAAAvA/W7eHeLO2cwI/s72-c/dia1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7887812320287441792</id><published>2010-04-09T17:21:00.000+01:00</published><updated>2010-04-09T17:21:48.765+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='minor'/><title type='text'>Monocaffe Connections Manager 0.9.2</title><content type='html'>Nueva versión de Monocaffe Connections Manager 0.9.2&lt;br /&gt;&lt;br /&gt;Esta es una revisión menor sobre el código de 0.9.1. Se arreglan algunos fallos menores y se han añadido y quitado cosas.&lt;br /&gt;&lt;br /&gt;Una de las cosas que me ha gustado es la posibilidad de ejecutar comandos SSH si los incluimos dentro de las opciones de la conexión. Por ejemplo, he creado un grupo llamado "MyJBoss" donde tengo una serie de conexiones SSH llamadas: myjboss-server.log, myjboss-access.log, etc. En las opciones de myjboss-server.log he añadido lo siguiente: "tail -f /opt/jboss/server/default/log/server.log". De esta forma, al utilizar esta conexión, veo directamente este log.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S79UCTlgm3I/AAAAAAAAAu4/gnG0HVv7EWI/s1600/screenshot_035.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S79UCTlgm3I/AAAAAAAAAu4/gnG0HVv7EWI/s400/screenshot_035.png" width="285" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Podéis descargarlo del lugar habitual: &lt;br /&gt;&lt;br /&gt;http://launchpad.net/mcm/+download&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7887812320287441792?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7887812320287441792/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/04/monocaffe-connections-manager-092.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7887812320287441792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7887812320287441792'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/04/monocaffe-connections-manager-092.html' title='Monocaffe Connections Manager 0.9.2'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/S79UCTlgm3I/AAAAAAAAAu4/gnG0HVv7EWI/s72-c/screenshot_035.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6047151603551765012</id><published>2010-04-08T09:46:00.000+01:00</published><updated>2010-04-08T09:46:24.670+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='lubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='10.04'/><title type='text'>MCM en Lubuntu 10.04</title><content type='html'>Hoy he instalado Lubuntu 10.04 en una máquina virtual para comprobar la instalación de MCM y mis primeras impresiones con esta primera iteración de LXDE para Ubuntu son muy positivas.&lt;br /&gt;La instalación de MCM ha funcionado igual que en Ubuntu y no he detectado ningún problema despues de realizar las pruebas pertinentes.&lt;br /&gt;Lo que más me ha llamado la atención de Lubuntu es que el navegador que viene por defecto instalado es Chromium que además, con su temática de tonos azules, se asemeja más al de LXDE.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S72XP1LskYI/AAAAAAAAAuw/iuX8kzgs8Dc/s1600/screenshot_034.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="333" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S72XP1LskYI/AAAAAAAAAuw/iuX8kzgs8Dc/s400/screenshot_034.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Esta es la ventaja más importante de desarrollar con PyGTK: no estas limitado a GNOME, ya que muchos de los otros Desktop Managers como LXDE y XCDE utilizan GTK. Espero algún día ver un Desktop Manager ligero basado en Qt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6047151603551765012?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6047151603551765012/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/04/mcm-en-lubuntu-1004.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6047151603551765012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6047151603551765012'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/04/mcm-en-lubuntu-1004.html' title='MCM en Lubuntu 10.04'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/S72XP1LskYI/AAAAAAAAAuw/iuX8kzgs8Dc/s72-c/screenshot_034.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6654651987338930548</id><published>2010-03-17T16:52:00.000Z</published><updated>2010-03-17T16:52:06.353Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr'/><category scheme='http://www.blogger.com/atom/ns#' term='commit'/><category scheme='http://www.blogger.com/atom/ns#' term='bazaar'/><category scheme='http://www.blogger.com/atom/ns#' term='conflictos'/><category scheme='http://www.blogger.com/atom/ns#' term='resolve'/><title type='text'>Reparar conflictos en Bazaar</title><content type='html'>Bazaar es el sistema de control de versiones utilizado por &lt;a href="http://launchpad.net/"&gt;Launchpad&lt;/a&gt; para sus proyectos, por lo tanto Monocaffe Connections Manager utiliza &lt;a href="http://bazaar.canonical.com/en/"&gt;Bazaar&lt;/a&gt;. Al igual que CVS, SVN y GIT, bazaar (bzr) tiene sus raíces en la línea de comandos, pero además aporta una herramienta GTK muy fácil de utilizar llamada &lt;a href="http://wiki.bazaar.canonical.com/Olive/"&gt;Olive&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S6EIhIMwoQI/AAAAAAAAAuI/sa2zpgPTOjQ/s1600-h/screenshot_019.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="146" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S6EIhIMwoQI/AAAAAAAAAuI/sa2zpgPTOjQ/s320/screenshot_019.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Una de las cosas más llamativas de Bazaar es la resolución de conflictos. Cuando intentamos realizar un commit contra una rama que está en conflicto con nuestra rama local, Bazaar creará tres ficheros: .OTHER, .THIS y .BASE. Para resolver el conflicto podemos utilizar vimdiff, emacs o meld. Por defecto, Olive intentará utilizar meld, por lo que recomiendo tenerlo instalado y porque además es muy útil la herramienta.&lt;br /&gt;&lt;br /&gt;Estos tres ficheros serán abiertos por Meld, por lo que sólo tenemos que integrar los cambios que deseamos tal que los tres ficheros sean iguales (no entremos en detalles sobre cada uno de los ficheros y las posibilidades, esto es lo más sencillo y rápido para resolver el conflicto). Guardamos los ficheros y cerramos Meld. Aquí nos encontramos con un pequeño detalle del que adolece Olive, no tiene ninguna opción para resolver el conflicto, por lo que tendremos que tirar de línea de comandos y ejecutar lo siguiente:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr resolve file.txt&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;De esta forma, los tres ficheros desaparecerán y podremos realizar nuestro commit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6654651987338930548?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6654651987338930548/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/03/reparar-conflictos-en-bazaar.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6654651987338930548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6654651987338930548'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/03/reparar-conflictos-en-bazaar.html' title='Reparar conflictos en Bazaar'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/S6EIhIMwoQI/AAAAAAAAAuI/sa2zpgPTOjQ/s72-c/screenshot_019.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6392629005960954126</id><published>2010-03-16T15:44:00.000Z</published><updated>2010-03-16T15:44:09.968Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='nacar'/><title type='text'>NACAR</title><content type='html'>Finalmente puedo decir que sé lo que es NACAR. Después de mi &lt;a href="http://monocaffe.blogspot.com/2010/03/domingos-de-trabajos-i.html"&gt;entrada&lt;/a&gt; volví a ver una mención sobre NACAR y decidí comentarlo con la gente del curro. Uno de ellos se encontró con éste &lt;a href="http://www.accenture.com/NR/rdonlyres/C5924605-2637-448A-B2C0-6358F1B1C18F/0/8487bbvanacar.pdf"&gt;documento&lt;/a&gt; de Accenture.&lt;br /&gt;&lt;br /&gt;NACAR (Nueva Arquitectura de Canales de Acceso Remoto) o como lo solemos llamar comúnmente: SOAP. Con lo de canales se refiere a nivel bancario: telecajeros, oficinas, banca por Internet, etc. Así que ¿es un SOAP bancario?&lt;br /&gt;&lt;br /&gt;En fin, el documento no explica mucho a nivel técnico, por lo que no se pueden sacar más conclusiones. De todas formas suena demasiado "enterprisy".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6392629005960954126?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6392629005960954126/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/03/nacar.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6392629005960954126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6392629005960954126'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/03/nacar.html' title='NACAR'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-4363970615578057294</id><published>2010-03-16T11:39:00.000Z</published><updated>2010-03-16T11:39:48.064Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='gtk'/><category scheme='http://www.blogger.com/atom/ns#' term='glade'/><category scheme='http://www.blogger.com/atom/ns#' term='gtkbuilder'/><category scheme='http://www.blogger.com/atom/ns#' term='pygtk'/><category scheme='http://www.blogger.com/atom/ns#' term='libglade'/><title type='text'>Glade3 y GtkBuilder</title><content type='html'>Glade es una herramienta que permite realizar RAD (Rapid Application  Development) con una interfaz muy sencilla de utilizar para aplicaciones  GTK+. Glade genera unos ficheros .glade que son xml y pueden ser leidos  por las muchas implementaciones de GTK+ para Java, C, C++, Python, Perl  y un largo etcétera. &lt;br /&gt;&lt;br /&gt;Con Karmic Koala viene la nueva versión 3.6.7 de Glade que incluye un muy buen soporte para GtkBuilder.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;GtkBuilder y Libglade&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;GtkBuilder va a reemplazar a Libglade en el futuro no muy lejano y GtkBuilder forma parte integral de GTK, por lo que no hace falta añadir más dependencias a nuestros proyectos. Además, al utilizar GtkBuilder, podemos crear nuevos objetos y acciones que antes se tenian que crear en el código. Por ejemplo, los ListStore para añadir a los Views facilitan mucho la creación de este tipo de widgets.&lt;br /&gt;&lt;br /&gt;La razón por la cual se cambia de Libglade a GtkBuilder es que se ha convertido en algo muy común desarrollar la UI de forma dinámica en Glade por lo que no tenía sentido que el propio core de GTK no lo soportara. Aquí es donde entra GtkBuilder para además, añadir nuevas funcionalidades. La verdad es que no hay nada malo con Libglade, sólo que GtkBuilder extiende sobre Libglade y se añade directamente a GTK, haciendo el funcionamiento más sencillo y rápido.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;PyGTK&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para utilizar GtkBuilder en Python, seguimos las mismas pautas que con libglade, es decir, cargar el fichero, conectar las señales y obtener los widgets para actuar sobre estos.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import gtk&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x = gtk.Builder()&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x.add_from_file("/tmp/test.glade")&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;y = x.get_object("window1")&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;y.show()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cabe recalcar que MCM está desarrollada con Libglade y que poco a poco iré migrando a GtkBuilder viendo las posibilidades.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-4363970615578057294?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/4363970615578057294/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/03/glade3-y-gtkbuilder.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4363970615578057294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4363970615578057294'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/03/glade3-y-gtkbuilder.html' title='Glade3 y GtkBuilder'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7741054178244654390</id><published>2010-03-07T21:54:00.001Z</published><updated>2010-03-07T22:01:05.907Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='carnicas'/><category scheme='http://www.blogger.com/atom/ns#' term='ofertas'/><category scheme='http://www.blogger.com/atom/ns#' term='trabajo'/><title type='text'>Domingos de trabajos I</title><content type='html'>Los domingos por la noche me llegan al correo electrónico un resumen de ofertas de trabajo de InfoJobs desde hace años y las risas que me echo me indignan y creo que es hora de compartir esto. Empecemos con ésta:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Ni de coña&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;Precisamos de la incorporación de Desarrolladores en C embebido, drivers (microprocesadores a bajo nivel). Al menos 2 años de experiencia. Experiencia en C embebido. 18.000 € - 21.000 €&amp;nbsp;Bruto/año&lt;/blockquote&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S5QLr92CDhI/AAAAAAAAAtQ/XaE9w9UO1J4/s1600-h/screenshot_009.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="55" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S5QLr92CDhI/AAAAAAAAAtQ/XaE9w9UO1J4/s400/screenshot_009.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Programar en C y bien es muy jodido en x86, ahora imaginamos quitar el 90% de la memoria, un hardware con arquitecturas especiales y empezamos a ver lo complicado que es esto. ¿glibc?¿Qué es eso? Da suerte que puedes compilar y no bajar a ensamblador. Este tipo de labor conlleva conocer el lenguaje de programación tan bien que no existan fallos ya que es un poco difícil flashear una ROM vía Internet. Ambienta se deben conocer las distintas arquitecturas, APIs, librerías (si es que las tiene) y fallos de una gran variedad de chips. Muchas veces tendrá que además bajar a desarrollar en ensamblador (aunque no lo pone en la oferta, esto es casí seguro) por lo que una persona con éste nivel y vocación dudo que vaya a reducirse a cobrar 1.200€ al mes. Bueno, aunque por el momento hay dos inscritos en la oferta.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Generalista de cárnica&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Estas son las ofertas de "vamos a hacerle perder el tiempo a la peña" ya que no se especifican proyectos, sólo te hacen la entrevista y cuando le cuelen el cuchillo a algún ministerio, ahí que vas... 6 meses después y con el CV hinchado.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/S5QODfiw-fI/AAAAAAAAAtY/QUt-T3YT6tg/s1600-h/screenshot_010.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/S5QODfiw-fI/AAAAAAAAAtY/QUt-T3YT6tg/s320/screenshot_010.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Lo peor de ésta oferta es que ni siquiera se dignan a gastarse el dinero en sacar ofertas específicas para cada entorno. Quizás me equivoco y busquen a un tío que sepa de las dos (jeje). Lastima que no indiquen el rango de sueldos. En lo que me compete: "Entornos de desarrollo: Netbeans, Eclipse, UML." Claro signo de que vas a perder tu tiempo haciendo una entrevista con ellos.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-size: large;"&gt;Me aburro con leerte&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;No es que trabajar deba ser un deleite y pocas personas tienen la suerte de trabajar en lo que les gusta y en temas interesantes que sacan a relucir su ingenio, pero por lo general a los programadores nos gusta nuestro trabajo, aunque dudo que los candidatos a ésta oferta lleguen a casa para continuar con éste:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/S5QSxV4qRYI/AAAAAAAAAtg/2kicxjmp7wM/s1600-h/screenshot_011.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/S5QSxV4qRYI/AAAAAAAAAtg/2kicxjmp7wM/s320/screenshot_011.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Quizás me equivoque y es probable que la persona elegida vaya a ganar una pasta, pero no se puede negar que suena a trabajo en cubículo gris, en edificio sin ventanas y de traje con corbata.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Nacar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hace más de un año un colega me preguntó si sabía que era eso de Nacar ya que por lo visto tenía algo que ver con Java. Yo le pedí que me mostrase la oferta para ver si estaba diciendo alguna burrada, pero no, buscaban desarrolladores de Nacar para la zona norte de Madrid. Dicha oferta la volví a ver muchas veces y sinceramente creía que hoy la volvería a ver, pero no, es otra:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/S5QUmn3p62I/AAAAAAAAAto/BSpSUj2cdXQ/s1600-h/screenshot_012.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/S5QUmn3p62I/AAAAAAAAAto/BSpSUj2cdXQ/s320/screenshot_012.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Después de toda la synergia que se utiliza para motivar a posibles candidatos viene el tema de NACAR que sigo sin conocer de qué va, así que si algún lector se digna a explicármelo. Por supuesto que una búsqueda en Google resulta infructuosa. NAKAR habría facilitado mucho el trabajo. He llegado a plantearme que sea una oferta trampa para pillar a alguno.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;No sé qué quiero, pero lo quiero todo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ejemplo perfecto de una oferta de trabajo que no saben ni lo que quieren:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S5QYm9ePwPI/AAAAAAAAAt4/6WCAvvN4FLE/s1600-h/screenshot_014.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S5QYm9ePwPI/AAAAAAAAAt4/6WCAvvN4FLE/s320/screenshot_014.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Es decir, quieren un tío, no tía (lo dice la oferta) con 10 años de experiencia en ir dando botes sin saber qué hacer con su vida: 2 de C++ Linux (¿GTK?, ¿Qt?, ¿Tc?) 2 de C++ Windows, 2 .Net Windows, 2 .Net Linux (¿Mono?) y 2 en BB.DD. Fantástico lo específico de la oferta, seguro que llegas y el trabajo es de PHP + ActionScript + iPhone.&lt;br /&gt;&lt;br /&gt;Si la anterior sufre de ser poco específica, la siguiente es un despilfarro de ancho de banda:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S5QaYPKi54I/AAAAAAAAAuA/vEt8q7dbgIk/s1600-h/screenshot_015.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S5QaYPKi54I/AAAAAAAAAuA/vEt8q7dbgIk/s320/screenshot_015.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Leyendo la lista no puedo dejar de preguntarme si realmente existe alguien que... ¿Symbian? Vale, ésta gente está flipando en colores. Lo que me llamo la atención fue el título "Programador Web Python". Mira que chulo - pensé. Pero luego meten JSF y Struts y tiran RoR, un poco de jQuery por aquí y por allá, mezclamos con WebOS y Maemo, una pizca de iPhone y de Android, unas cucharaditas de MySQL y de PostgreSQL, untamos una salsa de CMS's más rica que la salsa rosada (Drupal, Joomla y WordPress) y para finalizar gratinamos con Visio y Office. Resultado, 1.300€/mes y 6 inscritos que no deben haber leído bien la oferta. LMAO!!!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;No todo es tan malo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Claro que no todas pueden ser malas o peores, alguna decente tiene que haber... estoy buscando...&amp;nbsp; todavía... digo yo que alguna habrá...&amp;nbsp; por fin, aunque de dicha empresa no haya escuchado cosas buenas:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/S5QWI3Loj9I/AAAAAAAAAtw/VqFyZN14SQY/s1600-h/screenshot_013.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/S5QWI3Loj9I/AAAAAAAAAtw/VqFyZN14SQY/s320/screenshot_013.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Posibilidades de irte de paseo por Europa, ganar más dinero y utilizar Flex, que es de lo mejorcito que se ha creado en los últimos años. Se ve que conocen del tema al no pedir 3 años de experiencia en Flex. Lo malo es que no especifican el rango salarial y que poca gente se quiere ir a Luxemburgo con dicha empresa sin saber por cuanto: una.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7741054178244654390?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7741054178244654390/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/03/domingos-de-trabajos-i.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7741054178244654390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7741054178244654390'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/03/domingos-de-trabajos-i.html' title='Domingos de trabajos I'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/S5QLr92CDhI/AAAAAAAAAtQ/XaE9w9UO1J4/s72-c/screenshot_009.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6328657091971189270</id><published>2010-03-01T14:42:00.002Z</published><updated>2010-03-01T14:42:00.227Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='failure'/><title type='text'>Bash debug/failure</title><content type='html'>&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Cuando realizo scripts en Bash que son bastante complicados y deseo ver muy bien lo que estan haciendo, suelo crear una funciona llamada debug tal que:&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: black;"&gt;debug&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: #990000;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; $&lt;span style="color: #990000;"&gt;{&lt;/span&gt;DEBUG&lt;span style="color: #990000;"&gt;}&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;eq &lt;span style="color: #993399;"&gt;0&lt;/span&gt; &lt;span style="color: #990000;"&gt;];&lt;/span&gt; then&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;echo &lt;span style="color: red;"&gt;"[DEBUG] ${1}"&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #993399;"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;eval &lt;span style="color: red;"&gt;"${1}"&lt;/span&gt; &lt;span style="color: #990000;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #990000;"&gt;/&lt;/span&gt;dev&lt;span style="color: #990000;"&gt;/&lt;/span&gt;null &lt;span style="color: #993399;"&gt;2&lt;/span&gt;&lt;span style="color: #990000;"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&lt;/b&gt; $&lt;span style="color: #990000;"&gt;?&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;fi&lt;br /&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Por lo que en lugar de hacer las llamadas directamente, se utiliza esto:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;debug "mv ${old} ${new}"&lt;/div&gt;&lt;br /&gt;Si ejecutamos el script con la variable DEBUG=0 entonces, en lugar de ejecutar el comando, aparecerá el mensaje de debug con el comando. El mayor problema de esto y que se tiene que tener &lt;b&gt;muy&lt;/b&gt; en cuenta, es que con esta función tambien podemos incluir comentarios como:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;debug "Vamos a mover el directorio"&lt;/div&gt;&lt;br /&gt;Estos comentarios no nos traen problemas ya que &lt;i&gt;eval &lt;/i&gt;intentará ejecutar &lt;i&gt;Vamos&lt;/i&gt; como si fuera un comando y fallaría sin problemas, pero cuidado con estos comentarios.&lt;br /&gt;&lt;br /&gt;Otra función que está en mi "Toolbox" es &lt;i&gt;failure&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: black;"&gt;failure&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;()&lt;/span&gt; &lt;span style="color: #990000;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt;&lt;/b&gt; &lt;span style="color: #990000;"&gt;[&lt;/span&gt; $&lt;span style="color: #990000;"&gt;{&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt; &lt;span style="color: #990000;"&gt;-&lt;/span&gt;ne &lt;span style="color: #993399;"&gt;0&lt;/span&gt; &lt;span style="color: #990000;"&gt;];&lt;/span&gt; then&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;echo &lt;span style="color: red;"&gt;"[FAIL] (${1}): ${2}"&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;exit $&lt;span style="color: #990000;"&gt;{&lt;/span&gt;&lt;span style="color: #993399;"&gt;1&lt;/span&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/b&gt;fi&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: #990000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;La utilizamos después de ejecutar cualquier comando:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;failure $? "Failed to mkdir ${archive_dir}${2}"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La función recibe el código de salida del comando anterior y muestra el mensaje que deseamos en caso de haber fallado. En caso de fallar, devuelve el código de error del comando como el código de error de nuestro script. &lt;span style="font-family: Verdana,sans-serif;"&gt;Tambien podemos utilizarla para resolver algún otro test:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt;&lt;span style="color: #990000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt;&lt;span style="color: #990000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;z &lt;/span&gt;&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"${1}"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt;&lt;span style="color: #990000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;]&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt;&lt;span style="color: #990000; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; then&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;         failure &lt;/span&gt;&lt;span style="color: #993399; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &lt;/span&gt;&lt;span style="color: red; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"No existe el directorio ${1}"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;     fi&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Las dos funciones pueden ser utilizadas en conjunto:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;debug "mkdir ${archive_dir}${2}"&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;failure $? "Failed to mkdir ${archive_dir}${2}"&lt;/div&gt;&lt;br /&gt;Además, las ventajas de estas dos funciones es que podemos escribir en un log sin modificar todas nuestras lineas, podemos añadir colores y modificar el formato de salida en un solo lugar y funcionan bastante bien.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6328657091971189270?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6328657091971189270/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/03/bash-debugfailure.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6328657091971189270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6328657091971189270'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/03/bash-debugfailure.html' title='Bash debug/failure'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8570159423339652324</id><published>2010-02-25T12:24:00.000Z</published><updated>2010-02-25T12:24:01.374Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='highlight'/><category scheme='http://www.blogger.com/atom/ns#' term='code2blog'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax'/><title type='text'>Código fuente en Blogger con code2blog</title><content type='html'>Hoy he descubierto una herramienta llamada &lt;a href="http://code.google.com/p/code2blog/"&gt;code2blog&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S4Zp0YFj3QI/AAAAAAAAAss/90Gi2w9rCH8/s1600-h/screenshot_008.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S4Zp0YFj3QI/AAAAAAAAAss/90Gi2w9rCH8/s320/screenshot_008.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Es una herramienta muy sencilla que funciona como GUI para source-highlight, excelente herramienta de Lorenzo Bettini. Es una herramienta muy sencilla que utiliza PyGTK y Glade y es sólo un fichero de 34K. Para utilizarla primero la descargamos:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;wget http://code2blog.googlecode.com/svn/trunk/code2blog&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Si tenemos instalado source-highlight ejecutamos con python y listo. Un ejemplo del HTML generado:&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;!-- Generator: GNU source-highlight 3.1by Lorenzo Bettinihttp://www.lorenzobettini.ithttp://www.gnu.org/software/src-highlite --&gt;&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;scan_tree&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;pathname&lt;font color="#990000"&gt;,&lt;/font&gt; calls&lt;font color="#990000"&gt;=[&lt;/font&gt;&lt;font color="#FF0000"&gt;'_'&lt;/font&gt;&lt;font color="#990000"&gt;]):&lt;/font&gt;&lt;br /&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;    """Scans a tree for translatable strings."""&lt;/font&gt;&lt;/i&gt;&lt;br /&gt;    out &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;StringCollection&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;pathname&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; folder&lt;font color="#990000"&gt;,&lt;/font&gt; _&lt;font color="#990000"&gt;,&lt;/font&gt; files &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; os&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;walk&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;pathname&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;        &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; filename &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; files&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;            filename &lt;font color="#990000"&gt;=&lt;/font&gt; os&lt;font color="#990000"&gt;.&lt;/font&gt;path&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;join&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;folder&lt;font color="#990000"&gt;,&lt;/font&gt; filename&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;            &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; filename&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;endswith&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'.py'&lt;/font&gt;&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;                result &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;scan_python_file&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;filename&lt;font color="#990000"&gt;,&lt;/font&gt; calls&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;                &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; result &lt;b&gt;&lt;font color="#0000FF"&gt;is&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;not&lt;/font&gt;&lt;/b&gt; None&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;                    &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; lineno&lt;font color="#990000"&gt;,&lt;/font&gt; string &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; result&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;                        out&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;feed&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;filename&lt;font color="#990000"&gt;,&lt;/font&gt; lineno&lt;font color="#990000"&gt;,&lt;/font&gt; string&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;            &lt;b&gt;&lt;font color="#0000FF"&gt;elif&lt;/font&gt;&lt;/b&gt; filename&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;endswith&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'.glade'&lt;/font&gt;&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;                result &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;scan_glade_file&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;filename&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;                &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; result &lt;b&gt;&lt;font color="#0000FF"&gt;is&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;not&lt;/font&gt;&lt;/b&gt; None&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;                    &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; string &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; result&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;                        out&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;feed&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;filename&lt;font color="#990000"&gt;,&lt;/font&gt; None&lt;font color="#990000"&gt;,&lt;/font&gt; string&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; line &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; out&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;        yield line&lt;/tt&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8570159423339652324?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8570159423339652324/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/codigo-fuente-en-blogger-con-code2blog.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8570159423339652324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8570159423339652324'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/codigo-fuente-en-blogger-con-code2blog.html' title='Código fuente en Blogger con code2blog'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GKVx1yC7np0/S4Zp0YFj3QI/AAAAAAAAAss/90Gi2w9rCH8/s72-c/screenshot_008.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2295530213462779262</id><published>2010-02-22T12:06:00.000Z</published><updated>2010-02-22T12:06:35.674Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='revision'/><title type='text'>Monocaffe Connections Manager 0.9.1</title><content type='html'>He sacado un revisión de la versión 0.9 de MCM para arreglar algunos fallos que pueden ser molestos para algunos usuarios y añadido características que no deben influenciar en su uso.&lt;br /&gt;&lt;br /&gt;Podeis descargar la nueva versión &lt;a href="http://launchpad.net/mcm/+milestone/0.9.1"&gt;aquí.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2295530213462779262?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2295530213462779262/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/monocaffe-connections-manager-091.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2295530213462779262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2295530213462779262'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/monocaffe-connections-manager-091.html' title='Monocaffe Connections Manager 0.9.1'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5503175140068893592</id><published>2010-02-14T21:37:00.000Z</published><updated>2010-02-14T21:37:21.003Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='puttycm'/><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='poderosa'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='mremote'/><title type='text'>PuTTY Opciones</title><content type='html'>Buscando en la red información para importar ficheros de registro de PuTTY a MCM, he encontrado una aplicación que se parece bastante a MCM y que tienen muy buena pinta.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;a href="http://puttycm.free.fr/"&gt;PuTTY Connection Manager&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.thegeekstuff.com/wp-content/uploads/2008/08/2-puttycm.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.thegeekstuff.com/wp-content/uploads/2008/08/2-puttycm.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Es muy parecido a MCM, por lo que permite conectar a diferentes sesiones de SSH y utiliza pestañas para navegar. De igual forma tiene un árbol que muestra las conexiones del usuario.&lt;br /&gt;&lt;br /&gt;Diferencias con MCM:&lt;br /&gt;&lt;br /&gt;Sólo para SSH, Telnet ¿y FTP?&lt;br /&gt;Sólo para Windows &lt;br /&gt;No permite enviar comandos a varias terminales (cluster mode).&lt;br /&gt;No tiene una barra de referencia.&lt;br /&gt;No es OSS.&lt;br /&gt;Tiene una opción que me gusta por la cual permite el Autologon y se la voy a copiar :)&lt;br /&gt;&lt;br /&gt;Es una solución para usuarios de Windows que deseen algo parecido a MCM, pero claro, sin toda la funcionalidad que podrían tener si usarán Linux.&lt;br /&gt;&lt;br /&gt;Indagando un poco más he encontrado incluso más soluciones para Windows:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;a href="http://www.mremote.org/"&gt;mRemote&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.mremote.org/wiki/GetFile.aspx?File=Screenshot_V1.15_SSH.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="262" src="http://www.mremote.org/wiki/GetFile.aspx?File=Screenshot_V1.15_SSH.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Es GPL y solo funciona sobre Windows pero soporta todo tipo de conexiones (incluso ICA).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;a href="http://en.poderosa.org/"&gt;Poderosa&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://en.poderosa.org/?plugin=ref&amp;amp;page=index&amp;amp;src=screen1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="220" src="http://en.poderosa.org/?plugin=ref&amp;amp;page=index&amp;amp;src=screen1.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Es parecido a PuTTYCM aunque no han lanzado ninguna nueva versión desde el 2006.&lt;br /&gt;&lt;br /&gt;Así que para Windows existen soluciones muy buenas y estables (con cosas muy interesantes para copiar), por lo que ni me molesto :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-5503175140068893592?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/5503175140068893592/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/putty-opciones.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5503175140068893592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5503175140068893592'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/putty-opciones.html' title='PuTTY Opciones'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-323897765853568574</id><published>2010-02-13T21:48:00.000Z</published><updated>2010-02-13T21:48:05.767Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='translation'/><category scheme='http://www.blogger.com/atom/ns#' term='traduccion'/><title type='text'>Tanslations in Monocaffe</title><content type='html'>I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms. Any one can help on translations to their respective idioms.&lt;br /&gt;&lt;br /&gt;&lt;span class="short_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;我已经上传到Monocaffe必要的变化，可以很容易地转换为不同的成语。&lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;任何人能够帮助到他们各自的成语翻译。&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;He pujat els canvis necessaris per Monocaffe per la qual cosa es pot traduir fàcilment a diferents idiomes. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Qualsevol pot ajudar en les traduccions als seus idiomes respectius.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;Olen ladannut tarvittavat muutokset Monocaffe joten se on helppo kääntää eri sanontojen. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Tahansa voi auttaa käännöksiä omille idioms.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;Ich habe die notwendigen Änderungen an Monocaffe hochgeladen wurde, so kann es leicht auf verschiedene Idiome übersetzt. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Jeder kann helfen, auf Übersetzungen in ihre jeweiligen Redewendungen.&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;Ho caricato le modifiche necessarie per Monocaffe in modo che possa essere facilmente tradotto in idiomi diversi. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Nessuno può aiutare il traduzioni alle proprie rispettivi idiomi.&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;Я загрузил необходимые изменения в Monocaffe поэтому она может быть легко переведена на различные идиомы. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Любой может помочь на переводы в свои соответствующие идиомы.&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;Jag har lagt upp de nödvändiga ändringarna Monocaffe så det kan lätt översättas till olika idiom. &lt;/span&gt;&lt;span title="Any one can help on translations to their respective idioms."&gt;Någon kan hjälpa på översättningar till sina respektive idiom.&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: #ebeff9;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;He subido los cambios necesarios para Monocaffe por lo que se puede traducir fácilmente a diferentes idiomas. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Cualquiera puede ayudar en las traducciones a sus idiomas respectivos.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: #ebeff9;" title="I've uploaded the necessary changes to Monocaffe so it can be easily translated to different idioms."&gt;Fiz upload as mudanças necessárias para Monocaffe para que possa ser facilmente traduzidas para idiomas diferentes. &lt;/span&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;Qualquer um pode ajudar em traduções de seus respectivos idiomas.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;http://translations.launchpad.net/mcm/trunk&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="medium_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="short_text" id="result_box"&gt;&lt;span style="background-color: white;" title="Any one can help on translations to their respective idioms."&gt; &lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-323897765853568574?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/323897765853568574/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/tanslations-in-monocaffe.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/323897765853568574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/323897765853568574'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/tanslations-in-monocaffe.html' title='Tanslations in Monocaffe'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3932381144876220126</id><published>2010-02-07T17:17:00.000Z</published><updated>2010-02-07T17:17:41.676Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><title type='text'>Desarrollo de Monocaffe Connections Manager</title><content type='html'>Varias personas ya me han preguntado cómo he desarrollado MCM y ésta entrada va de ello, sobre las herramientas y tecnologías utilizadas y la justificación detrás de cada una de las razones y consecuencias. Aunque parezca una aplicación sencilla, utiliza muchas tecnologias creadas por muchas otras personas y que sin alguna de estas, quizás MCM no existiria.&lt;br /&gt;&lt;br /&gt;Resumen&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Python&lt;/li&gt;&lt;ul&gt;&lt;li&gt;PyGTK&lt;/li&gt;&lt;li&gt;VteTerminal&lt;/li&gt;&lt;li&gt;minidom&lt;/li&gt;&lt;li&gt;json&lt;/li&gt;&lt;li&gt;csv&lt;/li&gt;&lt;li&gt;urllib&lt;/li&gt;&lt;li&gt;optpars &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;VIM&lt;/li&gt;&lt;ul&gt;&lt;li&gt;exuberant-ctags&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Glade&lt;/li&gt;&lt;li&gt;Bazaar&lt;/li&gt;&lt;li&gt;Dialog&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;Desarrollo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En su totalidad, MCM está escrito en Python y utilizando sólo las herramientas propias de Python y PyGTK. Esto me permite distribuir MCM sin que dependa de instalaciones complicadas o de cientos de paquetes ya que estos vienen por defecto con cualquier instalación de GNOME.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/S271S0TrfZI/AAAAAAAAAsk/fPilrngS2rQ/s1600-h/screenshot_009.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/S271S0TrfZI/AAAAAAAAAsk/fPilrngS2rQ/s320/screenshot_009.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt; &lt;i&gt;&lt;span style="font-size: xx-small;"&gt;mcm + vim + exuberant-tags&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;Para escribir MCM, ninguna herramienta mejor que VIM. Exuberant-ctags permite mostrar una ventana dentro de VIM para navegar las clases y métodos de un fichero.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;GUI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para crear el GUI, se crea la mayoria de ventanas y dialogos utilizando Glade. Es un GUI para crear GUI's. Con una interfaz sencilla podemos crear todos estos widgets y configurar sus propiedades y señales. Para efectos dinamicos o widgets más complicados (como el breadcrumb) utilizamos PyGTK directamente. Despues de crear los widgets y sus señales, para manejarlas en código debemos leer el fichero que genera Glade (un XML):&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;gtk.glade.XML(glade_file)&lt;/div&gt;&lt;br /&gt;Para interactuar desde el código con los objetos creados por libglade, debemos referenciarlos:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;self.main_window = self.xml.get_widget("main_mcm")&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;gtk.window (gtkwindow="" 0x8e1e9dc="" 0x8f048b0)="" at="" object=""&gt;&lt;/gtk.window&gt;&lt;/div&gt;&lt;br /&gt;Glade permite ahorrar una cantidad de trabajo y código gigante. Al ser XML los ficheros que genera, no es necesario utilizar Glade para realizar modificaciones sencillas (nombres de objetos, señales, etc.) y creo que cualquier lenguaje serio tiene una librería para leer estos ficheros y generar interfaces.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S2709yaxpFI/AAAAAAAAAsc/fkxkqDpcBko/s1600-h/screenshot_008.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S2709yaxpFI/AAAAAAAAAsc/fkxkqDpcBko/s320/screenshot_008.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Con Glade hay que ir con cuidado porque de vez en cuando le da por no funcionar como debe, pero nada que no se arregle guardando a menudo y reiniciando.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Launchpad&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En launchpad.net se nos ofrece para nuestro proyectos OSS todo lo necesario y a la ultima, como el gestor Bazaar que viene con una GUI muy sencilla. Bazaar es un sistema de versiones distribuido, lo que significa que no hace falta un repositorio central para utilizarle. Los merge se hacen de forma muy sencilla al igual que crear ramas. El sistema de gestión de bugs de Launchpad es muy sencillo y me gusta mucho la relación real que existe entre los fallos, los milestones y los releases. Tambien ofrecen una herramienta para ayudar en la traducción de proyectos, pero hace falta algo de trabajo para hacerla funcionar correctamente y espero conseguir tiempo en el futuro para esto.&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;¿Microsoft Windows?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dado que GTK y Python funcionan perfectamente sobre Windows, me imagino que MCM también. No he llegado a probarlo por lo que si alguien se anima, que me comente sus resultados y si hay interés, se puede hacer una rama aparte para su desarrollo. El único problema que veo ahora mismo sería el modo en el que se generan las terminales utilizando VteTerminal y no estoy seguro de que estas funcionen correctamente en Windows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3932381144876220126?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3932381144876220126/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/desarrollo-de-monocaffe-connections.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3932381144876220126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3932381144876220126'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/desarrollo-de-monocaffe-connections.html' title='Desarrollo de Monocaffe Connections Manager'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/S271S0TrfZI/AAAAAAAAAsk/fPilrngS2rQ/s72-c/screenshot_009.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-874085551485732756</id><published>2010-02-07T14:53:00.000Z</published><updated>2010-02-07T14:53:25.646Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><title type='text'>Wooops... Fallo en MCM 0.9</title><content type='html'>Gracias a mis beta testers :) he arreglado un par de fallos en la nueva versión de MCM 0.9. Por una parte, el script de instalación no copia el fichero "tips.json" al directorio del usuario, el script de arranque no añadía una nueva linea de configuración "buffer.size" al fichero mcm.conf y finalmente, por alguna razón mágica, Glade dejo de escribir las señales de los eventos para las acciones de importar y exportar. Todos estos fallos has sido resueltos, así que si habéis tenido estos problemas, descargad los ficheros nuevamente y todo debería funcionar sin problemas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-874085551485732756?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/874085551485732756/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/wooops-fallo-en-mcm-09.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/874085551485732756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/874085551485732756'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/wooops-fallo-en-mcm-09.html' title='Wooops... Fallo en MCM 0.9'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3213947150948354283</id><published>2010-02-04T00:43:00.000Z</published><updated>2010-02-04T00:43:20.742Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='new'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><title type='text'>Monocaffe Connections Manager 0.9</title><content type='html'>Nueva versión de Monocaffe Connections Manager con una gran adición de la que estoy muy contento. Un widget al estilo breadcrumb para acceder a referencias a comandos, tal que el usuario no tenga que recordar cada opción, comando o conjunto de teclas de cada aplicación que usa.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S2oXBvPKGDI/AAAAAAAAAsM/CNq0VqEf_MY/s1600-h/screenshot_007.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="24" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S2oXBvPKGDI/AAAAAAAAAsM/CNq0VqEf_MY/s640/screenshot_007.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Este widget además permite añadir nuevos "Tips" y compartirlos con el mundo. Aun hay que desarrollar un poco más éste widget, pero es 95% funcional y espero os guste la idea.&lt;br /&gt;&lt;br /&gt;Tambien se han resulto algunos fallos y molestias que mis compañeros de trabajo han ido encontrando al utilizar mcm y es que tengo un equipo de beta-testers de elite.&lt;br /&gt;&lt;br /&gt;Screenshot!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/S2oX6tX6kEI/AAAAAAAAAsU/MyRlROFgDFc/s1600-h/screenshot_005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="356" src="http://1.bp.blogspot.com/_GKVx1yC7np0/S2oX6tX6kEI/AAAAAAAAAsU/MyRlROFgDFc/s400/screenshot_005.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Descargad desde aquí:&lt;br /&gt;&lt;a href="http://launchpad.net/mcm/+download"&gt;http://launchpad.net/mcm/+download&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3213947150948354283?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3213947150948354283/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/02/monocaffe-connections-manager-09.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3213947150948354283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3213947150948354283'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/02/monocaffe-connections-manager-09.html' title='Monocaffe Connections Manager 0.9'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GKVx1yC7np0/S2oXBvPKGDI/AAAAAAAAAsM/CNq0VqEf_MY/s72-c/screenshot_007.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7360715768582175761</id><published>2010-01-03T01:00:00.001Z</published><updated>2010-01-03T01:05:08.795Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='yahoo'/><category scheme='http://www.blogger.com/atom/ns#' term='mail'/><title type='text'>Venga Yahoo!</title><content type='html'>Mi cuenta de correo personal durante mucho tiempo (diciembre de 1997) ha sido bajo el dominio Yahoo.com. Entonces, tengo una cuenta de correo con 12 años de historia a sus espaldas y a la que he entrado día tras día. Poco a poco ha sido semana tras semana y últimamente, cuando me acuerdo.&lt;br /&gt;¿Qué demonios le ha pasado a Yahoo para que no evolucione o se adapte a las nuevas tecnologías? ¿Cómo pierden a un usuario después de 12 años?&lt;br /&gt;Por gilipoces como estas:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/Sz_hYvi053I/AAAAAAAAAr0/9bIG3Dl5DNE/s1600-h/screenshot_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/Sz_hYvi053I/AAAAAAAAAr0/9bIG3Dl5DNE/s320/screenshot_002.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Sólo os falta "Yahoo! Recommends Windows 7" en el mensaje ese.&lt;br /&gt;Ya llevo un tiempo con éste mensaje: ¡desde el 2007! ¿En dos años no habéis podido montar un Ubuntu, Fedora o Debian y probarlo? ¿Qué clase de mensaje enviáis a vuestros usuarios al respecto? Os lo digo yo: que sois &lt;b&gt;patéticos&lt;/b&gt;. Además me recomendáis a "actualizar mi sistema" ¡lo he actualizado 5 veces desde que lanzasteis la nueva versión de Yahoo! Mail! Hasta KDE ha sacado una nueva versión en todo éste tiempo y vosotros con el mismo mensaje.&lt;br /&gt;Más &lt;b&gt;patético&lt;/b&gt; aun es que estáis mostrando un mensaje sobre un sistema operativo, lo cual es ridículo para una plataforma independiente, ya que para vuestro gran asombro, funciona sobre un navegador o como vosotros seguro lo llamáis: el internet o la "E" azul.&lt;br /&gt;Si no sois capaces de comprender ésta diferencia, que esteis tan desfasados en comparación a Google y Microsoft no me asombra nada. Sólo con utilizar otros de vuestros "servicios" se puede ver que sois un ente moribundo de la red. El "Bloc de Notas" y vuestro calendario son lo mismo de hace 10 años y las únicas diferencias son que los banners de publicidad son más grandes para acomodar las nuevas resoluciones de los monitores.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_GKVx1yC7np0/Sz_rZmQ8YeI/AAAAAAAAAr8/aRJpNy3xwb0/s1600-h/screenshot_003.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_GKVx1yC7np0/Sz_rZmQ8YeI/AAAAAAAAAr8/aRJpNy3xwb0/s320/screenshot_003.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Este es otro tema que me enerva de Yahoo! Mail, es imposible de utilizar a 1024x768. ¿Quién usa esas resoluciones hoy en día? ¡Despertad! ¡Los netbooks! (Bueno, y la gente mayor que tiene problemas de vista) Así que ¿en qué demonios estáis trabajando? ¿En añadir más publicidad basura a vuestros banners? Porque esto es lo que ha derramado el vaso, que un sitio que llevas utilizando durante doce años, muestre un banner con audio que casi me deja sordo.&lt;br /&gt;Ciertas cosas sí he de reconocer y es que las nuevas aplicaciones para teléfonos móvil son realmente espectaculares y el L&amp;amp;F de la versión web es también muy llamativo (aunque no se pueda cambiar) y las librerías JS son realmente útiles y no demasiado pesadas, pero se pueden mejorar, mucho.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://images.ientrymail.com/webpronews/articlepictures/yahoogo3a.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="292" src="http://images.ientrymail.com/webpronews/articlepictures/yahoogo3a.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;&lt;span style="font-size: xx-small;"&gt;Yahoo! Go en el N95&lt;/span&gt;&lt;/i&gt; &lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;Sólo eso es lo que me gustaría, que mejoréis para que un día no me encuentre mi vieja dirección de correo (mi primera) bloqueada porque llevaba seis meses sin acceder a ella.&lt;br /&gt;Una ultima cosa, desde que lanzasteis la versión Beta de Yahoo! Mail al público, funciona bastante bien en Ubuntu, Fedora y CentOS... perdón ¡en Firefox, en Chromium y en Opera!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/Sz_rpkn9xGI/AAAAAAAAAsE/4WXqpWhyUGs/s1600-h/screenshot_004.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/Sz_rpkn9xGI/AAAAAAAAAsE/4WXqpWhyUGs/s320/screenshot_004.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;&lt;span style="font-size: xx-small;"&gt;Yahoo! Mail en Ubuntu 9.10 64... digo, en Firefox.&lt;/span&gt;&lt;/i&gt; &lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7360715768582175761?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7360715768582175761/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2010/01/venga-yahoo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7360715768582175761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7360715768582175761'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2010/01/venga-yahoo.html' title='Venga Yahoo!'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/Sz_hYvi053I/AAAAAAAAAr0/9bIG3Dl5DNE/s72-c/screenshot_002.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5927418690998359440</id><published>2009-12-24T00:56:00.001Z</published><updated>2009-12-24T01:02:08.727Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='closure'/><title type='text'>Java7 Closures</title><content type='html'>Al votar hoy en la encuesta de &lt;a href="http://javahispano.org/"&gt;JavaHispano.org&lt;/a&gt; acerca de los closures en Java 7&amp;nbsp;pude ver que los resultados reflejaban que una gran cantidad de personas registradas en este sitio no conocen los closures. La verdad es que cualquier programador que&amp;nbsp;haya trabajado con otros lenguajes como Lisp, JavaScript o Ruby conocerá los closures decerca. Incluso Groovy, tiene closures.&lt;br /&gt;&lt;h1&gt;Funciones-objeto y closures&lt;/h1&gt;Lo primero que hay que entender es la diferencia entre funciones como objetos y closures. Una&amp;nbsp;función&amp;nbsp;puede ser&amp;nbsp;anónima&amp;nbsp;o definida, pero&amp;nbsp;también&amp;nbsp;pueden ser objetos en si mismas. Esto nos&amp;nbsp;permite utilizar funciones como argumentos, ser devueltas por otras funciones o ser almacenadas&amp;nbsp;en estructuras de datos. Vamos, son objetos de primera clase o de primer orden.&lt;br /&gt;Un closure es una&amp;nbsp;función&amp;nbsp;más su entorno y estos pueden ser de igual forma tratados como objetos&amp;nbsp;de primera clase, pero al contener un entorno, podemos acceder a variables (o funciones) de este&amp;nbsp;entorno incluso cuando el mismo no este activo. Existen lenguajes que soportan funciones-objetos o&amp;nbsp;closures o ambos, y muchos de los lenguajes funcionales en su mayoria utilizan funciones y funciones-closure.&lt;br /&gt;Entonces, un closure, por ejemplo, nos permite definir una función que tiene acceso a una variable, así que podemos almacenar esta funcion en un objeto y acceder a ella. El contexto de la función no se limita sólo a los objetos a los que tiene acceso directo, pero también a las variables que obtiene vía el entorno.&lt;br /&gt;&lt;h1&gt;¿Cómo encaja esto dentro de Java?&amp;nbsp;&lt;/h1&gt;Veamos un ejemplo clásico de sort con un método anónimo:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;anArray.sort(new Comparator&lt;myclass&gt;() {&lt;/myclass&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public int compare(MyClass a, MyClass b) {&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return a.myProperty().compareTo(b.myProperty();&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;});&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Con closures&amp;nbsp;haríamos&amp;nbsp;esto:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;ol&gt;&lt;li&gt;anArray.sort( (a, b) =&amp;gt; a.myProperty().compareTo(b.myProperty() );&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Es algo muy usual realizar operaciones sobre cada objeto de una lista, por ejemplo:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;public List&lt;integer&gt; squareIntegers( List&lt;integer&gt; iList) {&lt;/integer&gt;&lt;/integer&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;List&lt;integer&gt; result = new ArrayList&lt;integer&gt;(iList.size());&lt;/integer&gt;&lt;/integer&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for (Integer i : iList){&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; result.add(i*i);&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return result;&lt;/li&gt;&lt;li&gt;}&lt;/li&gt;&lt;li&gt;iList = squareIntegers(iList);&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Con un closure:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;iList = iList.map( { Integer i =&amp;gt; i*i } );&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Pero estas son realmente funciones-objetos que son pasadas como argumentos a otras funciones. Así que una&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;definición&amp;nbsp;teórica&amp;nbsp;de closure, es decir, un método que puede obtener o hacer "close over" sobre el contexto del&amp;nbsp;código al que pertenece sería:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;public Collection&lt;dvd&gt; getSpanishDvd( Collection&lt;dvd&gt; dvds ){&lt;/dvd&gt;&lt;/dvd&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return select( dvds, { Dvd aDvd =&amp;gt; dvd.isSpanish() } );&lt;/li&gt;&lt;li&gt;}&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;public static &lt;t&gt; Collection&lt;t&gt; select(Collection&lt;t&gt; source, {T=&amp;gt;Boolean} predicate) {&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Collection&lt;t&gt; result = new ArrayList&lt;t&gt;();&lt;/t&gt;&lt;/t&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for (T o : source) {&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (predicate.invoke(o)) result.add(o);&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/li&gt;&lt;li&gt;}&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;h1&gt;¿Son utiles los closures?&lt;/h1&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;En lenguajes como Python llevan mucho tiempo discutiendo sobre la necesidad de lambda y la verdad es que IMO&amp;nbsp;no son algo necesario, pero que es bueno tener a mano para cuando las circunstancias lo precisen. Este tema es&amp;nbsp;parecido al de los for-each con Java6 donde muchas personas desconfiaban de la implementación de estos y de&amp;nbsp;su utilidad. Como sucede con cualquier herramienta, es mejor entenderla antes de utilizarla para no terminar con código spaghetti que dificulte la lectura y el mantenimiento.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Os recomiendo leer el libro &lt;a href="http://mitpress.mit.edu/sicp/"&gt;SICP&lt;/a&gt;&amp;nbsp;para comprender los closures en su totalidad y además&amp;nbsp;un poco de Lisp.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-5927418690998359440?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/5927418690998359440/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/java7-closures.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5927418690998359440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5927418690998359440'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/java7-closures.html' title='Java7 Closures'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2273667591311466469</id><published>2009-12-20T23:30:00.000Z</published><updated>2009-12-20T23:30:48.738Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mencoder'/><category scheme='http://www.blogger.com/atom/ns#' term='koala'/><category scheme='http://www.blogger.com/atom/ns#' term='karmic'/><category scheme='http://www.blogger.com/atom/ns#' term='thoggen'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>DVD Rip en Ubuntu 9.10</title><content type='html'>Estos dias me he puesto a hacer copias de seguridad de toda la filmoteca de DVDs que tenemos para los niños y es un arduo trabajo. Por suerte he empezado a utilizar una herramienta que viene con Ubuntu Karmic Koala llamada&amp;nbsp;&lt;a href="http://thoggen.net/"&gt;Thoggen&lt;/a&gt;&amp;nbsp;que hace un gran trabajo al simplificar todo el proceso.&lt;br /&gt;Lo primero que me gusto fue lo sencillo de su interfaz y que automaticamente selecciona los capitulos que piensa pueden ser los importantes, por lo que no hace falta adivinar cuales son. Dado que sólo codifica en OGG Vorbis, sólo tenemos que seleccionar el tamaño y el idioma.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://thoggen.net/images/0.7/config-dialog-mini.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://thoggen.net/images/0.7/config-dialog-mini.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Que sólo permita utilizar OGG tambien puede ser un problema si vamos a reproducir estos videos en black-box-appliances como lo son los reproductores de DIVx de toda la vida. Es muy raro encontrar alguno con soporte para OGG Vorbis, pero esto tampoco es un problema gracias a mencoder.&lt;br /&gt;&lt;br /&gt;Con el siguiente comando, podreis convertir vuestros videos a MPEG-4 que cualquier reproductor en el mercado será capaz de reproducir. Además, junta todos nuestros capitulos en un único fichero:&lt;br /&gt;&lt;br /&gt;$mencoder -oac mp3lame -ovc xvid -xvidencopts vhq=1:bitrate=2200:nopacked:nogmc:noqpel:nocartoon:bvhq=0:max_bframes=2:quant_type=mpeg ficheros_entrada.* -o fichero_salida.avi&lt;br /&gt;&lt;br /&gt;Espero os sea util.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2273667591311466469?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2273667591311466469/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/dvd-rip-en-ubuntu-910.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2273667591311466469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2273667591311466469'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/dvd-rip-en-ubuntu-910.html' title='DVD Rip en Ubuntu 9.10'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8704008847087707080</id><published>2009-12-18T19:22:00.000Z</published><updated>2009-12-18T19:22:05.373Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><title type='text'>Monocaffe Connections Manager 0.8</title><content type='html'>Ya está disponible la nueva versión de MCM para ser descargada desde el sitio habitual.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://launchpad.net/mcm/"&gt;http://launchpad.net/mcm/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para esta nueva versión se han arreglado gran variedad de fallos y se han añadido algunos cambios que mejoran la interfaz.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/SyvV-f_sPuI/AAAAAAAAArs/-2RWp8L3RfE/s1600-h/screenshot_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/SyvV-f_sPuI/AAAAAAAAArs/-2RWp8L3RfE/s400/screenshot_002.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="javascript:void(0)"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8704008847087707080?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8704008847087707080/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/monocaffe-connections-manager-08.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8704008847087707080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8704008847087707080'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/monocaffe-connections-manager-08.html' title='Monocaffe Connections Manager 0.8'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/SyvV-f_sPuI/AAAAAAAAArs/-2RWp8L3RfE/s72-c/screenshot_002.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6147802773434532960</id><published>2009-12-07T00:43:00.000Z</published><updated>2009-12-07T00:43:28.414Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='karmic'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu Karmic Koala 9.10 amd64</title><content type='html'>Bah! Esto no es una review, sólo quiero dejar claro los cambios más importantes que he encontrado en ésta nueva versión de Ubuntu. La verdad, no había actualizado porque me sentía bastante cómodo con 8.10 Intrepid Ibex, que es una de las mejores versiones que he utilizado.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Empathy&lt;/span&gt;&lt;br /&gt;El nuevo cliente de mensajería está muy logrado aunque algunas cosillas faltan por arreglar, sólo espero que no empiecen con las mismas luchas internas que hicierón que Pidgin se separase.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Centro de Software de Ubuntu&lt;/span&gt;&lt;br /&gt;Me gusta su facilidad y que vaya instalando las aplicaciones y puedas continuar añadiéndolas a una cola que va instalando según va terminando.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Firefox 3.5&lt;/span&gt;&lt;br /&gt;Aunque llevo mucho tiempo utilizando Shiretoko, se nota la diferencia con la versión estable de FF3.5.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Temas&lt;/span&gt;&lt;br /&gt;Me gusta el nuevo tema por defecto con tonos marrones y grises. Muy sobrio y sencillos, que no molestan.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Ubuntu One&lt;/span&gt;&lt;br /&gt;Solía utilizar Dropbox, pero Ubuntu One se muestra como un gran competidor, espero que no me de los problemas de sincronía que me dio Dropbox.&lt;br /&gt;&lt;span style="font-size: large;"&gt;General&lt;/span&gt;&lt;br /&gt;Como siempre la re-instalación del sistema ha sido cuestión de una hora, como mucho, sin hacer un respaldo de mis datos en /home. Al terminar GNOME ha cogido la configuración de 8.10 sin problemas y ha cargado los widgets, fondo de pantalla y tema sin quejarse. Los nuevos "globos de aviso" o como se llamen, parecen un poco desfasados ya que aparecen en un sitio extraño, pero tengo entendido que esto es a propósito (Not a Bug, a feature), así que a probarlo. Tampoco es que como si aparecieran cada 5 minutos como en otros OS's.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Conclusión&lt;/span&gt;&lt;br /&gt;Estoy muy contento con la nueva versión que no me ha dado ningún problema y veo que Canonical está siguiendo un buen camino.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6147802773434532960?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6147802773434532960/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/ubuntu-karmic-koala-910-amd64.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6147802773434532960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6147802773434532960'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/ubuntu-karmic-koala-910-amd64.html' title='Ubuntu Karmic Koala 9.10 amd64'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3064762596361523372</id><published>2009-12-07T00:28:00.000Z</published><updated>2009-12-07T00:28:51.961Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><title type='text'>Monocaffe Connections Manage 0.7.5</title><content type='html'>Nueva versión de Monocaffe Connections Manager puede ser descargada desde el sitio habitual:&lt;br /&gt;&lt;a href="http://launchpad.net/mcm/trunk/0.7/+download/mcm-0.7.5.tar.gz"&gt; mcm-0.7.5.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Esta nueva version arregla algunos fallos y añade ciertas mejoras como:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Menu auxiliar de las consolas para: &lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Copiar/Pegar desde/a una consola.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Buscar en google a partir de la selección.&lt;/li&gt;&lt;li&gt;Cambiar el titulo de las pestañas.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;Eso es todo por ahora, aun queda algo de trabajo pero en curso para la release 0.8.&lt;br /&gt;&lt;br /&gt;Screenshot!!!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/SxxMOUuzPSI/AAAAAAAAArc/t3_q8sSNh04/s1600-h/mcm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/SxxMOUuzPSI/AAAAAAAAArc/t3_q8sSNh04/s320/mcm.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3064762596361523372?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3064762596361523372/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/monocaffe-connections-manage-075.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3064762596361523372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3064762596361523372'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/monocaffe-connections-manage-075.html' title='Monocaffe Connections Manage 0.7.5'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/SxxMOUuzPSI/AAAAAAAAArc/t3_q8sSNh04/s72-c/mcm.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2672092467680790115</id><published>2009-12-03T09:32:00.000Z</published><updated>2009-12-03T09:32:51.201Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='koala'/><category scheme='http://www.blogger.com/atom/ns#' term='karmic'/><category scheme='http://www.blogger.com/atom/ns#' term='instalacion'/><category scheme='http://www.blogger.com/atom/ns#' term='64'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Karmic 64</title><content type='html'>Hace unos días recibimos en la oficina PC's nuevos que son unos monstruos. El problema fue al intentar instalar las versión amd64 de Ubuntu o de Fedora 12. Ninguna de las versiones Live o Desktop llegaban a arrancar del todo. La solución es tan sencilla como utilizar la versión alternate de Ubuntu. Aunque no nos ofrezca una instalación gráfica y tarde un poco más, funciona.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2672092467680790115?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2672092467680790115/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/karmic-64.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2672092467680790115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2672092467680790115'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/karmic-64.html' title='Karmic 64'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-913066562356239205</id><published>2009-12-02T13:31:00.000Z</published><updated>2009-12-02T13:31:05.169Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='corrupcion'/><category scheme='http://www.blogger.com/atom/ns#' term='politicos'/><category scheme='http://www.blogger.com/atom/ns#' term='manifiesto'/><title type='text'>Manifiesto: En defensa de los derechos fundamentales en Internet</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;Ante la inclusión en el Anteproyecto de Ley de Economía sostenible de modificaciones legislativas que afectan al libre ejercicio de las libertades de expresión, información y el derecho de acceso a la cultura a través de Internet, los periodistas, bloggers, usuarios, profesionales y creadores de internet manifestamos nuestra firme oposición al proyecto, y declaramos que…&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;1.- Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;2.- La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;3.- La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;4.- La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;5.- Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;6.- Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;7.- Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;8.- Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;9.- Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;10.- En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;i&gt;Este manifiesto, elaborado de forma conjunta por varios autores, es de todos y de ninguno. Si quieres sumarte a él, difúndelo por Internet.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;i&gt;#Manifiesto&lt;br /&gt;@iescolar&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-913066562356239205?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/913066562356239205/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/12/manifiesto-en-defensa-de-los-derechos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/913066562356239205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/913066562356239205'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/12/manifiesto-en-defensa-de-los-derechos.html' title='Manifiesto: En defensa de los derechos fundamentales en Internet'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7653100039048549201</id><published>2009-11-25T10:13:00.000Z</published><updated>2009-11-25T10:13:59.111Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><title type='text'>Monocaffe Connections Manager 0.7</title><content type='html'>Monocaffe Connections Manager 0.7 está lista para ser descargada. Esta nueva versión contiene:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Configuración visual de las consolas (transparencia, fuente, colores)&lt;/li&gt;&lt;li&gt;Configuración de los clientes (binario y opciones por defecto)&lt;/li&gt;&lt;li&gt;Permite modificar fácilmente las conexiones.&lt;/li&gt;&lt;li&gt;Reordenado de las pestañas&lt;/li&gt;&lt;li&gt;Ayuda en linea&lt;/li&gt;&lt;li&gt;Instalación automatizada&lt;/li&gt;&lt;li&gt;Paquete .deb para Ubuntu &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Monocaffe Connections Manager 0.7 is ready for download. This new version adds:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Visual configuration of consoles.&lt;/li&gt;&lt;li&gt;Clients configurations (binary and default options).&lt;/li&gt;&lt;li&gt;Easily modify connections data.&lt;/li&gt;&lt;li&gt;Tabs rearrangement&lt;/li&gt;&lt;li&gt;Online Help&lt;/li&gt;&lt;li&gt;Automatic instalation by distutils&lt;/li&gt;&lt;li&gt;Ubuntu package&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;ScreenShots!!!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/Sw0CgeTiqhI/AAAAAAAAArM/uUm3fu9iLOk/s1600/mcm_4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/Sw0CgeTiqhI/AAAAAAAAArM/uUm3fu9iLOk/s320/mcm_4.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_GKVx1yC7np0/Sw0CuhCUJII/AAAAAAAAArU/_2bXkahQiSY/s1600/Screenshot-Preferences.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_GKVx1yC7np0/Sw0CuhCUJII/AAAAAAAAArU/_2bXkahQiSY/s320/Screenshot-Preferences.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7653100039048549201?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7653100039048549201/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-07.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7653100039048549201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7653100039048549201'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-07.html' title='Monocaffe Connections Manager 0.7'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/Sw0CgeTiqhI/AAAAAAAAArM/uUm3fu9iLOk/s72-c/mcm_4.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6766271862335745826</id><published>2009-11-20T17:42:00.000Z</published><updated>2009-11-20T17:42:32.604Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Monocaffe Connections Manager 0.6</title><content type='html'>Monocaffe Connections Manager 0.6 está lista para ser descargada. Además de arreglar algunos fallos he añadido una caracteristica genial, un línea de comandos en cluster. Marcando diferentes pestañas y luego escribiendo en la parte inferior, se verá reflejado en todas las pestañas marcadas. De ésta forma podemos trabajar en varias maquinas a la vez.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sites.google.com/site/monocaffe/_/rsrc/1258675651708/home/mcm/help/mcm_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="353" src="http://sites.google.com/site/monocaffe/_/rsrc/1258675651708/home/mcm/help/mcm_3.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Tambien he arreglado algunos bugs y añadido otros :-) los podeis ver en el launchpad de mcm en &lt;a href="http://launchpad.net/mcm"&gt;http://launchpad.net/mcm &lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Finalmente, me gustaria añadir una version hecha en Qt para KDE, pero prefiero continuar afinando las versiones de consola y de GTK, por lo que si alguien está interesado, que me deje un comentario aquí o en launchpad.&lt;br /&gt;&lt;br /&gt;Pronto haré una entrada sobre todo el proceso para poder montar un paquete en launchpad para Ubuntu, siempre que me acuerde de todos los pasos, porque es lioso de cojones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6766271862335745826?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6766271862335745826/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-06.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6766271862335745826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6766271862335745826'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-06.html' title='Monocaffe Connections Manager 0.6'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6226032009231118120</id><published>2009-11-16T00:21:00.000Z</published><updated>2009-11-16T00:21:34.669Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='version'/><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='gtk'/><category scheme='http://www.blogger.com/atom/ns#' term='new'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Monocaffe Connections Manager 0.5.3</title><content type='html'>La primera versión de &lt;a href="http://sites.google.com/site/monocaffe/home/mcm"&gt;mcm&lt;/a&gt; con el GUI GTK ya está listo para &lt;a href="http://sites.google.com/site/monocaffe/home/mcm/mcm-0.5.3.tgz?attredirects=0&amp;amp;d=1"&gt;descargarse&lt;/a&gt;. La versión en terminal no conlleva cambios importantes. La nueva versión en GTK está evolucionando incluso para convertirse en un reemplazo de las tipicas terminales, con distintas opciones para abrir pestañas en local y hacia las distintas conexiones. Se agradecen comentarios.&lt;br /&gt;&lt;br /&gt;New version of &lt;a href="http://sites.google.com/site/monocaffe/home/mcm"&gt;mcm&lt;/a&gt; with a GTK GUI. The terminal version hasn't changed since all changes apply to the new front-end. The new GTK version is evolving into a full replacement for a typical terminal application, with different options to open tabs on localhost and to the different connections. Comments are welcome.&lt;br /&gt;&lt;br /&gt;Screenshots!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_GKVx1yC7np0/SwCap82dz4I/AAAAAAAAArE/Cl78mawo2ik/s1600-h/mcm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_GKVx1yC7np0/SwCap82dz4I/AAAAAAAAArE/Cl78mawo2ik/s320/mcm.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif; font-size: xx-small;"&gt;Main Window&lt;/span&gt;&lt;/i&gt; &lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&amp;nbsp;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/SwCan_CX1XI/AAAAAAAAAq8/FqfzaL_nyVY/s1600-h/add.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/SwCan_CX1XI/AAAAAAAAAq8/FqfzaL_nyVY/s320/add.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: xx-small;"&gt;&lt;i&gt;Add a new connection&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6226032009231118120?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6226032009231118120/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-053.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6226032009231118120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6226032009231118120'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-053.html' title='Monocaffe Connections Manager 0.5.3'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GKVx1yC7np0/SwCap82dz4I/AAAAAAAAArE/Cl78mawo2ik/s72-c/mcm.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8837998573393881883</id><published>2009-11-15T23:22:00.000Z</published><updated>2009-11-15T23:22:19.008Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>My Tools of the Trade</title><content type='html'>Como todo buen artesano, todos tenemos nuestras herramientas preferidas a las hora de trabajar, siguiendo el ejemplo de éste &lt;a href="http://ucosp.wordpress.com/2009/10/22/my-tools-of-the-trade/"&gt;blog&lt;/a&gt; que me ha dado la idea y ya habiendo terminado por hoy con la versión GTK de mcm, voy a continuar éste &lt;a href="http://es.wikipedia.org/wiki/Meme"&gt;meme&lt;/a&gt;:&lt;br /&gt;Hardware:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;En casa prefiero utilizar mi portátil Thinkpad T42 que ya tiene sus años pero sigue funcionando de maravilla gracias a Ubuntu 8.10&lt;br /&gt;&lt;/li&gt;&lt;li&gt;En el trabajo, un HP Pentium IV algo antiguo pero gracias a Ubuntu, funciona muy bien. Con una pantalla de 17''. En unos dias nos los van a cambiar por unos mejores con pantallas de 22''. Que ganas!!!&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Software:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ubuntu Linux Intrepid Ibex.&lt;/li&gt;&lt;li&gt;Gnome Terminal siempre está abierto, deberia añadirlo al inicio de sesión de GNOME.&lt;/li&gt;&lt;li&gt;Firefox tambien deberia iniciarse con la sesión.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Echofon (Twitter)&lt;/li&gt;&lt;li&gt; Download Status Bar&lt;/li&gt;&lt;li&gt;GMarks&lt;/li&gt;&lt;li&gt;NoScripts&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;VIM para todo lo que no sea Java.&lt;/li&gt;&lt;li&gt;Eclipse para todo lo que sea Java.&lt;/li&gt;&lt;li&gt;SQuirreL SQL Client para todo lo que sea BBDD.&lt;/li&gt;&lt;li&gt;DIA para cuando necesito abordar un problema de forma gráfica.&lt;/li&gt;&lt;li&gt;Evolution para mis correos.&lt;/li&gt;&lt;li&gt;Gaim&lt;/li&gt;&lt;li&gt;Sin SSH el mundo no sería lo que es :)&lt;/li&gt;&lt;li&gt;Finalmente, y no por echarme flores, cada vez utilizo más y más mcm, que además si falla en algo, sé arreglarlo. De hecho he añadido la opción de abrir una consola local.&lt;/li&gt;&lt;/ul&gt;Utilizo muchas otras, pero diariamente, estas son las herramientas que siempre se encuentran abiertas en mis escritorios virtuales.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8837998573393881883?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8837998573393881883/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/my-tools-of-trade.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8837998573393881883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8837998573393881883'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/my-tools-of-trade.html' title='My Tools of the Trade'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8157150850850513965</id><published>2009-11-13T00:33:00.002Z</published><updated>2010-03-02T17:22:01.720Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='touch'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ipod'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Maldito iPod Touch</title><content type='html'>Necesito desfogarme para paliar un poco el odio que me merece Apple y todos sus productos. Hace unos dias, la empresa nos regalo a todos un iPod Touch de 8GB que realmente se agradece, es un dispositivo realmente hermoso, pero ya.&lt;br /&gt;Es increible lo complicado que es utilizar el cacharro si tienes Linux cuando el mismo iPod utiliza Darwin, MacOS es un maldito Darwin con colorines y los anormales de Apple son incapaces de sacar un maldito iTunes multiplataforma.&lt;br /&gt;¿Por qué? Sencillamente porque no les sale de los cojones al igual que a mi no me sale comprar un jodido Mac aunque me venga la vida en ello, seguiré repudiando todo lo que venga con la manzana.&lt;br /&gt;Desde el mismo primer maldito momento que lo enciendes ya te está tocando los cojones ¿tengo que soltar más de 100€ para poder utilizar el elemento electrónico éste? Va a ser que no Mr. Jobs. Luego también espera que descargue música de su iTunes Store o como cojones se llame ¿para qué? ¿para que el día que el cacharro se quede sin pila y no quiera pasar por caja pierda todas estas? Otra vez, no.&lt;br /&gt;Es irónico, mi primera computadora fue un Macintosh y sigo pensando que era un gran equipo con una excelente tecnología para su época.&lt;br /&gt;Mis desprecios a Apple.&lt;br /&gt;P.S. He hecho el jailbreak, instalado el mplayer y metido pelis via scp, por lo que al menos mi hija lo podrá utilizar para ver pelis... todo muy legal, sí señor.&lt;br /&gt;&lt;br /&gt;Last Update: Al final se lo regalé a mi hermana que si tiene un MacBookPro y le gustan las chorradas de Apple. Que lo disfrute.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8157150850850513965?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8157150850850513965/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/maldito-ipod-touch.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8157150850850513965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8157150850850513965'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/maldito-ipod-touch.html' title='Maldito iPod Touch'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8892381892376464689</id><published>2009-11-08T13:28:00.000Z</published><updated>2009-11-08T13:28:48.677Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='modulo'/><category scheme='http://www.blogger.com/atom/ns#' term='directorios'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='estructura'/><title type='text'>Estructura aplicaciones PyGTK</title><content type='html'>Quiero explicaros una de las cosas que veo menos en los tutoriales y es sobre las estructuras de directorios para aplicaciones Python. Sigue una estructura parecida a las de Unix (¿POSIX?). Esta es la que he seguido para &lt;a href="http://sites.google.com/site/monocaffe/home/mcm"&gt;mcm&lt;/a&gt; y estoy bastante satisfecho con ella, por lo que voy a utilizarla como ejemplo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;mcm&lt;/li&gt;&lt;ul&gt;&lt;li&gt;doc&lt;/li&gt;&lt;ul&gt;&lt;li&gt;INSTALL&lt;/li&gt;&lt;li&gt;CHANGELOG&lt;/li&gt;&lt;li&gt;BUGS&lt;/li&gt;&lt;li&gt;manpage&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;conf&lt;/li&gt;&lt;li&gt;logs &lt;br /&gt;&lt;/li&gt;&lt;li&gt;bin&lt;/li&gt;&lt;ul&gt;&lt;li&gt;mcm.sh &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;mcm&lt;/li&gt;&lt;ul&gt;&lt;li&gt;__init__.py&lt;/li&gt;&lt;li&gt;terminal&lt;/li&gt;&lt;ul&gt;&lt;li&gt;__init__.py &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;common&lt;/li&gt;&lt;ul&gt;&lt;li&gt;__init__.py&lt;/li&gt;&lt;li&gt;utils.py&lt;/li&gt;&lt;li&gt;models.py&lt;/li&gt;&lt;li&gt;controllers.py&lt;/li&gt;&lt;li&gt;exceptions.py&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;gtk&lt;/li&gt;&lt;ul&gt;&lt;li&gt;__init__.py&lt;/li&gt;&lt;li&gt;mcm-gtk.py&lt;/li&gt;&lt;li&gt;mcm.glade&lt;/li&gt;&lt;li&gt;mcm_icon.png&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;qt&lt;/li&gt;&lt;ul&gt;&lt;li&gt;__init__.py&lt;/li&gt;&lt;li&gt;mcm-qt.gtk&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;Una aplicación no es sólo el código fuente, por lo que el orden en la documentación, ficheros de configuración y otros, merecen un lugar donde desarrollarse de forma independiente al desarrollo de la aplicación misma.&lt;br /&gt;Cada páquete o modulo de Python es definido por el fichero __ini__.py y serán estos los que podremos importar dentro de nuestros modulos y conseguir un empaquetado bien definido que nos permitira cumplir con facilidad el principio DRY.&lt;br /&gt;De igual forma podemos ver que la misma estrúctura de directorios define un modelo MVC lo que facilita mucho el desarrollo para diferentes presentaciones. En &lt;a href="http://sites.google.com/site/monocaffe/home/mcm"&gt;mcm&lt;/a&gt;, reutilizamos las clases y métodos definidos para la aplicación CLI en las aplicaciones gráficas para GTK y Qt. Esto lo logramos, en el caso de GTK definiendo distintos eventos que utilizan a los controladores para crear y modificar nuestros modelos. Por ejemplo veamos como añadimos una conexión desde la vista GTK:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;def add_event(self, widget):&lt;/li&gt;&lt;li&gt;&amp;nbsp; &amp;nbsp; # Obtenemos de distintas formas los datos necesarios&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection = connections.connections_factory(x, y, z, a, b, c, d)&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; connections.append(connection)&lt;/li&gt;&lt;li&gt;def save_and_quit(self):&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dao = Dao()&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dao.save(connections)&lt;/li&gt;&lt;/ul&gt;Lo mejor es que esto mismo lo hacemos en la parte Qt y cualquier otra vista que se nos ocurra.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8892381892376464689?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8892381892376464689/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/estructura-aplicaciones-pygtk.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8892381892376464689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8892381892376464689'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/estructura-aplicaciones-pygtk.html' title='Estructura aplicaciones PyGTK'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7100958896536515665</id><published>2009-11-06T11:56:00.000Z</published><updated>2009-11-06T11:56:26.177Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='vimdiff'/><category scheme='http://www.blogger.com/atom/ns#' term='vimrc'/><title type='text'>Diferentes configuraciones para vim y vimdiff</title><content type='html'>Vimdiff es una utilidad muy importante de vim. Nos muestra en colores las diferencias entre dos o más ficheros o directorios y además podemos utilizarla como herramienta de "merge".&lt;br /&gt;Dado que vimdiff es sencillamente vim en modo diff, se carga el mismo fichero .vimrc. Asi que si deseamos definir distintas opciones según el modo que utilicemos os propongo ésta solución:&lt;br /&gt;&lt;br /&gt;Crear una función como:&lt;br /&gt;function Vimdiff()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nmap &amp;lt;F7&amp;gt; [czz&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nmap &amp;lt;F8&amp;gt; ]czz&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nmap &amp;lt;F2&amp;gt; do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nmap &amp;lt;F3&amp;gt; dp&lt;br /&gt;endfunction&lt;br /&gt;&lt;br /&gt;Y a continuación la magia, añadimos al final de nuestro .vimrc lo siguiente:&lt;br /&gt;au FilterWritePre * if &amp;amp;diff | call Vimdiff() | endif&lt;br /&gt;&lt;br /&gt;He definido que las teclas F7 y F8 vayan a la anterior y posterior diferencia y centren la pantalla en estas. Las teclas F2 y F3 mueven los cambios de un lado del buffer al otro.&lt;br /&gt;&lt;br /&gt;Espero os sea útil.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7100958896536515665?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7100958896536515665/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/diferentes-configuraciones-para-vim-y.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7100958896536515665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7100958896536515665'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/diferentes-configuraciones-para-vim-y.html' title='Diferentes configuraciones para vim y vimdiff'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-8877395573929998689</id><published>2009-11-06T11:16:00.000Z</published><updated>2009-11-06T11:16:26.309Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='connections'/><category scheme='http://www.blogger.com/atom/ns#' term='version'/><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='monocaffe'/><category scheme='http://www.blogger.com/atom/ns#' term='new'/><category scheme='http://www.blogger.com/atom/ns#' term='manager'/><title type='text'>Monocaffe Connections Manager 0.4</title><content type='html'>Nueva versión de &lt;b&gt;mcm&lt;/b&gt; para lo cual he creado un nuevo sitio para mantener toda la información al respecto.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/monocaffe/home/mcm"&gt;&amp;nbsp;&lt;span style="font-size: small;"&gt;&lt;span id="sites-page-title"&gt;Monocaffe Connections Manager&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Esta nueva versión añade la posibilidad de importar un fichero CSV generado a partir de una hoja de cálculo y de exportar a un fichero HTML. Tambien he añadido conexiones HTTP para consolas de Jboss. Además he iniciado la creación de la aplicación en GTK, por lo cual he añadido la opción de grupos para facilitar la ordenación. Finalmente he mejorado la introducción de opciones para los distintos clientes, por lo que ahora se pueden definir incluso túneles SSH.&lt;br /&gt;&lt;br /&gt;Descargad desde el sitio del proyecto.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-8877395573929998689?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/8877395573929998689/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-04.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8877395573929998689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/8877395573929998689'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/11/monocaffe-connections-manager-04.html' title='Monocaffe Connections Manager 0.4'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-560172231905323377</id><published>2009-10-28T18:49:00.000Z</published><updated>2009-10-28T18:49:17.404Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='wifi'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='live'/><category scheme='http://www.blogger.com/atom/ns#' term='xbox'/><title type='text'>Xbox Live Bridge</title><content type='html'>El siguiente es un sencillo script para crear un bridge y poder conectar una Xbox utilizando la wifi de un portátil. Si tienes la WiFi de la Xbox esto no hace falta.&lt;br /&gt;&lt;br /&gt;Lo que hace es crear un bridge utilizando IPTables que enruta el tráfico entre las dos interfaces. Solo hay que cambiar en el script el nombre de las interfaces de red.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.getdropbox.com/u/1181828/xboxlive-bridge.sh"&gt;Descargad&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-560172231905323377?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/560172231905323377/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/10/xbox-live-bridge.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/560172231905323377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/560172231905323377'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/10/xbox-live-bridge.html' title='Xbox Live Bridge'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7906723190379522860</id><published>2009-10-28T17:05:00.001Z</published><updated>2009-10-29T15:08:23.529Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rdp'/><category scheme='http://www.blogger.com/atom/ns#' term='connections'/><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='telnet'/><category scheme='http://www.blogger.com/atom/ns#' term='ftp'/><category scheme='http://www.blogger.com/atom/ns#' term='vnc'/><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='manager'/><title type='text'>Monocaffe Connections Manager 0.3</title><content type='html'>He terminado la versión 0.3 de MCM. Si tenemos "dialog" instalado, al ejecutar sin ningún argumento, nos mostrará un menú con los servidores y con pulsar ENTER sobre alguno, abrirá la conexión. También he cambiado el fichero .mcm donde se guardan los datos de las conexiones para utilizar XML y eliminar un pequeño bug que había. También he añadido conexiones FTP.&lt;br /&gt;&lt;br /&gt;Podéis descargarlo desde &lt;a href="http://dl.getdropbox.com/u/1181828/monocaffe_connections_manager-0.3.tar.gz"&gt;aqui&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This software is designed to ease the management of connections to several types of servers. Since I  couldn't find any solution to handle all types of connections from a console, mcm was born. The idea is to avoid having to maintain a separate spreadsheet or wiki page with all the servers I usually connect to and keep that monster open during my work sessions.&lt;br /&gt;There are other solutions, but each handled either ssh only connections, or graphical connections (like vnc). Also, this graphical connections managers were designed to have a GUI and a single command from the console is what I wanted.&lt;br /&gt;My main objective is to provide a fast and reliable mean to store the information of this connections and be able to reach them fast and easily.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dl.getdropbox.com/u/1181828/monocaffe_connections_manager-0.3.tar.gz"&gt;Click here to download version 0.3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Screenshot!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_GKVx1yC7np0/Sumv3D6BLkI/AAAAAAAAAq0/oMraYVuO_78/s1600-h/shot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_GKVx1yC7np0/Sumv3D6BLkI/AAAAAAAAAq0/oMraYVuO_78/s320/shot1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7906723190379522860?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7906723190379522860/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/10/monocaffe-connections-manager-03.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7906723190379522860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7906723190379522860'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/10/monocaffe-connections-manager-03.html' title='Monocaffe Connections Manager 0.3'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GKVx1yC7np0/Sumv3D6BLkI/AAAAAAAAAq0/oMraYVuO_78/s72-c/shot1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-981434211297861995</id><published>2009-10-22T17:48:00.003+01:00</published><updated>2009-10-22T18:00:32.350+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='connections'/><category scheme='http://www.blogger.com/atom/ns#' term='monocaffe'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='manager'/><title type='text'>Monocaffe Connections Manager 0.2</title><content type='html'>En un par de horas y ya lanzo la versión 0.2, esto es desarrollo ágil. Gracias a bob_f en el canal de #python en FreeNode he mejorado la presentación de las listas. Además de ello he arreglado un fallo con el RDP y bueno, me he acordado que Dropbox permite publicar cosas. Así que aquí os dejo la última versión.&lt;br /&gt;&lt;br /&gt;Descargar &lt;a href="http://dl.getdropbox.com/u/1181828/monocaffe_connections_manager-0.2.tar.gz"&gt;Monocaffe Connections Manager 0.2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Unas capturas&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_GKVx1yC7np0/SuCPhBRBdLI/AAAAAAAAAqs/4RjhKMMFs_Y/s1600-h/mcm2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 246px; height: 179px;" src="http://4.bp.blogspot.com/_GKVx1yC7np0/SuCPhBRBdLI/AAAAAAAAAqs/4RjhKMMFs_Y/s400/mcm2.png" alt="" id="BLOGGER_PHOTO_ID_5395470151028143282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_GKVx1yC7np0/SuCPgyxUoCI/AAAAAAAAAqk/-i_2jrHolJM/s1600-h/mcm1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 336px; height: 400px;" src="http://2.bp.blogspot.com/_GKVx1yC7np0/SuCPgyxUoCI/AAAAAAAAAqk/-i_2jrHolJM/s400/mcm1.png" alt="" id="BLOGGER_PHOTO_ID_5395470147137085474" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-981434211297861995?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/981434211297861995/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/10/monocaffe-connections-manager-02.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/981434211297861995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/981434211297861995'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/10/monocaffe-connections-manager-02.html' title='Monocaffe Connections Manager 0.2'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GKVx1yC7np0/SuCPhBRBdLI/AAAAAAAAAqs/4RjhKMMFs_Y/s72-c/mcm2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-2936790406306292527</id><published>2009-10-22T15:11:00.004+01:00</published><updated>2009-10-22T15:38:13.386+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='connections'/><category scheme='http://www.blogger.com/atom/ns#' term='mcm'/><category scheme='http://www.blogger.com/atom/ns#' term='monocaffe'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='manager'/><title type='text'>Monocaffe Connections Manager 0.1</title><content type='html'>Llevaba algún tiempo con esta idea rondandome la cabeza. Odio tener que abrir una hoja de cálculo o un página en una Wiki cada vez que necesito recordar los datos para conectarme a cierta máquina. Dado que todo esto lo hago desde una consola, otras soluciones que de todas formas no me convencían, funcionan sólo sobre el entorno gráfico (p.e. PuTTy).&lt;br /&gt;Así que, utilizando Python he creado una pequeña aplicación para mantener una lista con todos los servidores a los que me conecto y almacenar nombre, contraseña, conexión, etc. Está listo para funcionar sobre Ubuntu, pero es fácil de modificar para otras distribuciones en caso de ser necesario. Quizás algún día lo añadan a los repositorios de Debian.&lt;br /&gt;Para el futuro me gustaría añadir una interfaz ncurses, GTK y Qt, sólo por hobbie.&lt;br /&gt;Para instalarla:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;$tar -xvzf monocaffe_connections_manager-0.1.tar.gz&lt;/li&gt;&lt;li&gt;$cd mcm&lt;/li&gt;&lt;li&gt;$chmod 766 mcm&lt;/li&gt;&lt;/ol&gt;Si queréis instalarla como es debido:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;$tar -xvzf monocaffe_connections_manager-0.1.tar.gz&lt;/li&gt;&lt;li&gt;$sudo mv mcm /usr/share&lt;/li&gt;&lt;li&gt;$sudo chown -R root.root /usr/share/mcm&lt;/li&gt;&lt;li&gt;$sudo chmod 777 /usr/share/mcm/mcm&lt;br /&gt;&lt;/li&gt;&lt;li&gt;$cd /usr/bin/&lt;/li&gt;&lt;li&gt;$sudo ln -s /usr/share/mcm/mcm mcm&lt;/li&gt;&lt;/ol&gt;Supongo que tocara hacer un MakeFile para esto o incluso un .deb&lt;br /&gt;Para descargar&lt;br /&gt;&lt;ul&gt;&lt;li&gt;$wget http://rapidshare.com/files/296414487/monocaffe_connections_manager-0.1.tar.gz.html&lt;/li&gt;&lt;/ul&gt;O pulsando &lt;a href="http://rapidshare.com/files/296414487/monocaffe_connections_manager-0.1.tar.gz.html"&gt;aquí&lt;/a&gt;&lt;br /&gt;Espero le encontréis utilidad.&lt;br /&gt;El enlace de RapidShare es temporal, por lo que si veo que mucha gente se lo descarga (dejadme un comentario aquí si no funciona y lo arreglo)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-2936790406306292527?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/2936790406306292527/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/10/monocaffe-connections-manager-01.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2936790406306292527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/2936790406306292527'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/10/monocaffe-connections-manager-01.html' title='Monocaffe Connections Manager 0.1'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-6046092886452449963</id><published>2009-10-14T12:26:00.003+01:00</published><updated>2009-10-14T12:31:58.824+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='yast2'/><category scheme='http://www.blogger.com/atom/ns#' term='suse'/><title type='text'>Paquetes con Yast e imagenes ISO</title><content type='html'>Cuando intentamos instalar unos paquetes utilizando Yast2 y se pone algo tonto con el tema de no tener los CD's ya que es más cómodo mantener las ISO's de los mismos, podemos utilizar la siguiente linea para indicarlo:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;br /&gt;iso:///?iso=SLES-9-i386-RC5-CD1.iso&amp;url=dir:////opt/imagenes/&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Con esto no hace falta montar las imagenes, ni grabar CD's ni hostias.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-6046092886452449963?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/6046092886452449963/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/10/paquetes-con-yast-e-imagenes-iso.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6046092886452449963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/6046092886452449963'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/10/paquetes-con-yast-e-imagenes-iso.html' title='Paquetes con Yast e imagenes ISO'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7237761230432999429</id><published>2009-09-11T12:49:00.002+01:00</published><updated>2009-09-11T12:56:59.795+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='favoritos'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='trucos'/><title type='text'>Favoritos en BASH</title><content type='html'>Día a día, podemos pasar horas cambiando de directorios con 'cd' por lo que estaría bien que tuvieramos ciertos favoritos definidos para navegar entre los directorios que más usamos.&lt;br /&gt;&lt;br /&gt;Por ejemplo, &lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;/opt/jboss/server/default/&lt;/span&gt; suele ser un directorio al que vuelvo muchas veces durante el día, así que voy a definir un favorito utilizando 'alias':&lt;br /&gt;&lt;br /&gt;&lt;ol style="font-family: 'courier';"&gt;&lt;li&gt;$ alias jb="cd /opt/jboss/server/default/"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;De esta forma, la próxima vez, con ejecutar 'jb' me llevará a ese directorio.&lt;br /&gt;&lt;br /&gt;Ahora vayamos un poco más lejos e intentemos hacer de esto algo un poco más genérico. Abrimos nuestro fichero &lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;~/.bashrc&lt;/span&gt; y añadimos las siguientes lineas&lt;br /&gt;&lt;br /&gt;&lt;ol style="font-family: 'courier';"&gt;&lt;li&gt;# Favoritos&lt;/li&gt;&lt;li&gt;alias m1='alias g1="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m2='alias g2="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m3='alias g3="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m4='alias g4="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m5='alias g5="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m6='alias g6="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m7='alias g7="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m8='alias g8="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias m9='alias g9="cd `pwd`"'&lt;/li&gt;&lt;li&gt;alias favs='alias|grep -e "alias g[0-9]"|grep -v "alias m"'&lt;/li&gt;&lt;li&gt;alias favsave='alias|grep -e "alias g[0-9]"|grep -v "alias m" &gt; ~/.favs'&lt;/li&gt;&lt;li&gt;alias favload='alias | grep -e "alias g[0-9]"|grep -v "alias m"|sed "s/alias //"'&lt;/li&gt;&lt;li&gt;touch ~/.favs&lt;/li&gt;&lt;li&gt;source ~/.favs&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Las primeras nueve lineas definen los aliases que vamos a utilizar para crear y utilizar nuestros favoritos. Si deseamos marcar un directorio, utilizamos '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;m1&lt;/span&gt;' y para volver a éste, ejecutamos '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;g1&lt;/span&gt;'&lt;br /&gt;&lt;br /&gt;El alias '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;favs&lt;/span&gt;' nos muestra la lista de favoritos cargados en el entorno. El alias '&lt;span style="color: rgb(51, 204, 0); font-weight: bold;"&gt;favsave&lt;/span&gt;' almacena nuestros favoritos en el fichero &lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;.favs&lt;/span&gt; y los volvemos a cargar con '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;favload&lt;/span&gt;'. Esto es así, porque al terminar una sesión, todos los aliases que teníamos definidos se perderán sino los almacenamos. El alias '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;favsave&lt;/span&gt;' podemos añadirlo al fichero '&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;bash_logout&lt;/span&gt;' para que cada vez que termine la sesión, se guarden automáticamente.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7237761230432999429?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7237761230432999429/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/09/favoritos-en-bash.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7237761230432999429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7237761230432999429'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/09/favoritos-en-bash.html' title='Favoritos en BASH'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7141700055711529949</id><published>2009-09-08T09:03:00.003+01:00</published><updated>2009-09-08T09:14:10.962+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='outlet'/><category scheme='http://www.blogger.com/atom/ns#' term='españa'/><category scheme='http://www.blogger.com/atom/ns#' term='estafa'/><title type='text'>Outlets</title><content type='html'>Como comenté en la entrada anterior, una de las cuentas que sigo en Twitter es la del outlet de Dell UK (@DellOutletUK) y siempre estoy observando muy buenas ofertas que tienen. Si conectas al sitio web, resulta que tienen muchas más ofertas de refurbished. Esta palabreja es muy importante para la economía (para la mía al menos), y viene a definir aquellos equipos que luego de ser devueltos al fabricante, ya sea por fallos o por otras razones, vuelven a ser vendidos a un menor precio y con una garantía de menor duración. Algunas ofertas superan el 50% del valor del equipo nuevo y otras son configuraciones especificas que no se encuentran en los equipos del catalogo. Por ejemplo, mirad este &lt;a href="http://outlet.lenovo.com/laptops/ca7762rb1.html"&gt;Lenovo X61&lt;/a&gt; con un precio de venta de US$2.152 y un precio de outlet de US$692.&lt;br /&gt;Esto es así en UK y en EE.UU. aun más, ya que casi todos los fabricantes tienen un "outlet" y las ofertas de Dell, Lenovo y Apple son ciertamente alucinantes para el bolsillo. El problema está cuando empiezas a utilizar el TLD &lt;span style="font-weight: bold;"&gt;.es&lt;/span&gt; y te das cuenta de que la palabra outlet ni siquiera existe para los mismos fabricantes con tan jugosas ofertas. Ni Apple, Lenovo o Dell, ofrecen (no al menos de manera tan clara como los anglosajones) un outlet donde comprar con tan ventajosas ofertas. Y esto me hace dudar sobre sus productos que todos suponemos como "nuevos" ya que me intriga saber qué es lo que hacen con todos los ordenadores que por cualquier razón les son devueltos por los consumidores. ¿Les cambian el teclado y los venden en outlet extranjeros? Puede, aunque resulta una solución costosa. ¿Nos venden como nuevo un portátil refurbished? Es muy probable, y no tienes forma segura de saberlo. ¿Los tiran a la basura porque al cliente no le gusto el color de los píxeles? Lo dudo mucho, a alguna parte han de ir, pero a un outlet &lt;span style="font-weight: bold;"&gt;.es&lt;/span&gt; no.&lt;br /&gt;Voy a indagar un poco más sobre éste asunto y si algún lector conoce la respuesta a estas dudas, que deje un comentario.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7141700055711529949?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7141700055711529949/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/09/outlets.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7141700055711529949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7141700055711529949'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/09/outlets.html' title='Outlets'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-3063380345644588294</id><published>2009-08-13T09:00:00.003+01:00</published><updated>2009-08-13T09:19:47.472+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Life's a Tweet</title><content type='html'>Hoy, finalmente, después de meses utilizando Twitter y con 7 seguidores (qué patético) y siguiendo a unas  12 he descubierto tres cosas para las que twitter sirve:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Enterarte de ofertas de fabricantes como Dell @delloutletuk&lt;/li&gt;&lt;li&gt;Seguir a gente con cosas interesantes que decir sobre temas que puedan interesarte como @fourzerotwo quien siempre tiene temas frescos sobre el desarrollo de CoD:MW2&lt;/li&gt;&lt;li&gt;La más interesante, ver cómo dos personas se montan una twitt-novela y se tiran puntas entre ellos, como ahora mismo sucede entre @timoreilly (de O'Reilly) y @TheRealDvorak (John Dvorak).&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Bueno, si tenéis algo interesante que contar, añadir @ubersoldat y os seguire.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-3063380345644588294?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/3063380345644588294/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/08/lifes-tweet.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3063380345644588294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/3063380345644588294'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/08/lifes-tweet.html' title='Life&apos;s a Tweet'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-4618911359558114838</id><published>2009-07-17T11:45:00.004+01:00</published><updated>2009-07-17T11:54:40.714+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comandos'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><title type='text'>El té está listo</title><content type='html'>Después de pasar una semana de fuertes dolores gracias a una gastritis producida por tomar Ibuprofeno, me he aficionado a las infusiones. Esta línea muestra un mensaje de aviso para recordarnos que nuestra bebida está lista:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$sleep 3m &amp;amp;&amp;amp; xmessage -center "Su Te esta listo"&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_GKVx1yC7np0/SmBYLerSSzI/AAAAAAAAAqc/hviumaPHwoY/s1600-h/Screenshot-Untitled+Window.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 152px; height: 80px;" src="http://2.bp.blogspot.com/_GKVx1yC7np0/SmBYLerSSzI/AAAAAAAAAqc/hviumaPHwoY/s400/Screenshot-Untitled+Window.png" alt="" id="BLOGGER_PHOTO_ID_5359380510807313202" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Podemos añadir una función al &lt;i&gt; bashrc &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;function te&lt;br /&gt;{&lt;br /&gt;  $sleep 3m &amp;amp;&amp;amp; xmessage -center "Su Te esta listo"&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Fácil y rápido&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-4618911359558114838?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/4618911359558114838/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/07/el-te-esta-listo.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4618911359558114838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/4618911359558114838'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/07/el-te-esta-listo.html' title='El té está listo'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GKVx1yC7np0/SmBYLerSSzI/AAAAAAAAAqc/hviumaPHwoY/s72-c/Screenshot-Untitled+Window.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-7636386880528137788</id><published>2009-06-18T12:44:00.003+01:00</published><updated>2009-06-18T12:53:18.621+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='tomboy'/><category scheme='http://www.blogger.com/atom/ns#' term='gnote'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Muerte a Tomboy, Larga Vida Gnote</title><content type='html'>Desde hace ya algún tiempo llevo utilizando Tomboy para mantener notas a mano. Es una excelente aplicación por su sencillez y velocidad. Si además, lo hacemos funcionar con Dropbox, pues tendremos nuestras notas en donde las necesitemos.&lt;br /&gt;&lt;br /&gt;Pero siempre he tenido un noséque con Mono que no me gusta. Todo se reduce al tema de ver binarios .EXE en mis sistemas, lo que me da bastante grima&lt;br /&gt;&lt;br /&gt;Aparte de esto, y de otros temas sobre licencias y patentes, las aplicaciones hechas con Mono son excelentes: Monodevelop, F-Spot y Tomboy las más conocidas. De hecho, MonoCaffe se inicio como un proyecto sobre Mono pero que al final decidí reiniciar en un entorno más "limpio" y estable, pero eso es otra historia. La verdad es que Mono no trae nada nuevo a GNU/Linux y dudo que haya algo que sólo se pueda hacer en Mono que no se pueda en ningún otro lenguaje de los ya existentes y sin preocupaciones.&lt;br /&gt;&lt;br /&gt;Dada las &lt;a href="https://fedoraproject.org/wiki/Fedora_12_Alpha_release_notes#GNOME_2.28"&gt;noticias&lt;/a&gt; sobre Fedora eliminando Mono de su distribución (no completamente, se puede instalar, pero de forma opcional) me he enterado de &lt;a href="http://live.gnome.org/Gnote"&gt;Gnote&lt;/a&gt; el cual es igual a Tomboy, excepto por alguna funcionalidad. De hecho, según el sitio de Gnote, éste es un port a C++ lo cual lo hace más rápido que Tomboy.&lt;br /&gt;&lt;br /&gt;El primer problema que encontraremos con las versiones del momento (Junio 2009) es que no existe una funcionalidad para sincronizar notas. La verdad es que con Tomboy esto tampoco funcionaba (de hecho perdí algunas notas por su culpa) pero la formula que utilizaba Tomboy + Dropbox, también funciona con Gnote.&lt;br /&gt;&lt;h1&gt;Adiós Tomboy&lt;/h1&gt;&lt;br /&gt;Gnote trabaja con unos ficheros XML con la extensión ".note" que son los mismos que utiliza Tomboy, por lo que para utilizar nuestras notas de Tomboy en Gnote, sólo tendremos que copiarlas de un directorio a otro:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$cp ~/.tomboy/*.note ~/.gnote/&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;h1&gt;Gnote + Dropbox&lt;/h1&gt;&lt;br /&gt;Dropbox debería ser una herramienta disponible en el "multiverse" de Ubuntu y de todas las distribuciones. La verdad es que es muy útil y sencilla de utilizar. Instalarla es muy sencillo, sólo es necesario ir al sitio &lt;a href="http://www.getdropbox.com/"&gt;Get Dropbox&lt;/a&gt; y descargar el DEB para Ubuntu. A continuación creamos la cuenta de dropbox que nos dará 2GB de forma gratuita y repetimos estos pasos en cada uno de nuestros entornos.&lt;br /&gt;Lo siguiente será añadir Gnote a nuestra barra de herramientas. Dado que no existe dentro del los repositorios de Ubuntu todavía (para Karmic Koala sí) habrá que añadirlo siguiendo las instrucciones &lt;a href="https://launchpad.net/~gnote/+archive/ppa"&gt;aquí detalladas&lt;/a&gt;.&lt;br /&gt;Una vez que tenemos el icono de Gnote, abrimos una consola y ejecutamos el siguiente comando:&lt;br /&gt;$killall gnote&lt;br /&gt;GNOME mostrará una ventana advirtiendo que la aplicación ha dejado de funcionar y si deseamos recargarla. Contestad que no y abrid una instancia de Nautilus y navegad hasta el directorio compartido de Dropbox (~/Dropbox) donde creamos una carpeta llamada "gnote" o "notes" o como queráis.&lt;br /&gt;Lo siguiente será copiar todo el contenido de la carpeta de Gnote (~/.gnote) a esta nueva carpeta que hemos creado y eliminarla.&lt;br /&gt;Finalmente creamos un enlace simbolico llamado ".gnote" al nuevo directorio. En una consola sería algo así:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$killall gnote&lt;br /&gt;$mkdir ~/Dropbox/gnote&lt;br /&gt;$cp ~/.gnote/* ~/Dropbox/gnote/&lt;br /&gt;$mv ~/.gnote /tmp&lt;br /&gt;$ln -s ~/Dropbox/gnote/ ~/.gnote&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Ahora volver a añadir a Gnote a la barra de herramientas y listo. Repetid esto en todos vuestros entornos -&lt;i&gt;menos el paso en el que se copia el directorio ".gnote" ya que borrareis las notas que tengáis&lt;/i&gt;- y siempre tendréis las notas a manos. El mayor inconveniente de esto es que, aunque podremos ver nuestras notas desde el sitio de Dropbox, al estas ser XMLs, no podremos verlas en línea. Habrá que descargarlas y abrirlas en local.&lt;br /&gt;&lt;h1&gt;Adiós Mono&lt;/h1&gt;&lt;br /&gt;Dado que ya podía eliminar Tomboy de mi sistema y no utilizo ninguna otra herramienta basada en Mono, pues podemos hacer algo de limpieza. Para eliminar Mono y todo lo que tenga que ver con éste en Ubuntu, ejecutamos el siguiente comando:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$sudo aptitude purge mono-common libmono0&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Aceptad el calculo de dependencias y esto removerá todo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-7636386880528137788?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/7636386880528137788/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/06/muerte-tomboy-larga-vida-gnote.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7636386880528137788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/7636386880528137788'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/06/muerte-tomboy-larga-vida-gnote.html' title='Muerte a Tomboy, Larga Vida Gnote'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5283565905775887390</id><published>2009-06-08T15:08:00.003+01:00</published><updated>2009-06-08T15:18:06.960+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='criticas'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='estupidez'/><title type='text'>Porque Windows no esta listo para el escritorio</title><content type='html'>No me paso el día diciéndole a la gente cual sistema operativo deben o no utilizar en sus computadoras y por lo visto hay mucha gente que sí, para traerlos a sus blogs, supongo.&lt;br /&gt;&lt;br /&gt;El problema con estas críticas es siempre que el autor tiene ideas preconcebidas sobre que su sistema operativo preferido personifica la única forma de organizar el ecosistema del software y todos los demás son inferiores. Peor aun, dado que solo buscan la manera de justificar sus justificaciones, están totalmente desinformados acerca de sus quejas, las cuales son subjetivas o simplemente erróneas. &lt;br /&gt;&lt;br /&gt;Así que, a forma de parodia de todos los posts, artículos, etc.  Acerca de "Porque Linux no está listo para el escritorio" os traigo esta entrega.&lt;br /&gt;&lt;br /&gt;Sólo vamos a discutir las deficiencias de Windows mientras todos debemos tener en mente que existen áreas en las que ha logrado superar a los demás (¿marketing?).&lt;br /&gt;&lt;br /&gt;En un mundo donde GNU/Linux y sus primos BSD (incluido MacOSX) comparten el 99% de un mercado que se inicio bajo las premisas del OSS  y Windows sólo el 1% con Microsoft a la saga, la blogoesfera estaría repleta de artículos como el siguiente:&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Los mayores fallos y problemas de Windows&lt;/h1&gt;&lt;br /&gt;&lt;h2&gt;Premisa&lt;/h2&gt;&lt;br /&gt;El software libre está para quedarse indefinidamente. A lo largo de los años, se ha comprobado la eficacia de los métodos colaborativos de las comunidades para producir aplicaciones para las masas y donde poco a poco, los métodos de desarrollo cerrados van ganando avances en sectores de gran especialización.&lt;br /&gt;&lt;h2&gt;Seguridad&lt;/h2&gt;&lt;br /&gt;1. El mayor patio de juegos para software malicioso. Con maquinas desactualizadas siendo infectadas en cuestión de minutos al ser conectadas a Internet, para convertirse en esclavas de botnets y formar parte en operaciones ilegales de spam masivo y demás. Windows es una plaga en las infraestructura de Internet.&lt;br /&gt;2.Incontables aplicaciones para Windows, son creadas cada año con fallos de seguridad obvios lo que hace que los programadores de estas, los peores.&lt;br /&gt;3. Microsoft ha evitado tomar las medidas necesarias para hacer su sistema más seguro y limitar el daño potencial que binarios comprometidos, pueden causar. Consistentemente ha añadido medidas a medias por el miedo a confundir más a la gente con un "disco duro de 1.3GHz" en su escritorio.&lt;br /&gt;4. Cada aplicación intenta hacer malabares con el registro, instala ficheros, iconos que nunca limpia o peor aun, instala spyware o adware.&lt;br /&gt;5. Cualquier SO que deba ser limpiado y reinstalado para ser reparado cada 6 meses, está más allá de la tolerancia de cualquier persona en sus cabales.&lt;br /&gt;6. Una cantidad impresionante de fallos en todas las aplicaciones. Sólo hay que mirar Vista o llamar al Soporte de MS, pagar exorbitantes sumas y preguntarnos por que después de diez años aun existen los mismos "bugs" con otra docena de duplicados y nadie esté trabajando para resolverlos.&lt;br /&gt;&lt;h2&gt;Interfaz&lt;/h2&gt;&lt;br /&gt;1. No existe una API consistente: Win32, MFC, WinForms, WPF. ¿Cuál escoger?&lt;br /&gt;2. No existen conectores sencillos para lenguajes como Python, Perl, Ruby, Java, etc.&lt;br /&gt;3. Todo el sistema es un chiste monolítico, cerrado y rígido sin acceso para los desarrolladores externos. Cambios no-triviales en el aspecto de una ventana o cualquier widget, requiere de añadir herramientas de terceros o de chapas. Peor aún, muchas cosas están hardcodeadas por los diseñadores de Microsoft, de manera que no se pueden cambiar.&lt;br /&gt;4. Falta de una linea de comandos en condiciones, lo que hace que las aplicaciones visuales, no puedan ser utilizadas fuera de un entorno visual. ¿Por qué mostrar un mensaje luminoso de advertencia o de error a un usuario, cuando éste debería ser almacenado en un fichero a la espera de que un técnico cualificado pueda revisarlo?&lt;br /&gt;&lt;h2&gt;Interoperabilidad&lt;/h2&gt;&lt;br /&gt;1. Windows no soporta trabajar con otros sistemas que no sean Windows. Al instalar Windows, este destruye de forma autoritaria y arrogante, cualquier otro sistema de arranque que tengamos anteriormente. Peor aun, si no se tiene cuidado, eliminará todo vestigio de otros sistemas y ficheros del usuario que puedan estar almacenados en el disco duro.&lt;br /&gt;2. No soporta de forma nativa, otros sistemas de ficheros que no sean los anticuados FAT o NTFS.&lt;br /&gt;3. Debería ser posible configurar todo desde la linea de comandos. ¿Por qué tengo que causarme una enfermedad crónica por tener que mover el ratón a todas partes y haciendo click de forma frenética para realizar un cambio que con solo modificar dos lineas de texto habría sido suficiente?&lt;br /&gt;&lt;h2&gt;Drivers&lt;/h2&gt;&lt;br /&gt;1. El soporte de drivers en Windows está totalmente roto y de chiste. Cada fabricante de dispositivos debe incluir sus drivers junto al mismo dispositivo. Si se tiene que reinstalar Windows, ninguno de los dispositivos funcionara hasta que se vuelvan a reinstalar todos los drivers de forma individual, y Dios no lo quiera, teniendo todos los CD's a mano, porque en caso de tener que buscarlos en Internet, nos hará falta un master en ingenieria y toneladas de paciencia.&lt;br /&gt;2. Muchas veces estos necesitan ser instalados, modificados o configurados antes de ser utilizados, ya que la mayoría de las veces, estos no funcionan como deberían. Incluso peor, no suelen ser solo drivers, sino todo un conjunto de aplicaciones de cuestionable valor que consumen recursos y reducen la velocidad del sistema.&lt;br /&gt;3. Estos son los causantes de la gran mayoría de problemas de inestabilidad -después de los virus y malware- y su mala calidad hace que la experiencia con Windows sea frustrante.&lt;br /&gt;4. Windows no posee ninguna forma efectiva y segura de actualizar estos drivers cuando fallos críticos son encontrados y arreglados por el fabricante.&lt;br /&gt;&lt;h2&gt;Aplicaciones&lt;/h2&gt;&lt;br /&gt;1. Muy pocas aplicaciones para Windows, por volumen, son gratuitas o libre, lo que significa que se está totalmente a la merced de los fabricantes de software de formas que la ley nunca admitiría para fabricantes de productos físicos. ¿Tiene todos sus datos en un formato propietario cerrado cuando la licencia a caducado? ¿Ha perdido su USB antes de una presentación? ¿Ha tenido que transferir su aplicación a otro portátil porque se lo han robado? Lamentamos oír que se haya ido a la quiebra.&lt;br /&gt;2. Windows no tiene un ciclo regular de lanzamientos. Pagas una cantidad importante de dinero por algunas mejoras y muchos bugs. Puede que pasen algunos años antes de que estos sean arreglados, pero no cuente con ello. En cualquier caso, deberá volver a pagar por ello.&lt;br /&gt;3. Windows no tiene un sistema central de descargas que le permita descargar software nuevo, junto a sus dependencias y actualizaciones. Cada nueva aplicación debe ser adquirida desde un punto de venta autorizado -tienda física- o desde el sitio web del fabricante. No existe un registro de las dependencias -o peor, no existen librerías compartidas- y actualizar para resolver fallos de seguridad, nuevas características es en si mismo un proceso totalmente dependiente de las necesidades del fabricante. Es muy posible que algún fabricante utilice algún medio de actualización remota, para esconder actualizaciones ilegitimas y sin previo conocimiento ni aceptación.&lt;br /&gt;4. Una instalación fresca de Windows es totalmente inútil, por lo que antes de poder hacer algo útil, tendrá que pasar varias horas recordando las aplicaciones que tenía instaladas, buscarlas, descargarlas e instalarlas de forma individual, una a una y reiniciando el sistema después de cada nueva instalación.&lt;br /&gt;5. Las aplicaciones y librerías de Windows hacen que después de cada instalación u actualización, el sistema deba ser reiniciado. 1991 fue hace mucho, pero parece que no hayamos avanzado. &lt;br /&gt;6. Falta de gran cantidad de aplicaciones como grep, awk, gdb, valgrind, systap o SELinux. Así que los programadores ni se molestan en instalar un SO hasta que puedan trabajar en serio.&lt;br /&gt;&lt;br /&gt;Vale, esto llega hasta aquí. Recordad que esto es sólo un ejercicio para reflejar la cantidad de tonterias y falsas afirmaciones que se hacen en gran cantidad de críticas contra Linux, Mac y BSD. Muchas pueden ser verdad, otras no, pero reflejan de forma clara que todos estos articulos y fanboys -sean de la esquina que sean- sólo sirven para llamar la atención y que realmente no ofrecen nada nuevo para la mejora. So shut up!&lt;br /&gt;&lt;br /&gt;Vilmente copiado, editado y traducido de &lt;a href="http://climbing-the-hill.blogspot.com/2009/06/why-windows-is-not-yet-ready-for.html"&gt;aquí&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051686813-5283565905775887390?l=monocaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monocaffe.blogspot.com/feeds/5283565905775887390/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://monocaffe.blogspot.com/2009/06/porque-windows-no-esta-listo-para-el.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5283565905775887390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5022667766051686813/posts/default/5283565905775887390'/><link rel='alternate' type='text/html' href='http://monocaffe.blogspot.com/2009/06/porque-windows-no-esta-listo-para-el.html' title='Porque Windows no esta listo para el escritorio'/><author><name>Alejandro Ayuso</name><uri>https://profiles.google.com/107015655774974154914</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh6.googleusercontent.com/-NEHq7puhl6k/AAAAAAAAAAI/AAAAAAAAA1k/ocYtARoJvLU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5022667766051686813.post-5556780946551509795</id><published>2009-06-04T10:58:00.006+01:00</published><updated>2009-06-04T11:54:42.259+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pirateria'/><category scheme='http://www.blogger.com/atom/ns#' term='educacion'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>El software en la escuela</title><content type='html'>&lt;p&gt;A raíz de leer ésta &lt;a href="http://changlonet.com/blog/2009/cuando-necesitas-a-alguien-de-la-bsa-no-estan/"&gt;entrada&lt;/a&gt; en &lt;a href="http://changlonet.com/blog"&gt;Al otro lado del Mostrador&lt;/a&gt; y los comentarios, siento gran preocupación, sobretodo por el futuro de mis propios hijos y en cómo voy a manejar la situación cuando llegue el momento. Solo espero que algún supuesto profesor de los que utilizan estas idea, lean esta entrada y se den cuenta de su gran error. Resumiendo, en muchas escuelas y universidades, sólo permiten presentar trabajos y documentación utilizando herramientas específicas, yo lo he vivido y lo sigo viviendo cada día a nivel profesional.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Primero hablemos de la irresponsabilidad de estos profesores al no dar alternativas y en cambio, proponer medios ilegales para obtener estas herramientas. A diferencia de la música, libros, películas, etc. El intercambio de software es &lt;b&gt;ilegal&lt;/b&gt;. Listo. No podéis proponer a un chaval de instituto que se baje el Photoshop de la mula. Por favor, un poco de seriedad que sois profesores y la educación moral y social de nuestros hijos, están en buena parte en vuestras manos. Cómo puede un padre decirle a sus hijos que lo que les ha dicho su profesor, con quien pasan una parte importante de su día a día, es una estupidez y que es un tarado ignorante.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Me la resopla que mis hijos vayan al colegio a aprender informática, ya de eso me encargare yo o el centenar de academias preparadas para esto o si a ellos le interesa, lo harán por su cuenta. Esto es lo mejor de la informática, se puede ser totalmente autodidacta si se tiene el interés. Yo quiero que mis hijos aprendan matemáticas, literatura, biología, historia y a ser personas de bien. No quiero que les enseñes que está bien utilizar medios alternativos e ilegales para lograr un objetivo.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Quedando esto zanjado, y muy a mi pesar, la informática es la excusa perfecta para meter a un montón de chavales en una sala con computadoras y olvidarte de ellos mientras te conectas al facebook o te vas a tomar un café, así que no va a desaparecer de la oferta educativa. Pero al menos hacedlo de una forma correcta y que no atente contra la educación que intentamos impartir en el hogar, que no sea ilegal y que evite la discriminación.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Discriminación, vaya palabra, pero muchos niños seguramente se sentirán desplazados y discriminados, cuando sus padres no puedan pagar una licencia de Photoshop para que el profe pueda ver las dibujos de sus niños y aprobarlos en el excelente uso de los plugins que ha hecho. &lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;&lt;i&gt;Solo podéis entregarme los trabajos quienes tengan un Rolex. Si no tenéis, ya sabéis lo que tenéis que hacer&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Esto, señor profesor, es lo que le estáis diciendo a estos niños. Y lo peor es que podrían haber entregado el trabajo con un Casio y tan tranquilos.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;&lt;i&gt;Deben aprender a utilizar las herramientas informáticas más usadas&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Las herramientas que utilizamos hoy en día, nada tienen que ver con las que un niño de 10 años se va a encontrar cuando se inicie en el mundo laboral. De hecho, las herramientas que uno o dos años antes utilizaba usted mismo, ya no se utilizan en el mundo laboral. Más que enseñar a utilizar herramientas, debéis enseñar a aprender y a pensar. Parece que esto se os haya olvidado de la carrera. Al enseñar "herramientas" no estáis enseñando, estáis mecanizando sus mentes a funcionar como esa herramienta desea, a seguir una serie de pasos para hacer algo y no realmente a pensar en cómo resolver un problema o una asignación. Una parte importante en esto, es la búsqueda de las mejores herramientas para obtener los mejores resultados y seguro que esa herramienta, no es la usted propone.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;La informática a éste nivel en la educación es un error garrafal y sólo añade más complejidad y problemas a un sector que ya está bastante jodido para la gran importancia que tiene.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Nota&lt;/h2&gt;&lt;br /&gt;Cuando escribo Photoshop, es sólo como ejemplo que además, es perfecto, ya que existen cientos de aplicaciones que cumplen perfectamente con los requerimientos de un niño de instituto y que por alguna razón, todo **** cree que debe tener instalado para eliminar "los ojos rojos" de sus fotos del verano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5022667766051
