<?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-4699667848216680716</id><updated>2012-01-27T12:54:42.589+02:00</updated><category term='apache'/><category term='pitfalls'/><category term='click dating'/><category term='logging'/><category term='facebook'/><category term='data recovery'/><category term='flash'/><category term='hibernate'/><category term='javascript'/><category term='java'/><category term='php'/><category term='bugs'/><category term='howto'/><category term='Music'/><category term='junit'/><category term='AppEngine'/><category term='jdo'/><category term='video dating'/><category term='last.fm'/><category term='gwt'/><category term='flv'/><category term='metacafe.com'/><category term='tomcat'/><category term='slf4j'/><category term='offtopic'/><category term='google chrome'/><category term='log4j'/><category term='blind dating'/><category term='mobiledev'/><category term='Open Graph Protocol'/><category term='android'/><category term='blogger'/><category term='css'/><category term='guice'/><category term='wicket'/><category term='persistence'/><category term='unit testing'/><category term='video'/><category term='windows'/><category term='design'/><category term='codeark'/><category term='swf'/><category term='usb drive'/><category term='dating'/><category term='MySpace.com'/><category term='disk crash'/><category term='blogs'/><category term='google'/><title type='text'>Head to screen collision (H2SC)</title><subtitle type='html'>Put your helmet on...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-4985065749846758055</id><published>2011-08-15T19:48:00.004+03:00</published><updated>2011-08-15T20:17:10.879+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Time cost for creating a HashSet from an ArrayList</title><content type='html'>I ran this simple test to get a "feel":&lt;br /&gt;&lt;pre class="java" name="code"&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.HashSet;&lt;br /&gt;import java.util.List;&lt;br /&gt;import java.util.Random;&lt;br /&gt;&lt;br /&gt;public class Test {&lt;br /&gt;	public static void main(String... args) {&lt;br /&gt;		List&amp;lt;String&amp;gt; bigList = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;		List&amp;lt;String&amp;gt; smallList = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;&lt;br /&gt;		Random random = new Random();&lt;br /&gt;&lt;br /&gt;		// builds a 10000 items list made of items&lt;br /&gt;		// with string values generated from random&lt;br /&gt;		// numbers between 1000000 and 1999999&lt;br /&gt;		// this list has a higher chance to have duplicates&lt;br /&gt;		for (int i = 0; i &amp;lt; 10000; i++)&lt;br /&gt;			smallList.add(String.valueOf(random.nextInt(1000000) + 1000000));&lt;br /&gt;&lt;br /&gt;		// builds a 1000000 items list made of items&lt;br /&gt;		// with string values generated from random&lt;br /&gt;		// numbers between 1000000 and 1999999&lt;br /&gt;		for (int i = 0; i &amp;lt; 1000000; i++)&lt;br /&gt;			bigList.add(String.valueOf(random.nextInt(1000000) + 1000000));&lt;br /&gt;&lt;br /&gt;		int tests = 100;&lt;br /&gt;		&lt;br /&gt;		double smallListTransformationsTotalTime = 0;&lt;br /&gt;		&lt;br /&gt;		for (int i = 0; i &amp;lt; tests; i++) {&lt;br /&gt;			long start = System.currentTimeMillis();&lt;br /&gt;			new HashSet&amp;lt;String&amp;gt;(smallList);&lt;br /&gt;			long end = System.currentTimeMillis() - start;&lt;br /&gt;			smallListTransformationsTotalTime += end;&lt;br /&gt;		}		&lt;br /&gt;		System.out.println("Small list transformation average: " + (smallListTransformationsTotalTime / tests));&lt;br /&gt;		&lt;br /&gt;		double bigListTransformationsTotalTime = 0;&lt;br /&gt;		&lt;br /&gt;		for (int i = 0; i &amp;lt; tests; i++) {&lt;br /&gt;			long start = System.currentTimeMillis();&lt;br /&gt;			new HashSet&amp;lt;String&amp;gt;(bigList);&lt;br /&gt;			long end = System.currentTimeMillis() - start;			&lt;br /&gt;			bigListTransformationsTotalTime += end;&lt;br /&gt;		}&lt;br /&gt;		System.out.println("Big list transformation average: " + (bigListTransformationsTotalTime / tests));		&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Running this (100 tests) on my computer (i7 quad core using eclipse) yielded the following:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Small list transformation averaged 0.81ms&amp;nbsp;&lt;/li&gt;&lt;li&gt;Big list transformation averaged&amp;nbsp;196.31ms&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-4985065749846758055?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/4985065749846758055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=4985065749846758055' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4985065749846758055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4985065749846758055'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2011/08/time-cost-for-creating-hashset-from.html' title='Time cost for creating a HashSet from an ArrayList'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7531208707539274296</id><published>2011-04-27T16:15:00.001+03:00</published><updated>2011-04-27T16:16:48.538+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Better late than never</title><content type='html'>Just a shout out to my dear friend and colleague &lt;a href="http://blogs.microsoft.co.il/blogs/shair"&gt;Shai Raiten&lt;/a&gt; for getting his MVP award for the third year in a row.&lt;br /&gt;&lt;br /&gt;Shai is an exceptionally gifted professional, engaged in software development, consulting and lecturing on a daily basis. He is also funny as hell and fun to be around... what more can you ask for? :)&lt;br /&gt;&lt;br /&gt;So, Mazal tov!!!&lt;br /&gt;&lt;br /&gt;P.S See &lt;a href="http://blogs.microsoft.co.il/blogs/shair/archive/2011/04/01/vs-alm-microsoft-mvp-for-another-year.aspx"&gt;this post&lt;/a&gt; for the "official announcement"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7531208707539274296?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7531208707539274296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7531208707539274296' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7531208707539274296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7531208707539274296'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2011/04/better-late-than-never.html' title='Better late than never'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-4876832621563770238</id><published>2011-04-23T02:43:00.005+03:00</published><updated>2011-10-21T18:10:56.251+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='google chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Funky behavior of CSS Universal selector in Google Chrome Developer tools</title><content type='html'>Although its the middle of the night and I'm in an intense work / implementation session for one of the startups I work with (&lt;a href="http://zbang.it/"&gt;zbang.it&lt;/a&gt;) I had to pause for this.&lt;br /&gt;&lt;br /&gt;I was on the brink of loosing my sanity because of this weird problem where styles were merged with each other, when inspecting elements in Google Chrome developer tools (v10.0.648.205).&lt;br /&gt;&lt;br /&gt;First, here is the style sheet (or some of it), please note the CSS Universal selector at the beginning:&lt;br /&gt;&lt;pre class="css" name="code"&gt;*&lt;br /&gt;{&lt;br /&gt;    vertical-align: baseline;&lt;br /&gt;    font-weight: inherit;&lt;br /&gt;    font-family: inherit;&lt;br /&gt;    font-style: inherit;&lt;br /&gt;    font-size: 100%;&lt;br /&gt;    border: 0 none;&lt;br /&gt;    outline: 0;&lt;br /&gt;    padding: 0;&lt;br /&gt;    margin: 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;body&lt;br /&gt;{&lt;br /&gt;    font-family: Calibari, Arial;&lt;br /&gt;    font-size: 12px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;div.ui-layout-east&lt;br /&gt;{&lt;br /&gt;    width: 250px;&lt;br /&gt;    float: right;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;div.ui-innerLayout-north&lt;br /&gt;{&lt;br /&gt;    height: 70px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;. &lt;br /&gt;more css down here&lt;br /&gt;&lt;/pre&gt;Here is how it looked while inspecting &lt;b&gt;div.ui-layout-east&lt;/b&gt; on Google Chrome developer tools:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-xjPuCBPLGhM/TbIPJ4WahOI/AAAAAAAABQU/le6-fQu3Ung/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="502" src="http://2.bp.blogspot.com/-xjPuCBPLGhM/TbIPJ4WahOI/AAAAAAAABQU/le6-fQu3Ung/s640/Capture.PNG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Take a good look at the highlighted &lt;b&gt;height: 70px&lt;/b&gt;, its jumped up from &lt;b&gt;div.ui-innerLayout-north&lt;/b&gt;, don't believe me? I didn't believe myself at first, so I added a super noticeable style to &lt;b&gt;div.ui-innerLayout-north&lt;/b&gt;, like so:&lt;br /&gt;&lt;pre class="css" name="code"&gt;*&lt;br /&gt;{&lt;br /&gt;    vertical-align: baseline;&lt;br /&gt;    font-weight: inherit;&lt;br /&gt;    font-family: inherit;&lt;br /&gt;    font-style: inherit;&lt;br /&gt;    font-size: 100%;&lt;br /&gt;    border: 0 none;&lt;br /&gt;    outline: 0;&lt;br /&gt;    padding: 0;&lt;br /&gt;    margin: 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;body&lt;br /&gt;{&lt;br /&gt;    font-family: Calibari, Arial;&lt;br /&gt;    font-size: 12px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;div.ui-layout-east&lt;br /&gt;{&lt;br /&gt;    width: 250px;&lt;br /&gt;    float: right;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;div.ui-innerLayout-north&lt;br /&gt;{&lt;br /&gt;    height: 70px;&lt;br /&gt;    border: 3px dashed red;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;. &lt;br /&gt;more css down here&lt;br /&gt;&lt;/pre&gt;And, lo and behold&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-jS7MQG7xTFE/TbIQnHWAe1I/AAAAAAAABQc/GeLwxX5zluE/s1600/Capture.PNG" imageanchor="1"&gt;&lt;img border="0" height="243" src="http://1.bp.blogspot.com/-jS7MQG7xTFE/TbIQnHWAe1I/AAAAAAAABQc/GeLwxX5zluE/s640/Capture.PNG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It jumped right up again!!!&lt;br /&gt;&lt;br /&gt;At first I thought that I had a css syntax error somewhere but by way of elimination and after a long while I found out that this behavior happens only when the universal selector is the first style on the style sheet, and if its location changes:&lt;br /&gt;&lt;pre class="css" name="code"&gt;body&lt;br /&gt;{&lt;br /&gt;    font-family: Calibari, Arial;&lt;br /&gt;    font-size: 12px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;*&lt;br /&gt;{&lt;br /&gt;    vertical-align: baseline;&lt;br /&gt;    font-weight: inherit;&lt;br /&gt;    font-family: inherit;&lt;br /&gt;    font-style: inherit;&lt;br /&gt;    font-size: 100%;&lt;br /&gt;    border: 0 none;&lt;br /&gt;    outline: 0;&lt;br /&gt;    padding: 0;&lt;br /&gt;    margin: 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;div.ui-layout-east&lt;br /&gt;{&lt;br /&gt;    width: 250px;&lt;br /&gt;    float: right;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;div.ui-innerLayout-north&lt;br /&gt;{&lt;br /&gt;    height: 70px;&lt;br /&gt;    border: 3px dashed red;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;. &lt;br /&gt;more css down here&lt;br /&gt;&lt;/pre&gt;The universe goes to being expected again:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-JumNpQe2OJY/TbIR5m88wsI/AAAAAAAABQk/3Ih0yokEVxc/s1600/Capture.PNG" imageanchor="1"&gt;&lt;img border="0" height="185" src="http://3.bp.blogspot.com/-JumNpQe2OJY/TbIR5m88wsI/AAAAAAAABQk/3Ih0yokEVxc/s640/Capture.PNG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;By the way this does not affect the actual HTML in the browser, only the display in developer tools.&lt;br /&gt;&lt;br /&gt;Wasted a little over an hour of my life, hope it saves you one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-4876832621563770238?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/4876832621563770238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=4876832621563770238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4876832621563770238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4876832621563770238'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2011/04/funky-behavior-of-css-universal.html' title='Funky behavior of CSS Universal selector in Google Chrome Developer tools'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-xjPuCBPLGhM/TbIPJ4WahOI/AAAAAAAABQU/le6-fQu3Ung/s72-c/Capture.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-2904198467688368973</id><published>2011-04-21T18:06:00.001+03:00</published><updated>2011-10-04T14:39:55.743+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><title type='text'>Yet Another Facebook Search</title><content type='html'>Hi,&lt;br /&gt;&lt;br /&gt;Check out this website:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.yetanotherfacebooksearch.com"&gt;http://www.yetanotherfacebooksearch.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Which helps you search facebook for people, groups and pages. You will also get relevant results about a person and his friends, outside of facebook. This facebook search doesn't requires you to login as well.&lt;br /&gt;&lt;br /&gt;Check it out...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-2904198467688368973?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/2904198467688368973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=2904198467688368973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/2904198467688368973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/2904198467688368973'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2011/04/yet-another-facebook-search.html' title='Yet Another Facebook Search'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7070652781875682426</id><published>2011-04-02T17:09:00.000+03:00</published><updated>2011-04-02T17:09:31.247+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='AppEngine'/><title type='text'>A simple AppEngine Guice Module (Part 1)</title><content type='html'>This post is about a simple &lt;a href="http://code.google.com/p/google-guice/"&gt;Guice&lt;/a&gt; &lt;a href="http://code.google.com/appengine/"&gt;AppEngine&lt;/a&gt; module I've written, which I find very useful, hence, I decided to share it.&lt;br /&gt;&lt;br /&gt;The code is available &lt;a href="http://code.google.com/p/guice-app-engine-module/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The module will get your AppEngine project started quickly, here is a typical bootstrap (&lt;a href="http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/servlet/GuiceServletContextListener.html"&gt;GuiceServletContextListener&lt;/a&gt;) code for a simple app:&lt;br /&gt;&lt;pre class="java" name="code"&gt;package com.codeark.appengine;&lt;br /&gt;&lt;br /&gt;import com.codeark.appengine.objectify.ObjectifyModule;&lt;br /&gt;import com.google.inject.Guice;&lt;br /&gt;import com.google.inject.Injector;&lt;br /&gt;import com.google.inject.Module;&lt;br /&gt;import com.google.inject.servlet.GuiceServletContextListener;&lt;br /&gt;&lt;br /&gt;public class Bootstrap extends GuiceServletContextListener {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; protected Injector getInjector() {&lt;br /&gt;&lt;br /&gt;  Module aeModule = &lt;br /&gt;   AppEngineModule.build().withDatastoreService()&lt;br /&gt;    .withUrlFetchService().withMemcacheService().withMailService();&lt;br /&gt;&lt;br /&gt;  Module myModule = new MyOtherModule();&lt;br /&gt;  &lt;br /&gt;  return Guice.createInjector(aeModule, myModule);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The module's &lt;a href="http://en.wikipedia.org/wiki/Fluent_interface"&gt;Fluent Interface&lt;/a&gt; API(which I like so much) exposes a single static build() method which returns an instance of the module. You can then configure which services AppEngine should initialize using the .With*Service() methods.&lt;br /&gt;&lt;br /&gt;later you can do:&lt;br /&gt;&lt;pre class="java" name="code"&gt;class Classy {&lt;br /&gt; @Inject&lt;br /&gt; public Classy(MemcacheService service, MailService mail) {&lt;br /&gt; ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;There are several other goodies included in the source, which I will discuss in later posts: A simple abstraction over UrlFetchService and an &lt;a href="http://objectify-appengine.googlecode.com/"&gt;Objectify&lt;/a&gt; module.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7070652781875682426?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7070652781875682426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7070652781875682426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7070652781875682426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7070652781875682426'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2011/04/simple-appengine-guice-module-part-1.html' title='A simple AppEngine Guice Module (Part 1)'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-429082291462898574</id><published>2010-10-31T12:56:00.000+02:00</published><updated>2010-10-31T12:56:47.274+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>null is null ?</title><content type='html'>Here is a funny error message on Internet Explorer:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XnhytjnfyaU/TM1LKkQtFSI/AAAAAAAABOc/MiVajFgqgT0/s1600/nullIsNull.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="433" src="http://2.bp.blogspot.com/_XnhytjnfyaU/TM1LKkQtFSI/AAAAAAAABOc/MiVajFgqgT0/s640/nullIsNull.PNG" width="640" /&gt;&lt;/a&gt;&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/4699667848216680716-429082291462898574?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/429082291462898574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=429082291462898574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/429082291462898574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/429082291462898574'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/10/null-is-null.html' title='null is null ?'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XnhytjnfyaU/TM1LKkQtFSI/AAAAAAAABOc/MiVajFgqgT0/s72-c/nullIsNull.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-1042970019513964245</id><published>2010-10-08T03:33:00.000+02:00</published><updated>2010-10-08T03:33:25.228+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>How does a dog shortens your notebook's battery life?</title><content type='html'>So my notebook was having a severe drop in battery life. A few months ago I purchased a new battery (yes, yes...) and was quite disappointed that it had happened so quickly, however I've noticed that my cooling fan is doing overtime, even on a power saver plan, so I've decided to open up the patient and see whats going on.&lt;br /&gt;&lt;br /&gt;I was not that surprised to find a nice chunk of my dog's hair&amp;nbsp;and dust piled up between the heat sink and the cooling fan. As a result, heat wasn't getting transferred properly and thus the computer kept the cooling fan doing overtime == battery life plummets.&lt;br /&gt;&lt;br /&gt;Here is how it looked before cleaning &lt;span class="Apple-style-span" style="font-size: x-small;"&gt;(apologize for the slight blur in the pictures)&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XnhytjnfyaU/TK5v407e8fI/AAAAAAAABN0/zaiEFaoyM1c/s1600/IMG_20101008_020941.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="208" src="http://1.bp.blogspot.com/_XnhytjnfyaU/TK5v407e8fI/AAAAAAAABN0/zaiEFaoyM1c/s320/IMG_20101008_020941.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XnhytjnfyaU/TK5v8XVbOjI/AAAAAAAABN4/-bcNVHMI-z4/s1600/IMG_20101008_020947.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/_XnhytjnfyaU/TK5v8XVbOjI/AAAAAAAABN4/-bcNVHMI-z4/s320/IMG_20101008_020947.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And after I cleaned it up:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XnhytjnfyaU/TK5wy-FzEtI/AAAAAAAABOA/Wvhh1VLELYU/s1600/IMG_20101008_021538.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/_XnhytjnfyaU/TK5wy-FzEtI/AAAAAAAABOA/Wvhh1VLELYU/s320/IMG_20101008_021538.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here is my dog, her name is Layla:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/TK5zGyLpjKI/AAAAAAAABOE/2zbyJoKIbB0/s1600/37939_401778667324_625752324_4307336_2045111_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="http://4.bp.blogspot.com/_XnhytjnfyaU/TK5zGyLpjKI/AAAAAAAABOE/2zbyJoKIbB0/s400/37939_401778667324_625752324_4307336_2045111_n.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And finally, I want to express my sincere thanks to&amp;nbsp;&lt;a href="http://www.insidemylaptop.com/"&gt;insidemylaptop.com&lt;/a&gt;&amp;nbsp;for their guide on &lt;a href="http://www.insidemylaptop.com/disassemble-ho-530-notebook-pc-remove-top-cover/"&gt;how to disassemble an HP 530 notebook&lt;/a&gt;,&amp;nbsp;It's an old model, I know, but it still carries me :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-1042970019513964245?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/1042970019513964245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=1042970019513964245' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/1042970019513964245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/1042970019513964245'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/10/how-does-dog-shortens-your-notebooks.html' title='How does a dog shortens your notebook&apos;s battery life?'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XnhytjnfyaU/TK5v407e8fI/AAAAAAAABN0/zaiEFaoyM1c/s72-c/IMG_20101008_020941.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7858088225245095326</id><published>2010-09-24T15:13:00.002+02:00</published><updated>2011-10-21T20:05:23.601+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Has my cables provider's billing system been compromised?</title><content type='html'>My cable provider (internet and telephony infrastructure) in Israel is a company called &lt;a href="http://www.hot.net.il/"&gt;HOT&lt;/a&gt;. I get my invoices from their service into my mail, and this morning I got this email:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XnhytjnfyaU/TJygJr31fNI/AAAAAAAABNI/aRY982DllSw/s1600/suspected_phishing1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XnhytjnfyaU/TJygJr31fNI/AAAAAAAABNI/aRY982DllSw/s1600/suspected_phishing1.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This email's title is in hebrew, translated it says: "A notification about a change in billing service username" (roughly) the sender seems to be HOT but in fact it is not, as you can see, the red arrow points to the real underlying email address: "newsletter@em-sender1.com", this is how it looks normally (green arrow):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/TJygyzMM7TI/AAAAAAAABNM/ZNoflMXsjO8/s1600/ok_mail.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XnhytjnfyaU/TJygyzMM7TI/AAAAAAAABNM/ZNoflMXsjO8/s1600/ok_mail.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Normally, links in emails coming from HOT billing service lead to https://mybills.hot.net.il/something, e.g (green arrow):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XnhytjnfyaU/TJyhIYy7weI/AAAAAAAABNQ/kMu8Ibw2cHU/s1600/ok_mail1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XnhytjnfyaU/TJyhIYy7weI/AAAAAAAABNQ/kMu8Ibw2cHU/s1600/ok_mail1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;However, in the suspicious email the links looks very... err... suspicious :)&lt;br /&gt;(red arrow again)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/TJyhbAL1JUI/AAAAAAAABNU/G2MaPqrOPAk/s1600/suspected_phishing2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XnhytjnfyaU/TJyhbAL1JUI/AAAAAAAABNU/G2MaPqrOPAk/s1600/suspected_phishing2.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;So this email is either a very unwise attempt to use some external email sending service or, and I stress the OR, it means someone is trying a phishing move.&amp;nbsp;I find it hard to believe someone would try such a specific phishing email on a random bank of emails...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My only logical conjecture is: the sender had access to a list of HOT customers (business customer in my case), which is a very scary conjecture, one that I hope will be proven wrong...&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;UPDATE:&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;Further investigation reveals that &lt;a href="https://www.em-sender.com/default.aspx?"&gt;em-sender*.com&lt;/a&gt; might be connected to a company called &lt;a href="http://inwise.com/"&gt;inwise.com&lt;/a&gt;. Hmmm... this mail might be legit after all...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7858088225245095326?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7858088225245095326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7858088225245095326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7858088225245095326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7858088225245095326'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/09/has-my-cables-providers-billing-system.html' title='Has my cables provider&apos;s billing system been compromised?'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_XnhytjnfyaU/TJygJr31fNI/AAAAAAAABNI/aRY982DllSw/s72-c/suspected_phishing1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-5025061602496887568</id><published>2010-09-23T14:23:00.001+02:00</published><updated>2010-09-23T14:24:17.398+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Funny YouTube Internal Server Error message</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XnhytjnfyaU/TJtGu5DJecI/AAAAAAAABM0/p__sWB1Y6xI/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="211" src="http://2.bp.blogspot.com/_XnhytjnfyaU/TJtGu5DJecI/AAAAAAAABM0/p__sWB1Y6xI/s400/Capture.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-5025061602496887568?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/5025061602496887568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=5025061602496887568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5025061602496887568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5025061602496887568'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/09/funny-youtube-internal-server-error.html' title='Funny YouTube Internal Server Error message'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XnhytjnfyaU/TJtGu5DJecI/AAAAAAAABM0/p__sWB1Y6xI/s72-c/Capture.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-4199960784765917275</id><published>2010-09-17T20:13:00.002+02:00</published><updated>2010-09-17T20:13:52.295+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Chrome's new(?) invalid https certificate icon</title><content type='html'>How cool is that: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/TJOvwux4v2I/AAAAAAAABMg/3CzjWkLnYAQ/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XnhytjnfyaU/TJOvwux4v2I/AAAAAAAABMg/3CzjWkLnYAQ/s320/Capture.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-4199960784765917275?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/4199960784765917275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=4199960784765917275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4199960784765917275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4199960784765917275'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/09/chromes-new-invalid-https-certificate.html' title='Chrome&apos;s new(?) invalid https certificate icon'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XnhytjnfyaU/TJOvwux4v2I/AAAAAAAABMg/3CzjWkLnYAQ/s72-c/Capture.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7035442282319597383</id><published>2010-09-08T18:01:00.011+03:00</published><updated>2011-03-22T21:20:54.155+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Graph Protocol'/><title type='text'>Using Facebook Javascript SDK in your Blogger blog (Like button example)</title><content type='html'>Before you go any further you must read (and implement) my post about open graph:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.yanivkessler.com/2010/07/teach-your-blogger-blog-to-speak.html"&gt;Teach your Blogger Blog to speak Facebook's open graph protocol&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Open your blogger design interface and goto &lt;i&gt;edit html &lt;/i&gt;and&amp;nbsp;find the body opening tag (search page for &amp;lt;body). In another browser window open&amp;nbsp;this reference url on facebook's developers site: &lt;a href="http://developers.facebook.com/docs/reference/javascript/"&gt;http://developers.facebook.com/docs/reference/javascript/&lt;/a&gt;&amp;nbsp;copy the code there and paste it right after the body tag in your blogger template. The code snippet you just pasted should contain the following text:&amp;nbsp;&lt;b&gt;&lt;i&gt;appId: 'your app id' &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;(if it doesn't then facebook might have changed something and this post might not be relevant anymore).&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;If you properly followed the previous post (teach your blogger...) then you should have a Page on facebook for your blog by now, Go to it. We need the ID of that page, we can copy it from the address bar of our browser:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/TIegioDsmQI/AAAAAAAABMQ/e-ie8818YTo/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="161" src="http://4.bp.blogspot.com/_XnhytjnfyaU/TIegioDsmQI/AAAAAAAABMQ/e-ie8818YTo/s400/Capture.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;See the yellow marked number thats the ID of the page, copy it and paste it instead of&amp;nbsp;&lt;b&gt;&lt;i&gt;your app id &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;text (leave the single quotes in tact) in the code snippet we copy pasted from facebook. Save the template! :)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Time to add a like button to each post but first, make sure the &lt;/span&gt;&lt;i&gt;Expand widget template &lt;/i&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;checkbox is checked in your template editor:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XnhytjnfyaU/TIehtinlsHI/AAAAAAAABMY/KdXiJlhnvw4/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="67" src="http://1.bp.blogspot.com/_XnhytjnfyaU/TIehtinlsHI/AAAAAAAABMY/KdXiJlhnvw4/s400/Capture.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I've decided to place the like button beneath the title of each post and at the end of it, the exact position in the template depends on your blogger's template, when you locate the desired spot, paste the following code in it:&lt;br /&gt;&lt;pre class="html" name="code"&gt;&amp;lt;!-- facebook local post like button --&amp;gt;&lt;br /&gt;     &amp;lt;b:if cond='data:post.link'&amp;gt;&lt;br /&gt;       &amp;lt;fb:like expr:href='data:post.link' layout='button_count' show_faces='false' width='200'/&amp;gt;&lt;br /&gt;     &amp;lt;b:else/&amp;gt;&lt;br /&gt;        &amp;lt;b:if cond='data:post.url'&amp;gt;&lt;br /&gt;       &amp;lt;fb:like expr:href='data:post.url' layout='button_count' show_faces='false' width='200'/&amp;gt;&lt;br /&gt;        &amp;lt;b:else/&amp;gt;&lt;br /&gt;       &amp;lt;fb:like expr:href='data:url' layout='button_count' show_faces='false' width='200'/&amp;gt;&lt;br /&gt;        &amp;lt;/b:if&amp;gt;&lt;br /&gt;     &amp;lt;/b:if&amp;gt;&lt;br /&gt;&amp;lt;!-- facebook local post like button --&amp;gt;&lt;/pre&gt;And that should be it. If everything went right you should now see a like button on your blog, try it... and please try my button too ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7035442282319597383?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7035442282319597383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7035442282319597383' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7035442282319597383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7035442282319597383'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/09/integrating-facebook-javascript-sdk.html' title='Using Facebook Javascript SDK in your Blogger blog (Like button example)'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XnhytjnfyaU/TIegioDsmQI/AAAAAAAABMQ/e-ie8818YTo/s72-c/Capture.PNG' height='72' width='72'/><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-173687850213395912</id><published>2010-09-08T17:12:00.002+03:00</published><updated>2010-09-08T18:01:59.161+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><title type='text'>Using Blogger data tags inside script tags</title><content type='html'>Template will look like this:&lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;script type=&amp;#39;javascript&amp;#39;&amp;gt;&lt;br /&gt;var url=&amp;#39;&amp;lt;data:blog.url/&amp;gt;&amp;#39;;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;And the rendered result will look like this:&lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;script type=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;var url=&amp;#39;http://blog.yanivkessler.com/&amp;#39;;&lt;br /&gt;&amp;lt;/script&amp;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/4699667848216680716-173687850213395912?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/173687850213395912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=173687850213395912' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/173687850213395912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/173687850213395912'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/09/using-blogger-data-tags-in-script-tags.html' title='Using Blogger data tags inside script tags'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7803961346995247732</id><published>2010-09-08T17:08:00.001+03:00</published><updated>2010-09-08T18:02:15.818+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><title type='text'>Concatenating text in blogger data tags</title><content type='html'>I was messing around with my blogger template, testing the best way to integrate a facebook Like button into posts (this due to numerous demands to see how its done properly and not in a side bar).&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the methods I tested required me to generate different ids for different posts and the most logical way to do so would be to use to post id somehow. I searched the reference on blogger support but couldn't find any example, so I looked inside some templates and I found an example. So in the template we type this:&lt;/div&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;span expr:id='&amp;amp;quot;myId&amp;amp;quot; + data:post.id'&amp;gt;&amp;lt;/span&amp;gt;&lt;/pre&gt;Please note that I have to use &lt;b&gt;encoded quotes&lt;/b&gt; to surround the text and concatenate using the plus sign. This html will be rendered as a result by blogger engine:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;span id='myId8712387612387612'&amp;gt;&amp;lt;/span&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7803961346995247732?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7803961346995247732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7803961346995247732' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7803961346995247732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7803961346995247732'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/09/concatenating-text-in-blogger-data-tags.html' title='Concatenating text in blogger data tags'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-6144437086912779503</id><published>2010-07-12T18:33:00.006+03:00</published><updated>2010-10-26T00:36:13.814+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Graph Protocol'/><title type='text'>Teach your Blogger Blog to speak Facebook's open graph protocol</title><content type='html'>In your blog's control panel goto the &lt;b&gt;&lt;i&gt;Design&lt;/i&gt;&lt;/b&gt;&amp;nbsp;tab and select &lt;b&gt;&lt;i&gt;Edit HTML&lt;/i&gt;.&lt;/b&gt;&amp;nbsp;Find a tag called "&amp;lt;head&amp;gt;" (ctrl+f if you can't find it quickly) and add this code right after it:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;!-- Facebook open graph --&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;b:if cond='data:blog.pageType == &amp;amp;quot;item&amp;amp;quot;'&amp;gt;&lt;br /&gt;    &amp;lt;meta expr:content='&amp;amp;quot;the post: &amp;amp;quot; + data:blog.pageName' property='og:title'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='article' property='og:type'/&amp;gt; &lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;b:if cond='data:blog.pageType == &amp;amp;quot;archive&amp;amp;quot;'&amp;gt;&lt;br /&gt;    &amp;lt;meta expr:content='data:blog.pageName + &amp;amp;quot; posts&amp;amp;quot;' property='og:title'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='article' property='og:type'/&amp;gt; &lt;br /&gt;    &amp;lt;meta expr:content='data:blog.pageTitle' property='og:description'/&amp;gt; &lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;b:if cond='data:blog.pageType == &amp;amp;quot;index&amp;amp;quot;'&amp;gt;&lt;br /&gt;    &amp;lt;meta content='the blog' property='og:title'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='blog' property='og:type'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='Put your helmet on!' property='og:description'/&amp;gt; &lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;meta expr:content='data:blog.url' property='og:url'/&amp;gt; &lt;br /&gt;&amp;lt;meta content='http://3.bp.blogspot.com/_XnhytjnfyaU/TBI7ItnIPII/AAAAAAAABJY/SJRWM5RHDgI/S1600-R/header.png' property='og:image'/&amp;gt; &lt;br /&gt;&amp;lt;meta content='625752324' property='fb:admins'/&amp;gt; &lt;br /&gt;&amp;lt;meta expr:content='data:blog.title' property='og:site_name'/&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;!-- Facebook open graph --&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Here is a break down of whats going on here:&lt;/span&gt;&lt;br /&gt;This code is specific for&lt;i&gt; &lt;b&gt;item (post)&lt;/b&gt;&lt;/i&gt; pages, it tells facebook that the title for this page should be &lt;i&gt;&lt;b&gt;The post: &amp;lt;post name here&amp;gt;&lt;/b&gt;&lt;/i&gt; and the graph object type is &lt;i&gt;&lt;b&gt;article&lt;/b&gt; &lt;/i&gt;(this tells facebook that the content is transient, see link to reference at the end of this post).&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;b:if cond='data:blog.pageType == &amp;amp;quot;item&amp;amp;quot;'&amp;gt;&lt;br /&gt;    &amp;lt;meta expr:content='&amp;amp;quot;the post: &amp;amp;quot; + data:blog.pageName' property='og:title'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='article' property='og:type'/&amp;gt; &lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;br /&gt;&lt;/pre&gt;The result on the user's wall will look like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://1.bp.blogspot.com/_XnhytjnfyaU/TDsuSZ2i6BI/AAAAAAAABKQ/noj0kUG5VzU/s1600/likePost.PNG" imageanchor="1"&gt;&lt;img border="0" height="36" src="http://1.bp.blogspot.com/_XnhytjnfyaU/TDsuSZ2i6BI/AAAAAAAABKQ/noj0kUG5VzU/s400/likePost.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Next:&lt;/span&gt;&lt;br /&gt;This code handles &lt;i&gt;&lt;b&gt;archive&lt;/b&gt;&lt;/i&gt; pages (like &lt;a href="http://blog.yanivkessler.com/2010_06_01_archive.html"&gt;this one&lt;/a&gt;) and will tell facebook that the title should be &amp;lt;month year&amp;gt; posts e.g.&amp;nbsp;December 2008 posts.&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;b:if cond='data:blog.pageType == &amp;amp;quot;archive&amp;amp;quot;'&amp;gt;&lt;br /&gt;    &amp;lt;meta expr:content='data:blog.pageName + &amp;amp;quot; posts&amp;amp;quot;' property='og:title'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='article' property='og:type'/&amp;gt; &lt;br /&gt;    &amp;lt;meta expr:content='data:blog.pageTitle' property='og:description'/&amp;gt; &lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;br /&gt;&lt;/pre&gt;The result on the user's wall will look like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/_XnhytjnfyaU/TDsvuDz0qUI/AAAAAAAABKY/WOpH43S_yJE/s1600/likeArchive.PNG" imageanchor="1"&gt;&lt;img border="0" height="22" src="http://2.bp.blogspot.com/_XnhytjnfyaU/TDsvuDz0qUI/AAAAAAAABKY/WOpH43S_yJE/s400/likeArchive.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Next:&lt;/span&gt;&lt;br /&gt;Code to handle data in our &lt;i&gt;blog's index (homepage)&lt;/i&gt;, this will tell facebook that the title is &lt;i&gt;the blog &lt;/i&gt;and the type of the graph object is &lt;i&gt;blog.&lt;/i&gt; I also specified a static description text: &lt;i&gt;put your helmet!&lt;/i&gt;&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;b:if cond='data:blog.pageType == &amp;amp;quot;index&amp;amp;quot;'&amp;gt;&lt;br /&gt;    &amp;lt;meta content='the blog' property='og:title'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='blog' property='og:type'/&amp;gt; &lt;br /&gt;    &amp;lt;meta content='Put your helmet on!' property='og:description'/&amp;gt; &lt;br /&gt;&amp;lt;/b:if&amp;gt;&lt;br /&gt;&lt;/pre&gt;The result on the user's wall will look like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://1.bp.blogspot.com/_XnhytjnfyaU/TDswfbM2TdI/AAAAAAAABKg/rVBgLzFV-Zo/s1600/likeIndex.PNG" imageanchor="1"&gt;&lt;img border="0" height="25" src="http://1.bp.blogspot.com/_XnhytjnfyaU/TDswfbM2TdI/AAAAAAAABKg/rVBgLzFV-Zo/s400/likeIndex.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Finally, we're telling facebook about some general stuff: &lt;/span&gt;&lt;br /&gt;Here we wire the current page's url to the open graph protocol's url property:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;meta expr:content='data:blog.url' property='og:url'/&amp;gt; &lt;br /&gt;&lt;/pre&gt;The image facebook uses all around when displaying our graph object on facebook:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;meta content='http://3.bp.blogspot.com/_XnhytjnfyaU/TBI7ItnIPII/AAAAAAAABJY/SJRWM5RHDgI/S1600-R/header.png' property='og:image'/&amp;gt;&lt;br /&gt;&lt;/pre&gt;The user id (or ids) of the facebook profiles that administer this page (see how to find your user id &lt;a href="http://answers.yahoo.com/question/index?qid=20090622114157AATuZ0W"&gt;here&lt;/a&gt;):&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;meta content='625752324' property='fb:admins'/&amp;gt; &lt;br /&gt;&lt;/pre&gt;A title for the site:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;meta expr:content='data:blog.title' &lt;br /&gt;property='og:site_name'/&amp;gt; &lt;br /&gt;&lt;/pre&gt;Basically in places where we want a dynamic blogger property we use &lt;b&gt;&lt;i&gt;expr:&amp;lt;attribute&amp;gt;='&amp;lt;blogger data expression&amp;gt;' &lt;/i&gt;&lt;/b&gt;instead of simple html attributes like context="My title".&lt;br /&gt;&lt;br /&gt;If you want to see how Facebook reads your open graph protocol metadata you can use &lt;a href="http://developers.facebook.com/tools/lint/"&gt;Facebook's URL Linter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developers.facebook.com/docs/opengraph"&gt;Here&lt;/a&gt; you'll find the Open Graph Protocol's reference.&lt;br /&gt;&lt;br /&gt;For more information, please see &lt;a href="http://blog.yanivkessler.com/2010/09/integrating-facebook-javascript-sdk.html"&gt;my post&lt;/a&gt; on how to use Facebook Javascript SDK from your blog and properly add a "like" button to your posts.&lt;br /&gt;&lt;br /&gt;Also, check out some cool blogger books on amazon:&amp;nbsp;&lt;a href="http://www.amazon.com/s/?ie=UTF8&amp;amp;tag=headh2sc-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;search-alias=aps&amp;amp;field-keywords=blogger" target="_blank"&gt;Search Amazon.com  for blogger&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=headh2sc-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-6144437086912779503?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/6144437086912779503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=6144437086912779503' title='60 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6144437086912779503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6144437086912779503'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/07/teach-your-blogger-blog-to-speak.html' title='Teach your Blogger Blog to speak Facebook&apos;s open graph protocol'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XnhytjnfyaU/TDsuSZ2i6BI/AAAAAAAABKQ/noj0kUG5VzU/s72-c/likePost.PNG' height='72' width='72'/><thr:total>60</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-2697767623188677487</id><published>2010-06-23T02:08:00.001+03:00</published><updated>2010-07-29T15:51:52.808+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='AppEngine'/><category scheme='http://www.blogger.com/atom/ns#' term='pitfalls'/><category scheme='http://www.blogger.com/atom/ns#' term='jdo'/><title type='text'>Another parent child relationship pitfall (jdo)</title><content type='html'>Its a rookie's mistake but it stole an hour of my life, so at least I hope this will save someone else's time. I was making an experiment on AppEngine with big collections and I wrote these very simple parent and child classes to help in my test:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@PersistenceCapable&lt;br /&gt;public class ParentWithBidiOwnedChildren {&lt;br /&gt;&lt;br /&gt; @Persistent(mappedBy="parent")&lt;br /&gt; private Set&amp;lt;ChildWithBidiOwningParent&amp;gt; children;&lt;br /&gt;&lt;br /&gt; public ParentWithBidiOwnedChildren() {&lt;br /&gt;  children = new HashSet&amp;lt;ChildWithBidiOwningParent&amp;gt;();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @PrimaryKey&lt;br /&gt; @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt; public Key id;&lt;br /&gt;&lt;br /&gt; public void addNewChild() {&lt;br /&gt;  children.add(new ChildWithBidiOwningParent(this));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Set&amp;lt;ChildWithBidiOwningParent&amp;gt; getChildren() {&lt;br /&gt;  return children;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;And child:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@PersistenceCapable&lt;br /&gt;public class ChildWithBidiOwningParent { &lt;br /&gt; &lt;br /&gt; @PrimaryKey &lt;br /&gt; @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt; public Key id;&lt;br /&gt; &lt;br /&gt; @Persistent&lt;br /&gt; private final ParentWithBidiOwnedChildren parent;&lt;br /&gt;&lt;br /&gt; public ChildWithBidiOwningParent(ParentWithBidiOwnedChildren parent) {&lt;br /&gt;  this.parent = parent;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public ParentWithBidiOwnedChildren getParent() {&lt;br /&gt;  return parent;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;In Eclipse IDE when you hit ctrl+1 you can quickly create a member field from a constructor parameter:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XnhytjnfyaU/TCE_s38XmOI/AAAAAAAABKE/IyA1GVUOXKU/s1600/e1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="63" src="http://2.bp.blogspot.com/_XnhytjnfyaU/TCE_s38XmOI/AAAAAAAABKE/IyA1GVUOXKU/s400/e1.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;Eclipse generates a &lt;b&gt;final field&lt;/b&gt; which is recommended and desirable in most cases:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XnhytjnfyaU/TCE-Gm-p7dI/AAAAAAAABJ8/zl-PjJ_cFw0/s1600/e2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="77" src="http://3.bp.blogspot.com/_XnhytjnfyaU/TCE-Gm-p7dI/AAAAAAAABJ8/zl-PjJ_cFw0/s400/e2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;What happens next, when you try to persist a parent, you get an exception:&lt;/div&gt;&lt;br /&gt;&lt;i&gt;javax.jdo.JDOUserException: Class "com.codeark.appengine.bigcollections.ParentWithBidiOwnedChildren" has collection field "children" and this has no mapping in the table for the element class "com.codeark.appengine.bigcollections.ChildWithBidiOwningParent" owner field "parent"&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Immediately I started looking for an error in my annotations, but the smoking gun was that auto generated &lt;b&gt;final&lt;/b&gt; keyword, so here is the correct child code:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@PersistenceCapable&lt;br /&gt;public class ChildWithBidiOwningParent { &lt;br /&gt; &lt;br /&gt; @PrimaryKey &lt;br /&gt; @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)&lt;br /&gt; public Key id;&lt;br /&gt; &lt;br /&gt; @Persistent&lt;br /&gt; private ParentWithBidiOwnedChildren parent;&lt;br /&gt;&lt;br /&gt; public ChildWithBidiOwningParent(ParentWithBidiOwnedChildren parent) {&lt;br /&gt;  this.parent = parent;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public ParentWithBidiOwnedChildren getParent() {&lt;br /&gt;  return parent;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;That was a very unpleasent hour for me :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-2697767623188677487?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/2697767623188677487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=2697767623188677487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/2697767623188677487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/2697767623188677487'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/06/another-parent-child-relationship.html' title='Another parent child relationship pitfall (jdo)'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XnhytjnfyaU/TCE_s38XmOI/AAAAAAAABKE/IyA1GVUOXKU/s72-c/e1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-5619714250118458749</id><published>2010-06-11T16:34:00.001+03:00</published><updated>2010-06-11T16:34:32.793+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Blogger launches new template designer</title><content type='html'>Looks slick...&lt;br /&gt;&lt;br /&gt;Congrats !!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-5619714250118458749?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/5619714250118458749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=5619714250118458749' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5619714250118458749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5619714250118458749'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/06/blogger-launches-new-template-designer.html' title='Blogger launches new template designer'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-433069077084869031</id><published>2010-06-08T17:13:00.003+03:00</published><updated>2010-07-29T15:55:56.496+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='AppEngine'/><category scheme='http://www.blogger.com/atom/ns#' term='jdo'/><title type='text'>Lightweight JDO Persistence Filter using Guice</title><content type='html'>Here is a very lightweight and simple PersistenceFilter for your Guice powered webapps:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@Singleton&lt;br /&gt;public class PersistenceFilter implements Filter {&lt;br /&gt;&lt;br /&gt; private final Provider&amp;lt;PersistenceManager&amp;gt; pmp;&lt;br /&gt;&lt;br /&gt; @Inject&lt;br /&gt; public PersistenceFilter(Provider&amp;lt;PersistenceManager&amp;gt; pmp) {&lt;br /&gt;  this.pmp = pmp;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void destroy() {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {&lt;br /&gt;  PersistenceManager pm = pmp.get();&lt;br /&gt;  try {&lt;br /&gt;   chain.doFilter(request, response);&lt;br /&gt;  } finally {&lt;br /&gt;   pm.close();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void init(FilterConfig arg0) throws ServletException {&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This is no replacement for warp-persist and the soon to come guice persistence support, but look how simple it is, I love it! :-)&lt;br /&gt;&lt;br /&gt;So how does this work? the "magic" is done by using Guice scoping, basically PersistenceManager is tied to the Request scope and all we have to do is close it at the end of the request. I'm going to show this in the context of an AppEngine application (cuz thats what I'm working on right now), so here is our web.xml:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; xsi:schemaLocation="http://java.sun.com/xml/ns/javaee&lt;br /&gt;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; version="2.5"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;filter&amp;gt;&lt;br /&gt;  &amp;lt;filter-name&amp;gt;guiceFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;  &amp;lt;filter-class&amp;gt;com.google.inject.servlet.GuiceFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt; &amp;lt;/filter&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;  &amp;lt;filter-name&amp;gt;guiceFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;  &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt; &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;listener&amp;gt;&lt;br /&gt;  &amp;lt;listener-class&amp;gt;com.codeark.persistencefilterexample.Bootstrap&amp;lt;/listener-class&amp;gt;&lt;br /&gt; &amp;lt;/listener&amp;gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;br /&gt;&lt;/pre&gt;Its an ordinary, run of the mill Guice powered webapp web.xml config file (see &lt;a href="http://headtoscreencollision.blogspot.com/2010/05/wicket-and-guice-alternate-route.html"&gt;this post&lt;/a&gt; if you're using wicket, and why...) &lt;br /&gt;&lt;br /&gt;The Bootstrap listener looks like this:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public final class Bootstrap extends GuiceServletContextListener {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; protected Injector getInjector() {&lt;br /&gt;  return buildInjector();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Injector buildInjector() {  &lt;br /&gt;  Injector infrastructure = Guice.createInjector(    &lt;br /&gt;    new AppEngineModule(), &lt;br /&gt;    new PersistenceModule(), &lt;br /&gt;    new WebModule());&lt;br /&gt;&lt;br /&gt;  return infrastructure;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;AppEngineModule handles the bindings of GAE specific services:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class AppEngineModule extends AbstractModule {&lt;br /&gt; &lt;br /&gt; private static final PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("transactions-optional");&lt;br /&gt;  &lt;br /&gt; public AppEngineModule() {  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; protected void configure() {&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Provides&lt;br /&gt; PersistenceManagerFactory providesPersistenceManagerFactory() {&lt;br /&gt;  return pmf;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Provides&lt;br /&gt; UserService providesUserService() {&lt;br /&gt;  return UserServiceFactory.getUserService();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Inject&lt;br /&gt; @Provides&lt;br /&gt; @SessionScoped&lt;br /&gt; User providesCurrentUser(UserService userService) {&lt;br /&gt;  return userService.getCurrentUser();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Please note the &lt;b&gt;providesPersistenceManagerFactory()&lt;/b&gt; which localizes the use of static state to this module only. Additionally, diverging from the main topic of this post, take a look at &lt;b&gt;providesCurrentUser(UserService userService)&lt;/b&gt; which simply allows you to Inject the current Google Account User (if one is logged in this session) anywhere in your code, its really handy.&lt;br /&gt;&lt;br /&gt;Now comes the PersistenceModule:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class PersistenceModule extends AbstractModule {&lt;br /&gt; &lt;br /&gt; public PersistenceModule() {  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; protected void configure() {&lt;br /&gt;  bind(PersistenceManager.class).toProvider(PersistenceManagerProvider.class).in(RequestScoped.class);&lt;br /&gt;  bind(DataService.class).to(DataServiceImpl.class); &lt;br /&gt; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The most important line here is the first one where we bind PersistenceManager to the request scope. The provider follows:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class PersistenceManagerProvider implements Provider&amp;lt;PersistenceManager&amp;gt; {&lt;br /&gt;&lt;br /&gt; private final PersistenceManagerFactory pmf;&lt;br /&gt;&lt;br /&gt; @Inject&lt;br /&gt; public PersistenceManagerProvider(PersistenceManagerFactory pmf) {&lt;br /&gt;  this.pmf = pmf;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public PersistenceManager get() {&lt;br /&gt;  return pmf.getPersistenceManager();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;I could have used a @Provides method in PersistenceModule instead, but that would force me to inject PersistenceManagerFactory into PersistenceModule and I like to avoid module injection where possible. &lt;br /&gt;&lt;br /&gt;Last but not least, WebModule:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class WebModule extends ServletModule {&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; protected void configureServlets() {&lt;br /&gt;  filter("/*").through(PersistenceFilter.class);  &lt;br /&gt;  serve("/test").with(TestServlet.class);  &lt;br /&gt; }   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;It is important that PersistenceFilter will precede any other filters or servlets that need persistence (see &lt;a href="http://code.google.com/p/google-guice/wiki/ServletModule#Dispatch_Order"&gt;Dispatch order&lt;/a&gt; in Guice documentation) otherwise you might end up with a closed persistence manager.&lt;br /&gt;&lt;br /&gt;Finally, our test servlet which uses persistence via DataService:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@Singleton&lt;br /&gt;public class TestServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt; private final DataService dataService;&lt;br /&gt; private final Provider&amp;lt;User&amp;gt; currentUser;&lt;br /&gt;&lt;br /&gt; @Inject&lt;br /&gt; public TestServlet(DataService dataService, Provider&amp;lt;User&amp;gt; currentUser) {&lt;br /&gt;  this.dataService = dataService;&lt;br /&gt;  this.currentUser = currentUser;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {&lt;br /&gt;&lt;br /&gt;  resp.setContentType("text/plain");&lt;br /&gt;&lt;br /&gt;  User current = currentUser.get();&lt;br /&gt;&lt;br /&gt;  if (current == null) {&lt;br /&gt;   resp.getWriter().println("You are not signed in to your google account, but Hello, world! anyways :-)");&lt;br /&gt;  } else {&lt;br /&gt;   resp.getWriter().println(String.format("Hello, %s", current.getNickname()));&lt;br /&gt;   //records user and ip in datastore&lt;br /&gt;   dataService.persist(new MyEntity(current, req.getRemoteAddr()));&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The DataService implementation looks like this:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public final class DataServiceImpl implements DataService {&lt;br /&gt; &lt;br /&gt; private Provider&amp;lt;PersistenceManager&amp;gt; pmp;&lt;br /&gt; &lt;br /&gt; @Inject&lt;br /&gt; public DataServiceImpl(Provider&amp;lt;PersistenceManager&amp;gt; pmp) { &lt;br /&gt;  this.pmp = pmp; &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public &amp;lt;T&amp;gt; T persist(T instance) {&lt;br /&gt;  return pmp.get().makePersistent(instance);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void delete(Object instance) {&lt;br /&gt;  pmp.get().deletePersistent(instance);&lt;br /&gt; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;To summarize:&lt;/b&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;PersistenceManager is bound to a Request Scope, each request has its own PersistenceManager instance.&lt;/li&gt;&lt;li&gt;The PersistenceFilter is configured at the beginning of the request dispatch chain, its main role is to close the PersistenceManager at the end of each request.&lt;/li&gt;&lt;li&gt;Data Aware classes like DataServiceImpl use PersistenceManager by means of a Guice Provider (direct injection of PersistenceManager will impose a scope restriction on when we can instantiate classes that use it, so I think its best to avoid it)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;As explained at the beginning of the post, this implementation is good for prototyping and small projects, for large / complex projects I'd go with a more solid, tested and much more capable framework (like warp-persist and guice-persist when it comes out)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The source is available in the form of an eclipse project here:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="https://codeark.com/svn/persistence.filter.example/trunk/"&gt;https://codeark.com/svn/persistence.filter.example/trunk/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You will need Google AppEngine Eclipse plugin to make it work.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-433069077084869031?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/433069077084869031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=433069077084869031' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/433069077084869031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/433069077084869031'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/06/lightweight-jdo-persistence-filter.html' title='Lightweight JDO Persistence Filter using Guice'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-5137697405482251042</id><published>2010-06-01T20:46:00.005+03:00</published><updated>2010-06-08T03:12:48.886+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Writing unit tests for Guice and Wicket</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;There are excellent frameworks out there for bringing the Guice power into your JUnit tests, like&amp;nbsp;&lt;a href="http://code.google.com/p/atunit/"&gt;AtUnit&lt;/a&gt;&amp;nbsp;or&amp;nbsp;&lt;a href="http://code.google.com/p/guiceberry/"&gt;GuiceBerry&lt;/a&gt;, however,&amp;nbsp;for the sake of simplicity,&amp;nbsp;this post builds upon a simple Test Runner class described in another post written in 2008 by Gili Tzabari &lt;a href="http://cowwoc.blogspot.com/2008/10/integrating-google-guice-into-junit4.html"&gt;about Guice and JUnit4 integration&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;Here is a very simple MyGuiceTestRunner implementation:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class MyGuiceTestRunner extends GuiceTestRunner {&lt;br /&gt; public MyGuiceTestRunner(Class&amp;lt;?&amp;gt; classToRun) throws InitializationError {&lt;br /&gt;  super(classToRun, new WebModule(), new MyModule(), new HibernateModule());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;And here is an abstract wicket test to ease our work later:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@RunWith(MyGuiceTestRunner.class)&lt;br /&gt;public class AbstractWicketTest {&lt;br /&gt; &lt;br /&gt; private final WicketTester wicketTester;&lt;br /&gt; &lt;br /&gt; protected final WicketTester getWicketTester() {&lt;br /&gt;  return wicketTester;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public AbstractWicketTest(Injector injector) {&lt;br /&gt;  wicketTester = new WicketTester();&lt;br /&gt;  WebApplication app = wicketTester.getApplication();&lt;br /&gt;  app.addComponentInstantiationListener(new GuiceComponentInjector(app, injector));&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;Some points of intrest in this implementation:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Class is annotated with @RunWith, this tells JUnit to use MyGuiceTestRunner to run this test (and subclasses too).&lt;/li&gt;&lt;li&gt;In the constructor we create a &lt;a href="http://wicket.apache.org/docs/1.4/org/apache/wicket/util/tester/WicketTester.html"&gt;WicketTester&lt;/a&gt;&amp;nbsp;which in turn will create a dummy wicket web application for us (BaseWicketTester.DummyWebApplication is the exact type). If we need a custom application we could simply use other WicketTester constructors that take an Application instance and use it instead of the inner dummy one.&lt;/li&gt;&lt;li&gt;Once a WicketTester instance was created, we add attach a &lt;a href="http://wicket.apache.org/docs/1.4/org/apache/wicket/guice/GuiceComponentInjector.html"&gt;GuiceComponentInjector&lt;/a&gt;&amp;nbsp;just like&amp;nbsp;we would in a normal guicey wicket web application.&lt;/li&gt;&lt;/ul&gt;In a typical test subclass of AbstractWicketTest we get a reference to the injector using constructor injection (remember this test is injectable because it is being run by MyGuiceTestRunner):&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class SampleWicketTest extends AbstractWicketTest {&lt;br /&gt; &lt;br /&gt; @Inject&lt;br /&gt; public SampleWicketTest(Injector injector) {&lt;br /&gt;  super(injector);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Test&lt;br /&gt; public void test() {&lt;br /&gt;  WicketTester wicketTester = getWicketTester();&lt;br /&gt;  wicketTester.startPage(TestPage.class);&lt;br /&gt;  wicketTester.assertRenderedPage(TestPage.class);&lt;br /&gt;  wicketTester.assertLabel("meow", "Testing 1 2 3");&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;For the sake of completeness, here is the code for the test page itself (html markup omitted):&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class TestPage extends WebPage { &lt;br /&gt; &lt;br /&gt; @Inject private IService service;&lt;br /&gt; &lt;br /&gt; public TestPage() {&lt;br /&gt;  add(new Label("meow", "Testing 1 2 3"));&lt;br /&gt;  service.doSomething();&lt;br /&gt; } &lt;br /&gt;}&lt;/pre&gt;Thats it, you are now free to write Guice powered tests for your Guicey Wicket pages.&lt;br /&gt;&lt;br /&gt;Enjoy :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-5137697405482251042?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/5137697405482251042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=5137697405482251042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5137697405482251042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5137697405482251042'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/06/writing-unit-tests-for-guicey-wicket.html' title='Writing unit tests for Guice and Wicket'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-221165135510345198</id><published>2010-05-26T04:49:00.020+03:00</published><updated>2010-06-08T17:28:25.911+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='guice'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Wicket and Guice integration: an alternate route...</title><content type='html'>This post details a slightly different way of integrating Apache Wicket and Google Guice.&lt;br /&gt;&lt;br /&gt;Many posts, reference docs and demos I've seen on the Internet so far, do not employ one of my most favorite features in Guice: &lt;a href="http://code.google.com/p/google-guice/wiki/ServletModule"&gt;the ServletModule&lt;/a&gt;&amp;nbsp;to configure Wicket's filter. I really like this feature because&amp;nbsp;I really don't like configuration files and the Web Descriptor (a.k.a web.xml) file is one of the most disliked of them all :) but Thanks to Guice this file's annoyance goes almost unnoticed.&lt;br /&gt;&lt;br /&gt;So just to make it clear, the purpose of this integration is to bypass wicket's filter configuration in web.xml and put it in code instead.&lt;br /&gt;&lt;br /&gt;Before we start here are several links to posts and reference docs about Wicket and Guice integration that are more common (but do use web.xml to config wicket):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wicket.apache.org/docs/1.4/org/apache/wicket/guice/GuiceWebApplicationFactory.html"&gt;Wicket Guice GuiceWebApplicationFactory javadoc&lt;/a&gt;&lt;br /&gt;&lt;a href="http://herebebeasties.com/2007-06-20/wicket-gets-guicy/trackback/"&gt;Alastair Maw’s blog - Wicket gets guicy&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.wicket-library.com/wicket-examples/guice/"&gt;Wicket examples - Guice&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.atomicgamer.com/dev/2009/10/wicket-guice-2-0-warp-persist-2-0/"&gt;Atomic Gamer dev blog - Wicket, Guice and Warp-Persist&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We start with the web.xml file:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; xsi:schemaLocation="http://java.sun.com/xml/ns/javaee&lt;br /&gt;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&lt;br /&gt; version="2.5"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;filter&amp;gt;&lt;br /&gt;  &amp;lt;filter-name&amp;gt;guiceFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;  &amp;lt;filter-class&amp;gt;com.google.inject.servlet.GuiceFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt; &amp;lt;/filter&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;  &amp;lt;filter-name&amp;gt;guiceFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;  &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt; &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;listener&amp;gt;&lt;br /&gt;  &amp;lt;listener-class&amp;gt;com.codeark.wicketguicealt.Bootstrap&amp;lt;/listener-class&amp;gt;&lt;br /&gt; &amp;lt;/listener&amp;gt; &lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;br /&gt;&lt;/pre&gt;This web.xml only configures Guice filter and a GuiceServletContextListener as per the instructions&amp;nbsp;&lt;a href="http://code.google.com/p/google-guice/wiki/ServletModule"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Bootstrap class loads our modules:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public final class Bootstrap extends GuiceServletContextListener { &lt;br /&gt; @Override&lt;br /&gt; protected Injector getInjector() {  &lt;br /&gt;  return Guice.createInjector(new MyModule(), new WebModule());&lt;br /&gt; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The binding and configuration of Wicket happens in WebModule (a subclass of ServletModule):&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class WebModule extends ServletModule {&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; protected void configureServlets() {&lt;br /&gt;  bind(WebApplication.class).toProvider(WicketGuiceAppProvider.class);&lt;br /&gt;  &lt;br /&gt;  // avoids "Error initializing WicketFilter - you have no &amp;lt;filter-mapping&amp;gt; element..." &lt;br /&gt;  // IllegalArgumentException&lt;br /&gt;  Map&amp;lt;String, String&amp;gt; params = new HashMap&amp;lt;String, String&amp;gt;();  &lt;br /&gt;  params.put(WicketFilter.FILTER_MAPPING_PARAM, "/*");&lt;br /&gt;  &lt;br /&gt;  filter("/*").through(WicketGuiceFilter.class, params);&lt;br /&gt; }&lt;br /&gt;}&amp;nbsp;&lt;/pre&gt;&lt;div&gt;In the first line of configureServlets() we bind WebApplication to a provider, this provider will be our real application factory and will do all the work instead of &lt;a href="http://wicket.apache.org/docs/1.4/org/apache/wicket/guice/GuiceWebApplicationFactory.html"&gt;GuiceWebApplicationFactory&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The GuiceWebApplicationFactory implementation requires that the injector will be stashed in the Servlet Context or that modules will be listed in the web.xml in an init-param like this:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;init-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;module&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;com.company.MyModule,com.company.MyOtherModule&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;lt;/init-param&amp;gt;&lt;br /&gt;&lt;/pre&gt;I think both options contradicts the real notion of Guice: "&lt;i&gt;Rather than using an external XML file for configuration, Guice modules are written using regular Java code. Java is familiar, works with your IDE, and survives refactoring&lt;/i&gt;" and therefor I opted not to use GuiceWebApplicationFactory. Here is the provider we will use:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class WicketGuiceAppProvider implements Provider&amp;lt;WebApplication&amp;gt; {&lt;br /&gt; &lt;br /&gt; private final Injector injector;&lt;br /&gt;&lt;br /&gt; @Inject&lt;br /&gt; public WicketGuiceAppProvider(Injector injector) {&lt;br /&gt;  this.injector = injector;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public WebApplication get() {&lt;br /&gt;  WicketGuiceApp app = new WicketGuiceApp(injector);  &lt;br /&gt;  return app;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;It would be awesome if we could call&amp;nbsp;&lt;b&gt;addComponentInstantiationListener(new GuiceComponentInjector(app, injector)) &lt;/b&gt;here instead of passing the injector in the constructor (on injecting it) but &lt;a href="http://wicket.apache.org/docs/1.4/org/apache/wicket/guice/GuiceComponentInjector.html"&gt;GuiceComponentInjector&lt;/a&gt; uses &lt;a href="http://wicket.apache.org/docs/1.4.8/org/apache/wicket/injection/web/InjectorHolder.html"&gt;InjectorHolder&lt;/a&gt;&amp;nbsp;in its constructor:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public GuiceComponentInjector(Application app, Injector injector)&lt;br /&gt;{&lt;br /&gt; app.setMetaData(GuiceInjectorHolder.INJECTOR_KEY, new GuiceInjectorHolder(injector));&lt;br /&gt; InjectorHolder.setInjector(this);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;and InjectorHolder has a dependency on the application instance being tied to the current thread (&lt;b&gt;Application.get()&lt;/b&gt; uses ThreadLocal):&lt;br /&gt;&lt;pre class="java" name="code"&gt;public static void setInjector(ConfigurableInjector newInjector)&lt;br /&gt;{&lt;br /&gt; Application application = Application.get();&lt;br /&gt; application.setMetaData(INJECTOR_KEY, newInjector);&lt;br /&gt;}&lt;/pre&gt;Consequently, we can only call&amp;nbsp;&lt;b&gt;addComponentInstantiationListener() &lt;/b&gt;after &lt;b&gt;Application.set()&lt;/b&gt; is called and the best place to do so is&amp;nbsp;in the &lt;b&gt;init()&lt;/b&gt; method of our WebApplication implementation. we could use &lt;b&gt;Application.set()&lt;/b&gt; ourselves (tried that and it works fine) but the scary warnings in the javadoc are scary :-), so here is our WicketGuiceApp class with its &lt;b&gt;init()&lt;/b&gt; method:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class WicketGuiceApp extends WebApplication {&lt;br /&gt; &lt;br /&gt; private transient Injector injector;&lt;br /&gt; &lt;br /&gt; public WicketGuiceApp(Injector injector) {&lt;br /&gt;  this.injector = injector;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; protected void init() {  &lt;br /&gt;  addComponentInstantiationListener(new GuiceComponentInjector(this, injector));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Class&amp;lt;? extends Page&amp;gt; getHomePage() {&lt;br /&gt;  return HomePage.class;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Please note that I've marked the Injector as transient. Under the hood, GuiceComponentInjector will handle the Injector's reference serialization and deserialization.&lt;br /&gt;&lt;br /&gt;Back to WebModule, the second important thing we do in configureServlets() is to configure the Wicket filter and filter mapping. We are using our own WicketFilter subclass called&amp;nbsp;WicketGuiceFilter in order to utilize our provider and wire it into wicket's IWebApplicationFactory:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@Singleton&lt;br /&gt;public class WicketGuiceFilter extends WicketFilter {&lt;br /&gt;&lt;br /&gt; @Inject private Provider&amp;lt;WebApplication&amp;gt; appsProvider;&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; protected IWebApplicationFactory getApplicationFactory() {&lt;br /&gt;  return new IWebApplicationFactory() {   &lt;br /&gt;   @Override&lt;br /&gt;   public WebApplication createApplication(WicketFilter filter) {    &lt;br /&gt;    return appsProvider.get();&lt;br /&gt;   }&lt;br /&gt;  };&lt;br /&gt; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The reason I chose to subclass WicketFilter instead of doing this inside configureServlets():&lt;br /&gt;&lt;pre class="java" name="code"&gt;Map&amp;lt;String, String&amp;gt; params = new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt; &lt;br /&gt; params.put(WicketFilter.APP_FACT_PARAM, WicketGuiceAppFactory.class.getName());&lt;br /&gt; filter("/*").through(WicketFilter.class, params);&lt;br /&gt;&lt;/pre&gt;Is that WicketFilter instantiates the factory via reflection and the prevents Guice from doing its work.&lt;br /&gt;&lt;br /&gt;This concludes our integration, would love to hear any comments.&lt;br /&gt;&lt;br /&gt;You can download just the full source&amp;nbsp;of this post&amp;nbsp;and web.xml &lt;a href="http://www.codeark.com/WicketGuiceAltSource.zip"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;OR&lt;br /&gt;&lt;br /&gt;You can download a full&amp;nbsp;&lt;a href="http://www.codeark.com/WicketGuiceAlt.zip"&gt;eclipse dynamic web project&lt;/a&gt;&amp;nbsp;with dependencies included, you will need to import it to your workspace and reconfigure a servlet container runtime (such as apache tomcat) before you can build.&lt;br /&gt;&lt;br /&gt;OR&lt;br /&gt;&lt;br /&gt;Get the above eclipse project via svn&amp;nbsp;or simply browse the code for your&amp;nbsp;convenience here:&lt;br /&gt;&lt;a href="https://www.codeark.com/svn/wicket.guice.alt/trunk"&gt;https://www.codeark.com/svn/wicket.guice.alt/trunk&lt;/a&gt;&lt;br /&gt;This repository is read only for anonymous access.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-221165135510345198?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/221165135510345198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=221165135510345198' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/221165135510345198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/221165135510345198'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/05/wicket-and-guice-alternate-route.html' title='Wicket and Guice integration: an alternate route...'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-8507253449005433587</id><published>2010-05-13T21:37:00.006+03:00</published><updated>2010-05-24T17:48:21.510+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='mobiledev'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>HOWTO: Open a webpage programmatically in an android java application</title><content type='html'>Using an intent like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;Intent intent = new Intent("android.intent.action.VIEW", Uri.parse("http://www.codeark.com"));&lt;br /&gt;&lt;br /&gt;try {&lt;br /&gt; this.startActivity(intent);&lt;br /&gt;} catch (ActivityNotFoundException ex) {&lt;br /&gt; // do something about the exception, or not ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"this" is the Context.&lt;br /&gt;&lt;br /&gt;more info here: &lt;a href="http://developer.android.com/reference/android/content/Context.html#startActivity(android.content.Intent)"&gt;Context.startActivity()&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-8507253449005433587?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/8507253449005433587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=8507253449005433587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8507253449005433587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8507253449005433587'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/05/howto-open-browser-programmatically-in.html' title='HOWTO: Open a webpage programmatically in an android java application'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-2916267967910447679</id><published>2010-05-05T04:29:00.001+03:00</published><updated>2010-05-31T02:29:11.872+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google auto complete does computation?</title><content type='html'>only noticed it now:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XnhytjnfyaU/S-DJrvA8ipI/AAAAAAAAAv8/ilK-vx-tw3g/s1600/google_autocomplete_goes_realtime_computation1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XnhytjnfyaU/S-DJrvA8ipI/AAAAAAAAAv8/ilK-vx-tw3g/s320/google_autocomplete_goes_realtime_computation1.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/S-DJyS14hNI/AAAAAAAAAwE/VtchjZDO3Ho/s1600/google_autocomplete_goes_realtime_computation.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XnhytjnfyaU/S-DJyS14hNI/AAAAAAAAAwE/VtchjZDO3Ho/s320/google_autocomplete_goes_realtime_computation.PNG" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_XnhytjnfyaU/S-DJyS14hNI/AAAAAAAAAwE/VtchjZDO3Ho/s1600/google_autocomplete_goes_realtime_computation.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;nice!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-2916267967910447679?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/2916267967910447679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=2916267967910447679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/2916267967910447679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/2916267967910447679'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/05/google-auto-complete-does-computation.html' title='Google auto complete does computation?'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XnhytjnfyaU/S-DJrvA8ipI/AAAAAAAAAv8/ilK-vx-tw3g/s72-c/google_autocomplete_goes_realtime_computation1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-4904718434545407438</id><published>2010-04-02T02:36:00.001+03:00</published><updated>2010-04-02T02:37:33.404+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='gwt'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><title type='text'>Wicket vs. GWT</title><content type='html'>A very interesting and in depth comparison between the two:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://ptrthomas.wordpress.com/2008/09/04/wicket-and-gwt-compared-with-code/"&gt;http://ptrthomas.wordpress.com/2008/09/04/wicket-and-gwt-compared-with-code/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-4904718434545407438?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/4904718434545407438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=4904718434545407438' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4904718434545407438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4904718434545407438'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/04/wicket-vs-gwt.html' title='Wicket vs. GWT'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-3027433063304223189</id><published>2010-02-04T21:40:00.001+02:00</published><updated>2010-02-04T21:42:00.199+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP on Windows - WHY?</title><content type='html'>Check out this short overview by Shai Raiten:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/shair/archive/2010/01/30/php-on-windows-summary.aspx"&gt;http://blogs.microsoft.co.il/blogs/shair/archive/2010/01/30/php-on-windows-summary.aspx&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-3027433063304223189?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/3027433063304223189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=3027433063304223189' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/3027433063304223189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/3027433063304223189'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/02/php-on-windows-why.html' title='PHP on Windows - WHY?'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7149839553175958238</id><published>2010-01-30T11:47:00.003+02:00</published><updated>2010-01-30T11:59:43.671+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='disk crash'/><category scheme='http://www.blogger.com/atom/ns#' term='data recovery'/><category scheme='http://www.blogger.com/atom/ns#' term='usb drive'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>DiskDigger</title><content type='html'>It was a wonderful Saturday morning. I rose up and started my morning really slowly, was staying at a friend's house. At some point I took my laptop, plugged in my USB stick and prepared to do some useful things with my item.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;USB is not responding, oh well that happens every now and then, lets replug, still not working... A small alarm indicator went in my head. Lets try the other port, computer recognize the stick, the free/used space match, but... OH MY GOD, NO FILES!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Sigh* just two months ago I lost a 250g disk to a hardware malfunction... I've decided to run chkdsk, and indeed, errors were found, but there was insufficient disk space on the stick for chkdsk do finish his thing (and a good thing that!). &lt;b&gt;It was a mistake to use chkdsk, I should have used a recovery software right away.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The file system on the stick went caput :-(&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;From google, I got to checking &lt;a href="http://www.thefreecountry.com/"&gt;The Free Country&lt;/a&gt;, an excellent source of free software. After trying several utilities from the &lt;a href="http://www.thefreecountry.com/utilities/datarecovery.shtml"&gt;Data Recovery&lt;/a&gt; section, I found this excellent utility: &lt;a href="http://dmitrybrant.com/diskdigger"&gt;DiskDigger&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Unfortunately at this point all I was left to work with was scattered blocks of that on the hard drive, so simple undelete procedures didn't work. DiskDigger however, managed to recover most of my important files, the docs and pictures especially.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now I'm left with the annoying task of sorting through the unnamed files... This really ruined my Saturday.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Blah...&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7149839553175958238?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7149839553175958238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7149839553175958238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7149839553175958238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7149839553175958238'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/01/diskdigger.html' title='DiskDigger'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-9106296018538065586</id><published>2010-01-20T04:49:00.013+02:00</published><updated>2010-06-23T02:32:15.306+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='pitfalls'/><title type='text'>Parent/Child Hibernate pitfall</title><content type='html'>&lt;div&gt;Lets say we have these two interfaces:&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;import java.util.Set;&lt;br /&gt;&lt;br /&gt;public interface Parent {&lt;br /&gt;Set&amp;lt;Child&amp;gt; getChildren();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;public interface Child {&lt;br /&gt;Parent getParent();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;And here are their implementations, annotated for persistence:&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;import java.util.HashSet;&lt;br /&gt;import java.util.Set;&lt;br /&gt;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.GenerationType;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.OneToMany;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="parents")&lt;br /&gt;public class ParentImpl implements Parent {&lt;br /&gt;&lt;br /&gt;private Set&amp;lt;Child&amp;gt; children;&lt;br /&gt;private Long id;&lt;br /&gt;&lt;br /&gt;public ParentImpl() {&lt;br /&gt;this.children = new HashSet&amp;lt;Child&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;@OneToMany(targetEntity=ChildImpl.class, mappedBy="parent", cascade=CascadeType.ALL)&lt;br /&gt;public Set&amp;lt;Child&amp;gt; getChildren() {&lt;br /&gt;return children;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setChildren(Set&amp;lt;Child&amp;gt; children) {&lt;br /&gt;this.children = children;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Id&lt;br /&gt;@GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt;public Long getId() {&lt;br /&gt;return id;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setId(Long id) {&lt;br /&gt;this.id = id;&lt;br /&gt;}&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;And the child implementation:&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.GenerationType;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.ManyToOne;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="children")&lt;br /&gt;public class ChildImpl implements Child {&lt;br /&gt;&lt;br /&gt;private Parent parent;&lt;br /&gt;private Long id;&lt;br /&gt;&lt;br /&gt;public ChildImpl() {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;@ManyToOne(targetEntity=ParentImpl.class)&lt;br /&gt;public Parent getParent() {&lt;br /&gt;return parent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setParent(Parent parent) {&lt;br /&gt;this.parent = parent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Id&lt;br /&gt;@GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt;public Long getId() {&lt;br /&gt;return id;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setId(Long id) {&lt;br /&gt;this.id = id;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;So, where is the pitfall? Well, there are probably a few lying about, but the one I ran into will become apparent shortly. First, consider this code snippet:&lt;pre name="code" class="java"&gt;Parent p = new ParentImpl();&lt;br /&gt;Child c = new ChildImpl();&lt;br /&gt;&lt;br /&gt;p.getChildren().add(c);&lt;br /&gt;((ChildImpl)c).setParent(p);&lt;br /&gt;&lt;br /&gt;// persist to database&lt;br /&gt;DAOFactory.getParentDAO().persist(p);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Now, another programmer joined the show, and decided to have his own Child implementation:&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;public class AnotherChildImpl implements Child {&lt;br /&gt;&lt;br /&gt;private Parent parent;&lt;br /&gt;&lt;br /&gt;public AnotherChildImpl() {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void someOtherNewMethods() {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public Parent getParent() {&lt;br /&gt;return parent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setParent(Parent p) {&lt;br /&gt;this.parent = p;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;A perfectly legal implementation, lets have a look at another code snippet:&lt;pre name="code" class="java"&gt;Parent p = new ParentImpl();&lt;br /&gt;Child c = new ChildImpl();&lt;br /&gt;Child c1 = new AnotherChildImpl();&lt;br /&gt;&lt;br /&gt;p.getChildren().add(c);&lt;br /&gt;p.getChildren().add(c1);&lt;br /&gt;((ChildImpl)c).setParent(p);&lt;br /&gt;((AnotherChildImpl)c1).setParent(p);&lt;br /&gt;&lt;br /&gt;// persist to database&lt;br /&gt;DAOFactory.getParentDAO().persist(p);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;What do you think will happen now? This code will compile, but during runtime Hibernate will hit us with an &lt;b&gt;IllegalArgumentException in class: com.codeark.parentchild.ChildImpl, getter method of property: id&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.codeark.parentchild.ChildImpl.id...&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is a result of me telling hibernate to expect a ChildImpl (targetEntity) while in practice that collection contained AnotherChildImpl class, which hibernate knows nothing about.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Why is this so bad? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This exception will not occur until the program tries to persist a ParentImpl with an AnotherChildImpl bomb waiting to explode in its children collection. That event can happen far into the (runtime) future. Although I doubt such a bug will make it to production if you have decent integration and QA, its still within the realm of possibilities; it would be best if we do what ever we can to prevent that eventuality.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is what I did to prevent this...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First I changed the parent Interface:&lt;/div&gt;&lt;div&gt;&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;import java.util.Set;&lt;br /&gt;&lt;br /&gt;public interface Parent {&lt;br /&gt;Set&amp;lt;? extends Child&amp;gt; getChildren();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Note that our children collection is now of an unknown type bounded by Child, instead of just Child.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I changed ParentImpl:&lt;/div&gt;&lt;div&gt;&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;import java.util.HashSet;&lt;br /&gt;import java.util.Set;&lt;br /&gt;&lt;br /&gt;import javax.persistence.CascadeType;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.GenerationType;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.OneToMany;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="parents")&lt;br /&gt;public final class ParentImpl implements Parent {&lt;br /&gt;&lt;br /&gt;private Set&amp;lt;ChildImpl&amp;gt; children;&lt;br /&gt;private Long id;&lt;br /&gt;&lt;br /&gt;public ParentImpl() {&lt;br /&gt;this.children = new HashSet&amp;lt;ChildImpl&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;@OneToMany(mappedBy="parent", cascade=CascadeType.ALL)&lt;br /&gt;public Set&amp;lt;ChildImpl&amp;gt; getChildren() {&lt;br /&gt;return children;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setChildren(Set&amp;lt;ChildImpl&amp;gt; children) {&lt;br /&gt;this.children = children;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Id&lt;br /&gt;@GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt;public Long getId() {&lt;br /&gt;return id;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setId(Long id) {&lt;br /&gt;this.id = id;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;Our HashSet collection is now of &lt;b&gt;ChildImpl&lt;/b&gt; type instead of just &lt;b&gt;Child&lt;/b&gt;, I've changed that throughout the class's internals and external API. Our class still complies with &lt;b&gt;Parent&lt;/b&gt;'s contract, since we've changed Parent.getChildren() from Set&amp;lt;Child&amp;gt; to Set&amp;lt;? extends Child&amp;gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;As an added bonus, we no longer need the targetEntity=ChildImpl.class annotation for ParentImpl.getChildren().&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Last small caveat, I've marked the class as "final" since subclassing it without proper annotations/mapping might expose us to similar problems.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another important change; in ChildImpl class:&lt;/div&gt;&lt;div&gt;&lt;pre name="code" class="java"&gt;package com.codeark.parentchild;&lt;br /&gt;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.GenerationType;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.ManyToOne;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="children")&lt;br /&gt;public final class ChildImpl implements Child {&lt;br /&gt;&lt;br /&gt;private ParentImpl parent;&lt;br /&gt;private Long id;&lt;br /&gt;&lt;br /&gt;public ChildImpl() {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;@ManyToOne&lt;br /&gt;public ParentImpl getParent() {&lt;br /&gt;return parent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setParent(ParentImpl parent) {&lt;br /&gt;this.parent = parent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Id&lt;br /&gt;@GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt;public Long getId() {&lt;br /&gt;return id;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setId(Long id) {&lt;br /&gt;this.id = id;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;All the &lt;b&gt;Parent&lt;/b&gt; references were changed to &lt;b&gt;ParentImpl&lt;/b&gt;, so I wouldn't face a similar problem if someone tries to add a non persistent parent to ChildImpl.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lets look at our buggy code again:&lt;/div&gt;&lt;div&gt;&lt;pre name="code" class="java"&gt;ParentImpl p = new ParentImpl();&lt;br /&gt;ChildImpl c = new ChildImpl();&lt;br /&gt;Child c1 = new AnotherChildImpl();&lt;br /&gt;&lt;br /&gt;p.getChildren().add(c);&lt;br /&gt;p.getChildren().add(c1);  // A Compile time error here!&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;Now the "other" programmer will get a compile time error, while trying to add his new (and improved) class to your parent Implementation, and the world is a slightly better place now.&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/4699667848216680716-9106296018538065586?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/9106296018538065586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=9106296018538065586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/9106296018538065586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/9106296018538065586'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2010/01/parentchild-hibernate-pitfall.html' title='Parent/Child Hibernate pitfall'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-5241966818323366935</id><published>2009-12-27T01:46:00.002+02:00</published><updated>2009-12-28T13:04:44.210+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Yet another magnificent blog</title><content type='html'>&lt;a href="http://acko.net/blog/"&gt;http://acko.net/blog/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Really cool design&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-5241966818323366935?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/5241966818323366935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=5241966818323366935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5241966818323366935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5241966818323366935'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/12/yet-another-magnificent-blog.html' title='Yet another magnificent blog'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-266569201926060587</id><published>2009-11-09T17:00:00.016+02:00</published><updated>2009-11-15T17:29:47.564+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='slf4j'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Tomcat and Wicket's unruly logging</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="color:#666666;"&gt;Note: if you want the solution just skip to the end...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Like many before me, I too ran into the problem where wicket was spamming log message into "catalina.out".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At first, naively, I tried to change my &lt;b&gt;log4.properties&lt;/b&gt; file, but alas, wicket seemed intent on ignoring these changes. Following that failure, I tried changing Tomcat's &lt;b&gt;logging.properties &lt;/b&gt;but that didn't seem to effect wicket's either.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Frustrated and naturally lazy I turned over to Google, the almighty human knowledge repository. If you know what to feed in that little search box, Google can save you loads of time and also the effort of actually understanding what is it you are doing (so basically good googling skills are essential to the &lt;a href="http://www.answers.com/topic/indolent"&gt;indolent&lt;/a&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this case however, this wonderful "googelazy" phenomenon was in fact hindering my efforts. Once I realized my salvation will not be so easy, I went on to read the documents of the logging lib used by Wicket: slf4j.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After perusing the documentation for a while I ran into this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.slf4j.org/manual.html#libraries"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 310px;" src="http://3.bp.blogspot.com/_XnhytjnfyaU/SwAbdYufLRI/AAAAAAAAAlc/OTbK2Kf8Q8E/s320/bindings.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5404349744512183570" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I've decided to check my classpath and see which implementation I'm using. It turns out I was using &lt;b&gt;slf4j-simple.jar &lt;/b&gt;which outputs everything to System.err:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:Verdana, Arial, SunSans-Regular, sans-serif;font-size:small;"&gt;&lt;dt&gt;&lt;i&gt;slf4j-simple-1.5.9.RC1.jar&lt;/i&gt;&lt;/dt&gt;&lt;dd&gt;&lt;i&gt;Binding for &lt;/i&gt;&lt;a href="http://www.slf4j.org/apidocs/org/slf4j/impl/SimpleLogger.html" style="color: rgb(0, 0, 204); background-color: transparent; text-decoration: none; "&gt;&lt;i&gt;Simple &lt;/i&gt;&lt;/a&gt;&lt;i&gt;implementation, which outputs all events to System.err. Only messages of level INFO and higher are printed. This binding may be useful in the context of small applications.&lt;/i&gt;&lt;/dd&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;The solution&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt; was simple after that, replace the &lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;slf4j-simple.jar&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt; with something else, in my case it was the &lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;slf4j-log4j12.jar&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;Sub conclusion:&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;if the answer was googlable it would have poped up straight away, next time I should &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/RTFM"&gt;&lt;span class="Apple-style-span"  style="font-size:normal;"&gt;rtfm&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-266569201926060587?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/266569201926060587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=266569201926060587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/266569201926060587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/266569201926060587'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/11/tomcat-and-wickets-unruly-logging.html' title='Tomcat and Wicket&apos;s unruly logging'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_XnhytjnfyaU/SwAbdYufLRI/AAAAAAAAAlc/OTbK2Kf8Q8E/s72-c/bindings.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-8671271250130516775</id><published>2009-10-22T00:36:00.002+02:00</published><updated>2009-10-22T00:37:43.915+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Thank you, diskinternals.com zip repair!</title><content type='html'>&lt;div&gt;For saving my 1.6 gigs zip codebase file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://www.diskinternals.com/zip-repair/"&gt;http://www.diskinternals.com/zip-repair/&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;god bless you! :-)&lt;/div&gt;&lt;div&gt;&lt;br /&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/4699667848216680716-8671271250130516775?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/8671271250130516775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=8671271250130516775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8671271250130516775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8671271250130516775'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/10/thank-you-diskinternalscom-zip-repair.html' title='Thank you, diskinternals.com zip repair!'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-6033587039887165657</id><published>2009-05-07T22:31:00.003+03:00</published><updated>2009-05-07T22:41:33.525+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music'/><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Dub FX</title><content type='html'>This human beatbox artist is just amazing. His music is really unique and refreshing!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Make some noise :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=OEPEleJVjOo"&gt;http://www.youtube.com/watch?v=OEPEleJVjOo&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=WhBoR_tgXCI"&gt;http://www.youtube.com/watch?v=WhBoR_tgXCI&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); text-decoration: underline;"&gt;&lt;a href="http://www.youtube.com/watch?v=8F6EoMdn95E"&gt;http://www.youtube.com/watch?v=8F6EoMdn95E&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Checkout his website too: &lt;a href="http://www.dubfx.net/"&gt;http://www.dubfx.net/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-6033587039887165657?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/6033587039887165657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=6033587039887165657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6033587039887165657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6033587039887165657'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/05/dub-fx.html' title='Dub FX'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-8770951571344792593</id><published>2009-04-16T07:25:00.003+03:00</published><updated>2009-05-07T22:31:38.606+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>A life saver: Privacy policy generator</title><content type='html'>&lt;a href="http://www.dmaresponsibility.org/PPG/"&gt;http://www.dmaresponsibility.org/PPG/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-8770951571344792593?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/8770951571344792593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=8770951571344792593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8770951571344792593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8770951571344792593'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/04/life-save-privacy-policy-generator.html' title='A life saver: Privacy policy generator'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-4091578032272393019</id><published>2009-03-25T20:59:00.003+02:00</published><updated>2009-05-07T22:31:18.171+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codeark'/><title type='text'>My company's new website</title><content type='html'>&lt;a href="http://www.codeark.com/"&gt;http://www.codeark.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;comments will be happily accepted! :)&lt;br /&gt;&lt;br /&gt;(even negative ones, just be gentle...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-4091578032272393019?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/4091578032272393019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=4091578032272393019' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4091578032272393019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/4091578032272393019'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/03/my-companys-new-website.html' title='My company&apos;s new website'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-1595827505349255737</id><published>2009-03-14T02:34:00.007+02:00</published><updated>2009-03-14T03:22:12.926+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Wicket, Ajax, UTF-8 and Tomcat connectors</title><content type='html'>While working on one of my backoffice applications, I stumbled upon a problem where hebrew text would turn into encoded gibberish after inputing it into an ajax editable control (like &lt;a href="http://www.wicketframework.org/wicket-extensions/apidocs/wicket/extensions/ajax/markup/html/AjaxEditableLabel.html"&gt;AjaxEditableLabel&lt;/a&gt; or &lt;a href="http://www.wicketframework.org/wicket-extensions/apidocs/wicket/extensions/ajax/markup/html/AjaxEditableMultiLineLabel.html"&gt;AjaxEditableMultiLineLabel&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;After looking around in wicket's ajax debug console I found out that the problem was on the server side, quick googling action turned out the following possible problem/solution, the tomcat connector's declaration is missing a &lt;span style="font-weight:bold;"&gt;URIEncoding&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt; attribute:&lt;pre name="code" class="xml"&gt;&amp;lt;Connector port=&amp;quot;8080&amp;quot; maxHttpHeaderSize=&amp;quot;8192&amp;quot;&lt;br /&gt;     maxThreads=&amp;quot;150&amp;quot; minSpareThreads=&amp;quot;25&amp;quot; maxSpareThreads=&amp;quot;75&amp;quot;&lt;br /&gt;     enableLookups=&amp;quot;false&amp;quot; redirectPort=&amp;quot;8443&amp;quot; acceptCount=&amp;quot;100&amp;quot;&lt;br /&gt;     connectionTimeout=&amp;quot;20000&amp;quot; disableUploadTimeout=&amp;quot;true&amp;quot;     &lt;br /&gt;     URIEncoding=&amp;quot;UTF-8&amp;quot;/&amp;gt;&lt;/pre&gt;&lt;a href="http%3A//mail-archives.apache.org/mod_mbox/wicket-users/200808.mbox/%3C19216327.post@talk.nabble.com%3E"&gt;Original post here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I was very happy its a simple solution and was almost 100% this would solve the problem, However, it didn't do the trick! why?!&lt;br /&gt;&lt;br /&gt;Well, My tomcat sits behind an apache httpd server (proxy), because I like to complicate things sometimes (and because my server is a hybrid serving php, java, python perl and so on). Now, apache and tomcat communicate via AJP protocol, so the URIEncoding attribute should be present for that connector declaration as well:&lt;pre name="code" class="xml"&gt;&amp;lt;Connector&lt;br /&gt;     server=&amp;quot;Apache PowerCore&amp;quot;&lt;br /&gt;     port=&amp;quot;8009&amp;quot;&lt;br /&gt;     protocol=&amp;quot;AJP/1.3&amp;quot;&lt;br /&gt;     URIEncoding=&amp;quot;UTF-8&amp;quot; /&amp;gt;&lt;/pre&gt;For the sake of computer voodoo, I left the encoding attribute in the http connector as well. Computer voodoo is a powerful thing :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-1595827505349255737?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/1595827505349255737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=1595827505349255737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/1595827505349255737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/1595827505349255737'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/03/wicket-ajax-utf-8-and-tomcat-connectors.html' title='Wicket, Ajax, UTF-8 and Tomcat connectors'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-6531008887674420291</id><published>2009-01-06T03:05:00.010+02:00</published><updated>2009-01-06T04:29:40.858+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='swf'/><category scheme='http://www.blogger.com/atom/ns#' term='metacafe.com'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='flv'/><title type='text'>Extracting flv video files from Metacafe.com</title><content type='html'>&lt;a href="http://www.metacafe.com"&gt;Metacafe.com&lt;/a&gt;, another excellent content provider on the net. The people at Metacafe.com made a sincere effort, hiding their flv files, so this actually took 30 minutes or so.&lt;br /&gt;&lt;br /&gt;Now, for the method itself, we'll start with a classical video page at Metacafe (a real funny one too):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.metacafe.com/watch/1185371/hidden_camera_sex_tape_by_liv_films/"&gt;http://www.metacafe.com/watch/1185371/hidden_camera_sex_tape_by_liv_films/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Searching the page's source for the almighty string "flv" reveals the follow piece of literature inside:&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;$('FlashMsg').removeClass('Hidden');&lt;br /&gt;var so = playerSwfObjectInstace = new SWFObject(&amp;quot;http://s.mcstatic.com/Flash/vp/PortalVideoPlayer_6.1.0.3.swf&amp;quot;, &amp;quot;fpObj&amp;quot;, &amp;quot;100%&amp;quot;, &amp;quot;100%&amp;quot;, &amp;quot;8&amp;quot;);&lt;br /&gt;&lt;br /&gt;so.addParam(&amp;quot;flashvars&amp;quot;, '... lots of vars here, one we are interested in mediaUrl ...');&lt;br /&gt;&lt;br /&gt;so.addParam(&amp;quot;wmode&amp;quot;, &amp;quot;transparent&amp;quot;);&lt;br /&gt;so.addParam(&amp;quot;AllowScriptAccess&amp;quot;, &amp;quot;always&amp;quot;);&lt;br /&gt;so.addParam(&amp;quot;allowFullScreen&amp;quot;, &amp;quot;true&amp;quot;);&lt;br /&gt;so.addParam(&amp;quot;quality&amp;quot;, &amp;quot;high&amp;quot;);&lt;br /&gt;so.useExpressInstall(&amp;quot;http://s.mcstatic.com/Flash/expressinstall.swf&amp;quot;);&lt;br /&gt;var fsManager = new FlashFS('FlashObj','FlashWrap');&lt;br /&gt;&lt;br /&gt;... more stuff down here...&lt;br /&gt;&lt;/pre&gt;In the midst of that big chunk of javscript we will find this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;mediaURL=http%3A%2F%2Fv.mccont.com%2FItemFiles%2F%255BFrom%2520www.metacafe.com%255D%25201185371.6511758.11.flv&amp;gdaKey=1231211887_23b55c6077f00398853fe903f8cd9905&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;if you try to just decode it, and put it in your browser you will get an error... hmm... well to make a long story short, and without boring you with too much technical details, after you decode this url into this:&lt;br /&gt;&lt;br /&gt;http://v.mccont.com/ItemFiles/%5BFrom%20www.metacafe.com%5D%201185371.6511758.11.flv&lt;span style="font-weight:bold;"&gt;&amp;gdaKey&lt;/span&gt;=1231211887_23b55c6077f00398853fe903f8cd9905&lt;br /&gt;&lt;br /&gt;replace the bolded text with this: &lt;span style="font-weight:bold;"&gt;?__gda__&lt;/span&gt; and it works.&lt;br /&gt;&lt;br /&gt;Final url will look like this:&lt;br /&gt;&lt;br /&gt;http://v.mccont.com/ItemFiles/%5BFrom%20www.metacafe.com%5D%201185371.6511758.11.flv&lt;span style="font-weight:bold;"&gt;?__gda__&lt;/span&gt;=1231211887_23b55c6077f00398853fe903f8cd9905&lt;br /&gt;&lt;br /&gt;Thats it, if this looks a bit too much you may wanna try this &lt;a href="http://recfree2.OurToolbar.com/exe"&gt;toolbar&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-6531008887674420291?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/6531008887674420291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=6531008887674420291' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6531008887674420291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6531008887674420291'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/01/extracting-flv-video-files-from.html' title='Extracting flv video files from Metacafe.com'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-3580914229931376077</id><published>2009-01-01T21:31:00.010+02:00</published><updated>2009-01-08T12:20:13.725+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='swf'/><category scheme='http://www.blogger.com/atom/ns#' term='last.fm'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='flv'/><title type='text'>Extracting flv video files behind Last.fm</title><content type='html'>This would be the third post in what seems to be an emerging "series" of posts portraying various methods of getting the flv resource files behind various popular video/media online hosting thinggies.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.last.fm/"&gt;Last.fm&lt;/a&gt; is a wonderful music service (go check it out!) that hosts a lot of media and ... bla bla bla... go check the &lt;a href="http://www.last.fm/about"&gt;about section&lt;/a&gt; there if you want more details.&lt;br /&gt;&lt;br /&gt;Anyways, after checking out the source code for a typical video page on &lt;a href="http://www.last.fm/"&gt;Last.fm&lt;/a&gt; I didn't find any obvious leads as to where they get they store their flv files. Also, Due to the late hour in which I was undertaking this fabulous activity, I've gotten lazy and decided to just turn on one of god's better gifts to the cyberworld called &lt;a href="http://www.fiddlertool.com/fiddler/"&gt;fiddler&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I picked a random page:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.last.fm/music/The+Police/+videos/12005751"&gt;http://www.last.fm/music/The+Police/+videos/12005751&lt;/a&gt; - The Police, King of pain :)&lt;div&gt;&lt;br /&gt;Switching to fiddler's session trace, search for the word "flv" and &lt;a href="http://www.blogger.com/'http://content.answers.com/main/content/ahd4/pron/V0138100.wav"&gt;voilà&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://farm4.static.flickr.com/3220/3157397346_4b6a779f0e.jpg?v=0"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); "&gt;&lt;img src="http://2.bp.blogspot.com/_XnhytjnfyaU/SV0jfXIZFSI/AAAAAAAAAGk/DGsKCRZ0BFs/s400/Fiddler_last_fm_flv_search.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5286420559294960930" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 206px; " /&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;"One session contained flv"&lt;/span&gt; Says the sign, couldn't be easier. Quickly copying the complete url from fiddler (right click + "copy &amp;gt; just url" or just hit ctrl + u):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;http://userserve-ak.last.fm/serve/flv/12005751.flv?1221640857&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What is the number after the question mark, you ask? I have no idea, I just elegantly ignored it and pasted the following url in the browser:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;http://userserve-ak.last.fm/serve/flv/12005751.flv&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And was rewarded with the flv file download dialog.&lt;br /&gt;&lt;br /&gt;So how do we do this without fiddler? simple, now that we know what to look for, we can clearly see that the flv file name is the id that appears on the video's page:&lt;br /&gt;&lt;br /&gt;http://www.last.fm/music/The+Police/+videos/&lt;span style="font-weight:bold;"&gt;12005751&lt;/span&gt;&lt;br /&gt;http://userserve-ak.last.fm/serve/flv/&lt;span style="font-weight:bold;"&gt;12005751&lt;/span&gt;.flv&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That's it, job's done.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Again after you download the flv, if you want to convert it to another format you might want to consider using this &lt;a href="http://www.regnow.com/softsell/nph-softsell.cgi?item=14271-15&amp;amp;affiliate=281487"&gt;this splendid piece of sponsored software here&lt;/a&gt; &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Addition to this post: &lt;br /&gt;&lt;br /&gt;To download the videos that appear in urls of the form: &lt;br /&gt;&lt;br /&gt;http://www.last.fm/videos / http://www.last.fm/videos/+tag/something&lt;br /&gt;&lt;br /&gt;View the source of the url and look for this:&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;noscript&amp;gt;&lt;br /&gt;&amp;lt;object type=&amp;quot;application/x-shockwave-flash&amp;quot; data=&amp;quot;http://cdn.last.fm/videoplayer/l/11/VideoPlayer.swf&amp;quot; codebase=&amp;quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0&amp;quot;&lt;br /&gt;        id=&amp;quot;lfmEmbed_50_16202025_1334568063&amp;quot;&lt;br /&gt;        width=&amp;quot;450&amp;quot; height=&amp;quot;373&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;movie&amp;quot; value=&amp;quot;http://cdn.last.fm/videoplayer/l/11/VideoPlayer.swf&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;flashvars&amp;quot; value=&amp;quot;title=Human&amp;amp;amp;uniqueName=16202025&amp;amp;amp;albumArt=http%3A%2F%2Fcdn.last.fm%2Fdepth%2Fcatalogue%2Fnoimage%2Fnocover_flashplayer.png&amp;amp;amp;duration=259&amp;amp;amp;image=http%3A%2F%2Fuserserve-ak.last.fm%2Fserve%2Fimage%3A320%2F16202025.jpg&amp;amp;amp;FSSupport=true&amp;amp;amp;creator=The+Killers&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;allowScriptAccess&amp;quot; value=&amp;quot;always&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;allowNetworking&amp;quot; value=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;allowFullScreen&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;quality&amp;quot; value=&amp;quot;high&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;bgcolor&amp;quot; value=&amp;quot;000000&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;wmode&amp;quot; value=&amp;quot;opaque&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;menu&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/object&amp;gt;&amp;lt;/noscript&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight:bold;"&gt;uniqueName=16202025&lt;/span&gt; contains the Id we need to feed to: &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;http://userserve-ak.last.fm/serve/flv/12005751.flv&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-3580914229931376077?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/3580914229931376077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=3580914229931376077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/3580914229931376077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/3580914229931376077'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/01/extracting-flv-video-files-behind.html' title='Extracting flv video files behind Last.fm'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XnhytjnfyaU/SV0jfXIZFSI/AAAAAAAAAGk/DGsKCRZ0BFs/s72-c/Fiddler_last_fm_flv_search.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-8952201804269658161</id><published>2009-01-01T14:41:00.003+02:00</published><updated>2009-05-07T22:30:38.593+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='offtopic'/><title type='text'>Pour your own pint</title><content type='html'>Just had to share with you this small bit of information a friend has told me about, last night he along with 19 other people booked a table at a bar in Cork City, Ireland, where you get a table with your own personal beer tap(s)! How awesome is that ?!&lt;br /&gt;&lt;br /&gt;The special taps measure how much beer you pour, so you can pay accordingly later...&lt;br /&gt;&lt;br /&gt;Check it out: &lt;a href="http://www.soho.ie/"&gt;Soho bar website&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-8952201804269658161?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/8952201804269658161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=8952201804269658161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8952201804269658161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/8952201804269658161'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2009/01/pour-your-own-pint.html' title='Pour your own pint'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-5601035893060312348</id><published>2008-12-30T03:10:00.008+02:00</published><updated>2009-01-01T20:34:31.772+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='swf'/><category scheme='http://www.blogger.com/atom/ns#' term='MySpace.com'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='flv'/><title type='text'>Extracting the flv file behind a MySpace.com video</title><content type='html'>Took me a few minutes to find this on the web, so here it is again, mostly for me, but maybe for you too.&lt;br /&gt;&lt;br /&gt;Providing we have the following MySpace.com video page:&lt;br /&gt;&lt;a href="http://vids.myspace.com/index.cfm?fuseaction=vids.individual&amp;videoid=45134031"&gt;http://vids.myspace.com/index.cfm?fuseaction=vids.individual&amp;videoid=45134031&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We extract the Video Id, which is &lt;span style="font-weight:bold;"&gt;45134031&lt;/span&gt; and then we feed it to MySpace RSS service:&lt;br /&gt;&lt;a href="http://mediaservices.myspace.com/services/rss.ashx?type=video&amp;mediaID=45134031"&gt;http://mediaservices.myspace.com/services/rss.ashx?type=video&amp;mediaID=45134031&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you check out the source of the result, our prize lies within:&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;rss version=&amp;quot;2.0&amp;quot; xmlns:media=&amp;quot;http://search.yahoo.com/mrss&amp;quot; xmlns:myspace=&amp;quot;http://myspace.com/&amp;quot;&amp;gt; &lt;br /&gt;  &amp;lt;channel&amp;gt; &lt;br /&gt;    &amp;lt;title&amp;gt;MySpace&amp;lt;/title&amp;gt; &lt;br /&gt;    &amp;lt;description&amp;gt;MySpace&amp;lt;/description&amp;gt; &lt;br /&gt;    &amp;lt;link&amp;gt;http://myspace.com/192982080&amp;lt;/link&amp;gt; &lt;br /&gt;    &amp;lt;lastBuildDate&amp;gt;Mon, 29 Dec 2008 16:26:41 GMT&amp;lt;/lastBuildDate&amp;gt; &lt;br /&gt;    &amp;lt;docs&amp;gt;http://myspace.com&amp;lt;/docs&amp;gt; &lt;br /&gt;    &amp;lt;generator&amp;gt;CHA1mwebnet1246&amp;lt;/generator&amp;gt; &lt;br /&gt;    &amp;lt;myspace:friendID&amp;gt;192982080&amp;lt;/myspace:friendID&amp;gt; &lt;br /&gt;    &amp;lt;item&amp;gt; &lt;br /&gt;      &amp;lt;title&amp;gt;VIMBY - Novato Skatepark&amp;lt;/title&amp;gt; &lt;br /&gt;      &amp;lt;pubDate&amp;gt;Mon, 29 Dec 2008 16:26:41 GMT&amp;lt;/pubDate&amp;gt; &lt;br /&gt;      &amp;lt;media:thumbnail url=&amp;quot;http://d4.ac-videos.myspacecdn.com/videos02/50/thumb0_afc9f68733bc87a1b7eb4dc9ec9a1bc7.jpg&amp;quot; /&amp;gt; &lt;br /&gt;      &amp;lt;media:content url=&amp;quot;http://cache01-videos02.myspacecdn.com/50/vid_afc9f68733bc87a1b7eb4dc9ec9a1bc7.flv&amp;quot; type=&amp;quot;video/x-flv&amp;quot; medium=&amp;quot;video&amp;quot; duration=&amp;quot;220&amp;quot; /&amp;gt; &lt;br /&gt;      &amp;lt;myspace:mediaID&amp;gt;45134031&amp;lt;/myspace:mediaID&amp;gt; &lt;br /&gt;      &amp;lt;myspace:mediaSource&amp;gt;Video&amp;lt;/myspace:mediaSource&amp;gt; &lt;br /&gt;      &amp;lt;myspace:itemID&amp;gt;45134031&amp;lt;/myspace:itemID&amp;gt; &lt;br /&gt;      &amp;lt;myspace:itemType&amp;gt;Video&amp;lt;/myspace:itemType&amp;gt; &lt;br /&gt;      &amp;lt;myspace:friendID&amp;gt;192982080&amp;lt;/myspace:friendID&amp;gt; &lt;br /&gt;    &amp;lt;/item&amp;gt; &lt;br /&gt;  &amp;lt;/channel&amp;gt; &lt;br /&gt;&amp;lt;/rss&amp;gt;&lt;/pre&gt;The xml element at line &lt;span style="font-weight:bold;"&gt;14&lt;/span&gt; "&amp;lt;media:content&amp;gt;" has a url attribute that contains a direct link to the flv file:&lt;br /&gt;&lt;a href="http://cache01-videos02.myspacecdn.com/50/vid_afc9f68733bc87a1b7eb4dc9ec9a1bc7.flv"&gt;http://cache01-videos02.myspacecdn.com/50/vid_afc9f68733bc87a1b7eb4dc9ec9a1bc7.flv&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There you go, you can now go ahead and download the flv and perhaps convert it to other video formats using &lt;a href="http://www.regnow.com/softsell/nph-softsell.cgi?item=14271-15&amp;affiliate=281487"&gt;this splendid piece of sponsored software here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-5601035893060312348?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/5601035893060312348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=5601035893060312348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5601035893060312348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/5601035893060312348'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2008/12/extracting-flv-file-behind-myspacecom.html' title='Extracting the flv file behind a MySpace.com video'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-7570097760278016100</id><published>2008-12-27T11:14:00.001+02:00</published><updated>2009-01-01T20:35:15.499+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>This works!</title><content type='html'>Here is a funny java code snippet for the hebrew speakers among us, this actually compiles:&lt;pre name="code" class="java"&gt;&lt;br /&gt;package com.codeark.rnd;&lt;br /&gt;&lt;br /&gt;public class הקלאס {&lt;br /&gt;&lt;br /&gt; private static String יניב = "123123";&lt;br /&gt;  &lt;br /&gt; public static void מתודה(String משתנה) {&lt;br /&gt;  System.out.println(משתנה);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @param args&lt;br /&gt;  */&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;  System.out.println(יניב);&lt;br /&gt;  מתודה("asdasd");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Funny :)&lt;br /&gt;&lt;br /&gt;p.s. the static member is named יניב and its value is "123123"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-7570097760278016100?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/7570097760278016100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=7570097760278016100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7570097760278016100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/7570097760278016100'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2008/12/this-works.html' title='This works!'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4699667848216680716.post-6713349733925632394</id><published>2008-01-22T02:10:00.000+02:00</published><updated>2008-10-26T18:04:22.320+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video dating'/><category scheme='http://www.blogger.com/atom/ns#' term='dating'/><category scheme='http://www.blogger.com/atom/ns#' term='blind dating'/><category scheme='http://www.blogger.com/atom/ns#' term='click dating'/><title type='text'>Click Dating</title><content type='html'>&lt;span style="font-family:verdana;"&gt;A controversial child in a long succession line of "&lt;em&gt;X dating&lt;/em&gt;".&lt;br /&gt;&lt;br /&gt;We've seen many of them around over the years: &lt;em&gt;Blind dating, Video dating, Speed dating&lt;/em&gt; and so on and so forth.&lt;br /&gt;&lt;br /&gt;What is &lt;strong&gt;Click Dating&lt;/strong&gt; you ask ?&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Click Dating&lt;/em&gt; is the term I give to all of those (mostly) facebook applications, where you sit like a mouse in a factory and &lt;strong&gt;click&lt;/strong&gt; &lt;em&gt;yes or no&lt;/em&gt; on portrait photos of the (sometimes :P ) opposite sex.&lt;br /&gt;&lt;br /&gt;Its a new kind of statistical dating... you click 100 times, you might be getting between 1 to 10 replies from which 0.1 to 1 might actually yield any result. Actually, come to think about it, its very much like Internet advertising. You can definitely apply terms like Conversion Rate and even Cost Per Click... (just be imaginative with the latter :P )&lt;br /&gt;&lt;br /&gt;So what happened to good old "Mommy and daddy met because daddy ran her over with his bicycle... and the rest is history" ?&lt;br /&gt;&lt;br /&gt;I mean what would you tell your children in this case ? "Mommy and Daddy met after 10000000 clicks on &lt;em&gt;Flirtable&lt;/em&gt;" ???&lt;br /&gt;&lt;br /&gt;I admit I have joined the mice community and I did had my share of "conversions" from this, but call me a hopeless romantic, I'm still hoping that meeting my future second half would be much more similar to some classic movie scene than to an Internet banner statistical report.&lt;br /&gt;&lt;br /&gt;Y&lt;br /&gt;&lt;br /&gt;P.S. I wonder what the next X Dating will be.... if you can answer this one, its worth a lot of $$$ :D&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4699667848216680716-6713349733925632394?l=blog.yanivkessler.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.yanivkessler.com/feeds/6713349733925632394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4699667848216680716&amp;postID=6713349733925632394' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6713349733925632394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4699667848216680716/posts/default/6713349733925632394'/><link rel='alternate' type='text/html' href='http://blog.yanivkessler.com/2008/01/click-dating.html' title='Click Dating'/><author><name>Yaniv Kessler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='23' src='http://4.bp.blogspot.com/-Xw3LFq0Pknk/TaIYJFZ_uYI/AAAAAAAABP0/h-JwcNsmBr4/s220/15027_323422707324_625752324_3011633_5781459_n.jpg'/></author><thr:total>0</thr:total></entry></feed>
