<?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-3601540515224416871</id><updated>2011-10-29T00:31:00.546+03:00</updated><category term='linux'/><category term='GWT'/><category term='mysql'/><category term='java'/><category term='C / C++'/><category term='Objective-C'/><title type='text'>Mits Log</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-7967933151448421979</id><published>2011-06-15T20:34:00.008+03:00</published><updated>2011-10-16T21:08:20.012+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>How to format a drive on Linux</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/lucid/man8/parted.8.html"&gt;parted&lt;/a&gt; : Partition manipulation program&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/lucid/en/man8/mkfs.ext2.8.html"&gt;mkfs.ext2&lt;/a&gt; : Create an ext2 filesystem&lt;/li&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/lucid/en/man8/mkfs.ext2.8.html"&gt;mkfs.ext3&lt;/a&gt; : Create an ext3 filesystem&lt;/li&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/lucid/en/man8/mkfs.ext2.8.html"&gt;mkfs.ext4&lt;/a&gt; : Create an ext4 filesystem&lt;/li&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/lucid/en/man8/mkfs.vfat.8.html"&gt;mkfs.vfat&lt;/a&gt; : Create a FAT filesystem&lt;/li&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/lucid/en/man8/mkntfs.8.html"&gt;mkntfs&lt;/a&gt; : Create a NTFS filesystem&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;e2label : Change the label on an ext filesystem&lt;/li&gt;&lt;li&gt;ntfslabel : Change the label on an NTFS filesystem&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Display the mounted filesystems table&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;df&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;Unmount the device as necessary&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;sudo umount /path/to/device&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;Create an Ext3 filesystem&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;sudo mkfs.ext3 /dev/sda1&lt;br /&gt;sudo e2label /dev/sda1 MyDrive&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;Create a FAT filesystem&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;mkfs.vfat -F 32 /dev/hda1&lt;/blockquote&gt;The option "-F 32" indicates FAT32.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create an NTFS filesystem&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;sudo mkntfs /dev/sda1&lt;br /&gt;sudo ntfslabel /dev/sda1 MyDrive&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/3601540515224416871-7967933151448421979?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/7967933151448421979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=7967933151448421979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7967933151448421979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7967933151448421979'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2011/06/how-to-format-drive-on-linux.html' title='How to format a drive on Linux'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-7837737605447134356</id><published>2011-05-23T13:42:00.003+03:00</published><updated>2011-05-23T13:52:40.543+03:00</updated><title type='text'>Styling form fields and buttons</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;Although HTML form fields and buttons seem similar, in markup and basic style properties, they behave differently when it comes to defining their size. For example:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;lt;input type="text" value="Text" /&amp;gt;&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Wd6K1oJcDXo/Tdo7msZuumI/AAAAAAAAAGc/uUReursxYrI/s1600/form-field.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-Wd6K1oJcDXo/Tdo7msZuumI/AAAAAAAAAGc/uUReursxYrI/s1600/form-field.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&amp;lt;input type="submit" value="Submit" /&amp;gt;&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-bFfwu7SBj5Y/Tdo7tFZnuII/AAAAAAAAAGg/nXplHZK0KiM/s1600/form-button.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-bFfwu7SBj5Y/Tdo7tFZnuII/AAAAAAAAAGg/nXplHZK0KiM/s1600/form-button.jpg" /&gt;&lt;/a&gt;&lt;/div&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: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Both have static position and inline display. Now we set to both elements the following style: "&lt;i&gt;border: 0; height: 30px; padding: 10px;&lt;/i&gt;". The text field behaves like a block element, i.e. respects the exact given height and padding. The submit button, however, treats the height as an outer total size and subtracts the padding, i.e. results to having height equal to 10px.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&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/3601540515224416871-7837737605447134356?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/7837737605447134356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=7837737605447134356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7837737605447134356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7837737605447134356'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2011/05/styling-form-fields-and-buttons.html' title='Styling form fields and buttons'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-Wd6K1oJcDXo/Tdo7msZuumI/AAAAAAAAAGc/uUReursxYrI/s72-c/form-field.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-7955997035290647240</id><published>2011-05-18T12:45:00.007+03:00</published><updated>2011-10-16T21:16:43.595+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Linux reminder</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;b&gt;ps -e&lt;/b&gt;&lt;br /&gt;All processes.&lt;br /&gt;&lt;pre style="overflow: auto;"&gt;PID TTY          TIME CMD&lt;br /&gt;    1 ?        00:00:01 init&lt;br /&gt;    2 ?        00:00:00 kthreadd&lt;br /&gt;    3 ?        00:00:00 migration/0&lt;br /&gt;    4 ?        00:00:00 ksoftirqd/0&lt;br /&gt;    5 ?        00:00:00 watchdog/0&lt;br /&gt; 2497 tty4     00:00:00 getty&lt;br /&gt; 2498 tty5     00:00:00 getty&lt;br /&gt; 2501 tty2     00:00:00 getty&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;ps -eH&lt;/b&gt;&lt;br /&gt;All processes, hierarchical.&lt;br /&gt;&lt;pre style="overflow: auto;"&gt;PID TTY          TIME CMD&lt;br /&gt;    2 ?        00:00:00 kthreadd&lt;br /&gt;    3 ?        00:00:00   migration/0&lt;br /&gt;    4 ?        00:00:00   ksoftirqd/0&lt;br /&gt;    5 ?        00:00:00   watchdog/0&lt;br /&gt;    1 ?        00:00:01 init&lt;br /&gt; 2497 tty4     00:00:00   getty&lt;br /&gt; 2498 tty5     00:00:00   getty&lt;br /&gt; 2501 tty2     00:00:00   getty&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;ps -ef&lt;/b&gt;&lt;br /&gt;All processes, full format.&lt;br /&gt;&lt;pre style="overflow: auto;"&gt;UID        PID  PPID  C STIME TTY          TIME CMD&lt;br /&gt;root         1     0  0 09:50 ?        00:00:01 /sbin/init&lt;br /&gt;root         2     0  0 09:50 ?        00:00:00 [kthreadd]&lt;br /&gt;root         3     2  0 09:50 ?        00:00:00 [migration/0]&lt;br /&gt;root         4     2  0 09:50 ?        00:00:00 [ksoftirqd/0]&lt;br /&gt;root         5     2  0 09:50 ?        00:00:00 [watchdog/0]&lt;br /&gt;root      2497     1  0 09:50 tty4     00:00:00 /sbin/getty 38400 tty4&lt;br /&gt;root      2498     1  0 09:50 tty5     00:00:00 /sbin/getty 38400 tty5&lt;br /&gt;root      2501     1  0 09:50 tty2     00:00:00 /sbin/getty 38400 tty2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;PID files&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A pid file is kept in /var/run and is called by the name of the executable, plus a .pid extension. It contains the process id of the executable, which is the same thing ps will tell when it lists it. Generally, programs which use pid files create one when they start, remove it when they quit.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Search and Destroy files&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;find &amp;lt;dir&amp;gt; [-type {f|d}] -name &amp;lt;name&amp;gt; -print0 | xargs -0 rm -r -f&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Search &amp;amp; Execute command on the same folder as the file&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;find &amp;lt;dir&amp;gt; [-type {f|d}] -name &amp;lt;name&amp;gt; -execdir &amp;lt;command&amp;gt; '{}' \;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-7955997035290647240?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/7955997035290647240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=7955997035290647240' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7955997035290647240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7955997035290647240'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2011/05/linux-reminder.html' title='Linux reminder'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-5685605018675426929</id><published>2011-04-22T14:30:00.003+03:00</published><updated>2011-10-29T00:31:00.566+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java reminder</title><content type='html'>&lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9"&gt;&lt;b&gt;Enums&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.&lt;br /&gt;&lt;br /&gt;An enum type is implicitly &lt;i&gt;final&lt;/i&gt; unless it contains at least one enum constant that has a class body. In any case, it is a compile-time error to explicitly declare an enum type to be final.&lt;br /&gt;&lt;br /&gt;Nested enum types are implicitly &lt;i&gt;static&lt;/i&gt;. It is permissable to explicitly declare a nested enum type to be static.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.2"&gt;&lt;b&gt;Interfaces&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;Every field declaration in the body of an interface is implicitly &lt;i&gt;public&lt;/i&gt;, &lt;i&gt;static&lt;/i&gt;, and &lt;i&gt;final&lt;/i&gt;. It is permitted to redundantly specify any or all of these modifiers for such fields.&lt;br /&gt;&lt;br /&gt;Every method declaration in the body of an interface is implicitly &lt;i&gt;abstract&lt;/i&gt;, so its body is always represented by a semicolon, not a block.&lt;br /&gt;&lt;br /&gt;Every method declaration in the body of an interface is implicitly &lt;i&gt;public&lt;/i&gt;.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3"&gt;&lt;b&gt;Nested Interfaces&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;Member interfaces are always implicitly &lt;i&gt;static&lt;/i&gt; so they are never considered to be inner classes.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-5685605018675426929?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/5685605018675426929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=5685605018675426929' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/5685605018675426929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/5685605018675426929'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2011/04/java-reminder.html' title='Java reminder'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-152043525099956310</id><published>2011-01-30T23:31:00.008+02:00</published><updated>2011-03-31T23:41:45.245+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><title type='text'>Maven + GWT</title><content type='html'>&lt;p&gt;This is how to setup a GWT project with vanilla Maven, i.e. using no plugins other than the built-in antrun.&lt;/p&gt;&lt;p&gt;1. Add GWT dependencies into the Maven POM file:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt; &amp;lt;groupId&amp;gt;com.google.gwt&amp;lt;/groupId&amp;gt;&lt;br /&gt; &amp;lt;artifactId&amp;gt;gwt-user&amp;lt;/artifactId&amp;gt;&lt;br /&gt; &amp;lt;version&amp;gt;2.2.0&amp;lt;/version&amp;gt;&lt;br /&gt; &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt; &amp;lt;groupId&amp;gt;com.google.gwt&amp;lt;/groupId&amp;gt;&lt;br /&gt; &amp;lt;artifactId&amp;gt;gwt-dev&amp;lt;/artifactId&amp;gt;&lt;br /&gt; &amp;lt;version&amp;gt;2.2.0&amp;lt;/version&amp;gt;&lt;br /&gt; &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;2. Configure ANT-RUN plugin into the Maven POM file:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt; &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt; &amp;lt;artifactId&amp;gt;maven-antrun-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!--&lt;br /&gt;  Configuration for gwt development mode.&lt;br /&gt;  It doesn't take part into the default build-lifecycle.&lt;br /&gt;  You have to fire it, explicitly, from the command line:&lt;br /&gt;  e.g. mvn clean compile war:exploded antrun:run&lt;br /&gt; --&amp;gt;&lt;br /&gt; &amp;lt;configuration&amp;gt;&lt;br /&gt;  &amp;lt;tasks&amp;gt;&lt;br /&gt;   &amp;lt;property name="classpath" refid="maven.compile.classpath" /&amp;gt;&lt;br /&gt;   &amp;lt;property name="src.dir" value="${project.build.sourceDirectory}" /&amp;gt;&lt;br /&gt;   &amp;lt;property name="war.dir" value="${project.build.directory}/${project.build.finalName}" /&amp;gt;&lt;br /&gt;   &amp;lt;property name="gwt.module" value="package.EntryPoint" /&amp;gt;&lt;br /&gt;   &amp;lt;property name="gwt.url" value="index.jsp" /&amp;gt;&lt;br /&gt;   &amp;lt;ant target="gwt.debug" /&amp;gt;&lt;br /&gt;  &amp;lt;/tasks&amp;gt;&lt;br /&gt; &amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!--&lt;br /&gt;  Configuration for gwt compile mode.&lt;br /&gt; --&amp;gt;&lt;br /&gt; &amp;lt;executions&amp;gt;&lt;br /&gt;  &amp;lt;execution&amp;gt;&lt;br /&gt;   &amp;lt;phase&amp;gt;prepare-package&amp;lt;/phase&amp;gt;&lt;br /&gt;   &amp;lt;configuration&amp;gt;&lt;br /&gt;    &amp;lt;tasks&amp;gt;&lt;br /&gt;     &amp;lt;property name="classpath" refid="maven.compile.classpath" /&amp;gt;&lt;br /&gt;     &amp;lt;property name="src.dir" value="${project.build.sourceDirectory}" /&amp;gt;&lt;br /&gt;     &amp;lt;property name="war.dir" value="${project.build.directory}/${project.build.finalName}" /&amp;gt;&lt;br /&gt;     &amp;lt;property name="gwt.module" value="package.EntryPoint" /&amp;gt;&lt;br /&gt;     &amp;lt;ant target="gwt.compile" /&amp;gt;&lt;br /&gt;    &amp;lt;/tasks&amp;gt;&lt;br /&gt;   &amp;lt;/configuration&amp;gt;&lt;br /&gt;   &amp;lt;goals&amp;gt;&lt;br /&gt;    &amp;lt;goal&amp;gt;run&amp;lt;/goal&amp;gt;&lt;br /&gt;   &amp;lt;/goals&amp;gt;&lt;br /&gt;  &amp;lt;/execution&amp;gt;&lt;br /&gt; &amp;lt;/executions&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;3. Setup ANT build file:&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;project name="project.name"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;path id="gwt.classpath"&amp;gt;&lt;br /&gt;  &amp;lt;path path="${classpath}" /&amp;gt;&lt;br /&gt;  &amp;lt;pathelement location="${src.dir}" /&amp;gt;&lt;br /&gt; &amp;lt;/path&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="gwt.compile"&amp;gt;&lt;br /&gt;  &amp;lt;java classname="com.google.gwt.dev.Compiler" fork="true"&amp;gt;&lt;br /&gt;   &amp;lt;classpath refid="gwt.classpath" /&amp;gt;&lt;br /&gt;   &amp;lt;arg line="-war ${war.dir} ${gwt.module}" /&amp;gt;&lt;br /&gt;  &amp;lt;/java&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="gwt.debug"&amp;gt;&lt;br /&gt;  &amp;lt;!-- com.google.gwt.dev.HostedMode for legacy GWT 1.x --&amp;gt;&lt;br /&gt;  &amp;lt;java classname="com.google.gwt.dev.DevMode" fork="true"&amp;gt;&lt;br /&gt;   &amp;lt;classpath refid="gwt.classpath" /&amp;gt;&lt;br /&gt;   &amp;lt;!-- http://java.sun.com/javase/technologies/core/toolsapis/jpda/ --&amp;gt;&lt;br /&gt;   &amp;lt;jvmarg value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:8000" /&amp;gt;&lt;br /&gt;   &amp;lt;arg line="-war ${war.dir} -startupUrl ${gwt.url} ${gwt.module}" /&amp;gt;&lt;br /&gt;  &amp;lt;/java&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-152043525099956310?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/152043525099956310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=152043525099956310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/152043525099956310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/152043525099956310'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2011/01/maven-gwt.html' title='Maven + GWT'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-721060650837893698</id><published>2010-12-28T04:12:00.006+02:00</published><updated>2011-02-11T02:00:08.424+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><title type='text'>Objective-C reminder</title><content type='html'>&lt;b&gt;id&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;typedef struct objc_object {&lt;br /&gt;    Class isa;&lt;br /&gt;} * id;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;SEL&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;typedef struct objc_selector * SEL;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;IMP&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;typedef id (* IMP) (id self, SEL _cmd, ...);&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;BOOL&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;typedef signed char BOOL;&lt;br /&gt;#define YES (BOOL) 1&lt;br /&gt;#define NO  (BOOL) 0&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/ObjC.pdf"&gt;The Objective-C Programming Language&lt;/a&gt;&lt;br /&gt;&lt;a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html"&gt;Objective-C Runtime Reference&lt;/a&gt;&lt;br /&gt;&lt;a href="http://users.telenet.be/stes/faq.html"&gt;F.A.Q. - comp.lang.objective-c&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-721060650837893698?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/721060650837893698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=721060650837893698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/721060650837893698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/721060650837893698'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2010/12/objective-c-reminder.html' title='Objective-C reminder'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-1869853149687519867</id><published>2010-11-28T18:20:00.009+02:00</published><updated>2011-07-07T11:29:07.376+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C / C++'/><title type='text'>Initializing arrays in C</title><content type='html'>Allocating an array at compile time is done using an initialization list. We can get the array size and length as the compiler knows that our pointer is pointing at an array block.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;const char* car[] = { "foo", "bar" };&lt;br /&gt;&lt;br /&gt;int car_size = sizeof(car);&lt;br /&gt;int car_length = car_size / sizeof(void*);&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Allocating an array at runtime is done using malloc. This time the procedure is reversed because the compiler does not know that we are dealing with an array pointer. We start by specifying the length and size and then move on to allocate and initialize memory.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;int rar_length = 2;&lt;br /&gt;int rar_size = rar_length * sizeof(void*);&lt;br /&gt;&lt;br /&gt;const char** rar = malloc(rar_size);&lt;br /&gt;&lt;br /&gt;rar[0] = "foo";&lt;br /&gt;rar[1] = "bar";&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-1869853149687519867?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/1869853149687519867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=1869853149687519867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/1869853149687519867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/1869853149687519867'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2010/11/initializing-arrays-in-c.html' title='Initializing arrays in C'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-2549162562258248431</id><published>2010-10-21T23:47:00.006+03:00</published><updated>2010-11-28T19:06:29.361+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><title type='text'>Creating custom, lazily rendered, GWT components</title><content type='html'>Unlike other UI toolkits, GWT components do not define some sort of a render() method in which they generate their DOM structure. Instead, in the majority of cases, they do that inside their constructor. Having the root element setup right after the constructor is sort of a soft requirement as most operations assume just that.&lt;br /&gt;&lt;br /&gt;Built-in GWT widgets do not face hurdles with such architecture as they tend to be spartan in their structure. In most cases, they are essentially a high level API around basic HTML elements. However, this does not hold true when you try to build complex widgets, especially if they have to support lazy rendering.&lt;br /&gt;&lt;br /&gt;The simplest approach of creating a complex widget is to extend the Composite class, setup a hierarchy of widgets linked together via standard HasWidgets operations and finally call initWidget() - all inside the constructor.&lt;br /&gt;&lt;br /&gt;A less simple approach is to have inner widgets linked only at the DOM level. In such a case, the parent takes responsibility to create and attach manually the children's element, again inside the constructor. Additionally, the parent has to override doAttachChildren() and call for each children onAttach(). This is necessary because the parent-child relationship exists only at a "physical" level, not "logical". An example of this is &lt;a href="http://code.google.com/p/google-web-toolkit/source/browse/tags/2.0.0/user/src/com/google/gwt/user/client/ui/DialogBox.java"&gt;DialogBox&lt;/a&gt; and its Caption inner widget.&lt;br /&gt;&lt;br /&gt;Finally a more complex example is to have inner widgets and also support lazy rendering. An example would be, creating the children conditionally depending on configuration that becomes available &lt;i&gt;after&lt;/i&gt; the parent widget has been created. For example consider the following:&lt;br /&gt;&lt;br /&gt;MyDialogBox dialog = new MyDialogBox();&lt;br /&gt;dialog.setClosable(true);&lt;br /&gt;dialog.show();&lt;br /&gt;&lt;br /&gt;You might not want to create the close Button, unless the closable flag has been set to true. To do so, MyDialogBox may override the onLoad() method, which will be called right after the component becomes attached to the document, and create the button lazily. For example:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;class MyDialogBox extends DialogBox {&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected void onLoad() {&lt;br /&gt;    super.onLoad();&lt;br /&gt;&lt;br /&gt;    if (isClosable()) {&lt;br /&gt;      Element topCenterInner = getCellElement(0, 1);&lt;br /&gt;      topCenterInner.insertFirst(getCloseButton().getElement());&lt;br /&gt;      adopt(getCloseButton());&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Notice that no overriding of onAttachChildren() or doDetachChildren() is necessary here. The call of adopt(child) will trigger the child's setParent(), which will also trigger onAttach(), because of it's parent being attached to the document.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-2549162562258248431?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/2549162562258248431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=2549162562258248431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2549162562258248431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2549162562258248431'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2010/10/creating-custom-lazily-rendered-gwt.html' title='Creating custom, lazily rendered, GWT components'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-2339185277112156429</id><published>2010-09-28T22:57:00.013+03:00</published><updated>2010-11-28T19:06:57.348+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><title type='text'>GWT component lifecycle</title><content type='html'>Efficient use of GWT requires good understanding of it's component lifecycle. So here are some important rules:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The constructor always initializes, at least, the root DOM element.&lt;/li&gt;&lt;li&gt;The attachment of a child to a parent widget, also causes binding at the DOM level. The former is referred as "logical attach" while the latter as "physical attach". Both are being handled by the parent - see add() and remove().&lt;/li&gt;&lt;li&gt;When the parent is attached to the document, onAttach() will be called. Note that overriding the this method, based on documentation, is not recommended. Instead, doAttachChildren() and onLoad() are callbacks that may be overriden.&lt;/li&gt;&lt;li&gt;The doAttachChildren() will recursively call the onAttach() of any child-widgets. Overriding is required, for the cases where sub-widgets are attached to their parent at the &lt;i&gt;"physical"&lt;/i&gt; level but not at the &lt;i&gt;"logical"&lt;/i&gt; level.&lt;/li&gt;&lt;li&gt;A similar operation flow, but in reverse order, takes place upon detaching a child from a parent widget.&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://code.google.com/p/google-web-toolkit/source/browse/tags/2.0.0/user/src/com/google/gwt/user/client/ui/Widget.java" target="_blank"&gt;Widget&lt;/a&gt;, &lt;a href="http://code.google.com/p/google-web-toolkit/source/browse/tags/2.0.0/user/src/com/google/gwt/user/client/ui/Panel.java" target="_blank"&gt;Panel&lt;/a&gt;, &lt;a href="http://code.google.com/p/google-web-toolkit/source/browse/tags/2.0.0/user/src/com/google/gwt/user/client/ui/SimplePanel.java" target="_blank"&gt;SimplePanel&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-2339185277112156429?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/2339185277112156429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=2339185277112156429' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2339185277112156429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2339185277112156429'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2010/09/gwt-component-lifecycle.html' title='GWT component lifecycle'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-2000723095288281358</id><published>2009-12-07T20:00:00.005+02:00</published><updated>2011-07-07T11:30:48.689+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C / C++'/><title type='text'>Initializing class value member with C++</title><content type='html'>&lt;blockquote&gt;&lt;pre&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;class Bar&lt;br /&gt;{&lt;br /&gt;    public:&lt;br /&gt;    Bar() {&lt;br /&gt;        std::cout &amp;lt;&amp;lt; "Bar constructor { this: " &amp;lt;&amp;lt; this &amp;lt;&amp;lt; " }" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    Bar(const Bar&amp;amp; ref) {&lt;br /&gt;        std::cout &amp;lt;&amp;lt; "Bar copy constructor { this: " &amp;lt;&amp;lt; this &amp;lt;&amp;lt; ", ref: " &amp;lt;&amp;lt; &amp;amp;ref &amp;lt;&amp;lt; " }" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    Bar&amp;amp; operator=(const Bar&amp;amp; ref) {&lt;br /&gt;        std::cout &amp;lt;&amp;lt; "Bar assignment operator { this: " &amp;lt;&amp;lt; this &amp;lt;&amp;lt; ", ref: " &amp;lt;&amp;lt; &amp;amp;ref &amp;lt;&amp;lt; " }" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;        return *this;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Foo&lt;br /&gt;{&lt;br /&gt;    public:&lt;br /&gt;    Foo(const Bar&amp;amp; bar) : m_bar(bar) {&lt;br /&gt;        std::cout &amp;lt;&amp;lt; "Foo constructor" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    void doStuff() {&lt;br /&gt;        std::cout &amp;lt;&amp;lt; "Foo doStuff" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private:&lt;br /&gt;    Bar m_bar;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;    Foo(Bar()).doStuff();&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-2000723095288281358?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/2000723095288281358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=2000723095288281358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2000723095288281358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2000723095288281358'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2009/12/initializing-class-value-member-with-c.html' title='Initializing class value member with C++'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-3588195168085563028</id><published>2009-11-15T12:40:00.006+02:00</published><updated>2010-01-21T21:22:22.057+02:00</updated><title type='text'>How to extract audio from video on Ubuntu Linux</title><content type='html'>Extracting audio from video on linux is easy; however it can be very time consuming searching for the right packages to install and then going through the myriad of command options.&lt;br /&gt;&lt;br /&gt;First we need to install the &lt;a href="http://ffmpeg.org/"&gt;FFmpeg&lt;/a&gt; package. We may also need to install the &lt;a href="http://lame.sourceforge.net/"&gt;LAME&lt;/a&gt; package too.&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;sudo apt-get install ffmpeg&lt;br /&gt;sudo apt-get install lame&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;In the simplest case we can use only ffmpeg like this:&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;ffmpeg -i invideo.mp4 outaudio.mp3&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This however will encode by default the output at only 64kb. We can set a higher bit rate by using the -ab parameter like this:&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;ffmpeg -i invideo.mp4 -ab 128 outaudio.mp3&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This will encode the output at a constant 128kb rate. We may set it up to 320kb for the better quality.&lt;br /&gt;Finally we can use ffmpeg together with lame for a finer control of the encoding process.&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;ffmpeg -i invideo.mp4 outaudio.wav&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This will extract the output without any encoding (raw pcm). Now we can encode the mp3 with lame in any way we like.&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;lame -m s -h -b 128 output.wav out.mp3&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This will encode output.wav using stereo mode, high quality algorithm and a constant 128kb rate.&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;lame -m s -q 2 -V 4 -b 128 -B 320 output.wav out.mp3&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This will encode output.wav using stereo mode, high quality algorithm and a variable 128kb minimum / 320kb maximum rate.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-3588195168085563028?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/3588195168085563028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=3588195168085563028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/3588195168085563028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/3588195168085563028'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2009/11/how-to-extract-audio-from-video-on.html' title='How to extract audio from video on Ubuntu Linux'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-933224996601138225</id><published>2009-11-14T19:06:00.005+02:00</published><updated>2009-11-14T20:00:39.430+02:00</updated><title type='text'>James Gosling must be loving the Go language</title><content type='html'>Google introduced &lt;a href="http://golang.org/"&gt;Go&lt;/a&gt; earlier this week, their very own programming language. Go looks like a good mixture of languages like C, Java and Pascal. It is a statically typed, native compiled language. It also supports modern features like garbage collection and concurrency fro the get-go. &lt;br /&gt;&lt;br /&gt;The most interesting part of this new language, in my opinion, is its approach on object orientation and polymorphism. Here is what the &lt;a href="http://golang.org/doc/go_faq.html#Object_Oriented_Programming"&gt;FAQ&lt;/a&gt; says:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;Is Go an object-oriented language?&lt;/span&gt;&lt;br /&gt;Yes and no. Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. The concept of "interface" in Go provides a different approach that we believe is easy to use and in some ways more general. There are also ways to embed types in other types to provide something analogous—but not identical—to subclassing. Moreover, methods in Go are more general than in C++ or Java: they can be defined for any sort of data, not just structs.&lt;br /&gt;&lt;br /&gt;Also, the lack of type hierarchy makes “objects” in Go feel much more lightweight than in languages such as C++ or Java.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;How do I get dynamic dispatch of methods?&lt;/span&gt;&lt;br /&gt;The only way to have dynamically dispatched methods is through an interface. Methods on structs or other types are always resolved statically.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;At this point I recalled James Gosling, the creator of Java, saying on an interview that if he were to recreate Java, he would make it a delegation-only language. I searched a bit and I found the relevant pieces. So here they are:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;a href="http://www.artima.com/intv/gosling34.html"&gt;James Gosling on Java, May 2001&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;Bill Venners&lt;/span&gt;: When asked what you might do differently if you could recreate Java, you've said you've wondered what it would be like to have a language that just does delegation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;James Gosling&lt;/span&gt;: Yes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Bill Venners&lt;/span&gt;: And we think you mean maybe throwing out class inheritance, just having interface inheritance and composition. Is that what you mean?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;James Gosling&lt;/span&gt;: In some sense I don't know what I mean because if I knew what I meant, I would do it. There are various places where people have completed delegation-like things. Plenty of books talk about style and say delegation can be a much healthier way to do things. But specific mechanisms for how you would implement that tend to be problematic. Maybe if I was in the right mood, I'd blow away a year and just try to figure out the answer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Bill Venners&lt;/span&gt;: But by delegation, you do mean this object delegating to that object without it being a subclass?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;James Gosling&lt;/span&gt;: Yes -- without an inheritance hierarchy. Rather than subclassing, just use pure interfaces. It's not so much that class inheritance is particularly bad. It just has problems. &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;a href="http://www.artima.com/intv/gosling13.html"&gt;James Gosling on Java, May 1999&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;Bill Venners&lt;/span&gt;: In Java you included multiple inheritance of interface, but left out multiple inheritance of implementation. Were you trying to say anything to designers by making the interface a separate construct? Were you trying to say anything by leaving out multiple inheritance of implementation? How did that come about?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;James Gosling&lt;/span&gt;: It listened to people from the C++ and Objective-C camps, and I tried to sort out who had the most happy experiences. The Objective-C notion of a pure interface with no implementation seemed to have worked out really well for people. It avoids a lot of the sticky issues such as disambiguation that people get into in C++. It's still kind of messy. It's an area that I don't feel totally happy with.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Bill Venners&lt;/span&gt;: In what way?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;James Gosling&lt;/span&gt;: Another way for doing these things is a technique called delegation. Some ideas in the delegation camp felt good, but I never came up with anything that really worked. I ended up with the interface construct, which felt simple enough to be comprehensible, sophisticated enough to be useful. It also avoided any of the tar pits that the other folks got into. &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-933224996601138225?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/933224996601138225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=933224996601138225' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/933224996601138225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/933224996601138225'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2009/11/james-gosling-must-be-loving-go.html' title='James Gosling must be loving the Go language'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-2127743090461105774</id><published>2009-08-05T22:02:00.006+03:00</published><updated>2010-06-09T01:12:16.992+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>How to setup a static IP on Ubuntu Linux</title><content type='html'>&lt;p&gt;Lets say we want to set our IP address to 192.168.1.100:&lt;/p&gt;&lt;p&gt;First we have to edit /etc/network/interfaces and change it from something like that:&lt;/p&gt;&lt;blockquote&gt;auto lo&lt;br /&gt;iface lo inet loopback&lt;/blockquote&gt;&lt;p&gt;to that:&lt;/p&gt;&lt;blockquote&gt;auto lo&lt;br /&gt;iface lo inet loopback&lt;br /&gt;&lt;br /&gt;&lt;b&gt;auto eth0&lt;br /&gt;iface eth0 inet static&lt;br /&gt;address 192.168.1.100&lt;br /&gt;netmask 255.255.255.0&lt;br /&gt;gateway 192.168.1.254&lt;/b&gt;&lt;/blockquote&gt;&lt;p&gt;Then we also have to edit /etc/resolv.conf, which is responsible for our DNS entries, to something like that:&lt;/p&gt;&lt;blockquote&gt;nameserver 194.219.227.1&lt;br /&gt;nameserver 193.92.150.3&lt;/blockquote&gt;&lt;p&gt;Finaly we have to apply our changes by executing:&lt;/p&gt;&lt;blockquote&gt;sudo /etc/inid.d/networking restart&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-2127743090461105774?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/2127743090461105774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=2127743090461105774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2127743090461105774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2127743090461105774'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2009/08/how-to-setup-static-ip-on-ubuntu-linux.html' title='How to setup a static IP on Ubuntu Linux'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-2176460839737442756</id><published>2009-07-04T19:04:00.006+03:00</published><updated>2010-03-22T15:11:50.899+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>How to create an ISO image from a CD on Linux</title><content type='html'>Another mini Linux HOW-TO. I am writing these mostly for myself :)&lt;br /&gt;&lt;br /&gt;1) un-mount the cd&lt;br /&gt;2) dd if=/dev/cdrom of=/home/.../cd.iso&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-2176460839737442756?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/2176460839737442756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=2176460839737442756' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2176460839737442756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/2176460839737442756'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2009/07/how-to-create-iso-image-from-cd-on.html' title='How to create an ISO image from a CD on Linux'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-6142328750605176946</id><published>2009-01-03T23:08:00.050+02:00</published><updated>2010-06-06T14:48:29.340+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Flexible Repository 2</title><content type='html'>&lt;p&gt;In my earlier &lt;a href="../../2008/11/flexible-repository.html"&gt;post&lt;/a&gt; I briefly discussed the generic repository (DAO) pattern. In short, I argued how it can be enhanced with paging and entity relation initialization capabilities. This time I am going to take on the pattern design itself, identify its weak spots and introduce an alternative and possibly more elegant form.&lt;/p&gt;&lt;p&gt;The typical DAO consists of an interface and implementation pair like the following&lt;/p&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" style="background-color: #F5F5DC;"&gt;&lt;div style="padding: 0 10px; font-family: monospace;"&gt;&lt;pre&gt;interface Repository {&lt;br /&gt;    + create&lt;br /&gt;    + update&lt;br /&gt;    + delete&lt;br /&gt;    + findById&lt;br /&gt;    + findAll&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style="width: 15px;"&gt;&lt;/div&gt;&lt;/td&gt;&lt;td valign="top" style="background-color: #F5F5DC;"&gt;&lt;div style="padding: 0 10px; font-family: monospace;"&gt;&lt;pre&gt;class RepositoryImpl implements Repository {&lt;br /&gt;    // implementation ...&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;When we want to add additional operations we need to create a new interface and class pair that extend the generic ones. That though, quickly becomes a cumbersome way of reusing code because of the single inheritance model of Java.&lt;/p&gt;&lt;p&gt;If we take a look back to the JDBC API, we see a more modular approach where each operation is represented by a separate object, all using the same interface. In that regard as one moves from JDBC, to JPA, to DAO, gradually gives up flexibility in favor of staticness.&lt;/p&gt;&lt;p&gt;What follows is an introduction of a different interface that maintains all the modularity of JDBC, the abstraction of JPA and the strong typing of DAO. The solution is to break each DAO operation into a separate query object and transform the DAO itself into a query factory and configuration container. The tricky part then, is to avoid exposing the query implementation to the client. To do so we need to break &lt;i&gt;again&lt;/i&gt; each query component into a specification part and an implementation part. Without any more talking bellow are the core interfaces:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;interface Query&amp;lt;E, R&amp;gt; { }&lt;br /&gt;&lt;br /&gt;interface Repository&amp;lt;E&amp;gt; {&lt;br /&gt;    &amp;lt;R&amp;gt; R execute(Query&amp;lt;E, R&amp;gt; spec);&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Notice the high abstraction level of this API. The Query interface represents the specification part of the query components. It has two generic parameters, E for the entity type and R for the result type. Of course we still need the actual implementation for each operation. &lt;i&gt;Parenthesis; at first I had an additional interface for these parts that followed the command pattern (so the title) though I figured later that it wasn't really necessary as a public API.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;To demonstrate the “findById” operation consider the following:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;class FindById&amp;lt;E&amp;gt; implements Query&amp;lt;E, E&amp;gt; {&lt;br /&gt;    Object Id;&lt;br /&gt;&lt;br /&gt;    FindById(Object id) {&lt;br /&gt;        this.id = id;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;We can call this operation for an entity, lets say “Person”, with id 2 like this:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;FindById&amp;lt;Person&amp;gt; spec = new FindById&amp;lt;Person&amp;gt;(2);&lt;br /&gt;Person p = repository.execute(spec);&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Or simply abbreviated like this:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;Person p = repository.execute(new FindById&amp;lt;Person&amp;gt;(2));&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;So far we have gained little against using the standard DAO form and created more artifacts, though here comes the good stuff. We can now configure custom repositories by mix and matching any operations we like. This can be easy especialy with a dependency injection container like Spring. In the last example I demonstrate such a potential configuration with a read-only and a read-write template:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;&amp;lt;!-- This is a repository with read only operations --&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id=”readOnly” class="impl.Repository"&amp;gt;&lt;br /&gt;    &amp;lt;property name="queryCommands"&amp;gt;&lt;br /&gt;        &amp;lt;map&amp;gt;&lt;br /&gt;            &amp;lt;entry key="FindById" value="impl.FindByIdQuery" /&amp;gt;&lt;br /&gt;            &amp;lt;entry key="FindAll"  value="impl.FindAllQuery" /&amp;gt;&lt;br /&gt;        &amp;lt;/map&amp;gt;&lt;br /&gt;    &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- This is a repository with read and write operations --&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id=”readWrite” class="impl.Repository"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;property name="queryCommands"&amp;gt;&lt;br /&gt;        &amp;lt;map&amp;gt;&lt;br /&gt;            &amp;lt;entry key="FindById" value="impl.FindByIdQuery" /&amp;gt;&lt;br /&gt;            &amp;lt;entry key="FindAll"  value="impl.FindAllQuery" /&amp;gt;&lt;br /&gt;            &amp;lt;entry key="Create"   value="impl.CreateQuery" /&amp;gt;&lt;br /&gt;            &amp;lt;entry key="Update"   value="impl.UpdateQuery" /&amp;gt;&lt;br /&gt;            &amp;lt;entry key="Delete"   value="impl.DeleteQuery" /&amp;gt;&lt;br /&gt;        &amp;lt;/map&amp;gt;&lt;br /&gt;    &amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-6142328750605176946?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/6142328750605176946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=6142328750605176946' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/6142328750605176946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/6142328750605176946'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2009/01/data-access-using-command-pattern.html' title='Flexible Repository 2'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-1597508877826685869</id><published>2008-11-25T17:40:00.026+02:00</published><updated>2010-06-06T14:47:15.061+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Flexible Repository</title><content type='html'>&lt;p&gt;I have been using a repository class for data access following closely the &lt;a href="http://www.google.gr/search?q=generic+dao"&gt;generic DAO&lt;/a&gt; pattern. Due to my requirements though, the api evolved and became quite inflexible. This is my first post about my quest to design a more flexible generic repository.&lt;/p&gt;&lt;p&gt;The initial version of the repository interface looked like most of the examples available throughout the net:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;public interface Repository&amp;lt;E, I&amp;gt; {&lt;br /&gt;    E create(E entity);&lt;br /&gt;    E update(E entity);&lt;br /&gt;    void delete(I id);&lt;br /&gt;    E findById(I id);&lt;br /&gt;    List&amp;lt;E&amp;gt; findAll();&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;This worked for the most simple cases, though it is obvious that there is a serious issue with the methods that return multiple results, their size could easily turn too big. For this reason I altered them and applied a paging policy as follows:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;&lt;b&gt;DataPage&amp;lt;E&amp;gt;&lt;/b&gt; findAll(&lt;b&gt;int pageStart, int pageCount, String pageOrder&lt;/b&gt;);&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Where DataPage is a simple bean container like this:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;public class DataPage&amp;lt;E&amp;gt; implements Serializable {&lt;br /&gt;    private Collection&amp;lt;E&amp;gt; data;&lt;br /&gt;    private int total;&lt;br /&gt;    // getters &amp;amp; setters&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;That was better, yet still not very flexible for my needs.&lt;/p&gt;&lt;p&gt;Entities have two different kinds of properties, values and relations. The default fetch policy for relations is lazy. I wanted to have a uniform way to define relation properties that should be initialized. For that I added to all retrieval methods a String vararg as such:&lt;/p&gt;&lt;blockquote  style="background-color: #F5F5DC; font-family: monospace;"&gt;&lt;pre&gt;    E findById(I id, &lt;b&gt;String... initRelations&lt;/b&gt;);&lt;br /&gt;&lt;br /&gt;    DataPage&amp;lt;E&amp;gt; findAll(int pageStart, int pageCount, String pageOrder, &lt;b&gt;String... initRelations&lt;/b&gt;);&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;At this stage the interface supported all my requirements but one. I wanted the clients of this class to be able to extend its functionality, though without necessarily having to extend its implementation! Additionally after the above modifications, its interface had lost some its initial elegance and it was whispering re-factoring.&lt;/p&gt;&lt;p&gt;The final part of the modularization I will explain the next post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-1597508877826685869?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/1597508877826685869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=1597508877826685869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/1597508877826685869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/1597508877826685869'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2008/11/flexible-repository.html' title='Flexible Repository'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-8890839756488809269</id><published>2008-05-21T22:16:00.008+03:00</published><updated>2009-04-20T10:05:51.140+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>How to install NFS in Ubuntu Linux</title><content type='html'>To install the client packages:&lt;br /&gt;&lt;blockquote&gt;sudo apt-get install nfs-common&lt;/blockquote&gt;&lt;br /&gt;To install the client and server packages:&lt;br /&gt;&lt;blockquote&gt;sudo apt-get install nfs-kernel-server&lt;/blockquote&gt;&lt;br /&gt;Once the server is installed, we can setup the directories that will be shared with the file:&lt;br /&gt;&lt;blockquote&gt;/etc/exports&lt;/blockquote&gt;&lt;br /&gt;To share, for example, the directory /mnt/shared to a typical local network with the default settings we need to put the following line:&lt;br /&gt;&lt;blockquote&gt;/mnt/shared 192.168.1.1/255.255.255.0(sync,ro,root_squash,wdelay)&lt;/blockquote&gt;&lt;br /&gt;After we save the file we can activate the changes with the following commands:&lt;br /&gt;&lt;blockquote&gt;exportfs -ua&lt;br /&gt;exportfs -a&lt;/blockquote&gt;&lt;br /&gt;Now to enable the share from a client computer we execute the following:&lt;br /&gt;&lt;blockquote&gt;mount -t nfs  server_address:/mnt/shared  /local/path&lt;server&gt;&lt;/server&gt;&lt;/blockquote&gt;&lt;br /&gt;PS. The default options when we export a directory are: &lt;span style="font-style: italic;"&gt;ro, sync, wdelay, root_squash, no_subtree_check&lt;/span&gt; and they are implicit. Thous in the following examples are equal:&lt;br /&gt;&lt;blockquote&gt;/mnt/shared 192.168.1.1/255.255.255.0(rw)&lt;br /&gt;/mnt/shared 192.168.1.1/255.255.255.0(rw,sync,wdelay,root_squash,no_subtree_check)&lt;/blockquote&gt;&lt;br /&gt;For more information see &lt;a href="http://linux.die.net/man/5/exports"&gt;exports&lt;/a&gt; and &lt;a href="http://linux.die.net/man/8/exportfs"&gt;exportfs&lt;/a&gt; man pages&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-8890839756488809269?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/8890839756488809269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=8890839756488809269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/8890839756488809269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/8890839756488809269'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2008/05/how-to-install-nfs-in-ubuntu-linux.html' title='How to install NFS in Ubuntu Linux'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-7689421652733617089</id><published>2008-03-22T11:12:00.006+02:00</published><updated>2009-07-04T19:23:12.436+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>How to install MySQL autonomously on Linux</title><content type='html'>These are the necessary steps to install MySQL autonomously on Linux under the /opt directory.&lt;br /&gt;&lt;br /&gt;First we need to fetch the program from the &lt;a href="http://dev.mysql.com/"&gt;official MySQL web site&lt;/a&gt;. From the download area we choose the &lt;span&gt;"MySQL Community Server"&lt;/span&gt;, then the version we like and then the option &lt;span&gt;"Linux (non RPM packages) downloads&lt;/span&gt;". In this case I picked the latest stable 5 version:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;mysql-5.0.45-linux-i686-glibc23.tar.gz&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;From then we log as root to execute the installation scripts. The tasks we have to do are the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a specific user and group&lt;/li&gt;&lt;li&gt;Extract the zipped file to its destination&lt;/li&gt;&lt;li&gt;Create a basic configuration file&lt;/li&gt;&lt;li&gt;Initialize the database&lt;/li&gt;&lt;li&gt;Set up file permissions&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Set up the service startup script&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Create mysql user and group&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;groupadd mysql&lt;br /&gt;useradd -m -g mysql mysql&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Extract the zipped file to /opt&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;tar xzf mysql-5.0.45-linux-i686-glibc23.tar.gz -C /opt&lt;br /&gt;ln -s /opt/mysql-5.0.45-linux-i686-glibc23 /opt/mysql&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Create the configuration file&lt;/span&gt;&lt;br /&gt;With a text editor we create a file my.cnf under /etc with the following basic configuration data:&lt;br /&gt;&lt;blockquote&gt;[mysqld]&lt;br /&gt;basedir=/opt/mysql&lt;br /&gt;datadir=/opt/mysql/data&lt;br /&gt;character-sets-dir=/opt/mysql/share/mysql/charsets/&lt;br /&gt;character-set-server=utf8&lt;br /&gt;user=mysql&lt;br /&gt;port=3306&lt;br /&gt;socket=/tmp/mysql.sock&lt;br /&gt;&lt;br /&gt;[client]&lt;br /&gt;default-character-set=utf8&lt;br /&gt;port=3306&lt;br /&gt;socket=/tmp/mysql.sock&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Initialize the database&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;cd /opt/mysql&lt;br /&gt;scripts/mysql_install_db --user=mysql&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Set up file permissions&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;chown -R mysql:mysql /opt/mysql&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;Set up service startup&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;cp /opt/mysql/support-files/mysql.server /etc/init.d/mysql&lt;br /&gt;chmod +x /etc/init.d/mysql&lt;/blockquote&gt;Finaly for Fedora Linux:&lt;br /&gt;&lt;blockquote&gt;chkconfig --add mysql&lt;/blockquote&gt;and for Ubuntu / Debian Linux:&lt;br /&gt;&lt;blockquote&gt;update-rc.d mysql defaults&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-7689421652733617089?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/7689421652733617089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=7689421652733617089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7689421652733617089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7689421652733617089'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2008/03/how-to-install-mysql-autonomously-on.html' title='How to install MySQL autonomously on Linux'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3601540515224416871.post-7141518169514485319</id><published>2007-11-10T01:24:00.008+02:00</published><updated>2009-05-12T10:46:09.046+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>FHS is flawed</title><content type='html'>Recently I had a strong discussion with a couple of linux enthusiasts regarding the &lt;a href="http://www.pathname.com/fhs/pub/fhs-2.3.html"&gt;filesystem hierarchy&lt;/a&gt; and &lt;a href="http://www.pathname.com/fhs/pub/fhs-2.3.html#THEUSRHIERARCHY"&gt;/usr&lt;/a&gt; in particular which motivated me to write a blog about it. For those who might not know, /usr is the place where Linux systems hold most of their applications' files and it is subdivided into the following directories:&lt;br /&gt;&lt;br /&gt;&lt;table class="CALSTABLE" border="0" frame="void"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="FILENAME"&gt;bin&lt;/tt&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Most user commands&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="FILENAME"&gt;include&lt;/tt&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Header files included by C programs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="FILENAME"&gt;lib&lt;/tt&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Libraries&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="FILENAME"&gt;local&lt;/tt&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Local hierarchy (empty after main installation)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="FILENAME"&gt;sbin&lt;/tt&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Non-vital system binaries&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="FILENAME"&gt;share&lt;/tt&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Architecture-independent data&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;This certainly looks like a reasonable scheme. The important thing though is that files, are kept &lt;span style="font-weight: bold;"&gt;merged&lt;/span&gt; all together within each of the above directories and a couple of other places - like /etc for configuration and /var for data. This is an architecture that I claim to be flawed from certain aspects.&lt;br /&gt;&lt;br /&gt;The most apparent flaw is the misuse of Unix's central component, &lt;span style="font-style: italic;"&gt;the file system&lt;/span&gt;. As a naming system its primary job is to provide distinct hierarchical name spaces for software packages. Consequently it would seem logical for each distinct program to live in its own separate space but this is not the case with Linux.&lt;br /&gt;&lt;br /&gt;Lets see an example. A listing of my /usr/bin reports 1850 files. Here are a few of them:&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;apt-cache&lt;br /&gt;apt-config&lt;br /&gt;apt-extracttemplates&lt;br /&gt;apt-get&lt;br /&gt;...&lt;br /&gt;gnome-about             &lt;br /&gt;gnome-accessibility-keyboard-properties&lt;br /&gt;gnome-audio-profiles-properties&lt;br /&gt;gnome-background-properties&lt;br /&gt;gnome-btdownload        &lt;br /&gt;gnome-calculator        &lt;br /&gt;gnome-cd                &lt;br /&gt;...&lt;br /&gt;ssh&lt;br /&gt;ssh-add&lt;br /&gt;ssh-copy-id&lt;br /&gt;ssh-keygen&lt;br /&gt;ssh-keyscan&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Do we see a pattern here? The name-space is embedded directly into the filename, an ugly side effect of the /usr architecture. This is just an inconvenience though, as the real problem is that we cannot tell which other files in other directories constitute each of the above programs.&lt;br /&gt;&lt;br /&gt;For this reason Linux distributions have invented special programs in order to hold these information called package-managers. These programs provide convenient features like central access to massive software repositories and dependencies resolution. Their primary function however is to keep track of the several components (binaries, libraries, data) that are scattered throughout the entire system so when there is a need to remove or update a program the package managers know exactly which files should be handled and from where.&lt;br /&gt;&lt;br /&gt;Another flaw of the /usr design is it's inflexibility. Many programs do not strictly comply with the above static structure if at all. For example a default Apache Tomcat installation from tar.gz is structured as such:&lt;br /&gt;&lt;br /&gt;tomcat/bin&lt;br /&gt;tomcat/conf&lt;br /&gt;tomcat/logs&lt;br /&gt;tomcat/lib&lt;br /&gt;tomcat/shared&lt;br /&gt;tomcat/temp&lt;br /&gt;tomcat/webapps&lt;br /&gt;tomcat/work&lt;br /&gt;&lt;br /&gt;but we install it through the package manager, we end up with this:&lt;br /&gt;&lt;br /&gt;/usr/share/tomcat/bin&lt;br /&gt;/usr/share/tomcat/lib&lt;br /&gt;/etc/tomcat&lt;br /&gt;/var/log/tomcat/logs&lt;br /&gt;/var/lib/tomcat/shared&lt;br /&gt;/var/tmp/tomcat&lt;br /&gt;/var/lib/tomcat/webapps&lt;br /&gt;/var/run/tomcat&lt;br /&gt;&lt;br /&gt;In the former case we are dealing with a a &lt;span style="font-weight: bold;"&gt;solid self-contained&lt;/span&gt; package while in the later with several &lt;span style="font-weight: bold;"&gt;fragmented&lt;/span&gt; pieces. Moreover the source code of the program possibly had to be altered in order for this reorganization to work, a process which is often poorly executed from people not affiliated with the organization or the developers that made the program in the first place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3601540515224416871-7141518169514485319?l=zoomblab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zoomblab.blogspot.com/feeds/7141518169514485319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3601540515224416871&amp;postID=7141518169514485319' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7141518169514485319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3601540515224416871/posts/default/7141518169514485319'/><link rel='alternate' type='text/html' href='http://zoomblab.blogspot.com/2007/11/usr-is-flawed.html' title='FHS is flawed'/><author><name>Δημητριος Μενουνος</name><uri>http://www.blogger.com/profile/07416863812258576754</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry></feed>
