<?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:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6855603</id><updated>2010-07-20T10:14:59.102-07:00</updated><title type='text'>Weblog for Costin Manolache</title><subtitle type='html'>Technical stuff</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.webinf.info/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default?start-index=26&amp;max-results=25'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>69</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6855603.post-2080384871907783880</id><published>2010-07-08T16:36:00.000-07:00</published><updated>2010-07-08T16:36:42.923-07:00</updated><title type='text'>Finding an entity in appengine console</title><content type='html'>Appengine has a nice "datastore viewer" - you can browse your data, but if you want to find a specific row you need to run a query. &amp;nbsp;The syntax is not obvious from the documentation if you're selecting by primary key:&lt;br /&gt;&lt;br /&gt;SELECT * FROM DeviceInfo WHERE __key__ = Key('DeviceInfo', 'my_key')&lt;br /&gt;&lt;br /&gt;I have a DeviceInfo table, with a primary key called 'name'. You can find about __key__ and Key in the docs, but I had to try many combinations to find that the first param is actually the type and the key name doesn't matter.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-2080384871907783880?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/2080384871907783880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=2080384871907783880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/2080384871907783880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/2080384871907783880'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2010/07/finding-entity-in-appengine-console.html' title='Finding an entity in appengine console'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-5019373606996268078</id><published>2010-05-28T10:34:00.001-07:00</published><updated>2010-05-28T10:34:55.738-07:00</updated><title type='text'>Server to Android messages</title><content type='html'>Also check: http://code.google.com/p/chrometophone&lt;br /&gt;&lt;br /&gt;Froyo required.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-5019373606996268078?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://code.google.com/android/c2dm/' title='Server to Android messages'/><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/5019373606996268078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=5019373606996268078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/5019373606996268078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/5019373606996268078'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2010/05/server-to-android-messages.html' title='Server to Android messages'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-7678976470617424533</id><published>2010-02-22T10:09:00.000-08:00</published><updated>2010-02-22T10:09:41.618-08:00</updated><title type='text'>Backup windows from linux</title><content type='html'>ntfsclone - to copy/backup to, included on ubuntu live/install CD.&amp;nbsp;Tar doesn't seem to work very well.&lt;br /&gt;&lt;br /&gt;This is for moving windows to a larger disk, or making a snapshot to restore later.&lt;br /&gt;&lt;br /&gt;I got a new netbook, removed all the garbage, installed my stuff ( chrome, firefox, etc ), saved the 'restore point' and installed ubuntu. I only use windows for netflix and occasional testing - so I don't want to deal with any windows-specific backup program or to have to reinstall.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-7678976470617424533?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/7678976470617424533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=7678976470617424533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/7678976470617424533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/7678976470617424533'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2010/02/backup-windows-from-linux.html' title='Backup windows from linux'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-1304228592007935262</id><published>2010-01-11T12:49:00.000-08:00</published><updated>2010-01-11T12:49:43.319-08:00</updated><title type='text'>ZLib memory overhead</title><content type='html'>I was testing some compression code - and the load tests were running out of memory. Looks like ZLib allocates about &amp;nbsp;256K per compressor. I tried this with both &amp;nbsp;BEST_COMPRESSION and BEST_SPEED - looking at Shallow Heap in eclipse heap analyzer, 2x32k short[] and 2x64k byte[].&lt;br /&gt;&lt;br /&gt;With SPDY you need to keep the header compressor around for the entire kept-alive connection. HTTP connections only use gzip for individual requests - the context and memory can be reclaimed, so a kept-alive connection has a very small cost - can be as low as just a socket in a selector, sometimes few extra buffers.In tomcat-lite there is one 8k buffer associated with the connection - not hard to get rid of it, but low priority.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-1304228592007935262?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/1304228592007935262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=1304228592007935262' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/1304228592007935262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/1304228592007935262'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2010/01/zlib-memory-overhead.html' title='ZLib memory overhead'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-7177880132719813278</id><published>2010-01-06T11:06:00.000-08:00</published><updated>2010-01-06T11:06:05.748-08:00</updated><title type='text'>Heap dumps - looking at all objects and fields in a live system, without a debugger</title><content type='html'>&lt;pre&gt;Do you have a java server - maybe in production - and you want to look at the value of some field ? You can't attach a debugger, this would require starting the server with various flags - but you can get a heap dump, which includes all objects, including the value of their fields. &lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;The other use is to generate a heap dump before and after running a load test - and look at garbage to evaluate how much work you put on the garbage collector and find leaks. There are profilers that can get better results - but this is pretty fast and free way to get the same result, and you can use it against running systems. &lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;Getting heap dumps:&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt; jmap -dump:format=b,file=heap3.bin PID_OF_JAVA_PROCESS&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;Using code ( in a servlet, etc ):&lt;/pre&gt;&lt;pre&gt;server = ManagementFactory.getPlatformMBeanServer();&lt;br /&gt;server.invoke(new ObjectName("com.sun.management:type=HotSpotDiagnostic"),&lt;br /&gt;              "dumpHeap",&lt;br /&gt;              new Object[] {fileName, Boolean.TRUE}, &lt;br /&gt;              new String[] {String.class.getName(), "boolean"});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Looking at the data:&lt;br /&gt;&lt;br /&gt;&lt;pre style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;  Eclipse &lt;a href="http://www.eclipse.org/mat/"&gt;MemoryAnalyzer&lt;/a&gt; &lt;/pre&gt;&lt;pre style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;or&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;  jhat heap3.bin&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;  open http://localhost:7000&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-7177880132719813278?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/7177880132719813278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=7177880132719813278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/7177880132719813278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/7177880132719813278'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2010/01/heap-dumps-looking-at-all-objects-and.html' title='Heap dumps - looking at all objects and fields in a live system, without a debugger'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-4692790828763093491</id><published>2010-01-02T09:38:00.000-08:00</published><updated>2010-01-27T11:10:59.674-08:00</updated><title type='text'>Flush() in a compressed stream</title><content type='html'>&lt;div&gt;I finally understood the difference between 'sync' and partial flush: &lt;a href="http://www.bolet.org/~pornin/deflate-flush.html"&gt;http://www.bolet.org/~pornin/deflate-flush.html&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Since last byte may not end on a 8-bit boundary - you need to pad, i.e. to end the current compression block and start a new one. &amp;nbsp;The interesting part is that a flush with Z_SYNC_FLUSH inserts 0x00 0x00 0xFF 0xFF - but protocols like PPP can strip it.&lt;br /&gt;&lt;br /&gt;Another good link:&amp;nbsp;http://www.zlib.net/zlib_tech.html&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-4692790828763093491?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.bolet.org/~pornin/deflate-flush.html' title='Flush() in a compressed stream'/><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/4692790828763093491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=4692790828763093491' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/4692790828763093491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/4692790828763093491'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2010/01/flush-in-compressed-stream.html' title='Flush() in a compressed stream'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-8035410230834211361</id><published>2009-12-22T22:45:00.000-08:00</published><updated>2009-12-22T22:45:08.191-08:00</updated><title type='text'>Chrome, SSL and Tomcat - or other JSSE-based engines</title><content type='html'>If you try to use Chromium with a java server running https - be aware of &amp;nbsp;this bug:&lt;br /&gt;http://bugs.sun.com/view_bug.do?bug_id=6728126&lt;br /&gt;&lt;br /&gt;Chrome will use a nice TLS extension - RFC4507, SessionTicket - to allow servers to reuse the session without a second roundtrip and without having to cache the session ( which is quite tricky if you use load balancing - there is no easy way in java to do so ). Of course - JSSE doesn't support the extension, the bug is that it can't even ignore it. Besides saving the roundtrip this also saves some CPU time on both ends - good thing chrome added this.&lt;br /&gt;&lt;br /&gt;I spent some time today trying to figure out what was happening - the good news seems to be that it's fixed in recent jdk builds. Unfortunately ubuntu doesn't have the fix yet (not even Karmic), and probably Mac is also behind.&lt;br /&gt;&lt;br /&gt;Filed a chrome bug as well - I think reversing the order of SessionTicket and hostname extension would solve this.&lt;br /&gt;&lt;br /&gt;The server name extension is another nice thing - it allows chrome to specify which host it's looking for in the first ClientHelo packet - so server can send the right certificate. The "Host" header will be sent after the encryption is started - this is why many https servers require one IP address per host and can't do virtual hosting with SSL.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-8035410230834211361?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/8035410230834211361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=8035410230834211361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8035410230834211361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8035410230834211361'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/12/chrome-ssl-and-tomcat-or-other-jsse.html' title='Chrome, SSL and Tomcat - or other JSSE-based engines'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-567757069726881746</id><published>2009-12-19T20:09:00.000-08:00</published><updated>2009-12-19T20:09:26.102-08:00</updated><title type='text'>Sipdroid, gizmo, android, NAT fun</title><content type='html'>Few notes on my setup - in hope others will not have to waste so much time. I have a couple of VOIP devices behind a router without SIP support, and SIP is very sensitive to UDP ports.&lt;br /&gt;&lt;br /&gt;Network looks like this:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;pretty dumb DSL router ( not modem !) - I'm setting it for my parents, that's what they have.&amp;nbsp;&lt;/li&gt;&lt;li&gt;a linux host running siproxd. Next I'll try with an even smaller box ( an openWRT router ) - to save power.&amp;nbsp;&lt;/li&gt;&lt;li&gt;One Grandstream box connected to a regular phone&lt;/li&gt;&lt;li&gt;Android device, with SipDroid.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;The firewall is set to forward all UDP and TCP to the linux box - I added a 'custom' rule, I don't want to deal with the dsl router, all real filtering in linux. You can specify the SIP range - 5060 + whatever RTP.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm using Gizmo - I like that it's integrated with google voice, relatively easy to set software for most OSes, etc. Well - not so easy to get sound to get gizmo to work on ubuntu with pulseaudio - lot of time wasted there too - I set gizmo to OSS and used "aoss gizmo", this seems to work for me.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One big problem: siproxd can't deal with the 2 identities, i.e. the ascii username and the phone number.&amp;nbsp;&lt;/div&gt;&lt;div&gt;As a rule, I ignore all the gizmo usernames and use only phone numbers.&amp;nbsp;That means user@proxy01.sipphone.com will not work, neither "call gizmo" in the UI. To dial you must use 1234@proxy01.sipphone.com, or "call SIP" in their UI.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On Grandstream - normal registration, with outbound proxy set, no STUN.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On Sipdroid - there is no direct support for proxy, but you can set the "Server" to the IP address of the linux box running siproxd, and than set Domain to proxy01.sipphone.com. Note that older versions of sipdroid don't have the option - just upgrade with latest from market.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So far no problems with the setup - getting my parents to figure out how to dial and where to connect the wires is another story.&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-567757069726881746?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/567757069726881746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=567757069726881746' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/567757069726881746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/567757069726881746'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/12/sipdroid-gizmo-android-nat-fun.html' title='Sipdroid, gizmo, android, NAT fun'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-5223435688655495538</id><published>2009-11-30T10:27:00.000-08:00</published><updated>2009-11-30T10:27:10.236-08:00</updated><title type='text'>Handbrake 0.9.4 on Hardy</title><content type='html'>Handbrake is a very nice tool - 'just works' in most cases, has good presets so you don't need to know arcane compression options. They just released a new version - which drops support for .AVI and few other things. I think it's great to see this happen - it's not that common for projects to cut features instead of half-supporting them. On the other hand some devices only work with .avi - so I'll keep the old version around.&lt;br /&gt;&lt;br /&gt;Another remarcable thing about Handbrake - they link statically, the binary has only very basic dependencies.&lt;br /&gt;&lt;br /&gt;The official download is for Ubuntu 9.10 - I had to compile from source, the CLI version is easy to compile - for GUI you need webkit and few other things, so I'll wait for an official backport. &lt;br /&gt;&lt;br /&gt;The only trick for compiling CLI is also compiling current yasm from source, the version in hardy is too old. Simple configure/make install works, just make sure you remove the package with "apt-get remove yasm" if you have the old version installed.&lt;br /&gt;&lt;br /&gt;Required packages (besides libtool/autoconf/build-essentials): zlib1g-dev libbz2-dev intltool libglib2.0-dev libdbus-glib-1-dev libgtk2.0-dev libhal-dev libhal-storage-dev &amp;nbsp;libnotify-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.webinf.info/public/handbrake-0.9.4-cli/HandBrakeCLI-0.9.4.gz"&gt;Compiled binary&lt;/a&gt;, if you want to skip the compilation -&lt;br /&gt;&amp;nbsp;"gzip -d &amp;nbsp;&amp;nbsp;HandBrakeCLI-0.9.4.gz ; chmod +x&amp;nbsp;HandBrakeCLI-0.9.4"&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-5223435688655495538?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/5223435688655495538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=5223435688655495538' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/5223435688655495538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/5223435688655495538'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/11/handbrake-094-on-hardy.html' title='Handbrake 0.9.4 on Hardy'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-1184709316186344549</id><published>2009-10-14T18:08:00.000-07:00</published><updated>2009-10-14T18:08:31.440-07:00</updated><title type='text'>Trying Maven</title><content type='html'>I have never used maven in a project I'm working on - mostly because I disliked the rigidity and 'we know better &amp;nbsp; than you what you need and want'.&lt;br /&gt;&lt;br /&gt;Today I wanted to make it a bit easier to build tomcat-lite - and decided to add a maven option. Tomcat-lite is far simpler than tomcat - it may work. I even accepted moving few files around - I couldn't get myself to create the ugly, deep hierarchy - but it seems you can specify 'sourceDirectory' and include resources from the java tree.&lt;br /&gt;&lt;br /&gt;Results: I could build the connector and servlets just fine, downloading the deps was nicer than the custom ant tasks that tomcat uses. The main engine - which depends on some files from main tomcat - &amp;nbsp;it looks like no luck.&lt;br /&gt;&lt;br /&gt;I found no way to specify exclude patterns on sources, and using a pre-generated jar file is a mess - you must import it in the repository, far from easy or automated. And all the syntax I had to use took a lot of effort to find and tweak - documentation is certainly not targeted to how to make maven work the way you need, but to make you work in whatever way is easier for maven.&lt;br /&gt;&lt;br /&gt;Conclusion: Apache-Ivy does the download better - and has a nice task to copy the jars in a lib, and integrates quite nicely with ant. It is even easy to download Ivy and get it to download the rest. Far easier than Maven - and I just used the same pom.xml I was using for maven.&lt;br /&gt;&lt;br /&gt;I'll let the pom files around, in case someone wants to use them - but I will continue to avoid maven and projects that only build with maven.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-1184709316186344549?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/1184709316186344549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=1184709316186344549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/1184709316186344549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/1184709316186344549'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/10/trying-maven.html' title='Trying Maven'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-2593069912478166386</id><published>2009-09-27T20:56:00.000-07:00</published><updated>2009-09-27T20:56:48.963-07:00</updated><title type='text'>Fixing the annoying Java 2-line logging format</title><content type='html'>java.util.logging is far from perfect, but for me the main reason to not use it is the hard-to-read default formatter which shows the date on a whole row. There are more compact formatters - but you need to write code to install them, or edit the command line.&lt;br /&gt;&lt;br /&gt;So every time I install a JVM, I change the logging formatter:&lt;br /&gt;&lt;br /&gt;1. in $JAVA_HOME/jre/lib/logging.properties, replace&lt;br /&gt;&lt;br /&gt;java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter&lt;br /&gt;with&lt;br /&gt;&lt;br /&gt;java.util.logging.ConsoleHandler.formatter = org.apache.juli.JdkLoggerFormatter&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2. copy TOMCAT_HOME/bin/tomcat-juli.jar to JAVA_HOME/jre/lib/ext.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-2593069912478166386?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/2593069912478166386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=2593069912478166386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/2593069912478166386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/2593069912478166386'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/09/fixing-annoying-java-2-line-logging.html' title='Fixing the annoying Java 2-line logging format'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-2242273773872029042</id><published>2009-09-06T20:36:00.000-07:00</published><updated>2009-09-06T21:43:07.457-07:00</updated><title type='text'>Java flush() - not what you would expect</title><content type='html'>&lt;div&gt;What I expect: flush() on the output stream to send the data. After flush() is completed, I expect the receiver to be able to read the data. Operating system and network may have their own delays - flush()  is less than commit, so there is no guarantee that data is completely received, or it will ever be received when flush() is done, but it shouldn't be stuck in an intermediate java buffer with no way out until close().&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;OutputStream&lt;/span&gt;.flush() documentation seems to match: 'forces any output bytes to be written out' and clarifies that if any bytes have been buffered, they should be written to their "intended &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;destination&lt;/span&gt;". And it clarifies that the OS may further buffer "the bytes are passed to the OS for &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;writing&lt;/span&gt;", and not that "they are actually written".&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's take few examples: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;SocketOutputStream&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;FileOutputStream&lt;/span&gt; do nothing in flush() because they don't buffer anything, so write() will pass the bytes to the OS. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;BufferedOutputStream&lt;/span&gt; is the best example of what to do when buffering: it does send all the bytes to the next stream in the chain AND calls out.flush(), so the data will go to the 'intended &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;destination&lt;/span&gt;' - the buffer is just an intermediary. Well known that if you want any decent performance you should use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;BufferedOutputStream&lt;/span&gt;. Not so well known - you can use better buffers, for example one that doesn't reallocate and copy the byte[], but instead keeps a list of buffers. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The biggest offender: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;DeflaterOutputStream&lt;/span&gt;. Flush will just call out.flush()., but keeps recent bytes in its buffer. Worse - the actual &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Deflater&lt;/span&gt; doesn't even support &lt;a href="http://www.bolet.org/~pornin/deflate-flush.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;zlib&lt;/span&gt; flush&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Servlets&lt;/span&gt;, flush() does the right thing - the bytes go all the way to the net. Unless you're using compression, and the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;serlvet&lt;/span&gt; engine uses java &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Deflater&lt;/span&gt; - in which case flush() will not push bytes to the net, they get stuck in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;deflater&lt;/span&gt;. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;GZIPOutputStream&lt;/span&gt; extends &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Deflater&lt;/span&gt; and has the same problem - tomcat's coyote &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;GzipOutputFilter&lt;/span&gt; and the example compression filter won't actually flush to the net. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The alternative for compressed output that flush() - &lt;a href="http://www.jcraft.com/jzlib/"&gt;http://www.jcraft.com/jzlib/&lt;/a&gt;, BSD licence, pure java - has some good info about the flush() problem ). You can also use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;JNI&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;libz&lt;/span&gt; - Harmony's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Deflater&lt;/span&gt; is a good starting point - but Harmony has same bug as Sun &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;VM&lt;/span&gt;.&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/6855603-2242273773872029042?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/2242273773872029042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=2242273773872029042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/2242273773872029042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/2242273773872029042'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/09/java-flush-not-what-you-would-expect.html' title='Java flush() - not what you would expect'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-3070661129049770068</id><published>2009-06-04T11:33:00.001-07:00</published><updated>2009-06-04T11:33:39.002-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>More on FutureTask</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Adding to my previous &lt;a href='http://blog.webinf.info/2008/03/using-futuretask.html'&gt;FutureTask&lt;/a&gt; post: Future is a very nice interface, but the main problems with FutureTask are the lack of a callback and the clumsy constructor that requires a Callable. I guess their main use case was someone creating a FutureTask that performs a slow operation - as in my example, it is relatively easy to wrap the method in a Callable and then execute the FutureTask in a thread pool.&lt;br /&gt;&lt;br /&gt;It is possible to add a callback by overriding FutureTask.done(), which is called after FutureTask.set().&lt;br /&gt;&lt;br /&gt;There are few tricks to better use FutureTask. Let's say you have an operation that happens in background already, and you're notified with a callback. You want to wrap it in a Future to make it easier to use:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  interface Callback {&lt;br /&gt;    void done(Object1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  void doSomethingAsync(Callback callWhenDone) {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  class MyFuture extends FutureTask {&lt;br /&gt;    public MyFuture() { &lt;br /&gt;      // FutureTask _requires_ a callable - even if it's not using it. Let's give him a dummy one.&lt;br /&gt;     super(new Callable() { public Object1 call() { return null; }});&lt;br /&gt;    }&lt;br /&gt;    // set() is protected - need a visible method to let future know the result &lt;br /&gt;    public void gotTheResult(Object1 result) {&lt;br /&gt;      this.set(result);&lt;br /&gt;    } &lt;br /&gt;  }	&lt;br /&gt;&lt;br /&gt;  Future&amp;lt;div class="youtube-video"&amp;gt;&amp;lt;object1&amp;gt; getSomethingFuture() {&lt;br /&gt;    final MyFuture res = new MyFuture();&lt;br /&gt;    // We _don't_ submit it to an executor - so run() will not be called&lt;br /&gt;    doSomethingAsync(new Calback() {void done(Object1 result) {&lt;br /&gt;      // do what innerRun() does - i.e. call innerSet with the result. &lt;br /&gt;      // innerSet() will set state to RAN , even if the callable was never called.&lt;br /&gt;      res.gotTheResult(result);});&lt;br /&gt;    return res;&lt;br /&gt;  } &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=e1d65d7b-ac42-85b5-be4c-95f43c7658e7' class='zemanta-pixie-img'/&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/6855603-3070661129049770068?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/3070661129049770068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=3070661129049770068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/3070661129049770068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/3070661129049770068'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2009/06/more-on-futuretask.html' title='More on FutureTask'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-8721945113117819843</id><published>2008-11-10T15:51:00.001-08:00</published><updated>2008-11-10T15:51:24.886-08:00</updated><title type='text'>My synergy settings</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I have multiple laptops and computers, and sometimes use them at the same time - it is convenient to use a single keyboard&lt;br/&gt;and mouse. The problem is that the config is not fixed - and synergy is quite hard to reconfigure dynamically.&lt;br/&gt;&lt;br/&gt;I start a synergys server on each computer whose keyboard I may use, and use a couple of scripts to create tunnels and &lt;br/&gt;restart the clients. &lt;br/&gt;&lt;br/&gt;The trick is to not use specific hostnames - but dummy ones, and explicitly set the "-c clientname" param. Then all real &lt;br/&gt;config is done using ssh tunnels - with the extra benefit of &lt;br/&gt;&lt;br/&gt;Server: &lt;br/&gt;  synergys -n localhost -a 127.0.0.1:24800&lt;br/&gt;&lt;br/&gt;  # optional: ssh to shared server ( if the keyboard host is behind another firewall ):&lt;br/&gt;  ssh -f -N -R 24800:127.0.0.1:24800  public_computer_with_sshd&lt;br/&gt;&lt;br/&gt;Server config: ~/.synergy.conf&lt;br/&gt;&lt;br/&gt;&lt;pre&gt;section: screens&amp;lt;br /&amp;gt;      localhost:&amp;lt;br /&amp;gt;      up:&amp;lt;br /&amp;gt;      down:&amp;lt;br /&amp;gt;      left:&amp;lt;br /&amp;gt;      right:&amp;lt;br /&amp;gt;end&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;section: links&amp;lt;br /&amp;gt;      localhost:&amp;lt;br /&amp;gt;        down = down&amp;lt;br /&amp;gt;        up = up&amp;lt;br /&amp;gt;        left = left&amp;lt;br /&amp;gt;        right = right&amp;lt;br /&amp;gt;     up:&amp;lt;br /&amp;gt;        down = localhost&amp;lt;br /&amp;gt;     down:&amp;lt;br /&amp;gt;       up = localhost&amp;lt;br /&amp;gt;     left:&amp;lt;br /&amp;gt;       right = localhost&amp;lt;br /&amp;gt;     right:&amp;lt;br /&amp;gt;       left = localhost&amp;lt;br /&amp;gt;end&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;/pre&gt;On client: &lt;br/&gt;     &lt;br/&gt;   ssh -N 24800:127.0.0.1:24800 server &amp;amp;&lt;br/&gt;   echo $! &amp;gt; ~/.synergyssh.pid   &lt;br/&gt;&lt;br/&gt;   killall -9 synergyc&lt;br/&gt;   synergyc -n down localhost&lt;br/&gt;&lt;br/&gt;I have few client scripts, pointing to different keyboard servers and layouts. &lt;br/&gt;&lt;br/&gt;&lt;br/&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/6855603-8721945113117819843?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/8721945113117819843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=8721945113117819843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8721945113117819843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8721945113117819843'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2008/11/my-synergy-settings.html' title='My synergy settings'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-863543895604393073</id><published>2008-08-14T13:32:00.000-07:00</published><updated>2008-08-14T13:38:02.440-07:00</updated><title type='text'>Intercepting SIGTERM</title><content type='html'>The 'proper' way to terminate a java process on unix is by sending SIGTERM, waiting a bit, and then sending SIGKILL. This gives java a chance to clean - using Runtime.getRuntime().getShutdownHook().&lt;br /&gt;&lt;br /&gt;If you want to intercept this and do some early cleanup, before letting the others do theirs you need to use sun.misc.Signal - which can also be used to intercept other signals.&lt;br /&gt;&lt;br /&gt;Things to do in a shutdownHook ? Flush the logs, finish important background processes and much more.&lt;br /&gt;&lt;br /&gt;Code to intercept the signal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;oldSigTERM = Signal.handle(new Signal("TERM"),&lt;br /&gt;                new SignalHandler() {&lt;br /&gt;    public void handle(Signal signal) {&lt;br /&gt;      System.err.println("Quit using SIGTERM hook");&lt;br /&gt;      notificationHandler.prepareToQuit();&lt;br /&gt;      if (oldSigTERM != null) {&lt;br /&gt;        oldSigTERM.handle(signal);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&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/6855603-863543895604393073?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/863543895604393073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=863543895604393073' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/863543895604393073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/863543895604393073'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2008/08/intercepting-sigterm.html' title='Intercepting SIGTERM'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-8030846333346468665</id><published>2008-08-08T17:42:00.001-07:00</published><updated>2008-08-08T17:44:17.809-07:00</updated><title type='text'>Common-sense on unit testing</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;a href="http://cafe.elharo.com/testing/harolds-corollary-to-knuths-law/"&gt;The Cafes » Harold’s Corollary to Knuth’s Law&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-8030846333346468665?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/8030846333346468665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=8030846333346468665' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8030846333346468665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8030846333346468665'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2008/08/common-sense-on-unit-testing.html' title='Common-sense on unit testing'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-3427129031110613881</id><published>2008-03-20T10:46:00.001-07:00</published><updated>2009-06-04T10:42:42.189-07:00</updated><title type='text'>Using FutureTask</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;This is what I typically use to convert a sync method to a background Future. The benefit is that it avoids a lot of custom code (creating threads, locks, etc ) and seems simple enough, and it's relatively easy to cut&amp;amp;paste.&lt;br/&gt;&lt;br/&gt;Original: &lt;br/&gt;&lt;br/&gt;&lt;pre&gt; &lt;br /&gt;  Result1 slowMethod1(Param1 p1, Param2 p2) throws Exception1 {&lt;br /&gt;  }&lt;br /&gt;  Result2 slowMethod2() throws Exception2 {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  void caller() throws Exception1, Exception2 {&lt;br /&gt;    // slowMethod1 and slowMethod2 are independent of each other&lt;br /&gt;    Result1 r1 = slowMethod1(p1, p2); // first expensive operation&lt;br /&gt;    Result2 r2 = slowMethod2(); // other slow method, not using the result or side-effects of the first&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;New code:&lt;br/&gt;&lt;br/&gt;&lt;pre&gt; &lt;br/&gt;  Executor bgTasks = Executors.newCachedThreadPool(); &lt;br/&gt;&lt;br/&gt;  Future&lt;result1&gt;&lt;result&gt; slowMethod1Future(final Param1 p1, Param2 p2) {&lt;br/&gt;    FutureTask&lt;result&gt;&lt;result1&gt;  fr = new FutureTask&lt;result&gt;&lt;result1&gt;(new Callable&lt;result&gt;&lt;result1&gt;() { &lt;br/&gt;      public Result1 call() {&lt;br/&gt;        return slowMethod1(p1, p2);&lt;br/&gt;      }&lt;br/&gt;   });&lt;br/&gt;    bgTasks.execute(fr);&lt;br/&gt;    return fr;&lt;br/&gt;  }&lt;br/&gt;&lt;br/&gt;  void caller() {&lt;br/&gt;     Future&lt;result1&gt;&lt;result&gt; fr = slowMethod1Future(p1, p2);&lt;br/&gt;     Result2 r2 = slowMethod2(); &lt;br/&gt;     try {&lt;br/&gt;      Result1 r1 = fr.get();&lt;br/&gt;    } catch(InterruptedException e) { &lt;br/&gt;       throw new RuntimeException(...);&lt;br/&gt;    } catch (ExecutionException e) {&lt;br/&gt;       Throwable t = e.getCause();&lt;br/&gt;       if (t intanceof Exception1) { &lt;br/&gt;         throw (Exception1) t;&lt;br/&gt;       } else {&lt;br/&gt;         throw new RuntimeException(t);&lt;br/&gt;      }&lt;br/&gt;    } &lt;br/&gt;   }&lt;br/&gt;&lt;/result&gt;&lt;/result1&gt;&lt;/result1&gt;&lt;/result&gt;&lt;/result1&gt;&lt;/result&gt;&lt;/result1&gt;&lt;/result&gt;&lt;/result&gt;&lt;/result1&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/6855603-3427129031110613881?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/3427129031110613881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=3427129031110613881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/3427129031110613881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/3427129031110613881'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2008/03/using-futuretask.html' title='Using FutureTask'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-671777484399335020</id><published>2008-02-27T21:17:00.001-08:00</published><updated>2008-02-27T21:17:09.507-08:00</updated><title type='text'>JConsole in local mode and tomcat</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;After some debugging found that Jconsole will connect locally to a new MBeanServer created via ManagementFactory.getPlatformMBeanServer(). Tomcat will look for an existing MBeanServer and create one if needed - but this will be different than what jconsole uses.&lt;br/&gt;&lt;br/&gt;The fix is 2 lines - benefit is that you can start tomcat normally, without any special flag, then connect with jconsole and inspect/modify settings. It looks like they use some signal or other form of communication on Linux, which opens a TCP port. &lt;br/&gt;&lt;br/&gt;I'm not sure why someone would ever want to use MBeanServerFactory.findMBeanServer() and createMBeanServer. Sure, in the rarely used sandbox mode, if you want to strongly isolate apps it may be needed - assuming you want each untrusted app to have access to its own server, and grant it create mbean server rights.&lt;br/&gt;&lt;br/&gt;Time to send a patch - long time since I haven't done that...&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/6855603-671777484399335020?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/671777484399335020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=671777484399335020' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/671777484399335020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/671777484399335020'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2008/02/jconsole-in-local-mode-and-tomcat.html' title='JConsole in local mode and tomcat'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-8443959973992157416</id><published>2007-12-25T22:29:00.001-08:00</published><updated>2007-12-25T22:29:47.086-08:00</updated><title type='text'>OFX download for vanguard</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I've been using &lt;a href='http://www.jongsma.org/gc/'&gt;ofx.py&lt;/a&gt; to get my transactions from Vanguard, it stopped working sometimes this month. I have some code to parse and merge the sort-of-xml responses to an .xls file - which for me works much better than any alternative I tried. Moneydance is close, it provides an API that can be used to extract same data and it's a bit easier to setup, but it does some magic and seem to be less stable. Quicken, Money - never found a way to get my data back, and won't work on linux too well. &lt;br/&gt;&lt;br/&gt;Made few changes to get it working again, first the setup is: &lt;br/&gt;&lt;pre&gt;&lt;br/&gt;               "caps": [ "SIGNON", "INVSTMT" ],&lt;br/&gt;               "fiorg": "vanguard.com", &lt;br/&gt;               "url": "https://vesnc.vanguard.com/us/OfxDirectConnectServlet"&lt;br/&gt;&lt;/pre&gt;The main change besides url is the code to get the transactions, urllib2 seems to default to HTTP/1.0, couldn't find a way to force it to 1.1 so I changed the code to use httplib directly: &lt;br/&gt;&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;            garbage, path = urllib2.splittype(self.config["url"])&lt;br/&gt;            host, selector = urllib2.splithost(path)&lt;br/&gt;            h = httplib.HTTPSConnection(host)&lt;br/&gt;            h.request('POST', selector, query, &lt;br/&gt;                      { "Content-type": "application/x-ofx",&lt;br/&gt;                        "Accept": "*/*, application/x-ofx"&lt;br/&gt;                      })&lt;br/&gt;            res = h.getresponse()&lt;br/&gt;            response = res.read()&lt;br/&gt;            res.close()&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Old: &lt;br/&gt;&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;        request = urllib2.Request(self.config["url"],&lt;br/&gt;                                                query,&lt;br/&gt;                                               { "Content-type": "application/x-ofx",&lt;br/&gt;                                                  "Accept": "*/*, application/x-ofx"&lt;br/&gt;                                               })&lt;br/&gt;        print "RES: ", res, " ", res.status, " ", res.reason&lt;br/&gt;       f = urllib2.urlopen(request)&lt;br/&gt;       response = f.read()&lt;br/&gt;       f.close()&lt;br/&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/6855603-8443959973992157416?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/8443959973992157416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=8443959973992157416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8443959973992157416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/8443959973992157416'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2007/12/ofx-download-for-vanguard.html' title='OFX download for vanguard'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-3205660275943487296</id><published>2007-09-29T17:10:00.001-07:00</published><updated>2008-05-05T13:29:26.661-07:00</updated><title type='text'>JAAS and tomcat</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;The JAAS ( authentication/authorization ) API has been around for many years now - the idea is to use a standard API for all authentication, and plugins to use NT, LDAP, PAM, SSO and any other realm. JAAS seems modeled after PAM - the auth API for linux ( and unix in general).&lt;br /&gt;&lt;br /&gt;Tomcat supports JAAS auth and provides a sample LoginModule based on the simple clear-text xml file. Like most other apps using auth, tomcat also have direct modules to authenticate against DB, LDAP/JNDI, files - but it will never cover the same range of auth sources as PAM for example ( &lt;a href="http://www.kernel.org/pub/linux/libs/pam/modules.html"&gt;http://www.kernel.org/pub/linux/libs/pam/modules.html&lt;/a&gt; ).&lt;br /&gt;&lt;br /&gt;JAAS has few big problems - it is quite complex, it lacks modules and it lacks users. A benefit of using a tomcat-specific module is that it can be better optimized for the target environment. The only reason to use it would be to use a PAM auth source, there is now a JAAS-PAM implementation &lt;a href="http://jaas-pam.sourceforge.net/"&gt;http://jaas-pam.sourceforge.net/&lt;/a&gt; - seems very good, LGPL, uses JNI to interface with PAM.&lt;br /&gt;&lt;br /&gt;The default JAAS modules from Sun seem quite useless - they can authenticate the current user, not much more. The JDNI module is probably usable, but the tomcat JNDI source seems more customizable and simpler.&lt;br /&gt;&lt;br /&gt;Another option that wraps PAM is &lt;a href="http://www.scribblin.gs/software/sysauth.html"&gt;SysAuth&lt;/a&gt;&lt;br /&gt;(GPL2), it defines it's own simpler API, it could be wrapped in JAAS or&lt;br /&gt;in a tomcat module. Due to license and the fact that jaas-pam exists -&lt;br /&gt;probably not worth the effort. Another dead end is &lt;a href="http://www.bablokb.de/jaas/"&gt;ShadowJAAS&lt;/a&gt; - it supports unix&lt;br /&gt;user/password authentication, by parsing passwd/shadow files in a SUID&lt;br /&gt;root file.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&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/6855603-3205660275943487296?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/3205660275943487296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=3205660275943487296' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/3205660275943487296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/3205660275943487296'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2007/09/jaas-and-tomcat.html' title='JAAS and tomcat'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-114737210939809820</id><published>2006-05-11T11:28:00.000-07:00</published><updated>2006-05-11T11:28:29.406-07:00</updated><title type='text'>JMX names</title><content type='html'>Sun's advice &lt;a href="http://java.sun.com/products/JavaManagement/best-practices.html"&gt;http://java.sun.com/products/JavaManagement/best-practices.html&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Allways have type=&lt;/li&gt;&lt;li&gt;if singleton ( or one instance per domain ) - no&amp;nbsp; other key&lt;/li&gt;&lt;li&gt;otherwise: add name=&lt;/li&gt;&lt;li&gt;for grouping, add group=&lt;/li&gt;&lt;li&gt;j2eeType/jsr77 - they kind of agree it's a messs -&amp;nbsp; I think&lt;/li&gt;&lt;li&gt;they do actually define a 'containment scheme', using type=Server.Application.WebModule,..&amp;nbsp; and&amp;nbsp; Server=, Application=, etc. Not quite JSR77 - but close enough., and it makes more sense.&lt;/li&gt;&lt;li&gt;of course - an easier solution would be to just use&amp;nbsp; unix-like names name=//servername/appname/webname,&lt;/li&gt;&lt;/ul&gt;On mbeans, they advise:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;use standard MBeans - and use the interface with newProxyInstance. Not sure I agree with this one, if you want this kind of programmatic access use RMI/corba/etc if out of process, and the object directly if you are in process - you still have coupling and dependency, but no need for the JMX layer, which is not designed as RPC and is more inefficient than direct calls.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;advice against DynamicMBeans - instead extend StandardMBean.&amp;nbsp; I strongly disagree with this one.&lt;/li&gt;&lt;li&gt;On model mbeans, the correctly mention that they are hard to use by themself. The fact that they can't have interfaces is false AFAIK, you can define the interfaces if you want and the proxy will be generated, you can construct a dynamic proxy for anything if you want to write the interface. There is a decoupling since the implementation doesn't have to implement the method, but this can happen in any case if one side changes attributes/methods. See the above point on why I think dynamic proxies for JMX are a convoluted and bad idea.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;recommend using OpenMbeans - good idea, and avoiding RMI-specific features like downloading classes.&lt;/li&gt;&lt;/ul&gt;As usual for any 'best practice' document - don't believe all they say, ask first what 'practice' they had and how many applications they developed or considered before finding the 'best', and how they relate to your use case. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-114737210939809820?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/114737210939809820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=114737210939809820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/114737210939809820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/114737210939809820'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2006/05/jmx-names.html' title='JMX names'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-114710804545036528</id><published>2006-05-08T10:07:00.000-07:00</published><updated>2006-05-08T10:07:25.456-07:00</updated><title type='text'>Cleaning a firefox profile</title><content type='html'>&lt;a href="http://robert.accettura.com/archives/2006/05/03/cleaning-a-firefox-profile/"&gt;http://robert.accettura.com/archives/2006/05/03/cleaning-a-firefox-profile/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-114710804545036528?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/114710804545036528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=114710804545036528' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/114710804545036528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/114710804545036528'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2006/05/cleaning-firefox-profile.html' title='Cleaning a firefox profile'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-113268469918669091</id><published>2005-11-22T10:38:00.000-08:00</published><updated>2005-11-22T10:38:19.206-08:00</updated><title type='text'>JamVM -- A compact Java Virtual Machine</title><content type='html'>&lt;a href="http://jamvm.sourceforge.net/"&gt;JamVM&lt;/a&gt; - impressive VM, runs tomcat without problems, even eclipse works. All in less than 1/2 M. Speed is decent for simple use. And it supports ARM - so I can play with java and tomcat on my toys.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-113268469918669091?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://jamvm.sourceforge.net/' title='JamVM -- A compact Java Virtual Machine'/><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/113268469918669091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=113268469918669091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/113268469918669091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/113268469918669091'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2005/11/jamvm-compact-java-virtual-machine.html' title='JamVM -- A compact Java Virtual Machine'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-112871813001588642</id><published>2005-10-07T13:48:00.001-07:00</published><updated>2005-10-07T13:48:50.016-07:00</updated><title type='text'>Dashboard/konfabulator for Linux and firefox</title><content type='html'>&lt;a href="http://www.webweavertech.com/costin/archives/000425.html"&gt;Dashboard/konfabulator for Linux and firefox&lt;/a&gt;: "The 'killer feature' in Dashboard and konfabulator is (IMO) the ability to integrate a web-like interface with the OS. This opens the way for a lot of ideas in making Linux easier to use - for 'regular users' but also for advanced users who feel more comfortable using the browser than typing ( and remembering ) complex command lines.&lt;br /&gt;&lt;br /&gt;The implementation for firefox of a 'system/exec' feature similar with dashboard and konfabulator is not trivial, but not that complex. As I mentioned in a previous post, the async execution is the tricky part, but it has a reasonably straight solution. I'll try to find a server and post the sources - I'm sure there are better implementations using the event queue, but it works well enough for me.&lt;br /&gt;Now the remaining part is dealing with installing and running 'widgets' in firefox - and exactly emulating the interface. I'm not expecting Dashboard widgets to work unmodified, but with small changes.Â&amp;nbsp; Konfabulator has an simpler interface, but it's not HTML-like, I'll only see if I can implement a similar API for simpler transition. &lt;br /&gt;&lt;br /&gt;This has been a very interesting mini-project for me - I found a lot about how firefox works, and I hope it'll serve it's purpose and I'll be able to reduce my use of CLI and have a nicer interface for the linux commands I use. Even if some already have"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-112871813001588642?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.webweavertech.com/costin/archives/000425.html' title='Dashboard/konfabulator for Linux and firefox'/><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/112871813001588642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=112871813001588642' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/112871813001588642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/112871813001588642'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2005/10/dashboardkonfabulator-for-linux-and.html' title='Dashboard/konfabulator for Linux and firefox'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6855603.post-112871809589918326</id><published>2005-10-07T13:48:00.000-07:00</published><updated>2005-10-07T13:48:15.916-07:00</updated><title type='text'>A different implementation for commons-logging</title><content type='html'>Commons logging is an API attempting to hide the differences between JDK1.4 logging, log4j and other logging implementations. The reasons it exist is simple - JDK1.4 logging failed to become a de-facto standard ( even if it is bundled and the 'official' JSR for logging ), and many people preffer log4j or other implementations for logging.Â&amp;amp;nbsp; It is also one of the not-so-good APIs or implementations.&lt;br /&gt;&lt;br /&gt;The current implementation of common-logging uses a discovery mechanism, similar with what is used by JAXP. This has caused a lot of problems to many people, in particular if multiple class loaders are used - yet it is a reasonable solution.&lt;br /&gt;&lt;br /&gt;An alternative - that will work better in most cases - is to write a specific commons-logging implementation forÂ&amp;amp;nbsp; eachÂ&amp;amp;nbsp; backend, without any discovery. That means the logging .jar file will no longer work with or discover any backend - but that's not really a problem. If someone choose a particular logging backend, all he has to do is also deploy the matching commons-logging.jar. This way all the guesses and discovery are no longer needed, and if he changes his mind and wants a different logging - all he needs is to switch both jars. &lt;br /&gt;&lt;br /&gt;The ideal would be of course for log4j.jar to include a matching commons-logging implementation - but that won't happen for politic"&gt;A different implementation for commons-logging&lt;/a&gt;: "Commons logging is an API attempting to hide the differences between JDK1.4 logging, log4j and other logging implementations. The reasons it exist is simple - JDK1.4 logging failed to become a de-facto standard ( even if it is bundled and the 'official' JSR for logging ), and many people preffer log4j or other implementations for logging.Â&amp;nbsp; It is also one of the not-so-good APIs or implementations.&lt;br /&gt;&lt;br /&gt;The current implementation of common-logging uses a discovery mechanism, similar with what is used by JAXP. This has caused a lot of problems to many people, in particular if multiple class loaders are used - yet it is a reasonable solution.&lt;br /&gt;&lt;br /&gt;An alternative - that will work better in most cases - is to write a specific commons-logging implementation forÂ&amp;nbsp; eachÂ&amp;nbsp; backend, without any discovery. That means the logging .jar file will no longer work with or discover any backend - but that's not really a problem. If someone choose a particular logging backend, all he has to do is also deploy the matching commons-logging.jar. This way all the guesses and discovery are no longer needed, and if he changes his mind and wants a different logging - all he needs is to switch both jars. &lt;br /&gt;&lt;br /&gt;The ideal would be of course for log4j.jar to include a matching commons-logging implementation - but that won't happen for politic"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6855603-112871809589918326?l=blog.webinf.info' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.webinf.info/feeds/112871809589918326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6855603&amp;postID=112871809589918326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/112871809589918326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6855603/posts/default/112871809589918326'/><link rel='alternate' type='text/html' href='http://blog.webinf.info/2005/10/different-implementation-for-commons.html' title='A different implementation for commons-logging'/><author><name>Costin</name><uri>http://www.blogger.com/profile/03190426801284601248</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05630856778037701697'/></author><thr:total>0</thr:total></entry></feed>