<?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-6715087</id><updated>2012-01-27T22:46:29.910-08:00</updated><title type='text'>Dadidadida</title><subtitle type='html'>by Hanson Char</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default?start-index=101&amp;max-results=100'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>145</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6715087.post-2973244704557102696</id><published>2012-01-27T21:31:00.000-08:00</published><updated>2012-01-27T22:46:29.923-08:00</updated><title type='text'>Ex 4.32.1 Power Sets</title><content type='html'>&lt;pre&gt;Is it true that for all sets A and B, Ƥ(A ∩ B) = Ƥ(A) ∩ Ƥ(B) ?&lt;br /&gt;&lt;br /&gt;I think so, and here is the proof:&lt;br /&gt;&lt;br /&gt;  Let X ∈ Ƥ(A ∩ B)&lt;br /&gt;  We will show that X ∈ Ƥ(A) ∩ Ƥ(B)&lt;br /&gt;&lt;br /&gt;    From X ∈ Ƥ(A ∩ B), we get X ⊆ A ∩ B i.e., X ⊆ A and X ⊆ B&lt;br /&gt;    It follows that X ∈ Ƥ(A) and X ∈ Ƥ(B), i.e., X ∈ Ƥ(A) ∩ Ƥ(B)&lt;br /&gt;    Thus Ƥ(A ∩ B) ⇒ Ƥ(A) ∩ Ƥ(B)&lt;br /&gt;&lt;br /&gt;  Let Y ∈ Ƥ(A) ∩ Ƥ(B)&lt;br /&gt;  We will show that Y ∈ Ƥ(A ∩ B)&lt;br /&gt;&lt;br /&gt;    From Y ∈ Ƥ(A) ∩ Ƥ(B), we get Y ∈ Ƥ(A) and Y ∈ Ƥ(B), i.e., Y ⊆ A and Y ⊆ B&lt;br /&gt;    Let m ∈ Y.  Then m ∈ A and m ∈ B, i.e., m ∈ A ∩ B&lt;br /&gt;    So Y ⊆ A ∩ B&lt;br /&gt;    It follows that Y ∈ Ƥ(A ∩ B)&lt;br /&gt;    Thus Ƥ(A) ∩ Ƥ(B) ⇒ Ƥ(A ∩ B)&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/6715087-2973244704557102696?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/2973244704557102696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=2973244704557102696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2973244704557102696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2973244704557102696'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/ex-4321-power-sets.html' title='Ex 4.32.1 Power Sets'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-9093786834745817531</id><published>2012-01-22T20:57:00.000-08:00</published><updated>2012-01-22T22:18:14.687-08:00</updated><title type='text'>Proof Ex 4.17.2 Intersection</title><content type='html'>&lt;pre&gt;Show that A &amp;cap; B = A - (A - B)&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;    A - (A - B)&lt;br /&gt;  = x ∈ A ∧ x ∉ (A - B)&lt;br /&gt;  = x ∈ A ∧ ¬(x ∈ A ∧ x ∉ B)&lt;br /&gt;  = x ∈ A ∧ (x ∉ A &amp;or; x ∈ B)&lt;br /&gt;  = (x ∈ A ∧ x ∉ A) &amp;or; (x ∈ A ∧ x ∈ B)&lt;br /&gt;  = x ∈ A ∧ x ∈ B&lt;br /&gt;&lt;br /&gt;  ⇔ A &amp;cap; B&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-9093786834745817531?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/9093786834745817531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=9093786834745817531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/9093786834745817531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/9093786834745817531'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/proof-ex-4172-intersection.html' title='Proof Ex 4.17.2 Intersection'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8487627840624746986</id><published>2012-01-22T20:29:00.000-08:00</published><updated>2012-01-22T22:22:03.718-08:00</updated><title type='text'>Proof Ex 4.17.1 Subset</title><content type='html'>&lt;pre&gt;Show that A &amp;nsub; B ⇔ A - B ≠ ∅&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;    A &amp;nsub; B &lt;br /&gt;  = ¬&amp;forall;x(x ∈ A ⇒ x ∈ B)&lt;br /&gt;  = ¬&amp;forall;x(x ∉ A &amp;or; x ∈ B)&lt;br /&gt;  = &amp;exist;x(¬(x ∉ A &amp;or; x ∈ B))&lt;br /&gt;  = &amp;exist;x(x ∈ A &amp;and; x ∉ B)&lt;br /&gt;&lt;br /&gt;  ⇔ A - B ≠ ∅  &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8487627840624746986?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8487627840624746986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8487627840624746986' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8487627840624746986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8487627840624746986'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/proof-ex-417-subset.html' title='Proof Ex 4.17.1 Subset'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1098991251463070866</id><published>2012-01-22T10:35:00.000-08:00</published><updated>2012-01-22T11:15:35.105-08:00</updated><title type='text'>Proof Ex 4.7 Set of ordinary sets</title><content type='html'>&lt;pre&gt;Assume that A is a set of sets.  Show that {x ∈ A|x ∉ x} ∉ A.&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;  Let P(x) = x ∈ A ∧ x ∉ x, and F = {x|P(x)}&lt;br /&gt;  We will show that F ∉ A&lt;br /&gt;&lt;br /&gt;    Assume the contrary, F ∈ A&lt;br /&gt;    There are only two possibilities: either F ∉ F or F ∈ F&lt;br /&gt;&lt;br /&gt;    Suppose F ∉ F&lt;br /&gt;    From F ∈ A and F ∉ F, we get P(F)&lt;br /&gt;    From F = {x|P(x)}, it follows F ∈ F.  A contradiction.&lt;br /&gt;&lt;br /&gt;    Suppose F ∈ F&lt;br /&gt;    From F = {x|P(x)}, we get P(F)&lt;br /&gt;    From P(F) = F ∈ A ∧ F ∉ F, it follows F ∉ F.  A contradiction.&lt;br /&gt;&lt;br /&gt;  Thus F ∉ A, which means {x ∈ A|x ∉ x} ∉ A&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-1098991251463070866?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1098991251463070866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1098991251463070866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1098991251463070866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1098991251463070866'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/ex-47-set-of-ordinary-sets.html' title='Proof Ex 4.7 Set of ordinary sets'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7239778001876445644</id><published>2012-01-21T12:47:00.000-08:00</published><updated>2012-01-22T11:15:53.676-08:00</updated><title type='text'>Proof Ex 3.43 Prime 11</title><content type='html'>&lt;pre&gt;Prove that 11 is the only prime of the form p^2 + 2, with p prime&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;  Let n = p^2 + 2&lt;br /&gt;  If n is 11, p is 3&lt;br /&gt;  If n is not 11, p must be either of the form 3a+1 or 3a+2, with a ∈ ℕ&lt;br /&gt;&lt;br /&gt;  Suppose p = 3a+1&lt;br /&gt;  n = p^2 + 2 = (3a+1)^2 + 2 = 9a&lt;sup&gt;2&lt;/sup&gt; + 6a + 3&lt;br /&gt;&lt;br /&gt;  Suppose p = 3a+2&lt;br /&gt;  n = p^2 + 2 = (3a+2)^2 + 2 = 9a&lt;sup&gt;2&lt;/sup&gt; + 12a + 6&lt;br /&gt;&lt;br /&gt;  In both cases, n is divisible by 3 and therefore not prime&lt;br /&gt;  Thus 11 is the only prime of the form p^2+2, with p prime&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/6715087-7239778001876445644?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7239778001876445644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7239778001876445644' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7239778001876445644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7239778001876445644'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/ex-343-prime.html' title='Proof Ex 3.43 Prime 11'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8524012507418932594</id><published>2012-01-17T21:31:00.000-08:00</published><updated>2012-01-22T11:16:04.089-08:00</updated><title type='text'>Proof Ex 3.36 Mersenne Prime</title><content type='html'>&lt;pre&gt;Show that if n is composite, 2&lt;sup&gt;n&lt;/sup&gt; - 1 is composite too.&lt;br /&gt;&lt;br /&gt;(&lt;i&gt;Hint:&lt;/i&gt; Asume that n = ab and prove that xy = 2&lt;sup&gt;n&lt;/sup&gt; - 1 for the numbers x = 2&lt;sup&gt;b&lt;/sup&gt;- 1 and y = 1 + 2&lt;sup&gt;b&lt;/sup&gt; + 2&lt;sup&gt;2b&lt;/sup&gt; + ... + 2&lt;sup&gt;(a-1)b&lt;/sup&gt;)&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;  Assume n = ab where a, b ∈ ℕ&lt;br /&gt;  Let x = 2&lt;sup&gt;b&lt;/sup&gt; - 1 and y = 1 + 2&lt;sup&gt;b&lt;/sup&gt; + 2&lt;sup&gt;2b&lt;/sup&gt; + ... + 2&lt;sup&gt;(a-1)b&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;  xy = (2&lt;sup&gt;b&lt;/sup&gt; - 1)(1 + 2&lt;sup&gt;b&lt;/sup&gt; + 2&lt;sup&gt;2b&lt;/sup&gt; + ... + 2&lt;sup&gt;(a-1)b&lt;/sup&gt;)&lt;br /&gt;     =        2&lt;sup&gt;b&lt;/sup&gt; + 2&lt;sup&gt;2b&lt;/sup&gt; + ... + 2&lt;sup&gt;(a-1)b&lt;/sup&gt; + 2&lt;sup&gt;(a-1)b+b&lt;/sup&gt;&lt;br /&gt;       - (1 + 2&lt;sup&gt;b&lt;/sup&gt; + 2&lt;sup&gt;2b&lt;/sup&gt; + ... + 2&lt;sup&gt;(a-1)b&lt;/sup&gt;)&lt;br /&gt;     = 2&lt;sup&gt;ab&lt;/sup&gt; - 1&lt;br /&gt;     = 2&lt;sup&gt;n&lt;/sup&gt; - 1&lt;br /&gt;&lt;br /&gt;  This shows that if n is composite, 2&lt;sup&gt;n&lt;/sup&gt; - 1 is also composite since we can always find integers x and y of the form above.&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/6715087-8524012507418932594?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8524012507418932594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8524012507418932594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8524012507418932594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8524012507418932594'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/ex-336-mersenne-prime.html' title='Proof Ex 3.36 Mersenne Prime'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-245120767335272461</id><published>2012-01-16T23:02:00.000-08:00</published><updated>2012-01-22T11:16:13.577-08:00</updated><title type='text'>Proof Ex 3.34 Prime numbers</title><content type='html'>&lt;pre&gt;Let A = {4n + 3 | n ∈ ℕ}.  Show that A contains infinitely many prime numbers.&lt;br /&gt;&lt;br /&gt;(&lt;i&gt;Hint&lt;/i&gt;: any prime &gt; 2 is odd, hence of the form 4n + 1 or 4n + 3.)&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;  Assume there are only finitely many primes of the form 4n + 3, say p&lt;sub&gt;1&lt;/sub&gt;,...,p&lt;sub&gt;m&lt;/sub&gt;&lt;br /&gt;  &lt;br /&gt;    Consider the number N = 4p&lt;sub&gt;1&lt;/sub&gt;...p&lt;sub&gt;m&lt;/sub&gt; - 1 = 4(p&lt;sub&gt;1&lt;/sub&gt;...p&lt;sub&gt;m&lt;/sub&gt; - 1) + 3&lt;br /&gt;    We will show that N must have a factor p of the form 4n + 3&lt;br /&gt;  &lt;br /&gt;      Suppose N does not have a factor of the form 4n + 3&lt;br /&gt;      Note the fact that (4a + 1)(4b + 1) is of the form 4c + 1&lt;br /&gt;      If all factors of N is of the form 4n + 1, N will be of the form 4n + 1, but N is not&lt;br /&gt;      Thus N must have a factor of the form 4n + 3&lt;br /&gt;  &lt;br /&gt;    Based on the assumption, it follows p is a member of {p&lt;sub&gt;1&lt;/sub&gt;,...,p&lt;sub&gt;m&lt;/sub&gt;} and p divides N&lt;br /&gt;    But dividing N by p would result in the form 4c - 1/p which is a fraction (where c ∈ ℕ)&lt;br /&gt;    So p cannot divide N.  A contradiction.&lt;br /&gt;  &lt;br /&gt;  Thus there are infinitely many primes of the form 4n + 3.&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-245120767335272461?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/245120767335272461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=245120767335272461' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/245120767335272461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/245120767335272461'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/ex-334.html' title='Proof Ex 3.34 Prime numbers'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5078703427609383247</id><published>2012-01-09T08:27:00.000-08:00</published><updated>2012-01-17T21:58:08.111-08:00</updated><title type='text'>Proof Ex 2.19 Equivalence and logical validity</title><content type='html'>&lt;pre&gt;Prove that&lt;br /&gt;&lt;br /&gt;  ϕ &amp;equiv; ψ iff ϕ ⇔ ψ&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;  The above statement can be expanded into a conjunction of two sub-statements&lt;br /&gt;&lt;br /&gt;    ((ϕ &amp;equiv; ψ) ⇒ (ϕ ⇔ ψ)) ∧&lt;br /&gt;    ((ϕ ⇔ ψ) ⇒ (ϕ &amp;equiv; ψ))&lt;br /&gt;&lt;br /&gt;  which can be further expanded into&lt;br /&gt;&lt;br /&gt;    ((ϕ &amp;equiv; ψ) ⇒ ((ϕ ⇒ ψ) ∧ (ψ ⇒ ϕ))) ∧&lt;br /&gt;    (((ϕ ⇒ ψ) ∧ (ψ ⇒ ϕ)) ⇒ (ϕ &amp;equiv; ψ))&lt;br /&gt;&lt;br /&gt;  1) Given: ϕ &amp;equiv; ψ&lt;br /&gt;     To be proven: (ϕ ⇒ ψ) ∧ (ψ ⇒ ϕ)&lt;br /&gt;&lt;br /&gt;     Suppose ϕ and ψ&lt;br /&gt;     It follows (ϕ ⇒ ψ) ∧ (ψ ⇒ ϕ)&lt;br /&gt;&lt;br /&gt;  2) Given: (ϕ ⇒ ψ) ∧ (ψ ⇒ ϕ)&lt;br /&gt;     To be proven: ϕ &amp;equiv; ψ&lt;br /&gt;&lt;br /&gt;     Suppose ϕ, then ψ&lt;br /&gt;     Suppose ¬ϕ, then ¬ψ&lt;br /&gt;&lt;br /&gt;     Thus ϕ &amp;equiv; ψ&lt;br /&gt;&lt;br /&gt;Thus ϕ &amp;equiv; ψ iff ϕ ⇔ ψ&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/6715087-5078703427609383247?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5078703427609383247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5078703427609383247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5078703427609383247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5078703427609383247'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/proof-ex-219.html' title='Proof Ex 2.19 Equivalence and logical validity'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-3799279362884964414</id><published>2012-01-07T15:05:00.000-08:00</published><updated>2012-01-07T15:16:20.508-08:00</updated><title type='text'>Proof Ex 3.26</title><content type='html'>&lt;pre&gt;Given&lt;br /&gt;&lt;br /&gt;  &amp;forall;x&amp;exist;y(x&lt;b&gt;R&lt;/b&gt;y),&lt;br /&gt;  &amp;forall;x&amp;forall;y(x&lt;b&gt;R&lt;/b&gt;y =&gt; y&lt;b&gt;R&lt;/b&gt;x), &lt;br /&gt;  &amp;forall;x&amp;forall;y&amp;forall;z(x&lt;b&gt;R&lt;/b&gt;y ∧ y&lt;b&gt;R&lt;/b&gt;z =&gt; x&lt;b&gt;R&lt;/b&gt;z) &lt;br /&gt;&lt;br /&gt;Prove that&lt;br /&gt;&lt;br /&gt;  &amp;forall;x(x&lt;b&gt;R&lt;/b&gt;x)&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;  Let a be arbitrary&lt;br /&gt;  From &amp;forall;x&amp;exist;y(x&lt;b&gt;R&lt;/b&gt;y), it follows &amp;exist;y(a&lt;b&gt;R&lt;/b&gt;y)&lt;br /&gt;  Let b such that a&lt;b&gt;R&lt;/b&gt;b&lt;br /&gt;  From &amp;forall;x&amp;forall;y(x&lt;b&gt;R&lt;/b&gt;y =&gt; y&lt;b&gt;R&lt;/b&gt;x), it follows a&lt;b&gt;R&lt;/b&gt;b =&gt; b&lt;b&gt;R&lt;/b&gt;a&lt;br /&gt;  From &amp;forall;x&amp;forall;y&amp;forall;z(x&lt;b&gt;R&lt;/b&gt;y ∧ y&lt;b&gt;R&lt;/b&gt;z =&gt; x&lt;b&gt;R&lt;/b&gt;z), it follows a&lt;b&gt;R&lt;/b&gt;b ∧ b&lt;b&gt;R&lt;/b&gt;a =&gt; a&lt;b&gt;R&lt;/b&gt;a&lt;br /&gt;&lt;br /&gt;Thus &amp;forall;x(x&lt;b&gt;R&lt;/b&gt;x)&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/6715087-3799279362884964414?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/3799279362884964414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=3799279362884964414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3799279362884964414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3799279362884964414'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/proof-ex-326.html' title='Proof Ex 3.26'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7046843824928456398</id><published>2012-01-07T13:20:00.000-08:00</published><updated>2012-01-07T13:24:34.180-08:00</updated><title type='text'>Proof Ex 3.28</title><content type='html'>&lt;pre&gt;Given&lt;br /&gt;&lt;br /&gt;  &amp;forall;y&amp;exist;z&amp;forall;x&lt;i&gt;P&lt;/i&gt;(x,y,z)&lt;br /&gt;&lt;br /&gt;Prove that&lt;br /&gt;&lt;br /&gt;  &amp;forall;x&amp;forall;y&amp;exist;z&lt;i&gt;P&lt;/i&gt;(x,y,z)&lt;br /&gt;&lt;br /&gt;Proof:&lt;br /&gt;&lt;br /&gt;  Let a,b be arbitrary&lt;br /&gt;  We need to show &amp;exist;z&lt;i&gt;P&lt;/i&gt;(a,b,z)&lt;br /&gt;  Given &amp;forall;y&amp;exist;z&amp;forall;x&lt;i&gt;P&lt;/i&gt;(x,y,z), it follows &amp;exist;z&amp;forall;x&lt;i&gt;P&lt;/i&gt;(x,b,z)&lt;br /&gt;  Let c be such that &amp;forall;x&lt;i&gt;P&lt;/i&gt;(x,b,c)&lt;br /&gt;  So &lt;i&gt;P&lt;/i&gt;(a,b,c)&lt;br /&gt;&lt;br /&gt;Thus &amp;forall;x&amp;forall;y&amp;exist;z&lt;i&gt;P&lt;/i&gt;(x,y,z)&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/6715087-7046843824928456398?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7046843824928456398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7046843824928456398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7046843824928456398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7046843824928456398'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/proof-ex-328.html' title='Proof Ex 3.28'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8090761321347336414</id><published>2012-01-03T08:55:00.000-08:00</published><updated>2012-01-03T09:53:08.106-08:00</updated><title type='text'>Proof Ex 3.27.3</title><content type='html'>&lt;pre&gt;Given&lt;br /&gt;&lt;blockquote&gt;&amp;forall;x&amp;forall;y(x&lt;b&gt;R&lt;/b&gt;y ∧ x&amp;ne;y =&gt; ¬y&lt;b&gt;R&lt;/b&gt;x)&lt;/blockquote&gt;Prove that&lt;blockquote&gt;&amp;forall;x&amp;forall;y(x&lt;b&gt;R&lt;/b&gt;y ∧ y&lt;b&gt;R&lt;/b&gt;x =&gt; x=y)&lt;/blockquote&gt;Proof:&lt;br /&gt;&lt;br /&gt;  Suppose a and b are arbitrary objects, it follows (by definition)&lt;blockquote&gt;a&lt;b&gt;R&lt;/b&gt;b ∧ a&amp;ne;b =&gt; ¬b&lt;b&gt;R&lt;/b&gt;a&lt;/blockquote&gt;  Suppose: a&lt;b&gt;R&lt;/b&gt;b ∧ b&lt;b&gt;R&lt;/b&gt;a&lt;br /&gt;  To be proven: a=b&lt;br /&gt;&lt;br /&gt;  Proof:&lt;br /&gt;    Suppose: a&amp;ne;b&lt;br /&gt;    To be proven: ⊥ (ie contradiction)&lt;br /&gt;&lt;br /&gt;    Proof:&lt;br /&gt;      From a&lt;b&gt;R&lt;/b&gt;b ∧ a&amp;ne;b =&gt; ¬b&lt;b&gt;R&lt;/b&gt;a, and a&lt;b&gt;R&lt;/b&gt;b ∧ b&lt;b&gt;R&lt;/b&gt;a,&lt;br /&gt;      it follows ¬b&lt;b&gt;R&lt;/b&gt;a ∧ b&lt;b&gt;R&lt;/b&gt;a &amp;equiv; ⊥&lt;br /&gt;&lt;br /&gt;    Thus a=b&lt;br /&gt;&lt;br /&gt;  Thus &amp;forall;x&amp;forall;y(x&lt;b&gt;R&lt;/b&gt;y ∧ y&lt;b&gt;R&lt;/b&gt;x =&gt; x=y)&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/6715087-8090761321347336414?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8090761321347336414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8090761321347336414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8090761321347336414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8090761321347336414'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2012/01/proof-ex-3273.html' title='Proof Ex 3.27.3'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-2220230812677310834</id><published>2011-11-24T16:15:00.000-08:00</published><updated>2011-11-26T08:44:39.550-08:00</updated><title type='text'>Yet another Luhn check and digit generation</title><content type='html'>&lt;p&gt;But this time it's faster:&lt;pre&gt;&lt;blockquote&gt;    /**&lt;br /&gt;     * @param s non-empty string that contains only digits&lt;br /&gt;     * @return true only if the given digits pass the luhn check&lt;br /&gt;     */&lt;br /&gt;    boolean isLuhn(String s) {&lt;br /&gt;        char[] ca = s.toCharArray();&lt;br /&gt;        int sum = ca[ca.length-1] - '0';&lt;br /&gt;        &lt;br /&gt;        for (int i=ca.length-2; i &gt;= 0; i-=2) {&lt;br /&gt;            int x2 = (ca[i] - '0') &lt;&lt; 1;&lt;br /&gt;            sum += x2 &lt; 10 ? x2 : 1 + (x2 - 10);&lt;br /&gt;        }&lt;br /&gt;        for (int i=ca.length-3; i &gt;= 0; i-=2)&lt;br /&gt;            sum += ca[i] - '0';&lt;br /&gt;        return sum % 10 == 0;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param s non-empty string that contains only digits&lt;br /&gt;     * @return the generated Luhn digit&lt;br /&gt;     */&lt;br /&gt;    int calculateLuhnDigit(String s) {&lt;br /&gt;        char[] ca = s.toCharArray();&lt;br /&gt;        int sum = 0;&lt;br /&gt;        &lt;br /&gt;        for (int i=ca.length-1; i &gt;= 0; i-=2) {&lt;br /&gt;            int x2 = (ca[i] - '0') &lt;&lt; 1;&lt;br /&gt;            sum += x2 &lt; 10 ? x2 : 1 + (x2 - 10);&lt;br /&gt;        }&lt;br /&gt;        for (int i=ca.length-2; i &gt;= 0; i-=2)&lt;br /&gt;            sum += ca[i] - '0';&lt;br /&gt;        int mod = sum % 10;&lt;br /&gt;        return mod == 0 ? 0 : 10 - mod;&lt;br /&gt;    }&lt;/blockquote&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-2220230812677310834?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/2220230812677310834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=2220230812677310834' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2220230812677310834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2220230812677310834'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/11/yet-another-luhn-check-and-digit.html' title='Yet another &lt;a href=&quot;http://en.wikipedia.org/wiki/Luhn_algorithm&quot;&gt;Luhn check&lt;/a&gt; and digit generation'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8763263823010759478</id><published>2011-11-19T20:39:00.000-08:00</published><updated>2011-11-19T20:55:30.792-08:00</updated><title type='text'>Java 7 behaves differently on InetAddress.getHostName()</title><content type='html'>On my Mac, if I execute the following code in Java 6:&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;System.out.println(InetAddress.getLocalHost().getHostName());&lt;/blockquote&gt;&lt;/pre&gt;I got:&lt;pre&gt;&lt;blockquote&gt;5855pns93223&lt;/blockquote&gt;&lt;/pre&gt;But when run in Java 7, I got:&lt;pre&gt;&lt;blockquote&gt;5855pns93223.nznmba.com&lt;/blockquote&gt;&lt;/pre&gt;This causes problem with some existing Java mail code, with  exception like:&lt;pre&gt;&lt;blockquote&gt;Caused by: javax.mail.MessagingException: 501 5.0.0 HELO requires domain address&lt;br /&gt;        at com.sun.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:1363)&lt;br /&gt;        at com.sun.mail.smtp.SMTPTransport.helo(SMTPTransport.java:838)&lt;br /&gt;        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:375)&lt;br /&gt;        at javax.mail.Service.connect(Service.java:275)&lt;br /&gt;        at javax.mail.Service.connect(Service.java:156)&lt;br /&gt;        at javax.mail.Service.connect(Service.java:105)&lt;br /&gt;        at javax.mail.Transport.send0(Transport.java:168)&lt;br /&gt;        at javax.mail.Transport.send(Transport.java:98)&lt;/blockquote&gt;&lt;/pre&gt;This isn't good for unit testing when I need to run them locally.&lt;br /&gt;&lt;br /&gt;Solution ?&lt;br /&gt;&lt;br /&gt;Add two entries to my /etc/hosts:&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;127.0.0.1       5855pns93223&lt;br /&gt;127.0.0.1       5855pns93223.nznmba.com&lt;/blockquote&gt;&lt;/pre&gt;A hack, I know, but a quick fix at least for now :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8763263823010759478?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8763263823010759478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8763263823010759478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8763263823010759478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8763263823010759478'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/11/java-7-behaves-differently-on.html' title='Java 7 behaves differently on InetAddress.getHostName()'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7260102337037818796</id><published>2011-11-18T14:38:00.000-08:00</published><updated>2011-11-20T12:08:21.001-08:00</updated><title type='text'>Scriptfu comparing memcached hit counts</title><content type='html'>&lt;p&gt;If we have a text file "hosts" that contains all the host names in a memcached fleet, we can readily capture a snapshot of the memcached's "get_hits" counts of the entire fleet to a file "hits", like so:&lt;pre&gt;&lt;blockquote&gt;for i in `cat hosts`&lt;br /&gt;do&lt;br /&gt;  echo -ne 'stats\r\n' | nc -i1 $i:11211 | grep get_hits | cut -d ' ' -f3 | sed 's/[^0-9]//'&lt;br /&gt;done | tee hits&lt;/blockquote&gt;&lt;/pre&gt;&lt;br /&gt;(Do you see why we need to do the sed at the end ?)  Anyhow, here is the fun part: &lt;br /&gt;&lt;br /&gt;Given we have captured two files "hits.1" and "hits.2" at T1 and T2, how can we show the increments of the "get_hits" count of every host ?  With a one-liner, that is :)&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;paste -d '-' hits.2 hits.1 | xargs -I {} echo {} | bc -iq | paste hosts -&lt;/blockquote&gt;&lt;/pre&gt;Neat, huh ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-7260102337037818796?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7260102337037818796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7260102337037818796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7260102337037818796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7260102337037818796'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/11/scriptfu-comparing-memcached-hit-counts.html' title='Scriptfu comparing memcached hit counts'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-6201242381023972134</id><published>2011-11-12T11:07:00.002-08:00</published><updated>2011-11-12T11:22:51.427-08:00</updated><title type='text'>How to compile with Libevent on Mac ?</title><content type='html'>&lt;p&gt;Assuming &lt;a href="http://libevent.org/"&gt;Libevent&lt;/a&gt; has been installed on Mac, and now try to compile something that uses it such as the toy &lt;a href="http://www.wangafu.net/~nickm/libevent-book/01_intro.html"&gt;low-level ROT13 server with Libevent&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;$ gcc libeventBasedRot13Server.c&lt;/blockquote&gt;&lt;/pre&gt;would failed with something like:&lt;pre&gt;&lt;blockquote&gt;Undefined symbols:&lt;br /&gt;  "_evutil_make_socket_nonblocking", referenced from:&lt;br /&gt;      _do_accept in cc2B6M02.o&lt;br /&gt;      _run in cc2B6M02.o&lt;br /&gt;  "_event_new", referenced from:&lt;br /&gt;      _alloc_fd_state in cc2B6M02.o&lt;br /&gt;      _alloc_fd_state in cc2B6M02.o&lt;br /&gt;      _run in cc2B6M02.o&lt;br /&gt;  "_event_add", referenced from:&lt;br /&gt;      _do_read in cc2B6M02.o&lt;br /&gt;      _do_accept in cc2B6M02.o&lt;br /&gt;      _run in cc2B6M02.o&lt;br /&gt;  "_event_base_dispatch", referenced from:&lt;br /&gt;      _run in cc2B6M02.o&lt;br /&gt;  "_event_free", referenced from:&lt;br /&gt;      _alloc_fd_state in cc2B6M02.o&lt;br /&gt;      _free_fd_state in cc2B6M02.o&lt;br /&gt;      _free_fd_state in cc2B6M02.o&lt;br /&gt;  "_event_base_new", referenced from:&lt;br /&gt;      _run in cc2B6M02.o&lt;br /&gt;  "_event_del", referenced from:&lt;br /&gt;      _do_write in cc2B6M02.o&lt;br /&gt;ld: symbol(s) not found&lt;br /&gt;collect2: ld returned 1 exit status&lt;/blockquote&gt;&lt;/pre&gt;Solution:&lt;pre&gt;&lt;blockquote&gt;$ gcc libeventBasedRot13Server.c /usr/local/lib/libevent.a&lt;/blockquote&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-6201242381023972134?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/6201242381023972134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=6201242381023972134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/6201242381023972134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/6201242381023972134'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/11/how-to-compile-with-libevent-on-mac_7109.html' title='How to compile with Libevent on Mac ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1107648853933508194</id><published>2011-11-06T09:36:00.000-08:00</published><updated>2011-11-06T09:41:14.581-08:00</updated><title type='text'>How to turn off class file verification in junit ant task ?</title><content type='html'>&lt;p&gt;Example:&lt;pre&gt;    &amp;lt;junit printsummary="yes" haltonfailure="yes" fork="true"&gt;&lt;br /&gt;      &amp;lt;jvmarg value="-noverify" /&gt;&lt;br /&gt;      ...&lt;br /&gt;    &amp;lt;/junit&gt;&lt;br /&gt;&lt;/pre&gt;(Why ? This was necessary to get Cobertura to run in peace with Java 7)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-1107648853933508194?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1107648853933508194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1107648853933508194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1107648853933508194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1107648853933508194'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/11/how-to-turn-off-class-file-verification.html' title='How to turn off class file verification in junit ant task ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5882372063253117908</id><published>2011-10-27T13:13:00.000-07:00</published><updated>2011-11-12T11:31:59.892-08:00</updated><title type='text'>Scriptfu counting opened file descriptors</title><content type='html'>&lt;p&gt;How to count the number of opened file descriptors of all running JVM's on a Linux host ?&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;for ((;;))&lt;br /&gt;do&lt;br /&gt;  declare sum=0&lt;br /&gt;  for i in `pgrep -lf jdk | awk '{print $1}'`&lt;br /&gt;  do&lt;br /&gt;    ((sum += `sudo /usr/sbin/lsof -p $i | wc -l`))&lt;br /&gt;  done&lt;br /&gt;  echo "`date` java: $sum"&lt;br /&gt;  sleep 5&lt;br /&gt;done | tee fd-java.log&lt;/blockquote&gt;&lt;/pre&gt;&lt;br /&gt;Or a faster alternative:&lt;pre&gt;&lt;blockquote&gt;for ((;;))&lt;br /&gt;do&lt;br /&gt;  for i in `pgrep -lf jdk | awk '{print $1}'`&lt;br /&gt;  do&lt;br /&gt;    s="$s$i,"&lt;br /&gt;  done&lt;br /&gt;  echo "`date` java: `sudo /usr/sbin/lsof -p $s | wc -l`"&lt;br /&gt;  sleep 5&lt;br /&gt;done | tee fd-java.log&lt;/blockquote&gt;&lt;/pre&gt;&lt;br /&gt;What if you need a break down per JVM ?&lt;pre&gt;&lt;blockquote&gt;for ((;;))&lt;br /&gt;do&lt;br /&gt;  echo -n "`date` "&lt;br /&gt;  for i in `pgrep -lf jdk | awk '{print $1}'`&lt;br /&gt;  do&lt;br /&gt;    echo -n "[$i]:"&lt;br /&gt;    sudo /usr/sbin/lsof -p $i | wc -l | tr '\n' ','&lt;br /&gt;    echo -n " "&lt;br /&gt;  done&lt;br /&gt;  echo ""&lt;br /&gt;  sleep 5&lt;br /&gt;done | tee fd-jvms.log&lt;/blockquote&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5882372063253117908?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5882372063253117908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5882372063253117908' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5882372063253117908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5882372063253117908'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/10/scriptfu-counting-opened-file.html' title='Scriptfu counting opened file descriptors'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-639153588589434950</id><published>2011-10-18T16:11:00.000-07:00</published><updated>2011-10-18T19:56:50.999-07:00</updated><title type='text'>How to install the Haskell bundle for TextMate ?</title><content type='html'>&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Download the bundle eg &lt;pre&gt;&lt;blockquote&gt;&lt;a href="https://github.com/textmate/haskell.tmbundle/tarball/master"&gt;https://github.com/textmate/haskell.tmbundle/tarball/master&lt;/a&gt;&lt;/blockquote&gt;&lt;/pre&gt;&lt;li&gt;Uncompress the bundle eg&lt;pre&gt;&lt;blockquote&gt;tar xzf textmate-haskell.tmbundle-5d41f32.tgz&lt;/blockquote&gt;&lt;/pre&gt;&lt;li&gt;rename the directory to Haskell.tmbundle eg &lt;pre&gt;&lt;blockquote&gt;mv textmate-haskell.tmbundle-5d41f32 Haskell.tmbundle&lt;/blockquote&gt;&lt;/pre&gt;&lt;li&gt;&lt;pre&gt;mv Haskell.tmbundle /Library/Application\ Support/TextMate/Bundles/&lt;/pre&gt;&lt;li&gt;Restart TextMate&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-639153588589434950?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/639153588589434950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=639153588589434950' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/639153588589434950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/639153588589434950'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/10/how-to-install-haskell-bundle-in.html' title='How to install the Haskell bundle for TextMate ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-9130686271011573343</id><published>2011-10-18T10:11:00.000-07:00</published><updated>2011-10-18T19:54:57.145-07:00</updated><title type='text'>Cryptarithm: Math - Is = Fun</title><content type='html'>&lt;pre&gt;  MATH&lt;br /&gt;-   IS&lt;br /&gt;------&lt;br /&gt;   FUN&lt;/pre&gt;Given each alphabet is a digit, what are the possible solutions ?&lt;br /&gt;&lt;br /&gt;(Don't scroll down if you want to give it a shot)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Haskell in GHCI&lt;/b&gt;:&lt;pre&gt;[(m,a,t,h,i,s,f,u,n)|m &lt;- [0..9], a &lt;- [0..9], t &lt;- [0..9], h &lt;- [0..9], i &lt;- [0..9], s &lt;- [0..9], f &lt;- [0..9], u &lt;- [0..9], n &lt;- [0..9], (m*1000+a*100+t*10+h) - (i*10+s) == f*100+u*10+n, not (elem m [a,t,h,i,s,f,u,n]), not (elem a [t,h,i,s,f,u,n]), not (elem t [h,i,s,f,u,n]), not (elem h [i,s,f,u,n]), not (elem i [s,f,u,n]), not (elem s [f,u,n]), not (elem f [u,n]), not (u==n)]&lt;/pre&gt;&lt;b&gt;Alternatively, a much faster version (in a main.hs for example):&lt;/b&gt;&lt;pre&gt;module Main where&lt;br /&gt;main :: IO ()&lt;br /&gt;main = putStrLn (show &lt;br /&gt;    [(m,a,t,h,i,s,f,u,n)&lt;br /&gt;    | m &lt;- [0..9],&lt;br /&gt;      a &lt;- remove m [0..9],&lt;br /&gt;      t &lt;- remove' [m,a] [0..9],&lt;br /&gt;      h &lt;- remove' [m,a,t] [0..9],&lt;br /&gt;      i &lt;- remove' [m,a,t,h] [0..9],&lt;br /&gt;      s &lt;- remove' [m,a,t,h,i] [0..9],&lt;br /&gt;      f &lt;- remove' [m,a,t,h,i,s] [0..9],&lt;br /&gt;      u &lt;- remove' [m,a,t,h,i,s,f] [0..9],&lt;br /&gt;      n &lt;- remove' [m,a,t,h,i,s,f,u] [0..9],&lt;br /&gt;      (m*1000+a*100+t*10+h) - (i*10+s) == f*100+u*10+n&lt;br /&gt;    ])&lt;br /&gt;    &lt;br /&gt;-- remove an element once from the list&lt;br /&gt;remove :: (Eq a) =&gt; a -&gt; [a] -&gt; [a]&lt;br /&gt;remove _ [] = []&lt;br /&gt;remove a (x:xs)&lt;br /&gt;    | a == x = xs&lt;br /&gt;    | otherwise = [x] ++ (remove a xs)&lt;br /&gt;    &lt;br /&gt;-- remove each element in the removal list once from the target list&lt;br /&gt;remove' ::  (Eq a) =&gt; [a] -&gt; [a] -&gt; [a]&lt;br /&gt;remove' _ [] = []&lt;br /&gt;remove' [] xs = xs&lt;br /&gt;remove' (a:as) bs = remove' as (remove a bs)&lt;/pre&gt;&lt;b&gt;360 solutions:&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;M,A,T,H,I,S,F,U,N&lt;br /&gt;0,2,3,4,5,6,1,7,8&lt;br /&gt;0,2,3,4,5,8,1,7,6&lt;br /&gt;0,2,3,4,7,6,1,5,8&lt;br /&gt;0,2,3,4,7,8,1,5,6&lt;br /&gt;0,2,3,5,4,6,1,8,9&lt;br /&gt;0,2,3,5,4,9,1,8,6&lt;br /&gt;0,2,3,5,8,6,1,4,9&lt;br /&gt;0,2,3,5,8,9,1,4,6&lt;br /&gt;0,2,3,6,4,7,1,8,9&lt;br /&gt;0,2,3,6,4,9,1,8,7&lt;br /&gt;0,2,3,6,8,7,1,4,9&lt;br /&gt;0,2,3,6,8,9,1,4,7&lt;br /&gt;0,2,3,9,6,4,1,7,5&lt;br /&gt;0,2,3,9,6,5,1,7,4&lt;br /&gt;0,2,3,9,7,4,1,6,5&lt;br /&gt;0,2,3,9,7,5,1,6,4&lt;br /&gt;0,2,4,3,5,6,1,8,7&lt;br /&gt;0,2,4,3,5,7,1,8,6&lt;br /&gt;0,2,4,3,6,5,1,7,8&lt;br /&gt;0,2,4,3,6,8,1,7,5&lt;br /&gt;0,2,4,3,7,5,1,6,8&lt;br /&gt;0,2,4,3,7,8,1,6,5&lt;br /&gt;0,2,4,3,8,6,1,5,7&lt;br /&gt;0,2,4,3,8,7,1,5,6&lt;br /&gt;0,2,4,6,5,7,1,8,9&lt;br /&gt;0,2,4,6,5,9,1,8,7&lt;br /&gt;0,2,4,6,8,7,1,5,9&lt;br /&gt;0,2,4,6,8,9,1,5,7&lt;br /&gt;0,2,5,3,6,4,1,8,9&lt;br /&gt;0,2,5,3,6,9,1,8,4&lt;br /&gt;0,2,5,3,8,4,1,6,9&lt;br /&gt;0,2,5,3,8,9,1,6,4&lt;br /&gt;0,2,5,7,6,3,1,9,4&lt;br /&gt;0,2,5,7,6,4,1,9,3&lt;br /&gt;0,2,5,7,9,3,1,6,4&lt;br /&gt;0,2,5,7,9,4,1,6,3&lt;br /&gt;0,2,5,9,7,3,1,8,6&lt;br /&gt;0,2,5,9,7,6,1,8,3&lt;br /&gt;0,2,5,9,8,3,1,7,6&lt;br /&gt;0,2,5,9,8,6,1,7,3&lt;br /&gt;0,2,6,3,7,4,1,8,9&lt;br /&gt;0,2,6,3,7,9,1,8,4&lt;br /&gt;0,2,6,3,8,4,1,7,9&lt;br /&gt;0,2,6,3,8,9,1,7,4&lt;br /&gt;0,2,6,4,7,5,1,8,9&lt;br /&gt;0,2,6,4,7,9,1,8,5&lt;br /&gt;0,2,6,4,8,5,1,7,9&lt;br /&gt;0,2,6,4,8,9,1,7,5&lt;br /&gt;0,2,6,8,7,3,1,9,5&lt;br /&gt;0,2,6,8,7,5,1,9,3&lt;br /&gt;0,2,6,8,9,3,1,7,5&lt;br /&gt;0,2,6,8,9,5,1,7,3&lt;br /&gt;0,3,1,5,4,7,2,6,8&lt;br /&gt;0,3,1,5,4,8,2,6,7&lt;br /&gt;0,3,1,5,6,7,2,4,8&lt;br /&gt;0,3,1,5,6,8,2,4,7&lt;br /&gt;0,3,1,7,4,8,2,6,9&lt;br /&gt;0,3,1,7,4,9,2,6,8&lt;br /&gt;0,3,1,7,6,8,2,4,9&lt;br /&gt;0,3,1,7,6,9,2,4,8&lt;br /&gt;0,3,4,6,5,7,2,8,9&lt;br /&gt;0,3,4,6,5,9,2,8,7&lt;br /&gt;0,3,4,6,8,7,2,5,9&lt;br /&gt;0,3,4,6,8,9,2,5,7&lt;br /&gt;0,3,4,7,5,1,2,9,6&lt;br /&gt;0,3,4,7,5,6,2,9,1&lt;br /&gt;0,3,4,7,9,1,2,5,6&lt;br /&gt;0,3,4,7,9,6,2,5,1&lt;br /&gt;0,3,4,8,5,1,2,9,7&lt;br /&gt;0,3,4,8,5,7,2,9,1&lt;br /&gt;0,3,4,8,9,1,2,5,7&lt;br /&gt;0,3,4,8,9,7,2,5,1&lt;br /&gt;0,3,5,1,6,4,2,8,7&lt;br /&gt;0,3,5,1,6,7,2,8,4&lt;br /&gt;0,3,5,1,8,4,2,6,7&lt;br /&gt;0,3,5,1,8,7,2,6,4&lt;br /&gt;0,3,5,8,6,1,2,9,7&lt;br /&gt;0,3,5,8,6,7,2,9,1&lt;br /&gt;0,3,5,8,9,1,2,6,7&lt;br /&gt;0,3,5,8,9,7,2,6,1&lt;br /&gt;0,3,6,4,7,5,2,8,9&lt;br /&gt;0,3,6,4,7,9,2,8,5&lt;br /&gt;0,3,6,4,8,5,2,7,9&lt;br /&gt;0,3,6,4,8,9,2,7,5&lt;br /&gt;0,3,6,5,7,1,2,9,4&lt;br /&gt;0,3,6,5,7,4,2,9,1&lt;br /&gt;0,3,6,5,9,1,2,7,4&lt;br /&gt;0,3,6,5,9,4,2,7,1&lt;br /&gt;0,3,7,5,8,1,2,9,4&lt;br /&gt;0,3,7,5,8,4,2,9,1&lt;br /&gt;0,3,7,5,9,1,2,8,4&lt;br /&gt;0,3,7,5,9,4,2,8,1&lt;br /&gt;0,3,7,6,8,1,2,9,5&lt;br /&gt;0,3,7,6,8,5,2,9,1&lt;br /&gt;0,3,7,6,9,1,2,8,5&lt;br /&gt;0,3,7,6,9,5,2,8,1&lt;br /&gt;0,4,1,5,2,6,3,8,9&lt;br /&gt;0,4,1,5,2,9,3,8,6&lt;br /&gt;0,4,1,5,8,6,3,2,9&lt;br /&gt;0,4,1,5,8,9,3,2,6&lt;br /&gt;0,4,1,6,2,7,3,8,9&lt;br /&gt;0,4,1,6,2,9,3,8,7&lt;br /&gt;0,4,1,6,8,7,3,2,9&lt;br /&gt;0,4,1,6,8,9,3,2,7&lt;br /&gt;0,4,1,9,5,2,3,6,7&lt;br /&gt;0,4,1,9,5,7,3,6,2&lt;br /&gt;0,4,1,9,6,2,3,5,7&lt;br /&gt;0,4,1,9,6,7,3,5,2&lt;br /&gt;0,4,2,7,5,8,3,6,9&lt;br /&gt;0,4,2,7,5,9,3,6,8&lt;br /&gt;0,4,2,7,6,8,3,5,9&lt;br /&gt;0,4,2,7,6,9,3,5,8&lt;br /&gt;0,4,2,9,5,1,3,7,8&lt;br /&gt;0,4,2,9,5,8,3,7,1&lt;br /&gt;0,4,2,9,7,1,3,5,8&lt;br /&gt;0,4,2,9,7,8,3,5,1&lt;br /&gt;0,4,5,1,6,2,3,8,9&lt;br /&gt;0,4,5,1,6,9,3,8,2&lt;br /&gt;0,4,5,1,8,2,3,6,9&lt;br /&gt;0,4,5,1,8,9,3,6,2&lt;br /&gt;0,4,5,8,6,1,3,9,7&lt;br /&gt;0,4,5,8,6,7,3,9,1&lt;br /&gt;0,4,5,8,9,1,3,6,7&lt;br /&gt;0,4,5,8,9,7,3,6,1&lt;br /&gt;0,4,6,1,7,2,3,8,9&lt;br /&gt;0,4,6,1,7,9,3,8,2&lt;br /&gt;0,4,6,1,8,2,3,7,9&lt;br /&gt;0,4,6,1,8,9,3,7,2&lt;br /&gt;0,4,7,6,8,1,3,9,5&lt;br /&gt;0,4,7,6,8,5,3,9,1&lt;br /&gt;0,4,7,6,9,1,3,8,5&lt;br /&gt;0,4,7,6,9,5,3,8,1&lt;br /&gt;0,5,1,3,2,6,4,8,7&lt;br /&gt;0,5,1,3,2,7,4,8,6&lt;br /&gt;0,5,1,3,8,6,4,2,7&lt;br /&gt;0,5,1,3,8,7,4,2,6&lt;br /&gt;0,5,1,6,2,7,4,8,9&lt;br /&gt;0,5,1,6,2,9,4,8,7&lt;br /&gt;0,5,1,6,8,7,4,2,9&lt;br /&gt;0,5,1,6,8,9,4,2,7&lt;br /&gt;0,5,1,9,3,2,4,8,7&lt;br /&gt;0,5,1,9,3,7,4,8,2&lt;br /&gt;0,5,1,9,8,2,4,3,7&lt;br /&gt;0,5,1,9,8,7,4,3,2&lt;br /&gt;0,5,2,6,3,7,4,8,9&lt;br /&gt;0,5,2,6,3,9,4,8,7&lt;br /&gt;0,5,2,6,8,7,4,3,9&lt;br /&gt;0,5,2,6,8,9,4,3,7&lt;br /&gt;0,5,2,7,3,1,4,9,6&lt;br /&gt;0,5,2,7,3,6,4,9,1&lt;br /&gt;0,5,2,7,9,1,4,3,6&lt;br /&gt;0,5,2,7,9,6,4,3,1&lt;br /&gt;0,5,2,8,3,1,4,9,7&lt;br /&gt;0,5,2,8,3,7,4,9,1&lt;br /&gt;0,5,2,8,9,1,4,3,7&lt;br /&gt;0,5,2,8,9,7,4,3,1&lt;br /&gt;0,5,3,9,6,1,4,7,8&lt;br /&gt;0,5,3,9,6,8,4,7,1&lt;br /&gt;0,5,3,9,7,1,4,6,8&lt;br /&gt;0,5,3,9,7,8,4,6,1&lt;br /&gt;0,5,6,1,7,2,4,8,9&lt;br /&gt;0,5,6,1,7,9,4,8,2&lt;br /&gt;0,5,6,1,8,2,4,7,9&lt;br /&gt;0,5,6,1,8,9,4,7,2&lt;br /&gt;0,5,6,2,7,3,4,8,9&lt;br /&gt;0,5,6,2,7,9,4,8,3&lt;br /&gt;0,5,6,2,8,3,4,7,9&lt;br /&gt;0,5,6,2,8,9,4,7,3&lt;br /&gt;0,5,6,3,7,1,4,9,2&lt;br /&gt;0,5,6,3,7,2,4,9,1&lt;br /&gt;0,5,6,3,9,1,4,7,2&lt;br /&gt;0,5,6,3,9,2,4,7,1&lt;br /&gt;0,5,7,3,8,1,4,9,2&lt;br /&gt;0,5,7,3,8,2,4,9,1&lt;br /&gt;0,5,7,3,9,1,4,8,2&lt;br /&gt;0,5,7,3,9,2,4,8,1&lt;br /&gt;0,6,1,2,3,4,5,7,8&lt;br /&gt;0,6,1,2,3,8,5,7,4&lt;br /&gt;0,6,1,2,7,4,5,3,8&lt;br /&gt;0,6,1,2,7,8,5,3,4&lt;br /&gt;0,6,1,3,2,4,5,8,9&lt;br /&gt;0,6,1,3,2,9,5,8,4&lt;br /&gt;0,6,1,3,8,4,5,2,9&lt;br /&gt;0,6,1,3,8,9,5,2,4&lt;br /&gt;0,6,1,7,2,3,5,9,4&lt;br /&gt;0,6,1,7,2,4,5,9,3&lt;br /&gt;0,6,1,7,9,3,5,2,4&lt;br /&gt;0,6,1,7,9,4,5,2,3&lt;br /&gt;0,6,1,9,3,2,5,8,7&lt;br /&gt;0,6,1,9,3,7,5,8,2&lt;br /&gt;0,6,1,9,8,2,5,3,7&lt;br /&gt;0,6,1,9,8,7,5,3,2&lt;br /&gt;0,6,2,1,3,4,5,8,7&lt;br /&gt;0,6,2,1,3,7,5,8,4&lt;br /&gt;0,6,2,1,4,3,5,7,8&lt;br /&gt;0,6,2,1,4,8,5,7,3&lt;br /&gt;0,6,2,1,7,3,5,4,8&lt;br /&gt;0,6,2,1,7,8,5,4,3&lt;br /&gt;0,6,2,1,8,4,5,3,7&lt;br /&gt;0,6,2,1,8,7,5,3,4&lt;br /&gt;0,6,2,8,3,1,5,9,7&lt;br /&gt;0,6,2,8,3,7,5,9,1&lt;br /&gt;0,6,2,8,9,1,5,3,7&lt;br /&gt;0,6,2,8,9,7,5,3,1&lt;br /&gt;0,6,3,1,4,2,5,8,9&lt;br /&gt;0,6,3,1,4,9,5,8,2&lt;br /&gt;0,6,3,1,8,2,5,4,9&lt;br /&gt;0,6,3,1,8,9,5,4,2&lt;br /&gt;0,6,3,8,4,1,5,9,7&lt;br /&gt;0,6,3,8,4,7,5,9,1&lt;br /&gt;0,6,3,8,9,1,5,4,7&lt;br /&gt;0,6,3,8,9,7,5,4,1&lt;br /&gt;0,6,7,3,8,1,5,9,2&lt;br /&gt;0,6,7,3,8,2,5,9,1&lt;br /&gt;0,6,7,3,9,1,5,8,2&lt;br /&gt;0,6,7,3,9,2,5,8,1&lt;br /&gt;0,6,7,4,8,1,5,9,3&lt;br /&gt;0,6,7,4,8,3,5,9,1&lt;br /&gt;0,6,7,4,9,1,5,8,3&lt;br /&gt;0,6,7,4,9,3,5,8,1&lt;br /&gt;0,7,1,3,2,4,6,8,9&lt;br /&gt;0,7,1,3,2,9,6,8,4&lt;br /&gt;0,7,1,3,8,4,6,2,9&lt;br /&gt;0,7,1,3,8,9,6,2,4&lt;br /&gt;0,7,1,4,2,5,6,8,9&lt;br /&gt;0,7,1,4,2,9,6,8,5&lt;br /&gt;0,7,1,4,8,5,6,2,9&lt;br /&gt;0,7,1,4,8,9,6,2,5&lt;br /&gt;0,7,1,8,2,3,6,9,5&lt;br /&gt;0,7,1,8,2,5,6,9,3&lt;br /&gt;0,7,1,8,9,3,6,2,5&lt;br /&gt;0,7,1,8,9,5,6,2,3&lt;br /&gt;0,7,1,9,3,4,6,8,5&lt;br /&gt;0,7,1,9,3,5,6,8,4&lt;br /&gt;0,7,1,9,8,4,6,3,5&lt;br /&gt;0,7,1,9,8,5,6,3,4&lt;br /&gt;0,7,2,4,3,5,6,8,9&lt;br /&gt;0,7,2,4,3,9,6,8,5&lt;br /&gt;0,7,2,4,8,5,6,3,9&lt;br /&gt;0,7,2,4,8,9,6,3,5&lt;br /&gt;0,7,2,5,3,1,6,9,4&lt;br /&gt;0,7,2,5,3,4,6,9,1&lt;br /&gt;0,7,2,5,9,1,6,3,4&lt;br /&gt;0,7,2,5,9,4,6,3,1&lt;br /&gt;0,7,3,1,4,2,6,8,9&lt;br /&gt;0,7,3,1,4,9,6,8,2&lt;br /&gt;0,7,3,1,8,2,6,4,9&lt;br /&gt;0,7,3,1,8,9,6,4,2&lt;br /&gt;0,7,4,1,5,2,6,8,9&lt;br /&gt;0,7,4,1,5,9,6,8,2&lt;br /&gt;0,7,4,1,8,2,6,5,9&lt;br /&gt;0,7,4,1,8,9,6,5,2&lt;br /&gt;0,7,4,2,5,3,6,8,9&lt;br /&gt;0,7,4,2,5,9,6,8,3&lt;br /&gt;0,7,4,2,8,3,6,5,9&lt;br /&gt;0,7,4,2,8,9,6,5,3&lt;br /&gt;0,7,4,3,5,1,6,9,2&lt;br /&gt;0,7,4,3,5,2,6,9,1&lt;br /&gt;0,7,4,3,9,1,6,5,2&lt;br /&gt;0,7,4,3,9,2,6,5,1&lt;br /&gt;0,8,1,2,4,3,7,6,9&lt;br /&gt;0,8,1,2,4,9,7,6,3&lt;br /&gt;0,8,1,2,6,3,7,4,9&lt;br /&gt;0,8,1,2,6,9,7,4,3&lt;br /&gt;0,8,2,3,5,4,7,6,9&lt;br /&gt;0,8,2,3,5,9,7,6,4&lt;br /&gt;0,8,2,3,6,4,7,5,9&lt;br /&gt;0,8,2,3,6,9,7,5,4&lt;br /&gt;0,8,2,5,3,1,7,9,4&lt;br /&gt;0,8,2,5,3,4,7,9,1&lt;br /&gt;0,8,2,5,9,1,7,3,4&lt;br /&gt;0,8,2,5,9,4,7,3,1&lt;br /&gt;0,8,2,6,3,1,7,9,5&lt;br /&gt;0,8,2,6,3,5,7,9,1&lt;br /&gt;0,8,2,6,9,1,7,3,5&lt;br /&gt;0,8,2,6,9,5,7,3,1&lt;br /&gt;0,8,3,6,4,1,7,9,5&lt;br /&gt;0,8,3,6,4,5,7,9,1&lt;br /&gt;0,8,3,6,9,1,7,4,5&lt;br /&gt;0,8,3,6,9,5,7,4,1&lt;br /&gt;0,8,4,3,5,1,7,9,2&lt;br /&gt;0,8,4,3,5,2,7,9,1&lt;br /&gt;0,8,4,3,9,1,7,5,2&lt;br /&gt;0,8,4,3,9,2,7,5,1&lt;br /&gt;0,8,5,3,6,1,7,9,2&lt;br /&gt;0,8,5,3,6,2,7,9,1&lt;br /&gt;0,8,5,3,9,1,7,6,2&lt;br /&gt;0,8,5,3,9,2,7,6,1&lt;br /&gt;0,8,5,4,6,1,7,9,3&lt;br /&gt;0,8,5,4,6,3,7,9,1&lt;br /&gt;0,8,5,4,9,1,7,6,3&lt;br /&gt;0,8,5,4,9,3,7,6,1&lt;br /&gt;0,9,1,2,4,5,8,6,7&lt;br /&gt;0,9,1,2,4,7,8,6,5&lt;br /&gt;0,9,1,2,6,5,8,4,7&lt;br /&gt;0,9,1,2,6,7,8,4,5&lt;br /&gt;0,9,1,5,4,2,8,7,3&lt;br /&gt;0,9,1,5,4,3,8,7,2&lt;br /&gt;0,9,1,5,7,2,8,4,3&lt;br /&gt;0,9,1,5,7,3,8,4,2&lt;br /&gt;0,9,1,7,5,3,8,6,4&lt;br /&gt;0,9,1,7,5,4,8,6,3&lt;br /&gt;0,9,1,7,6,3,8,5,4&lt;br /&gt;0,9,1,7,6,4,8,5,3&lt;br /&gt;0,9,2,1,4,5,8,7,6&lt;br /&gt;0,9,2,1,4,6,8,7,5&lt;br /&gt;0,9,2,1,5,4,8,6,7&lt;br /&gt;0,9,2,1,5,7,8,6,4&lt;br /&gt;0,9,2,1,6,4,8,5,7&lt;br /&gt;0,9,2,1,6,7,8,5,4&lt;br /&gt;0,9,2,1,7,5,8,4,6&lt;br /&gt;0,9,2,1,7,6,8,4,5&lt;br /&gt;0,9,2,4,5,1,8,7,3&lt;br /&gt;0,9,2,4,5,3,8,7,1&lt;br /&gt;0,9,2,4,7,1,8,5,3&lt;br /&gt;0,9,2,4,7,3,8,5,1&lt;br /&gt;0,9,3,5,6,1,8,7,4&lt;br /&gt;0,9,3,5,6,4,8,7,1&lt;br /&gt;0,9,3,5,7,1,8,6,4&lt;br /&gt;0,9,3,5,7,4,8,6,1&lt;br /&gt;1,0,2,3,4,5,9,7,8&lt;br /&gt;1,0,2,3,4,8,9,7,5&lt;br /&gt;1,0,2,3,7,5,9,4,8&lt;br /&gt;1,0,2,3,7,8,9,4,5&lt;br /&gt;1,0,3,2,4,5,9,8,7&lt;br /&gt;1,0,3,2,4,7,9,8,5&lt;br /&gt;1,0,3,2,5,4,9,7,8&lt;br /&gt;1,0,3,2,5,8,9,7,4&lt;br /&gt;1,0,3,2,7,4,9,5,8&lt;br /&gt;1,0,3,2,7,8,9,5,4&lt;br /&gt;1,0,3,2,8,5,9,4,7&lt;br /&gt;1,0,3,2,8,7,9,4,5&lt;br /&gt;1,0,3,4,5,6,9,7,8&lt;br /&gt;1,0,3,4,5,8,9,7,6&lt;br /&gt;1,0,3,4,7,6,9,5,8&lt;br /&gt;1,0,3,4,7,8,9,5,6&lt;br /&gt;1,0,3,6,5,2,9,8,4&lt;br /&gt;1,0,3,6,5,4,9,8,2&lt;br /&gt;1,0,3,6,8,2,9,5,4&lt;br /&gt;1,0,3,6,8,4,9,5,2&lt;br /&gt;1,0,4,3,5,6,9,8,7&lt;br /&gt;1,0,4,3,5,7,9,8,6&lt;br /&gt;1,0,4,3,6,5,9,7,8&lt;br /&gt;1,0,4,3,6,8,9,7,5&lt;br /&gt;1,0,4,3,7,5,9,6,8&lt;br /&gt;1,0,4,3,7,8,9,6,5&lt;br /&gt;1,0,4,3,8,6,9,5,7&lt;br /&gt;1,0,4,3,8,7,9,5,6&lt;br /&gt;1,0,4,5,6,2,9,8,3&lt;br /&gt;1,0,4,5,6,3,9,8,2&lt;br /&gt;1,0,4,5,8,2,9,6,3&lt;br /&gt;1,0,4,5,8,3,9,6,2&lt;br /&gt;1,0,4,7,6,2,9,8,5&lt;br /&gt;1,0,4,7,6,5,9,8,2&lt;br /&gt;1,0,4,7,8,2,9,6,5&lt;br /&gt;1,0,4,7,8,5,9,6,2&lt;br /&gt;1,0,5,6,7,2,9,8,4&lt;br /&gt;1,0,5,6,7,4,9,8,2&lt;br /&gt;1,0,5,6,8,2,9,7,4&lt;br /&gt;1,0,5,6,8,4,9,7,2&lt;/pre&gt;... in response to another 6th grader's home work assignment :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-9130686271011573343?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/9130686271011573343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=9130686271011573343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/9130686271011573343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/9130686271011573343'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/10/cryptarithm-math-is-fun.html' title='Cryptarithm: Math - Is = Fun'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-6901183338327417436</id><published>2011-10-18T09:55:00.000-07:00</published><updated>2011-10-18T19:55:10.676-07:00</updated><title type='text'>Cryptarithm: Take + Home = Exam</title><content type='html'>&lt;pre&gt;  TAKE&lt;br /&gt;+ HOME&lt;br /&gt;------&lt;br /&gt;  EXAM&lt;/pre&gt;Given each alphabet is a digit, what are the possible solutions ?&lt;br /&gt;&lt;br /&gt;(Don't scroll down if you want to give it a shot)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Haskell in GHCI:&lt;/b&gt;&lt;pre&gt;[(t,a,k,e,h,o,m,x)|t &lt;- [0..9], a &lt;- [0..9], k &lt;- [0..9], e &lt;- [0..9], h &lt;- [0..9], o &lt;- [0..9], m &lt;- [0..9], x &lt;- [0..9], (t*1000+a*100+k*10+e) + (h*1000+o*100+m*10+e) == e*1000+x*100+a*10+m, not (elem t [a,k,e,h,o,m,x]), not (elem a [k,e,h,o,m,x]), not (elem k [e,h,o,m,x]), not (elem e [h,o,m,x]), not (elem h [o,m,x]), not (elem o [m,x]), not (m==x)]&lt;/pre&gt;&lt;b&gt;Alternatively, a much faster version (in a main.hs for example):&lt;/b&gt;&lt;pre&gt;module Main where&lt;br /&gt;main :: IO ()&lt;br /&gt;main = putStrLn (show &lt;br /&gt;    [ (t,a,k,e,h,o,m,x)&lt;br /&gt;    | t &lt;- [0..9],&lt;br /&gt;      a &lt;- remove t [0..9],&lt;br /&gt;      k &lt;- remove' [t,a] [0..9],&lt;br /&gt;      e &lt;- remove' [t,a,k] [0..9],&lt;br /&gt;      h &lt;- remove' [t,a,k,e] [0..9],&lt;br /&gt;      o &lt;- remove' [t,a,k,e,h] [0..9],&lt;br /&gt;      m &lt;- remove' [t,a,k,e,h,o] [0..9],&lt;br /&gt;      x &lt;- remove' [t,a,k,e,h,o,m] [0..9],&lt;br /&gt;      (t*1000+a*100+k*10+e) + (h*1000+o*100+m*10+e) == e*1000+x*100+a*10+m&lt;br /&gt;    ])&lt;br /&gt;    &lt;br /&gt;-- remove an element once from the list&lt;br /&gt;remove :: (Eq a) =&gt; a -&gt; [a] -&gt; [a]&lt;br /&gt;remove _ [] = []&lt;br /&gt;remove a (x:xs)&lt;br /&gt;    | a == x = xs&lt;br /&gt;    | otherwise = [x] ++ (remove a xs)&lt;br /&gt;    &lt;br /&gt;-- remove each element in the removal list once from the target list&lt;br /&gt;remove' ::  (Eq a) =&gt; [a] -&gt; [a] -&gt; [a]&lt;br /&gt;remove' _ [] = []&lt;br /&gt;remove' [] xs = xs&lt;br /&gt;remove' (a:as) bs = remove' as (remove a bs)&lt;/pre&gt;&lt;b&gt;124 possible solutions:&lt;/b&gt;&lt;pre&gt;T,A,K,E,H,O,M,X&lt;br /&gt;0,4,1,6,5,9,2,3&lt;br /&gt;0,5,7,4,3,6,8,2&lt;br /&gt;0,5,9,3,2,8,6,4&lt;br /&gt;0,7,1,3,2,8,6,5&lt;br /&gt;0,7,3,2,1,8,4,5&lt;br /&gt;0,7,3,2,1,9,4,6&lt;br /&gt;0,9,1,4,3,6,8,5&lt;br /&gt;0,9,1,4,3,7,8,6&lt;br /&gt;0,9,2,8,7,4,6,3&lt;br /&gt;0,9,2,8,7,5,6,4&lt;br /&gt;0,9,5,2,1,7,4,6&lt;br /&gt;0,9,5,2,1,8,4,7&lt;br /&gt;1,0,2,4,3,5,8,6&lt;br /&gt;1,0,2,4,3,6,8,7&lt;br /&gt;1,0,3,8,7,4,6,5&lt;br /&gt;1,0,4,3,2,7,6,8&lt;br /&gt;1,0,4,3,2,8,6,9&lt;br /&gt;1,0,5,7,6,2,4,3&lt;br /&gt;1,0,5,7,6,8,4,9&lt;br /&gt;1,0,7,6,5,3,2,4&lt;br /&gt;1,0,7,6,5,8,2,9&lt;br /&gt;1,2,5,8,7,0,6,3&lt;br /&gt;1,3,0,6,5,4,2,7&lt;br /&gt;1,3,2,5,4,6,0,9&lt;br /&gt;1,3,4,9,7,6,8,0&lt;br /&gt;1,3,5,4,2,6,8,0&lt;br /&gt;1,3,8,7,5,6,4,0&lt;br /&gt;1,3,8,7,6,5,4,9&lt;br /&gt;1,4,8,3,2,0,6,5&lt;br /&gt;1,5,0,7,6,3,4,8&lt;br /&gt;1,5,6,9,7,4,8,0&lt;br /&gt;1,5,7,4,3,0,8,6&lt;br /&gt;1,7,3,2,0,8,4,5&lt;br /&gt;1,7,3,2,0,9,4,6&lt;br /&gt;1,7,6,5,4,2,0,9&lt;br /&gt;1,7,9,4,2,5,8,3&lt;br /&gt;1,8,3,7,5,2,4,0&lt;br /&gt;1,8,5,6,4,9,2,7&lt;br /&gt;1,8,7,5,3,4,0,2&lt;br /&gt;1,8,7,5,3,6,0,4&lt;br /&gt;1,9,5,2,0,7,4,6&lt;br /&gt;1,9,5,2,0,8,4,7&lt;br /&gt;1,9,8,5,3,7,0,6&lt;br /&gt;2,0,1,9,7,3,8,4&lt;br /&gt;2,0,1,9,7,4,8,5&lt;br /&gt;2,0,1,9,7,5,8,6&lt;br /&gt;2,0,4,3,1,7,6,8&lt;br /&gt;2,0,4,3,1,8,6,9&lt;br /&gt;2,3,4,9,6,7,8,1&lt;br /&gt;2,3,4,9,7,1,8,5&lt;br /&gt;2,3,5,4,1,6,8,0&lt;br /&gt;2,4,5,9,7,1,8,6&lt;br /&gt;2,4,8,3,1,0,6,5&lt;br /&gt;2,5,9,3,0,8,6,4&lt;br /&gt;2,6,1,7,5,3,4,9&lt;br /&gt;2,7,0,8,5,4,6,1&lt;br /&gt;2,7,1,3,0,8,6,5&lt;br /&gt;2,7,6,5,3,1,0,8&lt;br /&gt;2,7,9,4,1,5,8,3&lt;br /&gt;2,8,3,7,5,1,4,9&lt;br /&gt;2,8,7,5,3,1,0,9&lt;br /&gt;3,0,1,9,6,4,8,5&lt;br /&gt;3,0,2,4,1,5,8,6&lt;br /&gt;3,0,2,4,1,6,8,7&lt;br /&gt;3,1,2,9,6,5,8,7&lt;br /&gt;3,1,4,8,5,0,6,2&lt;br /&gt;3,1,4,8,5,7,6,9&lt;br /&gt;3,2,5,8,4,7,6,0&lt;br /&gt;3,4,5,9,6,2,8,7&lt;br /&gt;3,5,7,4,0,6,8,2&lt;br /&gt;3,5,7,4,1,0,8,6&lt;br /&gt;3,6,7,9,5,4,8,1&lt;br /&gt;3,7,0,8,4,5,6,2&lt;br /&gt;3,7,0,8,5,2,6,9&lt;br /&gt;3,7,6,5,2,1,0,8&lt;br /&gt;3,8,7,5,1,4,0,2&lt;br /&gt;3,8,7,5,1,6,0,4&lt;br /&gt;3,8,7,5,2,1,0,9&lt;br /&gt;3,9,1,4,0,6,8,5&lt;br /&gt;3,9,1,4,0,7,8,6&lt;br /&gt;3,9,2,8,4,1,6,0&lt;br /&gt;3,9,8,5,1,7,0,6&lt;br /&gt;4,0,1,9,5,2,8,3&lt;br /&gt;4,0,1,9,5,6,8,7&lt;br /&gt;4,2,5,8,3,7,6,0&lt;br /&gt;4,3,2,5,1,6,0,9&lt;br /&gt;4,7,0,8,3,5,6,2&lt;br /&gt;4,7,6,5,1,2,0,9&lt;br /&gt;4,8,5,6,1,9,2,7&lt;br /&gt;4,9,2,8,3,1,6,0&lt;br /&gt;5,0,1,9,4,2,8,3&lt;br /&gt;5,0,1,9,4,6,8,7&lt;br /&gt;5,0,7,6,1,3,2,4&lt;br /&gt;5,0,7,6,1,8,2,9&lt;br /&gt;5,1,4,8,3,0,6,2&lt;br /&gt;5,1,4,8,3,7,6,9&lt;br /&gt;5,3,0,6,1,4,2,7&lt;br /&gt;5,3,8,7,1,6,4,0&lt;br /&gt;5,4,1,6,0,9,2,3&lt;br /&gt;5,6,1,7,2,3,4,9&lt;br /&gt;5,6,7,9,3,4,8,1&lt;br /&gt;5,7,0,8,2,4,6,1&lt;br /&gt;5,7,0,8,3,2,6,9&lt;br /&gt;5,8,3,7,1,2,4,0&lt;br /&gt;5,8,3,7,2,1,4,9&lt;br /&gt;6,0,1,9,3,4,8,5&lt;br /&gt;6,0,5,7,1,2,4,3&lt;br /&gt;6,0,5,7,1,8,4,9&lt;br /&gt;6,1,2,9,3,5,8,7&lt;br /&gt;6,3,4,9,2,7,8,1&lt;br /&gt;6,3,8,7,1,5,4,9&lt;br /&gt;6,4,5,9,3,2,8,7&lt;br /&gt;6,5,0,7,1,3,4,8&lt;br /&gt;7,0,1,9,2,3,8,4&lt;br /&gt;7,0,1,9,2,4,8,5&lt;br /&gt;7,0,1,9,2,5,8,6&lt;br /&gt;7,0,3,8,1,4,6,5&lt;br /&gt;7,2,5,8,1,0,6,3&lt;br /&gt;7,3,4,9,1,6,8,0&lt;br /&gt;7,3,4,9,2,1,8,5&lt;br /&gt;7,4,5,9,2,1,8,6&lt;br /&gt;7,5,6,9,1,4,8,0&lt;br /&gt;7,9,2,8,0,4,6,3&lt;br /&gt;7,9,2,8,0,5,6,4&lt;/pre&gt;... in response to a 6th grader's home work assignment :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-6901183338327417436?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/6901183338327417436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=6901183338327417436' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/6901183338327417436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/6901183338327417436'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/10/cryptarithm-take-home-exam.html' title='Cryptarithm: Take + Home = Exam'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8244252585756026213</id><published>2011-10-06T22:41:00.000-07:00</published><updated>2011-10-18T19:51:49.907-07:00</updated><title type='text'>List Comprehension in Haskell</title><content type='html'>To use Haskell to find a right angle triangle that has:&lt;ul&gt;&lt;li&gt;all three sides as integers&lt;br /&gt;&lt;li&gt;each side less than or equal to 10&lt;br /&gt;&lt;li&gt;a perimeter of 24&lt;br /&gt;&lt;/ul&gt;In &lt;a href="http://hackage.haskell.org/platform/mac.html"&gt;ghci&lt;/a&gt;, type:&lt;blockquote&gt;&lt;pre&gt;[(a,b,c) | c &lt;- [1..10], b &lt;- [1..c], a &lt;- [1..b], a+b+c == 24, a^2+b^2 == c^2]&lt;/pre&gt;&lt;/blockquote&gt;Output:&lt;blockquote&gt;&lt;pre&gt;[(6,8,10)]&lt;/pre&gt;&lt;/blockquote&gt;Pretty amazing :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8244252585756026213?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8244252585756026213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8244252585756026213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8244252585756026213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8244252585756026213'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/10/list-comprehension-in-haskell.html' title='List Comprehension in Haskell'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1252527625289770621</id><published>2011-06-09T15:55:00.001-07:00</published><updated>2011-06-09T15:57:23.013-07:00</updated><title type='text'>How to combine multiple PDF files into one in Mac OS X ?</title><content type='html'>&lt;pre&gt;&lt;br /&gt;python '/System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py' -o 'output.pdf' *.pdf&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/6715087-1252527625289770621?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1252527625289770621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1252527625289770621' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1252527625289770621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1252527625289770621'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2011/06/how-to-combine-multiple-pdf-files-into.html' title='How to combine multiple PDF files into one in Mac OS X ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7392237144353561312</id><published>2010-09-13T00:03:00.000-07:00</published><updated>2010-09-13T00:14:46.092-07:00</updated><title type='text'>How to recover /home from Snow Leopard ?</title><content type='html'>&lt;pre&gt;Rename the following line in /etc/auto_master :&lt;br /&gt;&lt;br /&gt;  /home auto_home -nobrowse&lt;br /&gt;&lt;br /&gt;To:&lt;br /&gt;&lt;br /&gt;  /home_auto auto_home -nobrowse&lt;br /&gt;&lt;br /&gt;&lt;a href="http://expressionengine.com/archived_forums/viewthread/74357/"&gt;More details&lt;/a&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/6715087-7392237144353561312?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7392237144353561312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7392237144353561312' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7392237144353561312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7392237144353561312'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2010/09/how-to-recover-home-from-snow-leopard.html' title='How to recover /home from Snow Leopard ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4849667394923196046</id><published>2010-08-28T20:50:00.000-07:00</published><updated>2010-08-28T21:54:14.926-07:00</updated><title type='text'>Using int or long as bit array</title><content type='html'>Ever consider making use of a primitive int or long as a bit array in Java ?  An int, for example, would provide a capacity of 32 bits.  But how would we go about setting and testing the nth bit efficiently ?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Possible solutions:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;(Don't peek if you want to give it a try!)&lt;blockquote&gt;&lt;pre&gt;    int setBitOn(int in, int pos) { return in | 1 &lt;&lt; pos; }&lt;br /&gt;    int setBitOff(int in, int pos) { return in &amp; (-1 ^ (1 &lt;&lt; pos)); }&lt;br /&gt;    boolean isBitOn(int in, int pos) { return (in &amp; (1 &lt;&lt; pos)) != 0; }&lt;br /&gt;    boolean isBitOff(int in, int pos) { return (in &amp; (1 &lt;&lt; pos)) == 0; }&lt;/pre&gt;&lt;/blockquote&gt;Similarly for long,&lt;blockquote&gt;&lt;pre&gt;    long setBitOn(long in, int pos) { return in | 1L &lt;&lt; pos; }&lt;br /&gt;    long setBitOff(long in, int pos) { return in &amp; (-1L ^ (1L &lt;&lt; pos)); }&lt;br /&gt;    boolean isBitOn(long in, int pos) { return (in &amp; (1L &lt;&lt; pos)) != 0; }&lt;br /&gt;    boolean isBitOff(long in, int pos) { return (in &amp; (1L &lt;&lt; pos)) == 0; }&lt;/pre&gt;&lt;/blockquote&gt;Any faster, better or simpler way to do this ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4849667394923196046?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4849667394923196046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4849667394923196046' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4849667394923196046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4849667394923196046'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2010/08/using-int-or-long-as-bit-array.html' title='Using int or long as bit array'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7769029139474577283</id><published>2010-03-08T01:51:00.000-08:00</published><updated>2010-03-08T02:01:29.011-08:00</updated><title type='text'>File Diff %</title><content type='html'>Given two text files v1.txt and v2.txt, how can we easily tell the percentage of total changes (including lines added, changed, and deleted) from v1.txt to v2.txt ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-7769029139474577283?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7769029139474577283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7769029139474577283' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7769029139474577283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7769029139474577283'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2010/03/file-diff.html' title='File Diff %'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-3370968774118681959</id><published>2010-03-07T20:38:00.000-08:00</published><updated>2010-03-07T20:48:02.072-08:00</updated><title type='text'>Additional Puzzle</title><content type='html'>In this little piece of addition, every digit from 0-9 is uniquely represented by a letter of the alphabet.  It may be assumed that T is not zero.  Can you work out the values of the various letters ?&lt;br /&gt;&lt;pre&gt;    TWENTY&lt;br /&gt;    TWENTY&lt;br /&gt;+   THIRTY&lt;br /&gt;----------&lt;br /&gt;   SEVENTY&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/6715087-3370968774118681959?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/3370968774118681959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=3370968774118681959' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3370968774118681959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3370968774118681959'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2010/03/additional-puzzle.html' title='Additional Puzzle'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-861389518548705697</id><published>2010-02-02T16:35:00.000-08:00</published><updated>2010-02-02T16:36:25.705-08:00</updated><title type='text'>What is the next line ?</title><content type='html'>&lt;pre&gt;3 4 1 2 2&lt;br /&gt;4 5 2 0 0&lt;br /&gt;5 6 3 0 0&lt;br /&gt;6 7 4 2 8&lt;br /&gt;7 8 5 6 3 0&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-861389518548705697?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/861389518548705697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=861389518548705697' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/861389518548705697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/861389518548705697'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2010/02/what-is-next-line.html' title='What is the next line ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5516135818010480825</id><published>2009-11-03T09:40:00.000-08:00</published><updated>2009-11-03T09:45:44.199-08:00</updated><title type='text'>SHA-1 and MD5: Mac vs Java</title><content type='html'>&lt;pre&gt;echo -n "" | openssl dgst -sha1&lt;br /&gt;=&gt; da39a3ee5e6b4b0d3255bfef95601890afd80709&lt;br /&gt;&lt;br /&gt;echo -n "" | md5&lt;br /&gt;=&gt; d41d8cd98f00b204e9800998ecf8427e&lt;br /&gt;&lt;br /&gt;public class FooCrypt {&lt;br /&gt;    public static void main(String[] args) throws Exception {&lt;br /&gt;        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");&lt;br /&gt;        System.out.println("sha-1: " + bytesToHex(sha1.digest("".getBytes("UTF-8"))));&lt;br /&gt;        MessageDigest md5 = MessageDigest.getInstance("MD5");&lt;br /&gt;        System.out.println("md5: " + bytesToHex(md5.digest("".getBytes("UTF-8"))));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static String bytesToHex(byte[] bs) {&lt;br /&gt;        StringBuilder ret = new StringBuilder(bs.length);&lt;br /&gt;        for (int i = 0; i &lt; bs.length; i++) {&lt;br /&gt;            String hex = Integer.toHexString(0x0100 + (bs[i] &amp; 0x00FF)).substring(1);&lt;br /&gt;            ret.append((hex.length() &lt; 2 ? "0" : "")).append(hex);&lt;br /&gt;        }&lt;br /&gt;        return ret.toString();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;=&gt; &lt;br /&gt;sha-1: da39a3ee5e6b4b0d3255bfef95601890afd80709&lt;br /&gt;md5: d41d8cd98f00b204e9800998ecf8427e&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5516135818010480825?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5516135818010480825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5516135818010480825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5516135818010480825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5516135818010480825'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2009/11/sha-1-and-md5-mac-vs-java.html' title='SHA-1 and MD5: Mac vs Java'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8293954121015940159</id><published>2009-10-26T18:15:00.000-07:00</published><updated>2009-10-26T18:16:58.478-07:00</updated><title type='text'>What comes next ?</title><content type='html'>3&lt;br /&gt;1 3&lt;br /&gt;1 1 1 3&lt;br /&gt;3 1 1 3&lt;br /&gt;1 3 2 1 1 3&lt;br /&gt;1 1 1 3 1 2 2 1 1 3&lt;br /&gt;3 1 1 3 1 1 2 2 2 1 1 3&lt;br /&gt;1 3 2 1 1 3 2 1 3 2 2 1 1 3&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8293954121015940159?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8293954121015940159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8293954121015940159' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8293954121015940159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8293954121015940159'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2009/10/what-comes-next.html' title='What comes next ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8866521705036608591</id><published>2009-10-25T16:56:00.000-07:00</published><updated>2009-11-01T01:00:03.668-08:00</updated><title type='text'>Experimenting with Oracle DBMS_LOCK</title><content type='html'>First, grant privilege to play with it.  For example,&lt;pre&gt;&lt;blockquote&gt;Login as user SYS with SYSDBA role, then&lt;br /&gt;&lt;br /&gt;  grant all on dbms_lock to public;&lt;/blockquote&gt;&lt;/pre&gt;How to try it out in SQL Developer ?&lt;pre&gt;&lt;blockquote&gt;set serveroutput on;&lt;br /&gt;&lt;br /&gt;declare&lt;br /&gt;  v_result integer;&lt;br /&gt;begin&lt;br /&gt;  v_result := DBMS_LOCK.REQUEST(123, 6, 0, true);&lt;br /&gt;  &lt;br /&gt;  dbms_output.put_line(&lt;br /&gt;           case &lt;br /&gt;              when v_result=0 then 'Success'&lt;br /&gt;              when v_result=1 then 'Timeout'&lt;br /&gt;              when v_result=2 then 'Deadlock'&lt;br /&gt;              when v_result=3 then 'Parameter Error'&lt;br /&gt;              when v_result=4 then 'Already owned'&lt;br /&gt;              when v_result=5 then 'Illegal Lock Handle'&lt;br /&gt;           end);&lt;br /&gt;end;&lt;br /&gt;&lt;/blockquote&gt;&lt;/pre&gt;How to do it in JDBC ?&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;  Connection conn = ...&lt;br /&gt;  CallableStatement stmt = conn.prepareCall("{call ? := DBMS_LOCK.REQUEST(?, 6, 0, true)}");&lt;br /&gt;  stmt.registerOutParameter(1, Types.INTEGER);&lt;br /&gt;  stmt.setBigDecimal(2, new BigDecimal(123));&lt;br /&gt;  stmt.execute();&lt;br /&gt;  int result = stmt.getInt(1);&lt;br /&gt;  System.out.println("result: " + result);&lt;/blockquote&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8866521705036608591?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8866521705036608591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8866521705036608591' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8866521705036608591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8866521705036608591'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2009/10/oracle-dbmslock-experiments.html' title='Experimenting with Oracle DBMS_LOCK'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-867488047772701207</id><published>2009-09-07T18:10:00.000-07:00</published><updated>2009-09-07T18:38:09.916-07:00</updated><title type='text'>S3/SimpleDB Limitations</title><content type='html'>&lt;a href="http://docs.amazonwebservices.com/AmazonS3/latest/BucketRestrictions.html"&gt;&lt;br /&gt;S3 Limits&lt;/a&gt; - max 100 buckets per account, unlimited number of objects per bucket with &lt;a href="http://docs.amazonwebservices.com/AmazonS3/latest/UsingObjects.html"&gt;object size &lt; 5GB&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/SDBLimits.html"&gt;SimpleDB Limits&lt;/a&gt; - max 10 GB per domain, max 100 domains per account, max 1KB attribute value, max 256 attributes per item&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-867488047772701207?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/867488047772701207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=867488047772701207' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/867488047772701207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/867488047772701207'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2009/09/aws-limitations.html' title='S3/SimpleDB Limitations'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4905154343612005849</id><published>2009-04-25T10:54:00.000-07:00</published><updated>2009-05-10T10:14:33.056-07:00</updated><title type='text'>Covariant Enum Idiom</title><content type='html'>Say we want to have a Java Enum that can return different types from the same method by different constants, how could we go about writing it ?  How about something like:&lt;blockquote&gt;&lt;pre&gt;/**&lt;br /&gt; * An enum that can polymorphically return different types of object.&lt;br /&gt; */&lt;br /&gt;public enum CovariantEnum {&lt;br /&gt;    A { &lt;br /&gt;        @Override public String getValue() { return "CovariantEnum.A"; } &lt;br /&gt;    },&lt;br /&gt;    B {&lt;br /&gt;        @Override public Integer getValue() { return 1; }&lt;br /&gt;    },&lt;br /&gt;    // etc.&lt;br /&gt;    ;&lt;br /&gt;    public abstract &amp;lt;T&gt; T getValue();&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;This would actually compile, except there are two problems.  First, there are compilation warnings about "return type requires unchecked conversion".  Second, it actually doesn't quite work as expected.  Client code such as:&lt;blockquote&gt;&lt;pre&gt;// This doesn't work :(&lt;br /&gt;String stringValue = CovariantEnum.A.getValue();&lt;/pre&gt;&lt;/blockquote&gt;would result in a type mismatch compilation error.  Explicit casting the returned value to the target type, such as String in the above example, would work, but that defeats the purpose of building CovariantEnum in the first place.&lt;br /&gt;&lt;br /&gt;So how can we get around these limitations ?&lt;br /&gt;&lt;br /&gt;Well, first, Java disallows enum declaration to have type parameters.  In other words, it is a syntax error to write:&lt;blockquote&gt;&lt;pre&gt;public enum CovariantEnum&amp;lt;T&gt; {&lt;br /&gt;...&lt;/pre&gt;&lt;/blockquote&gt;But what if we emulate a enum with an abstract class ?  This may lead to something like:&lt;blockquote&gt;&lt;pre&gt;/**&lt;br /&gt; * Basically a "CovariantEnum" that actually works and does not cause any compilation warnings.&lt;br /&gt; */&lt;br /&gt;public abstract class TypeSafeCovariantEnum&amp;lt;T&gt; {&lt;br /&gt;    public static final TypeSafeCovariantEnum&amp;lt;String&gt; A = new TypeSafeCovariantEnum&amp;lt;String&gt;() { &lt;br /&gt;        @Override public String getValue() { return "TypeSafeCovariantEnum.A"; } &lt;br /&gt;    };&lt;br /&gt;    public static final TypeSafeCovariantEnum&amp;lt;Integer&gt; B = new TypeSafeCovariantEnum&amp;lt;Integer&gt;() { &lt;br /&gt;        @Override public Integer getValue() { return 1; }&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;    private TypeSafeCovariantEnum() {}&lt;br /&gt;    public abstract T getValue();&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;Now compilation has zero warnings, and a client can enjoy using the "literal instances" in TypeSafeCovariantEnum as if it's a covariant enum without any need for explicit casting:&lt;blockquote&gt;&lt;pre&gt;// This works!&lt;br /&gt;String stringValue = TypeSafeCovariantEnum.A.getValue();&lt;br /&gt;Integer integerValue = TypeSafeCovariantEnum.B.getValue();&lt;/pre&gt;&lt;/blockquote&gt;Of course this is not an actual enum, and it involves a little complexity inside; but it provides 100% type safety, and simplicity to the clients outside :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4905154343612005849?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4905154343612005849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4905154343612005849' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4905154343612005849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4905154343612005849'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2009/04/covariant-enum-pattern.html' title='Covariant Enum Idiom'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7946110647380470533</id><published>2008-11-30T00:24:00.000-08:00</published><updated>2008-12-28T21:04:57.117-08:00</updated><title type='text'>Local vs Any address in Cajo</title><content type='html'>Looking into the &lt;a href="https://cajo.dev.java.net/"&gt;cajo&lt;/a&gt; source code, I see the default server side host address used by cajo is the local host address.  For example,&lt;blockquote&gt;&lt;pre&gt;host = InetAddress.getLocalHost().getHostAddress();&lt;/pre&gt;&lt;/blockquote&gt;This seems to work in most cases/platforms, except it breaks with the new Mac that I have.  How does it break ?  Well the server side binding works with the default (local) address, but the client would fail to connect to 127.0.0.1 or localhost.  To make the client connect, I needed to figure out the specific local address (like 192.168.0.3) used for the server side binding, and explicitly specify that for the client.&lt;br /&gt;&lt;br /&gt;When I tried to see if this was also the case outside cajo using the plain old ServerSocket(int), surprisingly it worked regardless of whether I specified locahost, 127.0.0.1, or 192.168.0.3.&lt;br /&gt;&lt;br /&gt;Digging more into the JDK source code, ServerSocket uses an "any address" rather than a "local address" as the default:&lt;blockquote&gt;&lt;pre&gt;InetAddress.anyLocalAddress();&lt;/pre&gt;&lt;/blockquote&gt;Sadly, this static method is package private.&lt;br /&gt;&lt;br /&gt;Anyhow, since the "any address" seems to work more so than the "local address", it would be nice if cajo can change the default server side address to the "any address", which would make cajo "just work" across more platforms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-7946110647380470533?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7946110647380470533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7946110647380470533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7946110647380470533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7946110647380470533'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/11/local-vs-any-address-in-cajo.html' title='Local vs Any address in Cajo'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-447773896266447223</id><published>2008-11-22T07:51:00.000-08:00</published><updated>2008-11-22T09:18:51.950-08:00</updated><title type='text'>Warming up a JVM</title><content type='html'>If you knew the actual set of classes that will be lazily loaded into the JVM for execution, wouldn't it be nice if these classes can be eagerly loaded into the JVM upon start-up ?  This particularly matters if you are writing web services, where the latency of the first few requests will be significantly impacted.&lt;br /&gt;&lt;br /&gt;Pre-loading classes is easy.  But how can we find out the precise set of classes to be preloaded ?  It turns out there exists a very nice JVM option:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;-verbose:class&lt;/pre&gt;&lt;/blockquote&gt;Also found an interesting technical report: &lt;a href="http://ecommons.library.cornell.edu/handle/1813/5832"&gt;Eager Class Initialization For Java&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-447773896266447223?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/447773896266447223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=447773896266447223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/447773896266447223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/447773896266447223'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/11/jvm-warm-up.html' title='Warming up a JVM'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-2375866515027723928</id><published>2008-11-11T11:43:00.000-08:00</published><updated>2008-11-12T08:17:54.536-08:00</updated><title type='text'>A little Java constructor pattern</title><content type='html'>Say we have a class Item:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;public class Item {&lt;br /&gt;    final String name;&lt;br /&gt;    final float val;&lt;br /&gt;    final int size;&lt;br /&gt;    &lt;br /&gt;    public Item(String name, int size, float val) {&lt;br /&gt;        this.name = name;&lt;br /&gt;        this.val = val;&lt;br /&gt;        this.size = size;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;and we'd like to initialize an Item array with some values:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;Item[] items = {&lt;br /&gt;    new Item("A", 3, 4),&lt;br /&gt;    new Item("B", 4, 5),&lt;br /&gt;    ...&lt;br /&gt;};&lt;/pre&gt;&lt;/blockquote&gt;Wouldn't it be nice if we can simplify it to:&lt;blockquote&gt;&lt;pre&gt;Item[] items = {&lt;br /&gt;    Item("A", 3, 4),&lt;br /&gt;    Item("B", 4, 5),&lt;br /&gt;    ...&lt;br /&gt;};&lt;/pre&gt;&lt;/blockquote&gt;?  &lt;br /&gt;&lt;br /&gt;Couldn't this be easily done by defining a static factory method with the same name as Item, and then use it via static import ?&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;public class Item {&lt;br /&gt;    // ... same as above&lt;br /&gt;&lt;br /&gt;    // A static factory method for the syntactic sugar&lt;br /&gt;    public static Item Item(String name, int size, float val) {&lt;br /&gt;        return new Item(name, size, val);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Usage:&lt;blockquote&gt;&lt;pre&gt;import static Item.Item;&lt;br /&gt;...&lt;br /&gt;Item[] items = {&lt;br /&gt;    Item("A", 3, 4),&lt;br /&gt;    Item("B", 4, 5),&lt;br /&gt;    ...&lt;br /&gt;};&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-2375866515027723928?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/2375866515027723928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=2375866515027723928' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2375866515027723928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2375866515027723928'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/11/little-java-constructor-pattern.html' title='A little Java constructor pattern'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5518153776399001494</id><published>2008-09-23T16:14:00.000-07:00</published><updated>2008-09-23T16:22:44.992-07:00</updated><title type='text'>Beanlib on BeanUtils wiki</title><content type='html'>It made my day when I proposed to use &lt;a href="http://beanlib.sourceforge.net/"&gt;Beanlib&lt;/a&gt; to solve a &lt;a href="http://www.nabble.com/PropertyUtils.copyProperties()-and-inherited-classes-td19622863.html"&gt;problem&lt;/a&gt; which the Jakarta Commons &lt;a href="http://commons.apache.org/beanutils/"&gt;BeanUtils&lt;/a&gt; was not well suited, Beanlib ended up being included in the &lt;a href="http://wiki.apache.org/commons/BeanUtils"&gt;BeanUtils wiki&lt;/a&gt; as a related project :)&lt;br /&gt;&lt;br /&gt;Thanks to Niall Pemberton for being open minded.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5518153776399001494?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5518153776399001494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5518153776399001494' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5518153776399001494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5518153776399001494'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/09/beanlib-on-beanutils-wiki.html' title='Beanlib on BeanUtils wiki'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4888878132253509738</id><published>2008-09-22T12:35:00.000-07:00</published><updated>2008-09-22T13:53:33.174-07:00</updated><title type='text'>No more infinitely blocking socket ?</title><content type='html'>One common problem Java programmer faces is the direct or indirect use of socket that could block forever.  If a socket connect or read operation blocks with an infinite timeout, there is basically nothing that can interrupt the blocking thread besides closing the socket.  Not Thread.interrupt(), nor even Thread.stop() would help.  Gaining access to the underlying socket could, however, be difficult, considering the socket could be buried deep down inside some third party library, such as a JDBC driver.&lt;br /&gt;&lt;br /&gt;Attending the &lt;a href="http://www.nofluffjuststuff.com/conference/seattle/2008/09/index.html"&gt;NFJS&lt;/a&gt; session, &lt;a href="http://www.nofluffjuststuff.com/speaker_topic_view.jsp?topicId=795"&gt;Busy Java Developer's Guide to JDK Hacking&lt;/a&gt; by &lt;a href="http://www.nofluffjuststuff.com/conference/speaker/ted_neward.html"&gt;Ted Neward&lt;/a&gt; yesterday, a solution came to my mind when Ted demonstrated how easy it was to slip in my own classes ahead of the JDK's.  Why not simply extend the existing JDK socket implementation with an additional system property to limit or default the socket timeout to some sensible values ?  See an example implementation below.  To make this work, simply &lt;ol&gt;&lt;li&gt;Set up a custom socket factory:&lt;blockquote&gt;&lt;pre&gt;Socket.setSocketImplFactory(new SocketImplFactory() {&lt;br /&gt;    @Override&lt;br /&gt;    public SocketImpl createSocketImpl() { return new NicerSocksSocketImpl(); }&lt;br /&gt;});&lt;/pre&gt;&lt;/blockquote&gt;&lt;li&gt;Slip in the implementation class and configure the socket timeout when starting up the JVM:&lt;blockquote&gt;&lt;pre&gt;java -Xbootclasspath/p:"/path/to/custom/jdk/classes" -DSO_TIMEOUT=1000 ...&lt;/pre&gt;&lt;/blockquote&gt;&lt;/ol&gt;Now if a socket timeout is not specified by the individual application or library, the blocking operation would be limited to a maximum of 1,000ms before throwing up.&lt;br /&gt;&lt;br /&gt;No more socket black hole sucking up resources:)&lt;blockquote&gt;&lt;pre&gt;package java.net;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;public class NicerSocksSocketImpl extends SocksSocketImpl {&lt;br /&gt;    private final int defaultSoTimeout; &lt;br /&gt;&lt;br /&gt;    public NicerSocksSocketImpl() { this.defaultSoTimeout = defaultSoTimeout(); }&lt;br /&gt;&lt;br /&gt;    public NicerSocksSocketImpl(String server, int port) {&lt;br /&gt;        super(server, port);&lt;br /&gt;        this.defaultSoTimeout = defaultSoTimeout();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public NicerSocksSocketImpl(Proxy proxy) {&lt;br /&gt;        super(proxy);&lt;br /&gt;        this.defaultSoTimeout = defaultSoTimeout();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private int defaultSoTimeout() {&lt;br /&gt;        String defaultSoTimeoutStr = System.getProperty("SO_TIMEOUT");&lt;br /&gt;        try {&lt;br /&gt;            return Integer.parseInt(defaultSoTimeoutStr);&lt;br /&gt;        } catch(RuntimeException ex) {&lt;br /&gt;            return 5000;    // default to 5 seconds&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    protected void connect(SocketAddress endpoint, int timeout) throws IOException {&lt;br /&gt;        super.connect(endpoint, timeout == 0 ? defaultSoTimeout : timeout);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void connect(String host, int port) throws UnknownHostException, IOException {&lt;br /&gt;        setTimeoutIfNecessary();&lt;br /&gt;        super.connect(host, port);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    protected void connect(InetAddress address, int port) throws IOException {&lt;br /&gt;        setTimeoutIfNecessary();&lt;br /&gt;        super.connect(address, port);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private void setTimeoutIfNecessary() throws SocketException {&lt;br /&gt;        int timeout = super.getTimeout();&lt;br /&gt;        &lt;br /&gt;        if (timeout == 0)&lt;br /&gt;            super.setOption(SO_TIMEOUT, defaultSoTimeout);&lt;br /&gt;        return;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4888878132253509738?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4888878132253509738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4888878132253509738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4888878132253509738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4888878132253509738'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/09/no-more-infinitely-blocking-socket.html' title='No more infinitely blocking socket ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8348964685212144201</id><published>2008-09-20T21:29:00.000-07:00</published><updated>2008-09-22T11:28:08.307-07:00</updated><title type='text'>When is NEVER ever ?</title><content type='html'>During one of today's &lt;a href="http://www.nofluffjuststuff.com/conference/seattle/2008/09/index.html"&gt;NFJS&lt;/a&gt; sessions, &lt;a href="http://www.infoq.com/minibooks/JTDS"&gt;Transaction Design Patterns&lt;/a&gt; by &lt;a href="http://www.nofluffjuststuff.com/conference/speaker/mark_richards.html"&gt;Mark Richards&lt;/a&gt;, the audience were asked when it would make sense to specify the transaction attribute &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/transaction/TransactionDefinition.html#PROPAGATION_NEVER"&gt;NEVER&lt;/a&gt; in a real-life application.  &lt;br /&gt;&lt;br /&gt;My immediate answer to this was that if a method is known to never get involved in a transactional context, then specifying &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/transaction/TransactionDefinition.html#PROPAGATION_NEVER"&gt;NEVER&lt;/a&gt; would allow the application to fail fast.  But what would be the practical circumstances where a method should never get involved in a transaction, to the extent of potentially causing an exception in production ?  And if there weren't really such circumstances, why not use the &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/transaction/TransactionDefinition.html#PROPAGATION_SUPPORTS"&gt;SUPPORTS&lt;/a&gt;  attribute instead ?  Asked Richard.&lt;br /&gt;&lt;br /&gt;On second thought, maybe we can use the NEVER attribute a lot more often and useful than it now is.  Let me explain.&lt;br /&gt;&lt;br /&gt;Consider the transaction attribute &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/transaction/TransactionDefinition.html#PROPAGATION_REQUIRES_NEW"&gt;REQUIRES_NEW&lt;/a&gt;, which basically creates a new transaction if one doesn't already exist.   But what if there already exists a transaction ?  Instead of throwing an exception, like NEVER, it would suspend the current transaction and creates a new one.  However, suspending a transaction is both expensive and usually not the intended semantics, as Richard pointed out.  &lt;br /&gt;&lt;br /&gt;So wouldn't it be nice if there exists a transaction attribute&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;NEVER_REQUIRES_NEW&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt; that would both guarantee there is no pre-existing transaction when a method is invoked, and then proceed to always create a new transaction ?  But there is no such transaction attribute either in &lt;a href="http://docs.sun.com/app/docs/doc/819-3669/6n5sg7cm3?a=view"&gt;JEE 5&lt;/a&gt;, nor in &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/transaction/TransactionDefinition.html"&gt;Spring&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here is what I think could achieve the NEVER_REQUIRES_NEW transaction semantics, assuming the service method name is M:&lt;ol&gt;&lt;li&gt;Split method M into M1 and M2, and move the implementation of M to M2;&lt;br /&gt;&lt;li&gt;M1 is a no-op annotated with the transaction attribute NEVER, whereas M2 is annotated with REQUIRES_NEW;&lt;br /&gt;&lt;li&gt;Provide a proxy service that always invokes M1 followed by M2, exposing in turn to the client only a service method M without any transactional annotation;&lt;br /&gt;&lt;/ol&gt;Now when client invokes M, the proxy would in turn invoke M1 that guarantees there is no pre-existing transaction, and then invoke M2 which would always create a new transaction, effectively resulting in NEVER_REQUIRES_NEW!&lt;br /&gt;&lt;br /&gt;Is this yet another Transaction Design Pattern ?  The use of NEVER could be forever changed :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8348964685212144201?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8348964685212144201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8348964685212144201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8348964685212144201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8348964685212144201'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/09/when-is-never-ever.html' title='When is NEVER ever ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5320005032909750078</id><published>2008-09-06T23:03:00.000-07:00</published><updated>2008-09-06T23:32:37.816-07:00</updated><title type='text'>Visiting Every Permutation ?</title><content type='html'>Given a set of objects, sometimes it's useful to find out all the &lt;a href="http://en.wikipedia.org/wiki/Permutation"&gt;permutation&lt;/a&gt; of these objects, and perform some action upon each permutation.  The order of the permutation generation would preferably be in some natural order such as lexicographic i.e. the order they would appear if they were sorted numerically.&lt;br /&gt;&lt;br /&gt;How would you go about writing such utility efficiently in Java ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;One possible answer:&lt;/span&gt;&lt;blockquote&gt;&lt;pre&gt;public class Permutation&amp;lt;T&gt; {&lt;br /&gt;    public static interface Visitor&amp;lt;T&gt; {&lt;br /&gt;        /** Visits each permutation of objects. */&lt;br /&gt;        public void visit(T[] entry);&lt;br /&gt;    }&lt;br /&gt;    private final T[] objects;&lt;br /&gt;    private T tmp;&lt;br /&gt;    private final Visitor&amp;lt;T&gt; visitor;&lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * @param objects set of n objects&lt;br /&gt;     * @param visitor used to visit each permutation&lt;br /&gt;     */&lt;br /&gt;    public Permutation(T[] objects, Visitor&amp;lt;T&gt; visitor) {&lt;br /&gt;        this.objects = objects.clone();&lt;br /&gt;        this.visitor = visitor;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void compute() { doCompute(0); }&lt;br /&gt;    &lt;br /&gt;    private void doCompute(final int pos) {&lt;br /&gt;        if (pos == objects.length) {&lt;br /&gt;            visitor.visit(objects);&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        doCompute(pos+1);&lt;br /&gt;        &lt;br /&gt;        for (int i=pos+1; i &lt; objects.length; i++) {&lt;br /&gt;            swap(pos, i);&lt;br /&gt;            doCompute(pos+1);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        if (pos &gt; 0)&lt;br /&gt;            for (int i=pos+1; i &lt; objects.length; i++)&lt;br /&gt;                swap(i-1, i);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private void swap(int p1, int p2) {&lt;br /&gt;        tmp = objects[p1];&lt;br /&gt;        objects[p1] = objects[p2];&lt;br /&gt;        objects[p2] = tmp;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;span style="font-weight:bold;"&gt;Demo:&lt;/span&gt;&lt;blockquote&gt;&lt;pre&gt;Visitor&amp;lt;Character&gt; visitor = new Visitor&amp;lt;Character&gt;() {&lt;br /&gt;    private Set&amp;lt;String&gt; set = new HashSet&amp;lt;String&gt;();&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void visit(Character[] entry) {&lt;br /&gt;        String s = Arrays.toString(entry);&lt;br /&gt;        set.add(s);&lt;br /&gt;        System.out.println(set.size() + ": " + s);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;String s = "abc";&lt;br /&gt;Character[] ca = new Character[s.length()];&lt;br /&gt;&lt;br /&gt;for (int i = s.length() - 1; i &gt; -1; i--)&lt;br /&gt;    ca[i] = s.charAt(i);&lt;br /&gt;new Permutation&amp;lt;Character&gt;(ca, visitor).compute();&lt;/pre&gt;&lt;/blockquote&gt;Would yield:&lt;blockquote&gt;&lt;pre&gt;1: [a, b, c]&lt;br /&gt;2: [a, c, b]&lt;br /&gt;3: [b, a, c]&lt;br /&gt;4: [b, c, a]&lt;br /&gt;5: [c, a, b]&lt;br /&gt;6: [c, b, a]&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5320005032909750078?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5320005032909750078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5320005032909750078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5320005032909750078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5320005032909750078'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/09/visiting-every-permutation.html' title='Visiting Every Permutation ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4618839521770669267</id><published>2008-09-02T23:22:00.000-07:00</published><updated>2008-09-03T20:11:11.756-07:00</updated><title type='text'>Visiting Every Combination ?</title><content type='html'>Given a set of objects, sometimes it's useful to find out all the &lt;a href="http://en.wikipedia.org/wiki/Combination"&gt;combination&lt;/a&gt; of these objects of a given size, and perform some action upon each combination.  For example, given a set of letters "abcde", print out all the combination of 4 letters from the set.&lt;br /&gt;&lt;br /&gt;How would you go about writing such utility efficiently in Java ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;One possible answer:&lt;/span&gt;&lt;blockquote&gt;&lt;pre&gt;public class Combination&amp;lt;T&gt; {&lt;br /&gt;    public static interface Visitor&amp;lt;T&gt; {&lt;br /&gt;        /** Visits each k-combination of objects. */&lt;br /&gt;        public void visit(T[] entry);&lt;br /&gt;    }&lt;br /&gt;    private final T[] objects; // Given set of objects&lt;br /&gt;    private final T[] entry;   // each combination of size k&lt;br /&gt;    private final Visitor&amp;lt;T&gt; visitor;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param objects set of n objects&lt;br /&gt;     * @param k size of each combination&lt;br /&gt;     * @param visitor used to visit each combination&lt;br /&gt;     */&lt;br /&gt;    public Combination(T[] objects, int k, Visitor&amp;lt;T&gt; visitor) {&lt;br /&gt;        this.objects = objects.clone();&lt;br /&gt;        entry = Arrays.copyOf(this.objects, k);&lt;br /&gt;        this.visitor = visitor;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void compute() { doCompute(0, 0); }&lt;br /&gt;&lt;br /&gt;    private void doCompute(int pos, int entryPos) {&lt;br /&gt;        if (entryPos == entry.length) {&lt;br /&gt;            visitor.visit(entry);&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;        // (entry.length - entryPos) is the remaining size&lt;br /&gt;        for (int i = pos, end = objects.length - (entry.length - entryPos) + 1; i &lt; end; i++) {&lt;br /&gt;            entry[entryPos] = objects[i];&lt;br /&gt;            doCompute(i + 1, entryPos + 1);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;span style="font-weight:bold;"&gt;Demo:&lt;/span&gt;&lt;blockquote&gt;&lt;pre&gt;Visitor&amp;lt;Character&gt; visitor = new Visitor&amp;lt;Character&gt;() {&lt;br /&gt;    private Set&amp;lt;String&gt; set = new HashSet&amp;lt;String&gt;();&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void visit(Character[] entry) {&lt;br /&gt;        String s = Arrays.toString(entry);&lt;br /&gt;        set.add(s);&lt;br /&gt;        System.out.println(set.size() + ": " + s);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;String s = "abcde";&lt;br /&gt;Character[] ca = new Character[s.length()];&lt;br /&gt;&lt;br /&gt;for (int i = s.length() - 1; i &gt; -1; i--)&lt;br /&gt;    ca[i] = s.charAt(i);&lt;br /&gt;&lt;br /&gt;final int size = 4;&lt;br /&gt;new Combination&amp;lt;Character&gt;(ca, size, visitor).compute();&lt;/pre&gt;&lt;/blockquote&gt;Would yield:&lt;blockquote&gt;&lt;pre&gt;1: [a, b, c, d]&lt;br /&gt;2: [a, b, c, e]&lt;br /&gt;3: [a, b, d, e]&lt;br /&gt;4: [a, c, d, e]&lt;br /&gt;5: [b, c, d, e]&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4618839521770669267?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4618839521770669267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4618839521770669267' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4618839521770669267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4618839521770669267'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/09/visiting-every-combination.html' title='Visiting Every Combination ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5066117563680214042</id><published>2008-08-05T12:46:00.000-07:00</published><updated>2008-08-23T16:57:41.975-07:00</updated><title type='text'>Root Cause Java Quiz</title><content type='html'>Can the following code leads to an endless loop ?&lt;blockquote&gt;&lt;pre&gt;    public static Throwable getRootCause(Throwable t) {&lt;br /&gt;        if (t == null)&lt;br /&gt;            return t;&lt;br /&gt;        Throwable cause = t.getCause();&lt;br /&gt;        &lt;br /&gt;        if (cause == null)&lt;br /&gt;            return t;&lt;br /&gt;        return getRootCause(cause);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Answer:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Don't try this at home ;)&lt;blockquote&gt;&lt;pre&gt;        Exception ex1 = new Exception("ex1");&lt;br /&gt;        Exception ex2 = new Exception("ex2");&lt;br /&gt;        ex1.initCause(ex2);&lt;br /&gt;        ex2.initCause(ex1);&lt;br /&gt;        getRootCause(ex1);&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5066117563680214042?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5066117563680214042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5066117563680214042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5066117563680214042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5066117563680214042'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/08/endless-root-cause-in-java.html' title='Root Cause Java Quiz'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4049311265692328948</id><published>2008-07-12T17:59:00.000-07:00</published><updated>2008-07-13T19:41:30.253-07:00</updated><title type='text'>Java Enum Puzzler</title><content type='html'>What does the following print ?&lt;blockquote&gt;&lt;pre&gt;public enum FooEnum {&lt;br /&gt;    FOO { @Override public void bar() {} };&lt;br /&gt;    public abstract void bar();&lt;br /&gt;    &lt;br /&gt;    public static void main(String...args) {&lt;br /&gt;        System.out.println(FOO.getClass().isEnum());&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;span style="font-weight:bold;"&gt;Answer:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;FOO is an enum value in FooEnum.  The class of FOO must therefore be an enum, and it should print "true".  Right ?  If you give it a try, surprisingly it will print "false".  Why ?&lt;br /&gt;&lt;br /&gt;Peeking into the JDK source code of Class.java,&lt;blockquote&gt;&lt;pre&gt;public boolean isEnum() {&lt;br /&gt;    // An enum must both directly extend java.lang.Enum and have&lt;br /&gt;    // the ENUM bit set; classes for specialized enum constants&lt;br /&gt;    // don't do the former.&lt;br /&gt;    return (this.getModifiers() &amp; ENUM) != 0 &amp;&amp; &lt;br /&gt;            this.getSuperclass() == java.lang.Enum.class;&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;Now if you tried to print out the super class of FOO.class, it would print FooEnum.class, rather than Enum.class.  The comparison of the super class of FOO.class against Enum.class would therefore fail in the second condition of the return statement.&lt;br /&gt;&lt;br /&gt;To me, this looks like a bug either in the javac compiler, or in the implementation of Class.isEnum().  &lt;br /&gt;&lt;br /&gt;Why is it probably a bug in the javac compiler ?  Well, shouldn't the super class of FOO.class be Enum.class, instead of FooEnum.class ?  (Special thanks to Dhanji&amp;nbsp;R.&amp;nbsp;Prasanna for pointing this out.)  &lt;br /&gt;&lt;br /&gt;Why is it probably a bug in Class.isEnum() ?  Well, shouldn't it recursively check all the super classes of FOO.class for Enum.class, instead of just the direct super class ?  And why does it need to compare the super class with Enum.class at all, when there is already the checking for the ENUM class modifier ?&lt;br /&gt;&lt;br /&gt;What do you think ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Update on 7/13/2008:&lt;/span&gt; Please vote for bug &lt;a href="http://bugs.sun.com/view_bug.do?bug_id=6710708"&gt;6710708&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4049311265692328948?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4049311265692328948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4049311265692328948' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4049311265692328948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4049311265692328948'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/07/java-enum-puzzler.html' title='Java Enum Puzzler'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4391690991396694181</id><published>2008-07-11T03:11:00.000-07:00</published><updated>2008-07-12T11:53:42.615-07:00</updated><title type='text'>Dumping a JavaBean as name/value pairs ?</title><content type='html'>Sometimes it's useful to deeply dump out the properties of a complex JavaBean as name/value pairs, perhaps for debugging purposes, even when none of the toString methods of the classes involved are defined.  This is especially the case when the JavaBean classes are written by a third party.&lt;br /&gt;&lt;br /&gt;Now how would you go about doing that ?&lt;br /&gt;&lt;br /&gt;How about using the Jarkarta commons-lang's &lt;a href="http://commons.apache.org/lang/api/org/apache/commons/lang/builder/ToStringBuilder.html#reflectionToString%28java.lang.Object%29"&gt;ToStringBuilder.reflectionToString&lt;/a&gt; method ?  It doesn't cut it, as it relies on the toString method of the individual classes involved.&lt;br /&gt;&lt;br /&gt;How about &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/beans/XMLEncoder.html"&gt;XMLEncoder&lt;/a&gt; or &lt;a href="http://xstream.codehaus.org/"&gt;XStream&lt;/a&gt; ?  They work pretty nicely.  However, by default XStream generates not just the public properties but all other fields as well.  In both cases, the generated XML would need to be further transformed into name/value pairs.&lt;br /&gt;&lt;br /&gt;Another way I can think of is to take advantage of the latest &lt;a href="http://beanlib.sourceforge.net/3.3.0beta18/api/net/sf/beanlib/spi/BeanSourceHandler.html"&gt;BeanSourceHandler&lt;/a&gt; SPI as a side effect of performing a deep clone via the open-source library &lt;a href="http://beanlib.sourceforge.net/"&gt;Beanlib&lt;/a&gt; (beanlib-3.3.0beta18).  What do I mean ?  Here is an example:&lt;blockquote&gt;&lt;pre&gt;Object bean = ...&lt;br /&gt;// Dump out the entire JavaBean&lt;br /&gt;// when none of the toString methods are defined.&lt;br /&gt;BeanReplicator.newBeanReplicatable(customTransformer()).replicateBean(bean);&lt;br /&gt;&lt;br /&gt;private static BeanTransformerSpi customTransformer() {&lt;br /&gt;    BeanTransformerSpi beanTransformer = BeanTransformer.newBeanTransformer();&lt;br /&gt;    return beanTransformer.initBeanSourceHandler(new BeanSourceHandler() {&lt;br /&gt;        public void handleBeanSource(Object fromBean, Method readerMethod, Object propertyValue) {&lt;br /&gt;            System.out.println(&lt;br /&gt;                String.valueOf(fromBean.getClass().getSimpleName() + "."&lt;br /&gt;                + readerMethod.getName() + "=" + propertyValue));&lt;br /&gt;        }&lt;br /&gt;    });&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4391690991396694181?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4391690991396694181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4391690991396694181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4391690991396694181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4391690991396694181'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/07/how-do-dump-javabean.html' title='Dumping a JavaBean as name/value pairs ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5096036793865008557</id><published>2008-07-02T10:32:00.000-07:00</published><updated>2008-07-02T10:51:39.580-07:00</updated><title type='text'>Little Java Quiz - File loaded from classpath</title><content type='html'>Given:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;a file with a given name;&lt;/li&gt;&lt;li&gt;the file is located in the file system;&lt;/li&gt;&lt;li&gt;the file can be loaded via the classpath;&lt;/li&gt;&lt;/ol&gt;How can the code figure out the physical location (ie absolute path) of the file ?&lt;br /&gt;&lt;br /&gt;(Don't peek if you want to give it a try!)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Answer&lt;/span&gt;:&lt;blockquote&gt;&lt;pre&gt;    String filePath = Thread.currentThread()&lt;br /&gt;                            .getContextClassLoader()&lt;br /&gt;                            .getResource(filename)&lt;br /&gt;                            .getFile();&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5096036793865008557?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5096036793865008557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5096036793865008557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5096036793865008557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5096036793865008557'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/07/little-java-quiz-file-loaded-from.html' title='Little Java Quiz - File loaded from classpath'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1736161014725363666</id><published>2008-04-11T00:20:00.000-07:00</published><updated>2008-04-11T12:11:29.879-07:00</updated><title type='text'>Tomcat 5.5 SSL Programming Puzzle</title><content type='html'>Assuming SSL client side authentication is enabled in Tomcat 5.5, how can a webapp go about retrieving the underlying client's X509 certificate of the SSL socket ?  &lt;br /&gt;&lt;br /&gt;Browsing through the Tomcat source code, such information can be found in the SSL session, which unfortunately seems totally unreachable from the servlet layer.&lt;br /&gt;&lt;br /&gt;Well, thanks to reflection, below is one such solution.  Do you know of a better one ?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;    /** &lt;br /&gt;     * Returns the requester's X509 SSL certificate(s) of the given request;&lt;br /&gt;     * or null if no such certificate can be determined. &lt;br /&gt;     */&lt;br /&gt;    static X509Certificate[] getPeerCertificates(HttpServletRequest req) {&lt;br /&gt;        // rip open the tomcat specific request object to retrieve the peer SSL cert(s)&lt;br /&gt;        try &lt;br /&gt;        {   // Dig out the org.apache.catalina.connector.Request object&lt;br /&gt;            Field f = req.getClass().getDeclaredField("request");&lt;br /&gt;            f.setAccessible(true);&lt;br /&gt;            Object catalinaConnectorRequest = f.get(req);&lt;br /&gt;            &lt;br /&gt;            // Dig out the org.apache.coyote.Request object&lt;br /&gt;            // by invoking org.apache.catalina.connector.Request.getCoyoteRequest()&lt;br /&gt;            Method getCoyoteRequestMethod = catalinaConnectorRequest.getClass().getMethod("getCoyoteRequest");&lt;br /&gt;            Object coyoteRequest = getCoyoteRequestMethod.invoke(catalinaConnectorRequest);&lt;br /&gt;&lt;br /&gt;            // Dig out the proper class loader&lt;br /&gt;            Class coyoteRequestClass = coyoteRequest.getClass();&lt;br /&gt;            ClassLoader classLoader = coyoteRequestClass.getClassLoader();&lt;br /&gt;            &lt;br /&gt;            // Dig out the ActionCode class loaded by the approprate class loader&lt;br /&gt;            Class actionCodeClass = classLoader.loadClass("org.apache.coyote.ActionCode");&lt;br /&gt;            &lt;br /&gt;            // Refer to the ActionCode.ACTION_REQ_SSL_CERTIFICATE&lt;br /&gt;            Field actionReqSslCertField = actionCodeClass.getDeclaredField("ACTION_REQ_SSL_CERTIFICATE");&lt;br /&gt;            Object actionReqSslCert = actionReqSslCertField.get(null);&lt;br /&gt;            &lt;br /&gt;            // Invoke org.apache.coyote.Request.action(ActionCode.ACTION_REQ_SSL_CERTIFICATE, null)&lt;br /&gt;            Method actionMethod = coyoteRequestClass.getMethod("action", actionReqSslCert.getClass(), Object.class);&lt;br /&gt;            actionMethod.invoke(coyoteRequest, actionReqSslCert, null);&lt;br /&gt;            &lt;br /&gt;            // Dig out the SSLSupport class loaded by the approprate class loader&lt;br /&gt;            Class sslSupportClass = classLoader.loadClass("org.apache.tomcat.util.net.SSLSupport");&lt;br /&gt;            &lt;br /&gt;            // Refer to the SSLSupport.CERTIFICATE_KEY&lt;br /&gt;            Field sslSupportCertKeyField = sslSupportClass.getDeclaredField("CERTIFICATE_KEY");&lt;br /&gt;            Object sslSupportCertKey = sslSupportCertKeyField.get(null);&lt;br /&gt;            &lt;br /&gt;            // Invoke org.apache.coyote.Request.getAttribute(SSLSupport.CERTIFICATE_KEY)&lt;br /&gt;            Method getAttributeMethod = coyoteRequest.getClass()&lt;br /&gt;                                                     .getMethod("getAttribute", sslSupportCertKey.getClass());&lt;br /&gt;            return (X509Certificate[])getAttributeMethod.invoke(coyoteRequest, sslSupportCertKey);&lt;br /&gt;        } catch(Throwable t) {&lt;br /&gt;        }&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;It turns out there is a much simpler way to solve this problem.  According to the spec (section SRV.4.7), if there is an SSL certificate associated with the request, it must be exposed by the servlet container to the servlet programmer as an array of objects of type java.security.cert.X509Certificate and accessible via a ServletRequest attribute of javax.servlet.request.X509Certificate.&lt;br /&gt;&lt;br /&gt;Thanks to Mark Thomas for pointing this out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-1736161014725363666?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1736161014725363666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1736161014725363666' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1736161014725363666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1736161014725363666'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/04/tomcat-55-ssl-programming-puzzle.html' title='Tomcat 5.5 SSL Programming Puzzle'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5748818964214717410</id><published>2008-04-03T10:00:00.000-07:00</published><updated>2008-04-03T16:16:17.873-07:00</updated><title type='text'>On Frugality</title><content type='html'>Be contra-variant in what you take, but covariant in what you give.  In other words, take less and give more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5748818964214717410?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5748818964214717410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5748818964214717410' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5748818964214717410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5748818964214717410'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/04/on-frugality.html' title='On Frugality'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8774114376050287123</id><published>2008-02-15T15:43:00.000-08:00</published><updated>2008-02-16T18:11:25.383-08:00</updated><title type='text'>Some JMX Quizzes</title><content type='html'>&lt;ol&gt;&lt;li&gt;Where can you find out all those Platform MBean Object Names ?&lt;/li&gt;&lt;li&gt;How would you connect via JMX with username and password programmatically ?&lt;/li&gt;&lt;/ol&gt;Some possible answers:&lt;ol&gt;&lt;li&gt;Where can you find out all those Platform MBean Object Names ?&lt;/li&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ManagementFactory.html"&gt;java.lang.management.ManagementFactory&lt;/a&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;li&gt;How would you connect via JMX with username and password programmatically ?&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;       &lt;pre&gt;    Map&amp;lt;String,String[]&gt; env = new HashMap&amp;lt;String,String[]&gt;();&lt;br /&gt;    env.put(JMXConnector.CREDENTIALS, new String[]{"username", "password"});&lt;br /&gt;    final String url = "service:jmx:rmi://" + host + "/jndi/rmi://" + host + ":" + port + "/jmxrmi";&lt;br /&gt;    JMXServiceURL jmxServiceUrl = new JMXServiceURL(url);&lt;br /&gt;    JMXConnector conn = JMXConnectorFactory.connect(jmxServiceUrl, env);&lt;br /&gt;    MBeanServerConnection mbsc = conn.getMBeanServerConnection();&lt;br /&gt;    ...&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8774114376050287123?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8774114376050287123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8774114376050287123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8774114376050287123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8774114376050287123'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/02/where-to-find-those-platform-mbean.html' title='Some JMX Quizzes'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1647418478229255137</id><published>2008-02-13T21:47:00.000-08:00</published><updated>2010-08-28T15:04:46.378-07:00</updated><title type='text'>Some Quizzes on Bits, Bytes, etc.</title><content type='html'>&lt;ol&gt;&lt;li&gt;Given a byte, how would you turn the nth bit on ?&lt;li&gt;Given a byte, how would you turn the nth bit off ?&lt;/li&gt;&lt;li&gt;Given a long, how would you return 8 bytes (in big-endian order) containing the two's-complement binary representation of the long ?&lt;/li&gt;&lt;li&gt;Given 8 bytes (in big-endian order) containing the two's-complement binary representation of a long, how would you return the long ?&lt;/li&gt;&lt;li&gt;Given a UUID, how would you return a BigInteger representing the numeric value of the underlying 128-bit ?&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;Some possible answers:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;(Don't peek if you want to give it a try!)&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Given a byte, how would you turn the nth bit on ?&lt;blockquote&gt;&lt;pre&gt;    public static byte setBitOn(byte b, int n) {&lt;br /&gt;        return (byte)(b | 1 &lt;&lt; n);&lt;br /&gt;    }&lt;/pre&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Given a byte, how would you turn the nth bit off ?&lt;blockquote&gt;&lt;pre&gt;    public static byte setBitOff(byte b, int n) {&lt;br /&gt;        int mask = 0xFF - (1 &lt;&lt; n);&lt;br /&gt;        return (byte)(b &amp; mask);&lt;br /&gt;    }&lt;/pre&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Given a long, how would you return 8 bytes (in big-endian order) containing the two's-complement binary representation of the long ?&lt;blockquote&gt;&lt;pre&gt;    public static byte[] longTobytes(long val) {&lt;br /&gt;        ByteBuffer bb = ByteBuffer.allocate(8);&lt;br /&gt;        bb.putLong(val);&lt;br /&gt;        return bb.array();&lt;br /&gt;    }&lt;/pre&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Given 8 bytes (in big-endian order) containing the two's-complement binary representation of a long, how would you return the long ?&lt;blockquote&gt;&lt;pre&gt;    public static long bytesTolong(byte[] ba) {&lt;br /&gt;        ByteBuffer bb = ByteBuffer.allocate(8);&lt;br /&gt;        bb.put(ba);&lt;br /&gt;        bb.flip();&lt;br /&gt;        return bb.getLong();&lt;br /&gt;    }&lt;/pre&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Given a UUID, how would you return a BigInteger representing the numeric value of the underlying 128-bit ?&lt;blockquote&gt;&lt;pre&gt;    public static BigInteger toBigInteger(UUID uuid) {&lt;br /&gt;        long msb = uuid.getMostSignificantBits();&lt;br /&gt;        long lsb = uuid.getLeastSignificantBits();&lt;br /&gt;        ByteBuffer bb = ByteBuffer.allocate(16);&lt;br /&gt;        bb.putLong(msb).putLong(lsb);&lt;br /&gt;        return new BigInteger(bb.array());&lt;br /&gt;    }&lt;/pre&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-1647418478229255137?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1647418478229255137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1647418478229255137' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1647418478229255137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1647418478229255137'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/02/some-quizzes-on-bits-bytes-etc.html' title='Some Quizzes on Bits, Bytes, etc.'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-101065176066307256</id><published>2008-01-30T21:18:00.000-08:00</published><updated>2008-03-09T20:11:00.588-07:00</updated><title type='text'>Tuning JVM with ICMS</title><content type='html'>Some readings:&lt;br /&gt;&lt;br /&gt;  http://www.sun.com/bigadmin/content/submitted/cms_gc_logs.html&lt;br /&gt;  http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html&lt;br /&gt;  http://java.sun.com/docs/hotspot/gc1.4.2/example.html&lt;br /&gt;  http://blogs.sun.com/jonthecollector/entry/when_the_sum_of_the&lt;br /&gt;&lt;br /&gt;  http://java.sun.com/j2se/1.5.0/docs/guide/vm/gc-ergonomics.html&lt;br /&gt;  http://performance.netbeans.org/howto/jvmswitches/index.html&lt;br /&gt;  http://java.sun.com/javase/6/docs/technotes/guides/vm/cms-6.html&lt;br /&gt;&lt;br /&gt;  http://java.sun.com/performance/reference/whitepapers/tuning.html&lt;br /&gt;  http://blogs.sun.com/watt/resource/jvm-options-list.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-101065176066307256?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/101065176066307256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=101065176066307256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/101065176066307256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/101065176066307256'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2008/01/tuning-jvm-with-icms.html' title='Tuning JVM with ICMS'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-2884032726316838090</id><published>2007-12-28T17:58:00.000-08:00</published><updated>2008-11-13T23:37:16.666-08:00</updated><title type='text'>File Distribution and Replication via JGroups</title><content type='html'>Here is how I used JGroups (2.6.1) to distribute and replicate files retrieved from a feed, so there is no single point of failure:&lt;blockquote&gt;&lt;a href="http://www.nabble.com/Re%3A-Streaming-Message-Transfer---p14510203.html"&gt;http://www.nabble.com/Re%3A-Streaming-Message-Transfer---p14510203.html&lt;/a&gt;&lt;/blockquote&gt;Here is a reply from Bela Ban basically confirming that the scheme works (via configuring a TCP stack):&lt;blockquote&gt;&lt;a href="http://www.nabble.com/Re%3A-Streaming-Message-Transfer---p14512866.html"&gt;http://www.nabble.com/Re%3A-Streaming-Message-Transfer---p14512866.html&lt;/a&gt;&lt;/blockquote&gt;The whole thread:&lt;blockquote&gt;&lt;a href="http://www.nabble.com/Streaming-Message-Transfer---td14476343.html"&gt;http://www.nabble.com/Streaming-Message-Transfer---td14476343.html&lt;/a&gt;&lt;/blockquote&gt;JGroups rocks!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Update on 13Nov08:&lt;/span&gt;  Or does it ?  After using JGroups for about a year now, it seems JGroups can be quite unreliable when the number of nodes in a cluster grow beyond half a dozen of nodes, especially if they span across a WAN.  Or maybe it's just me ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-2884032726316838090?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/2884032726316838090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=2884032726316838090' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2884032726316838090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2884032726316838090'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/12/file-distribution-and-replication-via.html' title='File Distribution and Replication via JGroups'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-3272865677292251272</id><published>2007-10-24T15:35:00.000-07:00</published><updated>2007-10-26T11:17:39.423-07:00</updated><title type='text'>TextIterable ?</title><content type='html'>Ever wonder why there doesn't exist a kind of Iterable in Java that can work with text file ?  For example:&lt;pre&gt;&lt;blockquote&gt;Iterable ti = new TextIterable(myfile);&lt;br /&gt;&lt;br /&gt;for (String line: ti) {&lt;br /&gt;  // do stuff with line&lt;br /&gt;}&lt;br /&gt;// file automatically opened and closed&lt;br /&gt;&lt;/blockquote&gt;&lt;/pre&gt;Or :&lt;pre&gt;&lt;blockquote&gt;TextIterable ti = new TextIterable(myfile);&lt;br /&gt;int count = 0;&lt;br /&gt;        &lt;br /&gt;for (String line : ti) {&lt;br /&gt;  if (++count &gt; 10)&lt;br /&gt;      break;&lt;br /&gt;  // do stuff with line&lt;br /&gt;}&lt;br /&gt;ti.close();  // explicitly close it&lt;/blockquote&gt;&lt;/pre&gt;You would think something so obvious/simple/needed that someone would have done it already. But search I may, I couldn't find any.  So I ended up building one.  See code below for the TextIterable and a helper class LineIterator.  Note:&lt;ol&gt;&lt;li&gt;You don't need to explicitly open the file and you don't have to explicitly close the file.  As long as you iterate through the entire file, you get the opening/closing automatically done.  Yet to ensure the underlying resource is closed even in the face of exceptions, the TextIterable can be explicitly closed in a finally block.&lt;/li&gt;&lt;li&gt;Or, if you choose to iterate through only part of the file, it can be explicitly closed afterwards.&lt;/li&gt;&lt;li&gt;Each line is loaded on demand, so it would incur minimal memory footprint.&lt;/li&gt;&lt;li&gt;Not only does TextIterable support file, it also support resource path, and for that matter, any url!&lt;/li&gt;&lt;li&gt;TextIterable is threadsafe, but the iterators it produces (ie LineIterator) is not (ie intended to be used in individual threads.)&lt;/li&gt;&lt;li&gt;Support Encodings.&lt;/li&gt;&lt;li&gt;Support Fluent API for configurations.&lt;/li&gt;&lt;li&gt;Think File, URL, resource, rather than Stream, Reader, etc.&lt;/li&gt;&lt;/ol&gt;I think it makes the code much simpler now.  What do you think ?&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Special thanks to &lt;a href="http://www.linkedin.com/in/codesith"&gt;John&amp;nbsp;Xiao&lt;/a&gt; for listening and triggering the support of (2), "lumpynose" for various suggestions, &lt;a href="http://www.yandell.org/henri/"&gt;Henri&amp;nbsp;Yandell&lt;/a&gt; for triggering the support of (6), and &lt;a href="http://www.javaspecialists.eu/"&gt;Dr. Heinz M. Kabutz&lt;/a&gt; for reminding me not to under-estimate the &lt;a href="http://www.javaspecialists.eu/archive/Issue103.html"&gt;force&lt;/a&gt; ;)&lt;/i&gt;&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;/**&lt;br /&gt; * @author Hanson Char&lt;br /&gt; */&lt;br /&gt;@ThreadSafe&lt;br /&gt;public class TextIterable implements Iterable&amp;lt;String&gt;, Closeable {&lt;br /&gt;    private final URL url;&lt;br /&gt;    private final List&amp;lt;LineIterator&gt; openedIterators = new ArrayList&amp;lt;LineIterator&gt;();&lt;br /&gt;    private volatile boolean returnNullUponEof;&lt;br /&gt;    private String charsetname;&lt;br /&gt;    private Charset charset;&lt;br /&gt;    private CharsetDecoder charsetDecoder;&lt;br /&gt;&lt;br /&gt;    public TextIterable(File file) throws MalformedURLException {&lt;br /&gt;        this(file.toURI().toURL());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public TextIterable(URL url) {&lt;br /&gt;        this.url = url;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public TextIterable(String resourcePath) {&lt;br /&gt;        this(&lt;br /&gt;            Thread.currentThread()&lt;br /&gt;                  .getContextClassLoader()&lt;br /&gt;                  .getResource(resourcePath));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public LineIterator iterator() {&lt;br /&gt;        LineIterator ret;&lt;br /&gt;        final String charsetname;&lt;br /&gt;        final Charset charset;&lt;br /&gt;        final CharsetDecoder charsetDecoder;&lt;br /&gt;        &lt;br /&gt;        synchronized(this) {&lt;br /&gt;            charsetname = this.charsetname;&lt;br /&gt;            charset = this.charset;&lt;br /&gt;            charsetDecoder = this.charsetDecoder;&lt;br /&gt;        }&lt;br /&gt;        try {&lt;br /&gt;            if (charsetDecoder != null)&lt;br /&gt;                ret = new LineIterator(this, url.openStream(), returnNullUponEof, charsetDecoder);&lt;br /&gt;            else if (charset != null)&lt;br /&gt;                ret = new LineIterator(this, url.openStream(), returnNullUponEof, charset);&lt;br /&gt;            else if (charsetname != null)&lt;br /&gt;                ret = new LineIterator(this, url.openStream(), returnNullUponEof, Charset.forName(charsetname));&lt;br /&gt;            else&lt;br /&gt;                ret = new LineIterator(this, url.openStream(), returnNullUponEof, (Charset)null);&lt;br /&gt;            synchronized (openedIterators) {&lt;br /&gt;                openedIterators.add(ret);&lt;br /&gt;            }&lt;br /&gt;            return ret;&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            throw new IllegalStateException(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void close() {&lt;br /&gt;        final LineIterator[] lineIterators;&lt;br /&gt;&lt;br /&gt;        synchronized (openedIterators) {&lt;br /&gt;            lineIterators = openedIterators.toArray(&lt;br /&gt;                                        new LineIterator[&lt;br /&gt;                                             openedIterators.size()]);&lt;br /&gt;            for (Iterator&amp;lt;LineIterator&gt; itr=openedIterators.iterator(); itr.hasNext();) {&lt;br /&gt;                itr.next();&lt;br /&gt;                itr.remove();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        for (LineIterator li : lineIterators)&lt;br /&gt;            li.closeInPrivate();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int numberOfopenedIterators() {&lt;br /&gt;        return openedIterators.size();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    void removeLineIterator(LineIterator li) {&lt;br /&gt;        synchronized (openedIterators) {&lt;br /&gt;            openedIterators.remove(li);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean isReturnNullUponEof() {&lt;br /&gt;        return returnNullUponEof;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setReturnNullUponEof(boolean returnNullUponEof) {&lt;br /&gt;        this.returnNullUponEof = returnNullUponEof;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public TextIterable withReturnNullUponEof(boolean returnNullUponEof) {&lt;br /&gt;        setReturnNullUponEof(returnNullUponEof);&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized Charset getCharset() {&lt;br /&gt;        return charset;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized void setCharset(Charset charset) {&lt;br /&gt;        this.charset = charset;&lt;br /&gt;        this.charsetname = null;&lt;br /&gt;        this.charsetDecoder = null;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public TextIterable withCharset(Charset charset) {&lt;br /&gt;        setCharset(charset);&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized CharsetDecoder getCharsetDecoder() {&lt;br /&gt;        return charsetDecoder;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized void setCharsetDecoder(CharsetDecoder charsetDecoder) {&lt;br /&gt;        this.charsetDecoder = charsetDecoder;&lt;br /&gt;        this.charsetname = null;&lt;br /&gt;        this.charset = null;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public TextIterable withCharsetDecoder(CharsetDecoder charsetDecoder) {&lt;br /&gt;        setCharsetDecoder(charsetDecoder);&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized String getCharsetname() {&lt;br /&gt;        return charsetname;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized void setCharsetname(String charsetname) {&lt;br /&gt;        this.charsetname = charsetname;&lt;br /&gt;        this.charset = null;&lt;br /&gt;        this.charsetDecoder = null;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public TextIterable withCharsetname(String charsetname) {&lt;br /&gt;        setCharsetname(charsetname);&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author Hanson Char&lt;br /&gt; */&lt;br /&gt;@NotThreadSafe&lt;br /&gt;class LineIterator implements Iterator&amp;lt;String&gt;, Closeable {&lt;br /&gt;    private boolean hasNextExecuted;&lt;br /&gt;    private String line;&lt;br /&gt;    private LineNumberReader lnr;&lt;br /&gt;    private final TextIterable textIterable;&lt;br /&gt;    private final boolean returnNullUponEof;&lt;br /&gt;&lt;br /&gt;    LineIterator(TextIterable textIterable, InputStream is, boolean returnNullUponEof, Charset charset) {&lt;br /&gt;        this.textIterable = textIterable;&lt;br /&gt;        this.returnNullUponEof = returnNullUponEof;&lt;br /&gt;        InputStreamReader isr = null;&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            isr = charset == null &lt;br /&gt;                ? new InputStreamReader(is) &lt;br /&gt;                : new InputStreamReader(is, charset)&lt;br /&gt;                ;&lt;br /&gt;            lnr = new LineNumberReader(isr);&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            try {&lt;br /&gt;                if (lnr != null)&lt;br /&gt;                    lnr.close();&lt;br /&gt;                else if (isr != null)&lt;br /&gt;                    isr.close();&lt;br /&gt;                else if (is != null)&lt;br /&gt;                    is.close();&lt;br /&gt;            } catch (Throwable ignore) {&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    LineIterator(TextIterable textIterable, InputStream is, boolean returnNullUponEof, CharsetDecoder decoder) {&lt;br /&gt;        this.textIterable = textIterable;&lt;br /&gt;        this.returnNullUponEof = returnNullUponEof;&lt;br /&gt;        InputStreamReader isr = null;&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            isr = new InputStreamReader(is, decoder);&lt;br /&gt;            lnr = new LineNumberReader(isr);&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            try {&lt;br /&gt;                if (lnr != null)&lt;br /&gt;                    lnr.close();&lt;br /&gt;                else if (isr != null)&lt;br /&gt;                    isr.close();&lt;br /&gt;                else if (is != null)&lt;br /&gt;                    is.close();&lt;br /&gt;            } catch (Throwable ignore) {&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean hasNext() {&lt;br /&gt;        if (hasNextExecuted)&lt;br /&gt;            return line != null;&lt;br /&gt;        try {&lt;br /&gt;            hasNextExecuted = true;&lt;br /&gt;&lt;br /&gt;            if (lnr != null) {&lt;br /&gt;                line = lnr.readLine();&lt;br /&gt;&lt;br /&gt;                if (line == null)&lt;br /&gt;                    close();&lt;br /&gt;            }&lt;br /&gt;            return line != null;&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            throw new IllegalStateException(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String next() {&lt;br /&gt;        if (hasNextExecuted) {&lt;br /&gt;            hasNextExecuted = false;&lt;br /&gt;            return line == null &lt;br /&gt;                 ? eof() &lt;br /&gt;                 : line&lt;br /&gt;                 ;&lt;br /&gt;        }&lt;br /&gt;        return hasNext() &lt;br /&gt;             ? next() &lt;br /&gt;             : eof()&lt;br /&gt;             ;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    private String eof() {&lt;br /&gt;        if (returnNullUponEof)&lt;br /&gt;            return null;&lt;br /&gt;        throw new NoSuchElementException();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void close() {&lt;br /&gt;        if (lnr != null) {&lt;br /&gt;            textIterable.removeLineIterator(this);&lt;br /&gt;            closeInPrivate();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public int getLineNumber() {&lt;br /&gt;        return lnr == null  &lt;br /&gt;             ? -1 &lt;br /&gt;             : lnr.getLineNumber()&lt;br /&gt;             ;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    void closeInPrivate() {&lt;br /&gt;        if (lnr != null) {&lt;br /&gt;            try {&lt;br /&gt;                lnr.close();&lt;br /&gt;            } catch (IOException ignore) {&lt;br /&gt;            }&lt;br /&gt;            line = null;&lt;br /&gt;            lnr = null;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void remove() {&lt;br /&gt;        throw new UnsupportedOperationException("remove not supported");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void finalize() {&lt;br /&gt;        try {&lt;br /&gt;            super.finalize();&lt;br /&gt;        } catch (Throwable ex) {&lt;br /&gt;        }&lt;br /&gt;        close();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-3272865677292251272?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/3272865677292251272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=3272865677292251272' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3272865677292251272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3272865677292251272'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/10/textiterable.html' title='TextIterable ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5812981552454609943</id><published>2007-10-01T10:59:00.000-07:00</published><updated>2007-10-01T11:04:16.681-07:00</updated><title type='text'>Nice command line parser</title><content type='html'>Other interesting ones &lt;a href="http://mult.ifario.us/articles/2006/01/11/command-line-argument-parsing-in-java"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5812981552454609943?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://code.google.com/p/cli-parser/' title='Nice command line parser'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5812981552454609943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5812981552454609943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5812981552454609943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5812981552454609943'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/10/my-favorite-command-line-parser.html' title='Nice command line parser'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-750346329356471405</id><published>2007-09-26T21:42:00.000-07:00</published><updated>2007-09-26T22:35:39.664-07:00</updated><title type='text'>Epigrams In Programming</title><content type='html'>by &lt;a href="http://en.wikiquote.org/wiki/Alan_Perlis"&gt;Alan J. Perlis&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-750346329356471405?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.cs.yale.edu/quotes.html' title='Epigrams In Programming'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/750346329356471405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=750346329356471405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/750346329356471405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/750346329356471405'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/09/epigrams-in-programming.html' title='Epigrams In Programming'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8039544336895169054</id><published>2007-09-26T19:23:00.000-07:00</published><updated>2007-09-26T19:26:36.827-07:00</updated><title type='text'>Perfection</title><content type='html'>Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.  -&amp;nbsp;Antoine&amp;nbsp;de&amp;nbsp;Saint-Exupery&amp;nbsp;(1900-1944)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8039544336895169054?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.quotationspage.com/quote/26979.html' title='Perfection'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8039544336895169054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8039544336895169054' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8039544336895169054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8039544336895169054'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/09/perfection.html' title='Perfection'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1180289268429264164</id><published>2007-09-01T20:11:00.000-07:00</published><updated>2007-09-05T23:16:51.481-07:00</updated><title type='text'>Parametric Initialization On Demand Holder Idiom</title><content type='html'>Similar to the &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl"&gt;Initialization On Demand Holder&lt;/a&gt; (IODH) Idiom , it occurs to me that sometimes not only is there a need to access a singleton instance, which is lazily initialized if constructed for the first time, but also to initialize with parameters, which are ignored if the singleton instance has already been constructed.  Also, if there is concurrent access to the singleton instance for the very first time, it doesn't matter from which thread the parameters are passed, as long as the parameters are specified by one of these threads (ie the parameters don't come "out-of-thin-air".)&lt;br /&gt;&lt;br /&gt;The API would be something like:&lt;blockquote&gt;&lt;pre&gt;   SomethingMore singleton = SomethingMore.getInstance(params);&lt;/pre&gt;&lt;/blockquote&gt;Now this begs the question: similar to the original IODH Idiom, can the implementation of such Parametric IODH Idiom be thread-safe without explicit synchronization ?&lt;br /&gt;&lt;br /&gt;See below for 2 proposed implementations.  &lt;a href="#piodhi-immutable"&gt;One&lt;/a&gt; requires the parameter to be immutable, and &lt;a href="#piodhi-thread-safe"&gt;the other&lt;/a&gt; requires the parameter to be only thread-safe.&lt;blockquote&gt;&lt;pre&gt;&lt;a name="piodhi-immutable"&gt;/**&lt;br /&gt; * Parametric Initialization On Demand Holder Idiom 1&lt;br /&gt; * - requires parameter to be immutable and thread-safe&lt;br /&gt; * even in the face of unsafe publication.&lt;br /&gt; * (Usually such immutability can be achieved via final fields.)&lt;br /&gt; *  &lt;br /&gt; * @author Hanson Char&lt;br /&gt; */&lt;/a&gt;&lt;br /&gt;public class SomethingMore &lt;br /&gt;{&lt;br /&gt;    /** &lt;br /&gt;     * An immutable value,&lt;br /&gt;     * such as a {@link String} instance. &lt;br /&gt;     */&lt;br /&gt;    private final Object value;&lt;br /&gt;    private SomethingMore(Object value) { this.value = value; }&lt;br /&gt;    public Object getValue() { return value; }&lt;br /&gt;&lt;br /&gt;    /** &lt;br /&gt;     * A temporary buffer to hold the immutable value used to initialize &lt;br /&gt;     * the singleton instance of SomethingMore.&lt;br /&gt;     * Note it is an unsafe publication, but that's ok as &lt;br /&gt;     * the immutable value passed in is required to be thread-safe even&lt;br /&gt;     * in the face of unsafe publication.&lt;br /&gt;     */&lt;br /&gt;    private static Object valueHolder;&lt;br /&gt;    private static class LazySomethingMoreHolder {&lt;br /&gt;        public static SomethingMore something = new SomethingMore(valueHolder);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    /**&lt;br /&gt;     * Returns the singleton instance of {@link SomethingMore}.&lt;br /&gt;     * &lt;br /&gt;     * @param value an immutable value used to initialize the &lt;br /&gt;     * singleton instance of SomethingMore, if the instance is &lt;br /&gt;     * constructed for the first time;  &lt;br /&gt;     * ignored otherwise.  &lt;br /&gt;     * Note immutability (ie lack of mutator methods) &lt;br /&gt;     * itself is not sufficient.&lt;br /&gt;     * The immutable value must be thread-safe even&lt;br /&gt;     * in the face of unsafe publication.&lt;br /&gt;     * (Usually such immutability can be achieved via final fields.)&lt;br /&gt;     * Caller of this method is responsible for passing in a&lt;br /&gt;     * value which is immutable and thread-safe even in the&lt;br /&gt;     * face of unsafe publication,&lt;br /&gt;     * such as a {@link String} instance. &lt;br /&gt;     */&lt;br /&gt;    public static SomethingMore getInstance(Object value) {&lt;br /&gt;        SomethingMore.valueHolder = value;&lt;br /&gt;        return LazySomethingMoreHolder.something;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;a name="piodhi-thread-safe"&gt;/**&lt;br /&gt; * &lt;strong&gt;Parametric Initialization On Demand Holder Idiom 2&lt;/strong&gt;&lt;br /&gt; * &lt;strong&gt;- requires parameter to be thread-safe.&lt;/strong&gt;&lt;br /&gt; * &lt;br /&gt; * @author Hanson Char&lt;br /&gt; */&lt;/a&gt;&lt;br /&gt;public class SomethingMoreSafe &lt;br /&gt;{&lt;br /&gt;    /** A thread-safe value, such as a {@link String} instance. */&lt;br /&gt;    private final Object value;&lt;br /&gt;    private SomethingMoreSafe(Object value) { this.value = value; }&lt;br /&gt;    public Object getValue() { return value; }&lt;br /&gt;    &lt;br /&gt;    private static final ThreadLocal&lt;Object&gt; tlocal = new ThreadLocal&lt;Object&gt;();&lt;br /&gt;    private static class LazySomethingMoreSafeHolder {&lt;br /&gt;        public static SomethingMoreSafe something = new SomethingMoreSafe(tlocal.get());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Returns the singleton instance of {@link SomethingMoreSafe}.&lt;br /&gt;     * &lt;br /&gt;     * @param value a thread-safe value used to initialize the &lt;br /&gt;     * singleton instance of SomethingMoreSafe, if the instance is &lt;br /&gt;     * constructed for the first time;  &lt;br /&gt;     * ignored otherwise.&lt;br /&gt;     * Caller of this method is responsible for passing in a&lt;br /&gt;     * value which is thread-safe, &lt;br /&gt;     * such as a {@link String} instance. &lt;br /&gt;     */&lt;br /&gt;    public static SomethingMoreSafe getInstance(Object value) {&lt;br /&gt;        tlocal.set(value);&lt;br /&gt;        try {&lt;br /&gt;            return LazySomethingMoreSafeHolder.something;&lt;br /&gt;        } finally {&lt;br /&gt;            tlocal.remove();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;Special thanks to Joe Bowbeer, David Holmes, Dhanji R. Prasanna and Jeremy Manson for their help in the &lt;a href="http://www.nabble.com/Parametric-Initialization-On-Demand-Holder-Idiom---tf4357446.html"&gt;JSR-166 concurrency forum&lt;/a&gt;.  More discussion can be found &lt;a href="http://www.nabble.com/Parametric-Initialization-On%09DemandHolder-Idiom---tf4384557.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-1180289268429264164?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1180289268429264164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1180289268429264164' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1180289268429264164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1180289268429264164'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/09/parametric-initialization-on-demand.html' title='Parametric Initialization On Demand Holder Idiom'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-1077283346531080433</id><published>2007-07-25T01:03:00.000-07:00</published><updated>2007-07-25T01:06:30.435-07:00</updated><title type='text'>SQL*Plus column formatting</title><content type='html'>column &lt;span style="font-family: courier new;"&gt;column_name&lt;/span&gt; format a50 word_wrapped&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-1077283346531080433?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.adp-gmbh.ch/ora/sqlplus/column.html' title='SQL*Plus column formatting'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/1077283346531080433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=1077283346531080433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1077283346531080433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/1077283346531080433'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/07/sqlplus-column-formatting.html' title='SQL*Plus column formatting'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-7585633183791775166</id><published>2007-06-26T14:53:00.000-07:00</published><updated>2007-06-26T14:55:27.611-07:00</updated><title type='text'>pgrep, ps, etc.</title><content type='html'>pgrep -lf jdk&lt;br /&gt;# Starting time or date of a process&lt;br /&gt;ps -o start_time &amp;lt;pid&gt;&lt;br /&gt;# Elapsed time of a process&lt;br /&gt;ps -o "%t" &amp;lt;pid&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-7585633183791775166?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/7585633183791775166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=7585633183791775166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7585633183791775166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/7585633183791775166'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/06/pgrep-ps-etc.html' title='pgrep, ps, etc.'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-2725262524368321045</id><published>2007-06-18T15:31:00.000-07:00</published><updated>2011-12-15T00:43:54.359-08:00</updated><title type='text'>OpenSsl/Keytool Cheat Sheet</title><content type='html'>&lt;pre&gt;# Convert an RSA public key from PEM to DER&lt;br /&gt;openssl rsa -inform PEM -in test-public-key.pem -outform DER -out test-public-key.der -pubin&lt;br /&gt;&lt;br /&gt;# Convert a X509 certificate from PEM to DER&lt;br /&gt;openssl x509 -in test-x509-cert.pem -inform PEM -out test-x509-cert.der -outform DER&lt;br /&gt;&lt;br /&gt;# Print a X509 certificate&lt;br /&gt;openssl x509 -text -in test-public-cert.pem&lt;br /&gt;&lt;br /&gt;# Import a certificate to JKS&lt;br /&gt;jdk1.6.0/bin/keytool -storepass changeit -keystore truststore.jks -importcert -alias mycert -file mycert.der -trustcacerts&lt;br /&gt;&lt;br /&gt;# &lt;a href="http://www.agentbob.info/agentbob/79.html"&gt;http://www.agentbob.info/agentbob/79.html&lt;/a&gt;&lt;br /&gt;# Read the javadoc in ImportKey.java for details of converting it to a keystore&lt;br /&gt;&lt;br /&gt;# Convert a private key from PEM to DER&lt;br /&gt;openssl pkcs8 -topk8 -nocrypt -in private-key.pem -out private-key.der -outform der&lt;br /&gt;&lt;br /&gt;# Convert cert from PEM to DER&lt;br /&gt;openssl x509 -in cert.pem -out cert.der -outform der&lt;br /&gt;&lt;br /&gt;# Convert private key and cert to keystore&lt;br /&gt;java -cp . ImportKey private-key.der cert.der&lt;br /&gt;&lt;br /&gt;# Change the storepass&lt;br /&gt;keytool -keystore keystore.jks -storepass importkey -storepasswd -new changeit&lt;br /&gt;&lt;br /&gt;# Change the alias&lt;br /&gt;keytool -keystore keystore.jks -storepass changeit -changealias -alias importkey -keypass importkey -destalias myhost&lt;br /&gt;&lt;br /&gt;# Change the keypass&lt;br /&gt;keytool -keystore keystore.jks -storepass changeit -alias myhost -keypasswd -keypass importkey -new changeit&lt;br /&gt;&lt;br /&gt;# List the keystore&lt;br /&gt;keytool -keystore keystore.jks -storepass changeit -list -v&lt;br /&gt;&lt;br /&gt;# How to generate a self-signed key pairs using keytool ?&lt;br /&gt;keytool -genkeypair -dname "cn=myname,ou=myunit,o=myorg,c=AU" -alias myalias -keypass changeit -keystore ./my-keystore.jks&lt;br /&gt;-keypass changeit -storepass changeit -validity 9999 -v&lt;br /&gt;&lt;br /&gt;### Extracting the certificate (public key) ###&lt;br /&gt;&lt;br /&gt;# Export the X509 certificate&lt;br /&gt;keytool -export -alias myalias -keystore my-keystore.jks -storepass changeit -file mycert.der&lt;br /&gt;&lt;br /&gt;# Display it&lt;br /&gt;openssl x509 -noout -text -in mycert.der -inform der&lt;br /&gt;&lt;br /&gt;# Convert to PEM&lt;br /&gt;openssl x509 -out mycert.pem -outform pem -in mycert.der -inform der&lt;br /&gt;&lt;br /&gt;### Extracting the private key ###&lt;br /&gt;&lt;br /&gt;#Download, compile &amp; run &lt;a href="http://mark.foster.cc/pub/java/ExportPriv.java"&gt;ExportPriv&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;# Export private key into pcks8 format&lt;br /&gt;javac ExportPriv.java&lt;br /&gt;java ExportPriv my-keystore.jks myalias changeit &amp;gt; my-key.pkcs8&lt;br /&gt;&lt;br /&gt;# Combine public and private key into pkcs12 format&lt;br /&gt;openssl pkcs12 -export -out my-key.p12 -inkey my-key.pkcs8 -in my-cert.pem&lt;br /&gt;&lt;br /&gt;# Convert pkc12 to PEM so it can be displayed&lt;br /&gt;openssl pkcs12 -in pkcs-12-certificate(-and-key-file) -out pem-certificate(-and-key-file)&lt;br /&gt;&lt;br /&gt;# Find out the MD5 of an X509 cert&lt;br /&gt;openssl x509 -fingerprint -md5 -in cert.pem &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/6715087-2725262524368321045?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/2725262524368321045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=2725262524368321045' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2725262524368321045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/2725262524368321045'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/06/opensslkeytool-cheat-sheet.html' title='OpenSsl/Keytool Cheat Sheet'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-437983095866418748</id><published>2007-06-13T09:38:00.000-07:00</published><updated>2007-06-13T10:15:34.670-07:00</updated><title type='text'>Hacking JGroups Util.java</title><content type='html'>Recently I encountered a resource loading problem in &lt;a href="http://www.jgroups.org/"&gt;JGroups&lt;/a&gt; from within a Tomcat webapp when trying to construct a &lt;a href="http://www.jgroups.org/javagroupsnew/docs/javadoc/org/jgroups/JChannel.html"&gt;JChannel&lt;/a&gt; when so triggered from a JMX MBean via the jconsole:&lt;blockquote&gt;&lt;pre&gt;    channel = new JChannel("tcp.xml");&lt;/pre&gt;&lt;/blockquote&gt;Basically if the JChannel is constructed from the webapp, it can locate the "tcp.xml" as a resource and works just fine.  However if the JChannel is constructed from an MBean call stack via the jconsole, it failed to locate the resource due to the fact that the context classloading of the executing thread is different.  So I hacked &lt;a href="http://www.jgroups.org/javagroupsnew/docs/javadoc/org/jgroups/util/Util.html"&gt;org.jgroups.util.Util&lt;/a&gt; to make it work in both cases.  I made the hack on jgroups 2.2.9.4 , but I tried the latest 2.5.0CR1 which also seemed to exhibit the same problem/behavior. More details below.&lt;br /&gt;&lt;br /&gt;My question is: should the hack I made be incorporated into the official version ?  Guess what ?  The next day, &lt;a href="http://www.cs.cornell.edu/home/bba/"&gt;Bela Ban&lt;/a&gt;, the JGroups Lead / JBoss Clustering team, unconditionally accepted this change into the official JGroups 2.4 branch and the CVS head.  &lt;span style="font-style:italic;"&gt;Yeah!&lt;/span&gt;&lt;blockquote&gt;&lt;pre&gt;public class Util {&lt;br /&gt;...&lt;br /&gt;    public static InputStream getResourceAsStream(String name, Class clazz) {&lt;br /&gt;        ClassLoader loader;&lt;br /&gt;                                                                                                                   &lt;br /&gt;        try {&lt;br /&gt;            loader=Thread.currentThread().getContextClassLoader();&lt;br /&gt;            if(loader != null) {&lt;br /&gt;// hack: returns only if resource is found&lt;br /&gt;//                return loader.getResourceAsStream(name);&lt;br /&gt;              InputStream is = loader.getResourceAsStream(name);&lt;br /&gt;                                                                                                                   &lt;br /&gt;              if (is != null)&lt;br /&gt;                  return is;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        catch(Throwable t) {&lt;br /&gt;        }&lt;br /&gt;                                                                                                                   &lt;br /&gt;        if(clazz != null) {&lt;br /&gt;            try {&lt;br /&gt;                loader=clazz.getClassLoader();&lt;br /&gt;                if(loader != null) {&lt;br /&gt;// hack: returns only if resource is found&lt;br /&gt;//                    return loader.getResourceAsStream(name);&lt;br /&gt;                    InputStream is = loader.getResourceAsStream(name);&lt;br /&gt;                                                                                                                   &lt;br /&gt;                    if (is != null)&lt;br /&gt;                        return is;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            catch(Throwable t) {&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        try {&lt;br /&gt;            loader= ClassLoader.getSystemClassLoader();&lt;br /&gt;            if(loader != null) {&lt;br /&gt;                return loader.getResourceAsStream(name);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        catch(Throwable t) {&lt;br /&gt;        }&lt;br /&gt;                                                                                                                   &lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-437983095866418748?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/437983095866418748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=437983095866418748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/437983095866418748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/437983095866418748'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/06/hacking-orgjgroupsutilutilgetresourceas.html' title='Hacking JGroups Util.java'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4390321173998232170</id><published>2007-06-11T11:57:00.000-07:00</published><updated>2007-06-11T12:55:38.193-07:00</updated><title type='text'>Two-Phase-Commit Activation Protocol</title><content type='html'>Continuing on the previous post on &lt;a href="http://hansonchar.blogspot.com/2007/06/guaranteed-db-activation-in-all-jvms.html"&gt;"&lt;span style="font-style: italic;"&gt;Guaranteed db activation in all JVM's before table unlock in HA-JDBC ?&lt;/span&gt;"&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;Actually, I think just doing a synchronous notification is not sufficient.  What is required is an atomic/transactional activation of the specified db in all nodes - either all commit or rollback.&lt;br /&gt;&lt;br /&gt;This naturally brings up the thought of using 2PC (Two Phase Commit) protocol.  Here is a proposal.  Say we have a synchronizing node S(ync), and two other members F(oo) and B(ar):&lt;h3&gt;2PC Activation Protocol&lt;/h3&gt;&lt;span style="font-family: verdana;"&gt;(Assuming tables in the active db are locked, and synchronization has just completed and S is now trying to atomically/transactionally activate the inactive db in all JVM's before unlocking the tables.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;&lt;span style="font-weight:bold;"&gt;From S's perspective:&lt;/span&gt;&lt;/span&gt;&lt;ol style="font-family: verdana;"&gt;&lt;li&gt;S synchronously sends an "ActivationReady" message to F and B.  If all such sending failed, simply aborts this 2PC activation procedure (ie inactive db stays inactive).  If some but not all such sending failed, S sends an "ActivationAbort" message to others that it has previously successfully sent the ActivationReady message, and then simply aborts this 2PC activation procedure (ie inactive db stays inactive).  Else proceed to (2).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;S synchronously sends an "ActivationCommit" message to F and B and then always activates the inactive db locally (regardless of whether any or all of the sending was successful.)&lt;br /&gt;&lt;br /&gt;(Note that S always unlocks the tables in the active db afterwards, regardless of whether the 2PC activation has been aborted or not.  However, if S detects any possible failure during commit or rollback, it must wait for the other nodes to timeout before unlocking the tables.)&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: verdana; "&gt;&lt;span style="font-weight:bold;"&gt;From F or B's perspective:&lt;/span&gt;&lt;/span&gt;&lt;ul style="font-family: verdana;"&gt;&lt;li&gt;If it receives an ActivationReady message followed by an ActivationAbort message, do nothing.&lt;/li&gt;&lt;li&gt;If it receives an ActivationReady message followed by an ActivationCommit message, activate the specified db locally.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In the extreme case that after an ActivationReady message is received but failed to received a subsequent ActivationCommit or ActivationAbort message received within, say, 5 secs, deactivate all db's locally.  (This is to prevent any possible compromise to data consistency caused by not knowing whether the db in concern has been activated in other JVM's or not.)&lt;/li&gt;&lt;/ul&gt;Too complex ?  Well, &lt;a href="http://freshmeat.net/~pferraro/"&gt;Paul Ferraro&lt;/a&gt;, the creator of &lt;a href="http://ha-jdbc.sourceforge.net/"&gt;HA-JDBC&lt;/a&gt;, seems to think so:&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"I think you are over-engineering this a bit...&lt;br /&gt;&lt;br /&gt;Database activation does not benefit from two-phase commit (2pc). The purpose of 2pc is to provide distributed consistency to a fallible operation.  The operation in this case, activating a database, is not fallible - it is merely the insertion of a element into a collection, i.e. Balancer.add(...).&lt;br /&gt;&lt;br /&gt;If you are curious about an instance where 2pc is warranted, check out the DistributableLockManager in HA-JDBC 2.0, which utilizes the JGroups TwoPhaseVotingAdapter."&lt;/span&gt;&lt;/blockquote&gt;But then what should we do in the case when the synchronous activation notification (presuming it has been implemented) to other JVM's resulted in partial success ?  In other words, some get notified (and therefore have the inactive db activated) and some not ?&lt;br /&gt;&lt;br /&gt;Wouldn't that result in data inconsistency (since some JVM which are succesfully notified would start to write to all the active db's in the cluster, whereas some JVM which are not succesfully notified would continue to write to only some but not all active db's in the cluster) ?&lt;br /&gt;&lt;br /&gt;Some interesting comments from &lt;a href="http://www.cs.cornell.edu/home/bba/"&gt;Bela Ban&lt;/a&gt;, the &lt;a href="http://www.cs.cornell.edu/home/bba/javagroups.html"&gt;JGroups&lt;/a&gt; Lead/ JBoss Clustering team:&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"Yes, if you want atomicity guarantees, you either have to use a uniform protocol (a message is only delivered if all receivers acked it, otherwise it will not get delivered at anyone) or 2PC as you outlined below. Uniform delivery is not part of JGroups, although it is on the todo list (&lt;a href="http://jira.jboss.com/jira/browse/JGRP-138"&gt;http://jira.jboss.com/jira/browse/JGRP-138&lt;/a&gt;). I once had an impl, but it was too slow so I trashed it.&lt;br /&gt;&lt;br /&gt;2PC is probably the way to go. I've done this in JBossCache: if you look at the code that is run when you have (a) a transaction and (b)synchronous method calls, then I pretty much run the classic PREPARE --&gt; success? COMMIT : ROLLBACK pattern.&lt;br /&gt;&lt;br /&gt;What you describe is such an implementation, but I guess that's something to be discussed in the scope of HA-JDBC. JGroups just provides the reliable transport with retransmission (lossless transport) and ordering."&lt;/span&gt;&lt;/blockquote&gt;More tips from Bela Ban:&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;"The RequestCorrelator is used by both MessageDispatcher and RpcDispatcher, it is at a lower abstraction level. I would suggest RpcDispatcher (for sync or async cluster-wide method calls) or MessageDispatcher (for sync or async cluster-wide message sending). Note that RpcDispatcher uses MessageDispatcher which uses RequestCorrelator.&lt;br /&gt;&lt;br /&gt;In both RpcDispatcher.callRemoteMethods() and MessageDispatcher.castMessage() you get back an RspList which contains the result per member:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The result (null if method was void)&lt;/li&gt;&lt;li&gt;Whether the member was suspected, e.g. if you invoke foo() on {A,B,C,D}, and C crashes while you wait for acks, then C will be flagged as suspected in the response list&lt;/li&gt;&lt;li&gt;Whether we received an ack (if the call is bounded by a timeout)&lt;/li&gt;&lt;/ul&gt;Paul, I'd suggest you use an {Rpc/Message}Dispatcher directly rather than NotificationBus. NB was designed to be a simple asynchronous notification mechanism."&lt;/span&gt;&lt;/blockquote&gt;What do you think ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4390321173998232170?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4390321173998232170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4390321173998232170' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4390321173998232170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4390321173998232170'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/06/two-phase-commit-activation-protocol.html' title='Two-Phase-Commit Activation Protocol'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4216416440082385780</id><published>2007-06-11T11:41:00.000-07:00</published><updated>2007-06-11T12:49:38.517-07:00</updated><title type='text'>Guaranteed db activation in all JVM's before table unlock in HA-JDBC ?</title><content type='html'>Say we have multiple JVM members accessing a &lt;a href="http://ha-jdbc.sourceforge.net/"&gt;HA-JDBC&lt;/a&gt; database cluster which involves a table locking synchronization strategy.  Currently after a (inactive) db is synchronized, the code in ha-jdbc 1.1.11, method&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;    private void LocalDatabaseCluster#activate(Database, List&lt;Database&gt;, SynchronizationStrategy) &lt;br /&gt;        throws java.sql.SQLException&lt;/pre&gt;&lt;/blockquote&gt;would activate the inactive db (both in the local JVM and other JVM's via jgroup notification) before executing a rollback which would unlock the tables in the active db.&lt;br /&gt;&lt;br /&gt;My question is that when the &lt;a href="http://www.jgroups.org/"&gt;JGroups&lt;/a&gt; notification of the activation to other JVM's is returned, does it mean&lt;br /&gt;a) all other JVM's have successfully received the notification, or&lt;br /&gt;b) some (or none or all) of the other JVM's have successfully received the notification, or&lt;br /&gt;c) whether this only means the notification has been sent to other JVM's which may or may not receive the notification ?&lt;br /&gt;&lt;br /&gt;If it is (b) or (c), is there any way to achieve/guarantee (a) ?  The reason is that, for data consistency purposes, I am trying to provide the guarantee that all JVM's must have the (inactive) database activated before the table locks are released, or otherwise I'd rather to have the activation fail (ie inactive db stays inactive).&lt;br /&gt;&lt;br /&gt;Unfortunately, at least for now, it turns out the answer is (c), as quoted from &lt;a href="http://freshmeat.net/~pferraro/"&gt;Paul Ferraro&lt;/a&gt;, the creator of &lt;a href="http://ha-jdbc.sourceforge.net/"&gt;HA-JDBC&lt;/a&gt;, at the &lt;a href="mailto:ha-jdbc-user@lists.sourceforge.net"&gt;ha-jdbc-user&lt;/a&gt; forum:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;"Excellent question...&lt;br /&gt;&lt;br /&gt;The distributed cluster state is implemented using a JGroups NotificationBus.  Database activations and deactivations trigger appropriate notification events to listening members.  I had always thought that NotificationBus operated synchronously, i.e. that NotificationBus.sendNotification(...) would not return until all nodes complete their NotificationBus.Consumer.handleNotificaiton(...) listener methods.  I just completed a test against both JGroups 2.2.9.4 and 2.5-beta-2 - unfortunately, this is not the case.  A synchronous messaging bus requires the use of a RequestCollator, and is not used by NotificationBus.  I don't remember at what point I made this assumption - but I was wrong.&lt;br /&gt;&lt;br /&gt;So the answer to your question - although my intention was (a), currently, it is (c).  This needs to change.  I need to re-implement DistributableDatabaseCluster (DistributableStateManager, in 2.0) to use a MessageDispatcher, DistributedQueue, or some other construct that utilizes a RequestCollator...."&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4216416440082385780?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4216416440082385780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4216416440082385780' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4216416440082385780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4216416440082385780'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/06/guaranteed-db-activation-in-all-jvms.html' title='Guaranteed db activation in all JVM&apos;s before table unlock in HA-JDBC ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4951711478608288512</id><published>2007-06-06T23:33:00.001-07:00</published><updated>2007-06-06T23:34:29.390-07:00</updated><title type='text'>Java Debug Interface</title><content type='html'>Just realize &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdi/"&gt;JDI&lt;/a&gt; is such a powerful interface with implementation available in the jdk's tools.jar.  Imagine you can write your own code to launch other VM's or attach to a running VM, inspect the executing threads, print out what methods the target VM is executing, etc.  Essentially, with JDI, you can programmatically do whatever a debugger can with ease!&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://search.cpan.org/src/PHILCROW/UML-Sequence-0.07/java/"&gt;here&lt;/a&gt; for some interesting sample code built on JDI.&lt;br /&gt;See &lt;a href="http://bracha.org/mirrors.pdf"&gt;here&lt;/a&gt; for an interesting article by Gilad Bracha and David Ungar about Meta-Programming facilities somehow related to JDI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4951711478608288512?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4951711478608288512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4951711478608288512' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4951711478608288512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4951711478608288512'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/06/java-debug-interface.html' title='Java Debug Interface'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-3851988195511373606</id><published>2007-05-21T00:39:00.001-07:00</published><updated>2009-01-07T13:56:16.518-08:00</updated><title type='text'>Heap Dump in Java 6</title><content type='html'>Just experimenting with the use of jmap and jhat in Java 6.  The Object Query Language in jhat that allows the use of javascript closure seems pretty powerful, though also pretty slow.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Practices&lt;/span&gt;&lt;br /&gt;# Find out the jvm pid&lt;br /&gt;jps &lt;br /&gt;# Trigger heap dump&lt;br /&gt;jmap -dump:format=b,file=/tmp/java_app-heap.bin &amp;lt;pid&gt;&lt;br /&gt;&lt;br /&gt;# Analyzing the heap dump&lt;br /&gt;jhat -J-Xmx326m /tmp/java_app-heap.bin&lt;br /&gt;&lt;br /&gt;http://localhost:7000/showInstanceCounts/&lt;br /&gt;http://localhost:7000/oql&lt;blockquote&gt;&lt;pre&gt;#Find out the total size of MyClass instances&lt;br /&gt;select sum(map(heap.objects('foo.bar.MyClass'), 'sizeof(it)'))&lt;br /&gt;&lt;br /&gt;# List out all class names matching "foo.bar"&lt;br /&gt;select filter(heap.classes(), "/foo.bar/(it.name)")&lt;br /&gt;&lt;br /&gt;# Ditto&lt;br /&gt;select map(filter(heap.classes(), "/foo.bar/(it.name)"),&lt;br /&gt;    function(c) {&lt;br /&gt;      return "&amp;lt;br&gt;"+ c.name;&lt;br /&gt;    })&lt;br /&gt;&lt;br /&gt;# List classes that match "foo.bar" with instances &gt; 0&lt;br /&gt;select map(filter(heap.classes(), "/foo.bar/(it.name)"),&lt;br /&gt;    function(c) {&lt;br /&gt;      var len = length(heap.objects(c));&lt;br /&gt;      if (len == 0) return "";&lt;br /&gt;      return "&amp;lt;br&gt;" + c.name + ", instances:" + len;&lt;br /&gt;    })&lt;br /&gt;&lt;br /&gt;# List classes that match "foo.bar" with instance sizes &gt; 0&lt;br /&gt;select map(filter(heap.classes(), "/foo.bar/(it.name)"),&lt;br /&gt;    function(c) {&lt;br /&gt;      var totalsize = sum(map(heap.objects(c), &lt;br /&gt;          function(o) {&lt;br /&gt;              return sizeof(o);&lt;br /&gt;          }&lt;br /&gt;      ));&lt;br /&gt;      if (totalsize == 0) return "";&lt;br /&gt;      return "&amp;lt;br&gt;" + c.name + ", size:" + totalsize;&lt;br /&gt;    })&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;More info&lt;/span&gt;&lt;br /&gt;&lt;a href="http://javatools.wordpress.com/2007/03/29/howto-find-java-memory-leaks/"&gt;How to find java memory leaks&lt;/a&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/tools.html"&gt;Troubleshooting Guide for Java SE 6 with HotSpot VM&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/alanb/entry/heapdumponoutofmemoryerror_option_in_5_0u7"&gt;HeapDumpOnOutOfMemoryError option in 5.0u7 and 1.4.2_12&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/sundararajan/entry/permanent_generation_analysis_with_oql"&gt;Permanent generation analysis with OQL&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/sundararajan/entry/what_s_in_my_java"&gt;What's in my Java heap?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/sundararajan/entry/querying_java_heap_with_oql"&gt;Querying Java heap with OQL&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/edwardchou/entry/javaone_bof_on_memory_leaks"&gt;JavaOne 2007 BOF on Memory Leaks&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/fkieviet/entry/javaone_2007"&gt;BOF9982: The java.lang.OutOfMemoryError: PermGen Space error demystified&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-3851988195511373606?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/3851988195511373606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=3851988195511373606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3851988195511373606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/3851988195511373606'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/05/heap-dump-in-java-6.html' title='Heap Dump in Java 6'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-5587314813130059520</id><published>2007-05-02T22:18:00.000-07:00</published><updated>2007-05-02T22:25:43.569-07:00</updated><title type='text'>CVS Access to JSR166</title><content type='html'>Here is the anonymous CVS access to JSR166:&lt;blockquote&gt;:pserver:anonymous@gee.cs.oswego.edu:/export/home/jsr166/jsr166&lt;/blockquote&gt;with project also named jsr166 (as in "cvs co jsr166").  Wouldn't it be nice if this information is included at the jsr166 web page,&lt;blockquote&gt;&lt;a href="http://g.oswego.edu/dl/concurrency-interest/"&gt;http://g.oswego.edu/dl/concurrency-interest/&lt;/a&gt;&lt;/blockquote&gt;in addition to the browsable CVS links ?&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://www.nabble.com/forum/ViewPost.jtp?post=10033091&amp;framed=y"&gt;Doug Lea&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-5587314813130059520?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/5587314813130059520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=5587314813130059520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5587314813130059520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/5587314813130059520'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/05/cvs-access-to-jsr166.html' title='CVS Access to JSR166'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4254789259590802156</id><published>2007-04-05T15:13:00.000-07:00</published><updated>2011-06-25T11:45:50.518-07:00</updated><title type='text'>Oracle Table Differential</title><content type='html'>Say you have two Oracle databases, db1 and db2, that contain the same schema.  Every table T in db1 should contain the same records as that in db2 .  Also, every table only allows read and insert operations (ie no updates or deletes), and every record has a creation date.&lt;br /&gt;&lt;br /&gt;Now for some reasons db2 went down.  Meanwhile there are continuously new records being inserted into T in db1.  When db2 is back up, how do we figure out the set of records that need to be inserted back to T in db2 ?&lt;br /&gt;&lt;br /&gt;Note you cannot assume db1 and db2 has the same clock time, but you can make the hypothetical assumption that the creation time of all the records in a specific table are in total chronological order.  (In reality multiple records can be created with the same creation date/time, but let's get to that later.)&lt;br /&gt;&lt;br /&gt;Here is one way of doing it.  Let's call it the &lt;a href="#difproc"&gt;Differential Procedure&lt;/a&gt;:&lt;blockquote&gt;&lt;pre&gt;db2Count = select count(*) from db2.T;&lt;br /&gt;db1Count = select count(*) from db1.T;&lt;br /&gt;diff = db1Count - db2Count;&lt;br /&gt;&lt;br /&gt;select * from (&lt;br /&gt;   select * from (&lt;br /&gt;       select * from (select * from db1.T order by creation_date) &lt;br /&gt;       where rownum &lt;= db1Count &lt;br /&gt;       order by creation_date desc))&lt;br /&gt;where rownum &lt;= diff &lt;br /&gt;order by creation_date;&lt;/pre&gt;&lt;/blockquote&gt;Can you think of a better/faster one ?&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Updated on 23Oct - Actually the above SQL can be simpler:&lt;/i&gt;&lt;blockquote&gt;&lt;pre&gt;select * from (&lt;br /&gt;   select * from (select * from db1.T order by creation_date) &lt;br /&gt;   where rownum &lt;= db1Count &lt;br /&gt;   order by creation_date desc)&lt;br /&gt;where rownum &lt;= diff &lt;br /&gt;order by creation_date;&lt;/pre&gt;&lt;/blockquote&gt;Now back to reality.  How do we handle those rows that got inserted into db1 as at the time when db2 went down ?  They all have the same creation date in db1 but some of them may exist in db2 and some may not!  Oh well, how about this:&lt;ol&gt;&lt;li&gt;Figure out all those rows that were created as at the time when db2 went down:&lt;/li&gt;&lt;blockquote&gt;&lt;pre&gt;select * from db1.T where creation_date = (&lt;br /&gt; select max(creation_date) from (&lt;br /&gt;   select creation_date from db1.T order by creation_date) where rownum &lt;= db2Count)&lt;/pre&gt;&lt;/blockquote&gt;&lt;li&gt;For each of these rows, insert it to db2 only if it doesn't already exist;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Now apply the &lt;a href="http://hansonchar.blogspot.com/2007/04/oracle-table-differential.html#difproc"&gt;Differential Procedure&lt;/a&gt; to db1 and db2.  This time, however, we got a set of records that must all exist in db1 but not in db2.  Yum!  Simply insert them all to db2.&lt;/li&gt;&lt;/ol&gt;Finally, if you are like me thinking about using &lt;a href="http://ha-jdbc.sourceforge.net/"&gt;HA-JDBC&lt;/a&gt; to cluster db1 and db2, how can we activate/synchronize db1 and db2 on the fly with minimal impact on the clients ?  In other words, can synchronization be done correctly without the tables being locked ?&lt;br /&gt;&lt;br /&gt;For example, take the hypothetical case above and say table T in db2 had 10 rows when it was deactivated.   When db2 becomes ready for activation, db1 may have already got 100 rows.  So to sync up, the extra 90 needs to be inserted in db2.  Yet once that's done, db1 may have gone up to 110.  The problem is db1 may just keep growing!&lt;br /&gt;&lt;br /&gt;Is there a clever way to get around this dynamic changing synchronization problem yet without resorting to the use of table locking ?  I can't really think of one :(&lt;br /&gt;&lt;br /&gt;But how about this:&lt;ol&gt;&lt;li&gt;Repeatedly apply a non-locking synchronization procedure, such as the &lt;a href="http://hansonchar.blogspot.com/2007/04/oracle-table-differential.html#difproc"&gt;Differential Procedure&lt;/a&gt;, until the delta of table T between the active and inactive db falls below a certain threshold;&lt;/li&gt;&lt;li&gt;Lock table T of all active databases&lt;/li&gt;&lt;li&gt;Apply the synchronization procedure to T for the last time&lt;/li&gt;&lt;li&gt;Active the inactive db&lt;/li&gt;&lt;li&gt;Release the table locks.  (Just like what &lt;a href="http://ha-jdbc.svn.sourceforge.net/viewvc/ha-jdbc/branches/1.1/src/net/sf/hajdbc/local/LocalDatabaseCluster.java?view=markup"&gt;LocalDatabaseCluster#activate&lt;/a&gt; does.)&lt;/li&gt;&lt;/ol&gt;There will still be impact on the clients, but the lock duration is minimized. &lt;br /&gt;&lt;br /&gt;What do you think ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4254789259590802156?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4254789259590802156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4254789259590802156' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4254789259590802156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4254789259590802156'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/04/oracle-table-differential.html' title='Oracle Table Differential'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-8782938032594234584</id><published>2007-03-24T23:44:00.000-07:00</published><updated>2011-08-01T17:09:25.357-07:00</updated><title type='text'>ssh tunnelling fun</title><content type='html'>To access a service that only accepts requests at localhost:9090 at myserver, I can ssh tunnel from mypc to myserver:&lt;br /&gt;&lt;blockquote&gt;ssh -L 9090:localhost:9090 -N myserver&lt;br /&gt;&lt;/blockquote&gt;Now, access to localhost:9090 at mypc would be forwarded to localhost:9090 at myserver.&lt;br /&gt;&lt;br /&gt;More info on ssh tunnelling &lt;a href="http://www.rzg.mpg.de/networking/tunnelling.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another example:&lt;br /&gt;&lt;br /&gt;Say host-A can access host-B whereas mypc can only ssh to host-A but cannot access host-B.  To access host-B from mypc:&lt;br /&gt;&lt;blockquote&gt;ssh -N -p 22 -c 3des userid@host-A -L 9090/host-B/9090&lt;br /&gt;&lt;/blockquote&gt;Now, access to localhost:9090 at mypc would be forwarded to host-B:9090&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;jconsole ssh tunnelling&lt;/h2&gt;Now say one can normally jconsole via a service url like:&lt;pre&gt;jconsole service:jmx:rmi://myhost:6160/jndi/rmi://myhost:6110/server&lt;/pre&gt;But if ports 6160 and 6110 are restricted, it would render jconsole almost useless.  Here is how ssh tunnelling may come to rescue (if you are allowed to ssh to the host):&lt;pre&gt;ssh -L 6160:localhost:6160 -N myhost&lt;br /&gt;ssh -L 6110:localhost:6110 -N myhost&lt;br /&gt;jconsole service:jmx:rmi://localhost:6160/jndi/rmi://localhost:6110/server&lt;/pre&gt;Oh, don't forget to start up the JVM with &lt;pre&gt;    -Djava.rmi.server.hostname=localhost&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-8782938032594234584?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/8782938032594234584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=8782938032594234584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8782938032594234584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/8782938032594234584'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/03/ssh-tunnelling-fun.html' title='ssh tunnelling fun'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-4055922381120248827</id><published>2007-03-19T14:31:00.000-07:00</published><updated>2007-03-19T14:43:53.463-07:00</updated><title type='text'>Sequoia 2.10.6</title><content type='html'>Ever tried the Sequoia 2.10.6's raidb1 demo ?  Here is something interesting: once the demo's local jmx server has been started by the Sequoia controller, you can peek into it via jconsole:&lt;br /&gt;&lt;blockquote&gt;jconsole service:jmx:rmi://localhost/jndi/rmi://localhost:1090/jrmp&lt;/blockquote&gt;and also:&lt;br /&gt;&lt;blockquote&gt;jconsole service:jmx:rmi://localhost/jndi/rmi://localhost:1091/jrmp&lt;/blockquote&gt;if you are running the raidb1 &lt;span style="font-style:italic;"&gt;distributed&lt;/span&gt; demo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-4055922381120248827?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://sequoia.continuent.org/HomePage' title='Sequoia 2.10.6'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/4055922381120248827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=4055922381120248827' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4055922381120248827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/4055922381120248827'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2007/03/sequoia-2106.html' title='Sequoia 2.10.6'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-116668241800924729</id><published>2006-12-20T22:26:00.000-08:00</published><updated>2006-12-22T19:57:22.480-08:00</updated><title type='text'>Photos@Belgium</title><content type='html'>&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-116668241800924729?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://picasaweb.google.com/hanson.char/Belgium' title='Photos@Belgium'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/116668241800924729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=116668241800924729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116668241800924729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116668241800924729'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/12/photosbelgium.html' title='Photos@Belgium'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-116613425232931380</id><published>2006-12-14T13:49:00.000-08:00</published><updated>2006-12-14T23:37:19.960-08:00</updated><title type='text'>JavaPolis 2006</title><content type='html'>This year the theme of &lt;span id="misp_compose_1" class="hm"&gt;JavaPolis&lt;/span&gt; is something like &lt;span style="font-style: italic;"&gt;there is a better place to meet your idols&lt;/span&gt;.  Oh well, I certainly did meet up with some of my idols. I could even ask a few questions or have a conversation with some of them face-to-face!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Brian+Goetz"&gt;Brian &lt;span id="misp_compose_2" class="hm"&gt;Goetz&lt;/span&gt;&lt;/a&gt; - The Java Concurrency hero. I asked him on the expressiveness of the concurrency annotations in &lt;span id="misp_compose_3" class="hm"&gt;JCIP&lt;/span&gt;, and whether the &lt;span id="misp_compose_4" class="hm"&gt;JDK&lt;/span&gt; should be annotated on thread &lt;span id="misp_compose_5" class="hm"&gt;safety&lt;/span&gt;. He pointed me to &lt;a href="http://jcp.org/en/jsr/detail?id=305"&gt;JSR305&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Mark+Reinhold"&gt;Mark Reinhold&lt;/a&gt; - Gave an interesting talk on integrating XML into the Java Language.  Apparently he has quite a few ideas about how this can be done in Java 7.   However, from some informal conversations, it seems Neal was not so sure about having such integration at the language level, as API such as &lt;span id="misp_compose_9" class="hm"&gt;JDOM&lt;/span&gt; should suffice to tackle the pain points.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Neal+Gafter"&gt;Neal Grafter&lt;/a&gt; - I asked Neal whether the Tree/Event hybrid XML streaming API presented by Mark Reinhold would degenerate to the behavior of a DOM API if a programmer carelessly matches the root document element. Neal kindly agreed. His presentation on Closure was as usual deep and thought provoking.&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Heinz+Kabutz"&gt;&lt;br /&gt;Dr. Heinz&lt;/a&gt; - I finally got the chance to talk to Dr. Heinz, the Java Specialist, whom I have been exchanging emails with in the past. An interesting and friendly guy with some serious insights into Java.  We had some Belgium fries together.  Yum.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Bill+Venners"&gt;Bill &lt;span id="misp_compose_6" class="hm"&gt;Venners&lt;/span&gt;&lt;/a&gt; - Talked about how to deal with software exceptions.  I asked him if a condition is considered something that should never occur, whether throwing an &lt;span id="misp_compose_7" class="hm"&gt;AssertionError&lt;/span&gt; would be more preferable to a &lt;span id="misp_compose_8" class="hm"&gt;RuntimeException&lt;/span&gt;.  He was not sure, and was honest about his uncertainty.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Marc+Fleury"&gt;Marc &lt;span id="misp_compose_10" class="hm"&gt;Fleury&lt;/span&gt;&lt;/a&gt; - Very entertaining guy. For some reasons he reminded me of Rocky &lt;span id="misp_compose_12" class="hm"&gt;Balbor&lt;/span&gt;. He gave an interesting presentation of different open source models, emphasized the importance of a brand name, and his personal advocate of the use of &lt;span id="misp_compose_13" class="hm"&gt;GPL&lt;/span&gt;/dual license for &lt;span id="misp_compose_14" class="hm"&gt;startup&lt;/span&gt; based on professional open-source.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javapolis.com/confluence/display/JP06/Erich+Gamma"&gt;Erich Gamma&lt;/a&gt; - Gave an interesting presentation about the Eclipse development process, how it moved from a totally closed development to completely &lt;span id="misp_compose_16" class="hm"&gt;open-source&lt;/span&gt;, and how transparency can help foster the health of a development process.  Something to learn about.&lt;br /&gt;&lt;br /&gt;And there is free Belgium beer. A remarkable conference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-116613425232931380?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.javapolis.com/confluence/display/JP06/Home' title='JavaPolis 2006'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/116613425232931380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=116613425232931380' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116613425232931380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116613425232931380'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/12/javapolis-2006.html' title='JavaPolis 2006'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-116605645260128473</id><published>2006-12-13T16:30:00.000-08:00</published><updated>2006-12-13T16:51:22.483-08:00</updated><title type='text'>Beanlib at JavaPolis 2006</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/2093/377/1600/693084/Quickie.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/x/blogger/2093/377/320/895550/Quickie.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I did a little quickie presentation on the &lt;a href="http://beanlib.sourceforge.net/"&gt;Beanlib&lt;/a&gt; opensource project at &lt;a href="http://www.javapolis.com/confluence/display/JP06/Home"&gt;JavaPolis 2006&lt;/a&gt;.  I'll try to post a link to the presentation here later on.&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-116605645260128473?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/116605645260128473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=116605645260128473' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116605645260128473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116605645260128473'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/12/beanlib-at-javapolis-2006.html' title='Beanlib at JavaPolis 2006'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-116198254640363757</id><published>2006-10-27T13:54:00.000-07:00</published><updated>2006-10-27T13:55:46.420-07:00</updated><title type='text'>Bamboo - Opensource DHT</title><content type='html'>Looks interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-116198254640363757?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://bamboo-dht.org/' title='Bamboo - Opensource DHT'/><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/116198254640363757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=116198254640363757' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116198254640363757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/116198254640363757'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/10/bamboo-opensource-dht.html' title='Bamboo - Opensource DHT'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115863267072533766</id><published>2006-09-18T19:15:00.000-07:00</published><updated>2006-09-18T19:29:43.856-07:00</updated><title type='text'>Jaxb2 jakarta-commons-lang Plugin</title><content type='html'>Just contributed to the reference implementation of &lt;a href="https://jaxb.dev.java.net/"&gt;Jaxb2&lt;/a&gt; a very simple plugin named &lt;a href="https://jaxb2-commons.dev.java.net/commons-lang-plugin/"&gt;jakarta-commons-lang plugin&lt;/a&gt; that would add toString(), hashCode() and equals() method to the xjc generated Pojo's using the &lt;a href="http://jakarta.apache.org/commons/"&gt;Jakarta Commons&lt;/a&gt;' &lt;a href="http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/ToStringBuilder.html"&gt;ToStringBuilder&lt;/a&gt;, &lt;a href="http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/HashCodeBuilder.html"&gt;HashCodeBuilder&lt;/a&gt; and  &lt;a href="http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/EqualsBuilder.html"&gt;EqualsBuilder&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;More Jaxb2 plugins can be found &lt;a href="https://jaxb2-commons.dev.java.net/"&gt;here&lt;/a&gt;.  Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115863267072533766?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115863267072533766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115863267072533766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115863267072533766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115863267072533766'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/09/jaxb2-jakarta-commons-lang-plugin.html' title='Jaxb2 jakarta-commons-lang Plugin'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115815594709850788</id><published>2006-09-13T06:54:00.000-07:00</published><updated>2006-09-13T22:16:08.620-07:00</updated><title type='text'>WriteThottleFilter in Mina</title><content type='html'>I was wondering if there is an easy way in Mina 0.8.2 to control the rate of physical network write operations to not exceed a specific number of messages.&lt;br /&gt;&lt;br /&gt;For example, can I say for a particular socket connection session Mina should write physically no more than 3 messages per second ?  Message here means the argument that get passed to ProtocolSession.write(Object).&lt;br /&gt;&lt;br /&gt;AFAIK the ProtocolSession.write() is a logical asyn operation, and Mina therefore reserves the right to buffer it underneath.  If so, controlling the rate of session.write() cannot be relied upon to control the rate of physical messages that get sent down the wire.&lt;br /&gt;&lt;br /&gt;So I posted the question to the &lt;a href="mailto:mina-dev@directory.apache.org"&gt;Mina developer forum&lt;/a&gt;, and here is the reply by &lt;a href="http://gleamynode.net/"&gt;Trustin Lee&lt;/a&gt;:&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;"You are correct, but you can make session.write() a blocking operation by inserting a filter which limits the write rate.  Please implement your filter's filterWrite() to throttle the write request.&lt;br /&gt;&lt;br /&gt;BTW this idea is nice.  Could you please create a JIRA issue for us so we can resolve it someday and you can switch over to our version of write rate limiting filter?  Otherwise you could contribute! ;)"&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;It turns out the implementation can be quite simple:&lt;blockquote&gt;&lt;pre&gt;...&lt;br /&gt;    SocketConnector socketConnector = new SocketConnector();&lt;br /&gt;    socketConnector.getFilterChain()&lt;br /&gt;                   .addLast("writeThrottleFilter",&lt;br /&gt;                            new WriteThrottleFilter(333));&lt;br /&gt;... &lt;br /&gt;&lt;br /&gt;public class WriteThrottleFilter extends IoFilterAdapter &lt;br /&gt;{&lt;br /&gt;    /** Delay in milli-seconds between writes. */&lt;br /&gt;    private final long delayMillis;&lt;br /&gt;    &lt;br /&gt;    public WriteThrottleFilter(long delayMillis) {&lt;br /&gt;        this.delayMillis = delayMillis;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    public synchronized void filterWrite(NextFilter nextFilter,&lt;br /&gt;            IoSession session, ByteBuffer buf, Object marker) &lt;br /&gt;            throws InterruptedException&lt;br /&gt;    {&lt;br /&gt;        nextFilter.filterWrite( session, buf, marker );&lt;br /&gt;        Thread.sleep(delayMillis);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;Thanks to &lt;a href="http://gleamynode.net/"&gt;Trustin Lee&lt;/a&gt;, this class will be included in the Mina 1.0 release!  More details &lt;a href="http://issues.apache.org/jira/browse/DIRMINA-262"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115815594709850788?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115815594709850788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115815594709850788' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115815594709850788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115815594709850788'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/09/writethottlefilter-in-mina.html' title='WriteThottleFilter in Mina'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115795814350685182</id><published>2006-09-10T23:52:00.000-07:00</published><updated>2007-10-22T14:45:42.871-07:00</updated><title type='text'>ConcurrentLinkedBlockingQueue</title><content type='html'>I've been wondering why there is &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html"&gt;ConcurrentLinkedQueue&lt;/a&gt; in Java 5+, but not something like a &lt;span style="font-weight:bold;"&gt;&lt;a href="http://beanlib.svn.sourceforge.net/viewvc/beanlib/trunk/beanlib/src/net/sf/beanlib/util/concurrent/ConcurrentLinkedBlockingQueue.java"&gt;ConcurrentLinkedBlockingQueue&lt;/a&gt;&lt;/span&gt;, which would allow the client to block on an empty queue via a "take" method, or block on an empty queue for a limited time via a "poll" method.&lt;br /&gt;&lt;br /&gt;I attempted to construct one by combining the use of a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html"&gt;Semaphore&lt;/a&gt; with a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html"&gt;ConcurrentLinkedQueue&lt;/a&gt;, but apparently it is less scalable than the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/LinkedBlockingQueue.html"&gt;LinkedBlockingQueue&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As pointed out by Doug Lea:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;"This IS a good thought....This way works, but reduces concurrency by using a single semaphore, so is a bit less scalable than current  inkedBlockingQueue. However, there is a path to much better scalability by using the "dual-queue" approach similar to what we did for Java 6 SynchronousQueue. My initial intent was to find a way to internally use such techniques to replace the unbounded case of LinkedBlockingQueue. But this turns out not to work out too well because of all the little compatibility problems encountered -- for example, maintaining the same Serialization form. So it is more likely that we'll put out a separate ConcurrentLinkedBlockingQueue that will be preferable to LinkedBlockingQueue unless you need capacity constraints. &lt;br /&gt;Stay tuned for it...&lt;/span&gt;"&lt;/blockquote&gt;In stead of waiting, I decided to try a different path and proceeded to make a second attempt.  This time the constructs I use included:&lt;br /&gt;* an extra &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html"&gt;ConcurrentLinkedQueue&lt;/a&gt; for the parking threads&lt;br /&gt;* volatile for marking if a thread is potentially parked or not&lt;br /&gt;* &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/LockSupport.html"&gt;LockSupport&lt;/a&gt;.[&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/LockSupport.html#unpark(java.lang.Thread)"&gt;un&lt;/a&gt;]&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/LockSupport.html#park()"&gt;park&lt;/a&gt;[&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/LockSupport.html#parkNanos(long)"&gt;Nano&lt;/a&gt;](...)&lt;br /&gt;&lt;br /&gt;One feature of such &lt;a href="http://svn.sourceforge.net/viewvc/beanlib/trunk/beanlib/src/net/sf/beanlib/util/concurrent/ConcurrentLinkedBlockingQueue.java"&gt;ConcurrentLinkedBlockingQueue&lt;/a&gt; is that it is unbounded, whereas even &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/LinkedBlockingQueue.html"&gt;LinkedBlockingQueue&lt;/a&gt; has a max capacity of &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html#MAX_VALUE"&gt;Integer.MAX_VALUE&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The source can be found &lt;a href="http://svn.sourceforge.net/viewvc/beanlib/trunk/beanlib/src/net/sf/beanlib/util/concurrent/ConcurrentLinkedBlockingQueue.java"&gt;here&lt;/a&gt;, whereas some performance tests can be found &lt;a href="http://svn.sourceforge.net/viewvc/beanlib/trunk/beanlib-test/src/net/sf/beanlib/util/concurrent/ "&gt;here&lt;/a&gt;.  Some initial load testing looks promising, although I only tested it with a single procesor machine, and it appears the test result is very sensitive to the GC and heap memory configuration for the JVM.  What I really need is some loading testing on a multi-processor environment where true concurrency is possible.&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Update on 11Sep2006&lt;/span&gt;:  Running the &lt;a href="http://svn.sourceforge.net/viewvc/beanlib/trunk/beanlib-test/src/net/sf/beanlib/util/concurrent/"&gt;test harness&lt;/a&gt; on an AMD Opteron dual processor using JDK-1.5.0_05, the CLBQ is on average 72% faster than the LBQ.  See &lt;a href="http://beanlib.sourceforge.net/pdf/060911/060911-clbq.pdf"&gt;here&lt;/a&gt; for more details.&lt;br /&gt;&lt;hr/&gt;&lt;a name="060919"&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;Update on 19Sep2006&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;More experiments seem to indicate that the CLBQ consistently outperform the LBQ for the mix of N-producer 1-consumer.  When there are N-producer and M-consumer, however, it seems the reverse is true.  Not exactly sure why.  Probably CLBQ incurs a slightly higher overhead as compared to LBQ in the M-consumer situation.&lt;hr/&gt;&lt;span style="font-style:italic;"&gt;&lt;a name="070404"&gt;&lt;span style="font-weight:bold;"&gt;Update on 4Apr2007&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;If anyone has a powerful box (with multi-processors) and is interested in comparing the performance of ConcurrentLinkedBlockingQueue vs LinkedBlockingQueue, please download a jar from:&lt;blockquote&gt;&lt;a href="http://beanlib.sourceforge.net/clbq/070407/q-test.jar"&gt;http://beanlib.sourceforge.net/clbq/070407/q-test.jar&lt;/a&gt;&lt;/blockquote&gt;and run it with either jdk5 or jdk6:&lt;blockquote&gt;java -DnumConsumer=10 -DnumProducer=100 -DwcRatio=20 -server -XX:CompileThreshold=1500 -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+DisableExplicitGC -jar q-test.jar&lt;/blockquote&gt;Note:&lt;ul&gt;&lt;li&gt;the number of concurrent producers can be specified via the system property "numProducer", which defaults to 10&lt;/li&gt;&lt;li&gt;multiple concurrent consumers is now supported via the system property "numConsumer", which defaults to 1&lt;/li&gt;&lt;li&gt;the W/C ratio (ie wait-time to compute-time) can be specified via the system property "wcRatio", which defaults to zero&lt;/li&gt;&lt;/ul&gt;For instance, the above example means to run the test with 100 producers, 10 consumers, and a W/C ratio of 20.  One interesting observation is that Windows XP Professional is really slow on LBQ even when there is only 1 producer and 1 consumer!  Feel free to tinkle with the parameters, and let me know what you find.&lt;br /&gt;&lt;br /&gt;The source jar of the test harness can be downloaded from:&lt;blockquote&gt;&lt;a href="http://beanlib.sourceforge.net/clbq/070407/q-test-sources.jar"&gt;http://beanlib.sourceforge.net/clbq/070407/q-test-sources.jar&lt;/a&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115795814350685182?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115795814350685182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115795814350685182' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115795814350685182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115795814350685182'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/09/concurrentlinkedblockingqueue.html' title='ConcurrentLinkedBlockingQueue'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115666044112469265</id><published>2006-08-26T23:24:00.000-07:00</published><updated>2006-08-27T08:50:00.953-07:00</updated><title type='text'>jsr166x in Java 5</title><content type='html'>&lt;span style="font-style:italic;"&gt;Update on 27Aug06:&lt;/span&gt; It turns out including ConcurrentLinkedDeque is not such a good idea, and therefore removed in &lt;a href="http://prdownloads.sourceforge.net/beanlib/beanlib-3.2.5.tar.gz?download"&gt;Beanlib 3.2.5&lt;/a&gt;.  As pointed out by Doug Lea, this class will be replaced with something much better in Java 7.  &lt;br /&gt;&lt;br /&gt;Ever thought of taking advantage of those concurrent classes such as &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListMap.html"&gt;ConcurrentSkipListMap&lt;/a&gt; in Java 6 beta, but still being trapped in a Java 5 environment ?  Well the entire &lt;a href="http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166x/"&gt;jsr166x&lt;/a&gt; package has now been ported to &lt;a href="http://prdownloads.sourceforge.net/beanlib/beanlib-3.2.4.tar.gz?download"&gt;beanlib 3.2.4&lt;/a&gt;, with sources augmented with the latest from Java 6 beta 2.  This included even the &lt;a href="http://beanlib.sourceforge.net/3.2.4/api/net/sf/beanlib/util/concurrent/ConcurrentLinkedDeque.html"&gt;ConcurrentLinkedDeque&lt;/a&gt; which is currently missing in Java 6.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115666044112469265?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115666044112469265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115666044112469265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115666044112469265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115666044112469265'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/08/jsr166x-in-java-5.html' title='jsr166x in Java 5'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115463572493678663</id><published>2006-08-03T13:00:00.000-07:00</published><updated>2006-08-17T09:04:18.693-07:00</updated><title type='text'>Enable Remote Debugging + JMX, etc. from Ant</title><content type='html'>Sample configuration:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;  &amp;lt;target name="mytarget"&gt;&lt;br /&gt;      &amp;lt;java classname="my.packagename.MyMainClassName"&lt;br /&gt;        fork="yes"&lt;br /&gt;      &gt;&lt;br /&gt;          &amp;lt;!-- For remote debugging --&gt;&lt;br /&gt;          &amp;lt;sysproperty key="DEBUG" value="true" /&gt;&lt;br /&gt;          &amp;lt;jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000" /&gt; &lt;br /&gt;          &amp;lt;!-- For enabling JMX monitoring --&gt;&lt;br /&gt;          &amp;lt;sysproperty key="com.sun.management.jmxremote.port" value="8001" /&gt;&lt;br /&gt;          &amp;lt;sysproperty key="com.sun.management.jmxremote.authenticate" value="false" /&gt;&lt;br /&gt;          &amp;lt;sysproperty key="com.sun.management.jmxremote.ssl" value="false" /&gt;&lt;br /&gt;          &amp;lt;!-- GC tuning. --&gt;&lt;br /&gt;          &amp;lt;jvmarg value="-verbose:gc" /&gt;&lt;br /&gt;          &amp;lt;jvmarg value="-server" /&gt; &lt;br /&gt;          &amp;lt;jvmarg value="-XX:+UseParallelGC" /&gt;&lt;br /&gt;          &amp;lt;jvmarg value="-XX:GCTimeRatio=19" /&gt;&lt;br /&gt;          &amp;lt;!-- Heap tuning. --&gt;&lt;br /&gt;          &amp;lt;jvmarg value="-Xms512m" /&gt;&lt;br /&gt;          &amp;lt;jvmarg value="-Xmx512m" /&gt;&lt;br /&gt;          &amp;lt;!-- JNI --&gt;&lt;br /&gt;          &amp;lt;env key="LD_LIBRARY_PATH" value="/my/so/directory" /&gt;&lt;br /&gt;          &amp;lt;!-- Arguments, if any --&gt;&lt;br /&gt;          &amp;lt;arg value="my.argument"/&gt;&lt;br /&gt;      &amp;lt;/java&gt;&lt;br /&gt;      &amp;lt;classpath&gt;&lt;br /&gt;          &amp;lt;pathelement path="${sample.dir}"/&gt;&lt;br /&gt;          &amp;lt;path refid="sample.classpath"/&gt;&lt;br /&gt;      &amp;lt;/classpath&gt;&lt;br /&gt;  &amp;lt;/target&gt;&lt;/pre&gt;&lt;/blockquote&gt;Nice resource for setting up &lt;a href="http://www.eclipsezone.com/eclipse/forums/t53459.html"&gt;Remote Debugging&lt;/a&gt; for Java.&lt;br /&gt;Nice articles on tuning GC can be found &lt;a href="http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html"&gt;here&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/vm/gc-ergonomics.html"&gt;here&lt;/a&gt; and &lt;a href="http://www.petefreitag.com/articles/gctuning/"&gt;here&lt;/a&gt;.&lt;br /&gt;Java Ant Task &lt;a href="http://ant.apache.org/manual/CoreTasks/java.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115463572493678663?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115463572493678663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115463572493678663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115463572493678663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115463572493678663'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/08/enable-remote-debugging-jmx-etc-from.html' title='Enable Remote Debugging + JMX, etc. from Ant'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115225506588102035</id><published>2006-07-06T23:49:00.000-07:00</published><updated>2006-07-08T22:31:31.620-07:00</updated><title type='text'>Spring 2.0RC2 is not backward compatible ?</title><content type='html'>&lt;i&gt;Update on 8Jul06&lt;/i&gt;: Jira issue created &lt;a href="http://opensource.atlassian.com/projects/spring/browse/SPR-2260"&gt;here&lt;/a&gt; as per &lt;a href="http://blog.springframework.com/rob"&gt;Rob Harrop's&lt;/a&gt; request.&lt;br /&gt;&lt;br /&gt;Once I replaced the 2.0 RC1 spring.jar with the one from 2.0 RC2, I got a NullPointerException.&lt;br /&gt;&lt;br /&gt;More details &lt;a href="http://forum.springframework.org/showthread.php?t=26668"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115225506588102035?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115225506588102035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115225506588102035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115225506588102035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115225506588102035'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/07/spring-20rc2-is-not-backward.html' title='Spring 2.0RC2 is not backward compatible ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115107671696316444</id><published>2006-06-23T08:28:00.000-07:00</published><updated>2006-07-06T23:53:48.116-07:00</updated><title type='text'>Bug Patch Mina 0.8.2</title><content type='html'>&lt;i&gt;Update on 6July06:&lt;/i&gt;It turns out the root cause of the problem is related to my Decoder implementation.  More details can be found in the &lt;a href="http://issues.apache.org/jira/browse/DIRMINA-224"&gt;JIRA Issue&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;The lesson is: Don't use Mina 0.8.2.  Go for Mina 0.9.4+ or else risk data corruption.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update on 4July06:&lt;/i&gt; &lt;a href="http://issues.apache.org/jira/browse/DIRMINA-224"&gt;JIRA Issue&lt;/a&gt; submitted to the Mina group.  &lt;br /&gt;&lt;br /&gt;Just found a nasty race condition in using &lt;blockquote&gt;&lt;pre&gt;org.apache.mina.util.Queue&lt;/pre&gt;&lt;/blockquote&gt;in Mina 0.8.2.  &lt;br /&gt;&lt;br /&gt;When invoked from &lt;i&gt;IOAdapter$SessionHandlerAdapter.dowrite()&lt;/i&gt;, the &lt;i&gt;Queue.isEmpty()&lt;/i&gt; is not properly synchronized.  This causes &lt;i&gt;&lt;span style="font-weight:bold;"&gt;data corruption&lt;/span&gt;&lt;/i&gt; when the network IO is under high load!  I was hit by it when I changed my log4j configuration to use pure asyn appenders.&lt;br /&gt;&lt;br /&gt;The good news is it's easy to patch.  I simply took the gut out of the original Mina's queue implementation, and replaced it with a simple delegation to&lt;blockquote&gt;&lt;pre&gt;java.util.concurrent.ConcurrentLinkedQueue&lt;/pre&gt;&lt;/blockquote&gt;There are some features lost such as the removal of the List interface (from the Mina's Queue class).  But in this case the additional List interface methods are not actually used anywhere else in Mina 0.8.2!&lt;br /&gt;&lt;br /&gt;IMHO, Mina should really take advantage of JKD5 features such as non-blocking synchronization , instead of having synchronized statements/blocks all over the places.  After all, isn't Mina all about performance ?&lt;br /&gt;&lt;br /&gt;(Will try to post the patch back to the Mina group when I got a chance.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115107671696316444?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115107671696316444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115107671696316444' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115107671696316444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115107671696316444'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/06/bug-patch-mina-082.html' title='Bug Patch Mina 0.8.2'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115052549479018937</id><published>2006-06-16T23:24:00.000-07:00</published><updated>2006-06-16T23:25:44.190-07:00</updated><title type='text'>Java Xml Binding</title><content type='html'>Thinking of which Java XML binding technology to use for building your&lt;br /&gt;next web services ?  JAXB, JiBX, Castor, XmlBean, XStream ?&lt;br /&gt;&lt;br /&gt;No more.  With &lt;a target="_blank" href="http://static.springframework.org/spring-ws/docs/1.0-m1/reference/pdf/spring-ws-core-reference.pdf"&gt;Spring Web Services 1.0M1&lt;/a&gt;, simply use the same&lt;br /&gt;Marshaller/Unmarshaller interfaces, and the different O/X mapping&lt;br /&gt;implementations can be instantly swapped in and out as you wish!  No&lt;br /&gt;brainer.  Or at least it seems so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115052549479018937?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115052549479018937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115052549479018937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115052549479018937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115052549479018937'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/06/java-xml-binding.html' title='Java Xml Binding'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-115009485660462038</id><published>2006-06-11T23:32:00.000-07:00</published><updated>2006-07-06T22:55:39.856-07:00</updated><title type='text'>Latest Jaxb RI 2.0.1 Fluent API Plugin available!</title><content type='html'>Due to the specific web service environment in my workplace, I didn't have a chance to touch &lt;a href="https://jaxb.dev.java.net/"&gt;JAXB RI 2.0.x&lt;/a&gt; for quite a while after writing the Fluent API plugin. There is recently an interesting request by Kenny MacLeod about enhancing the plugin to generate fluent setter method with variable arguments for List member fields.&lt;br /&gt;&lt;br /&gt;So I spent quite some time to refresh myself as to what exactly I have done, and went tweaking, and tweaking. Finally, the enhanced plugin is now available for &lt;a href="https://jaxb2-commons.dev.java.net/fluent-api/"&gt;download&lt;/a&gt; :)&lt;br /&gt;&lt;br /&gt;The plugin has also been submitted to maven 2 for distribution.  Details &lt;a href="http://jira.codehaus.org/browse/MAVENUPLOAD-949"&gt;here&lt;/a&gt; and &lt;a href="http://www.ibiblio.org/maven2/net/java/dev/jaxb2-commons/jaxb-fluent-api/2.0.1/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-115009485660462038?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/115009485660462038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=115009485660462038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115009485660462038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/115009485660462038'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/06/latest-jaxb-ri-201-fluent-api-plugin.html' title='Latest Jaxb RI 2.0.1 Fluent API Plugin available!'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114851383406800518</id><published>2006-05-24T16:35:00.000-07:00</published><updated>2006-06-01T08:26:52.033-07:00</updated><title type='text'>HalfSync</title><content type='html'>It seems we can easily construct something which is simple, thread-safe, and yet competitive to or even faster than j.u.c.a.AtomicInterger!&lt;br /&gt;&lt;br /&gt;Consider the code:&lt;blockquote&gt;&lt;pre&gt;// Only the write is synchronized, not the read&lt;br /&gt;public class HalfSync {&lt;br /&gt;    private volatile int count;&lt;br /&gt;   &lt;br /&gt;    public HalfSync(int count) {&lt;br /&gt;        this.count = count;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getCount() {&lt;br /&gt;        return count;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public synchronized int increment(int delta) {&lt;br /&gt;        return this.count += delta;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Interesting &lt;a target="_blank" href="http://altair.cs.oswego.edu/pipermail/concurrency-interest/2006-May/002596.html"&gt;comments&lt;/a&gt; by David Holmes:&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;pre&gt;"- reads: same&lt;br /&gt;    both do a LD with whatever memory barrier is needed on the&lt;br /&gt;    platform (which is probably none)&lt;br /&gt; - writes:&lt;br /&gt;   - uncontended: close call&lt;br /&gt;       AtomicInteger.get has a method call with LD and CAS plus MEMBAR&lt;br /&gt;       Half-sync: CAS for synchronized, LD, ST plus MEMBAR (depends if&lt;br /&gt;                  the runtime elides the redundant MEMBARS for sync+volatile&lt;br /&gt;  - contended:  Half-sync wins by avoiding ctx switches"&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114851383406800518?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114851383406800518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114851383406800518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114851383406800518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114851383406800518'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/05/halfsync.html' title='HalfSync'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114770758836612446</id><published>2006-05-15T08:25:00.000-07:00</published><updated>2006-06-01T08:24:55.046-07:00</updated><title type='text'>j.u.c.atomic.Atomic*.weakCompareAndSet</title><content type='html'>I have been wondering what it means when it "fails spuriously" in invoking those &lt;a target="_blank" href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summary.html"&gt;&lt;span style="font-weight: bold;"&gt;weakCompareAndSet&lt;/span&gt; methods&lt;/a&gt; in Java 5, and what a good use case would be like.  It turns out the spurious "failure" simply means the method would do nothing and return false for no apparent reason.&lt;br /&gt;&lt;br /&gt;Sample Usage:&lt;blockquote&gt;&lt;pre&gt;public class Foo {&lt;br /&gt;   private volatile int latency = -1;&lt;br /&gt;   private final AtomicInteger maxLatency = new AtomicInteger(-1);&lt;br /&gt;&lt;br /&gt;   public void setLatency(int latency)&lt;br /&gt;   {&lt;br /&gt;       this.latency = latency;&lt;br /&gt;       updateMaxLatency(latency);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void updateMaxLatency(int latency)&lt;br /&gt;   {&lt;br /&gt;       for (;;) {&lt;br /&gt;           int maxLatencySnapshot = this.maxLatency.get();&lt;br /&gt;         &lt;br /&gt;           if (latency &gt; maxLatencySnapshot)&lt;br /&gt;           {&lt;br /&gt;               if (!this.maxLatency.weakCompareAndSet (maxLatencySnapshot, latency))&lt;br /&gt;                   // race condition or just fail spuriously; so let's retry&lt;br /&gt;                   continue;&lt;br /&gt;           }&lt;br /&gt;           return;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   // ...&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;As &lt;a target="_blank" href="http://altair.cs.oswego.edu/pipermail/concurrency-interest/2006-May/002512.html"&gt;commented&lt;/a&gt; by &lt;a target="_blank" href="http://g.oswego.edu/"&gt;Doug Lea&lt;/a&gt;:&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"Yes, this is fine; it is a good example where either the plain or the weak form would work just as well, so you might as well use the weak form."&lt;/span&gt;&lt;/blockquote&gt;Special thanks to David Holmes for his generous and thorough explanation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114770758836612446?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114770758836612446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114770758836612446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114770758836612446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114770758836612446'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/05/jucatomicatomicweakcompareandset.html' title='j.u.c.atomic.Atomic*.weakCompareAndSet'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114557781819050453</id><published>2006-04-20T17:01:00.000-07:00</published><updated>2006-04-20T17:27:17.710-07:00</updated><title type='text'>Beanlib in maven2</title><content type='html'>Thanks to &lt;a href="http://sourceforge.net/users/joe_emporium/" target="_blank"&gt;Joe D. Velopar&lt;/a&gt;, &lt;a href="http://sourceforge.net/projects/beanlib/"&gt;beanlib&lt;/a&gt; is now available in the &lt;a target="_blank" href="http://www.ibiblio.org/maven2/net/sf/beanlib/"&gt;maven 2 repository&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The original request can be found &lt;a href="http://jira.codehaus.org/browse/MAVENUPLOAD-854" target="_blank"&gt;here&lt;/a&gt;, and &lt;a href="http://maven.apache.org/guides/mini/guide-ibiblio-upload.html" target="blank"&gt;here&lt;/a&gt; is the how-to guide.&lt;br /&gt;&lt;br /&gt;Simply add to the pom.xml something like:&lt;blockquote&gt;&lt;pre&gt;  &amp;lt;dependencies&gt;&lt;br /&gt;    ...&lt;br /&gt;    &amp;lt;dependency&gt;&lt;br /&gt;      &amp;lt;groupId&gt;net.sf.beanlib&amp;lt;/groupId&gt;&lt;br /&gt;      &amp;lt;artifactId&gt;beanlib&amp;lt;/artifactId&gt;&lt;br /&gt;      &amp;lt;version&gt;3.1.1&amp;lt;/version&gt;&lt;br /&gt;    &amp;lt;/dependency&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;dependency&gt;&lt;br /&gt;      &amp;lt;groupId&gt;net.sf.beanlib&amp;lt;/groupId&gt;&lt;br /&gt;      &amp;lt;artifactId&gt;beanlib-hibernate&amp;lt;/artifactId&gt;&lt;br /&gt;      &amp;lt;version&gt;3.1.1&amp;lt;/version&gt;&lt;br /&gt;    &amp;lt;/dependency&gt;&lt;br /&gt;    ....&lt;br /&gt;  &amp;lt;/dependencies&gt;&lt;/pre&gt;&lt;/blockquote&gt;and your are all set.  &lt;br /&gt;&lt;br /&gt;Go maven 2!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114557781819050453?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114557781819050453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114557781819050453' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114557781819050453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114557781819050453'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/04/beanlib-in-maven2.html' title='Beanlib in maven2'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114393691108047300</id><published>2006-04-01T16:13:00.000-08:00</published><updated>2006-04-01T16:15:11.093-08:00</updated><title type='text'>How to make a software engineer excel ?</title><content type='html'>What do you think ?  What's the ideal working environment for you as a software engineer ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114393691108047300?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114393691108047300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114393691108047300' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114393691108047300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114393691108047300'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/04/how-to-make-software-engineer-excel.html' title='How to make a software engineer excel ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114387597738365725</id><published>2006-03-31T23:16:00.000-08:00</published><updated>2006-04-26T13:06:22.473-07:00</updated><title type='text'>Ant built-in properties</title><content type='html'>A nice Ant target to print out all the Ant's built-in properties:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;target name="echo" &gt;&lt;br /&gt;    &amp;lt;echo message="os.name:          ${os.name}"          /&gt;&lt;br /&gt;    &amp;lt;echo message="basdir:           ${basedir}"          /&gt;&lt;br /&gt;    &amp;lt;!-- absolute path of the build file. --&gt;&lt;br /&gt;    &amp;lt;echo message="ant.file:         ${ant.file}"         /&gt;&lt;br /&gt;    &amp;lt;!-- path to executing ant's root directory. --&gt;&lt;br /&gt;    &amp;lt;echo message="ant.home:         ${ant.home}"         /&gt;&lt;br /&gt;    &amp;lt;echo message="ant.version:         ${ant.version}"   /&gt;&lt;br /&gt;    &amp;lt;echo message="ant.project.name: ${ant.project.name}" /&gt;&lt;br /&gt;    &amp;lt;echo message="ant.java.version: ${ant.java.version}" /&gt;&lt;br /&gt;    &amp;lt;!-- System properties. --&gt;&lt;br /&gt;    &amp;lt;echo message="user.home:         ${user.home}"   /&gt;&lt;br /&gt;    &amp;lt;echo message="user.name:         ${user.name}"   /&gt;&lt;br /&gt;    &amp;lt;echo message="java.home:         ${java.home}"   /&gt;&lt;br /&gt;&amp;lt;/target&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Originally found &lt;a target="_blank" href="http://www.adp-gmbh.ch/java/ant/properties.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114387597738365725?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114387597738365725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114387597738365725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114387597738365725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114387597738365725'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/03/ant-built-in-properties.html' title='Ant built-in properties'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114283710528549887</id><published>2006-03-19T22:40:00.000-08:00</published><updated>2006-03-29T22:19:14.866-08:00</updated><title type='text'>int to bytes</title><content type='html'>Here is a fun quiz: What is the best possible way (fastest with least memory) to convert an int to a byte array (of size 4) in big endian in Java ?  ie.&lt;blockquote&gt;&lt;pre&gt;public static byte[] toBigEndianBytes(int i) {&lt;br /&gt;// ??&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;It turns out the code below is the best I've found so far:&lt;blockquote&gt;&lt;pre&gt;public static byte[] toBigEndianBytes(int i) {&lt;br /&gt;        return new byte[] {&lt;br /&gt;                (byte)(i &gt;&gt;&gt; 24), &lt;br /&gt;                (byte)(i &gt;&gt;&gt; 16),&lt;br /&gt;                (byte)(i &gt;&gt;&gt; 8),&lt;br /&gt;                (byte)i&lt;br /&gt;        };&lt;br /&gt;}&lt;/pre&gt;&lt;/blockquote&gt;Can you think of a better one ?&lt;br /&gt;&lt;br /&gt;Update on 21Mar06: Interesting class to look at java.nio.Bits.&lt;br /&gt;Update on 29Mar06: &lt;a target="_blank" href="http://mult.ifario.us/articles/2006/03/20/say-8220-bit-shift-8221-ten-times-quickly"&gt;Paul Brown&lt;/a&gt; has more details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114283710528549887?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114283710528549887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114283710528549887' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114283710528549887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114283710528549887'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/03/int-to-bytes.html' title='int to bytes'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114206566413416208</id><published>2006-03-11T00:25:00.000-08:00</published><updated>2006-03-11T00:27:44.143-08:00</updated><title type='text'>Backup.sh</title><content type='html'>A simple little script that does the backup for me to a remote machine:&lt;blockquote&gt;&lt;pre&gt;backup.sh&lt;br /&gt;---------&lt;br /&gt;filename=`date +%y%m%d`-`date +%H%M%S`-xyz-projects.tar&lt;br /&gt;echo $filename&lt;br /&gt;tar cf $filename ProjectXyz*&lt;br /&gt;gzip $filename&lt;br /&gt;scp $filename.gz hchar.desktop:/home/hchar/backup/&lt;br /&gt;rm $filename.gz&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114206566413416208?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114206566413416208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114206566413416208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114206566413416208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114206566413416208'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/03/backupsh.html' title='Backup.sh'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114167721283124767</id><published>2006-03-06T12:27:00.000-08:00</published><updated>2006-03-12T01:23:59.033-08:00</updated><title type='text'>Windows Subversioned</title><content type='html'>Just got SVN server running on Windows.  So far so good!  I installed both the TortoiseSVN and SVN server using the &lt;a href="http://svn1clicksetup.tigris.org/"&gt;SVN 1-Click Setup&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's not obvious how to specify the SVN URL.  For example, if the SVN repository is created at C:\svnrepos, the URL will be &lt;blockquote&gt;&lt;pre&gt;file:///C:/svnrepos&lt;/pre&gt;&lt;/blockquote&gt;I then imported my Java project to it from Eclipse 3.1.2 via the Subclipse plugin.  My project is now actually under dual version control by SVN and P4 :)&lt;br /&gt;&lt;br /&gt;To remote access it, the SVN URL is simply:&lt;blockquote&gt;&lt;pre&gt;svn://myhostname&lt;/pre&gt;&lt;/blockquote&gt;Pretty neat.&lt;br /&gt;&lt;br /&gt;Update on 12Mar06: just upgraded my svn client to TortoiseSVN 1.3.2 and svn server to &lt;a href="http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91"&gt;SVN 1.3.0&lt;/a&gt; on Windows.  I didn't uninstall the previous subversion (both client and server), but I needed to manually disable the SVNService before I could install SVN 1.3.0 without failure.&lt;br /&gt;&lt;br /&gt;I've used subversion seriously only for a week.  Love it so far.  In fact, I've  disabled my CVSNT service (although not yet uninstalled).  There is even utility to convert existing CVS repository to SVN.  So I am not looking back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114167721283124767?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114167721283124767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114167721283124767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114167721283124767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114167721283124767'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/03/windows-subversioned.html' title='Windows Subversioned'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-114088904363316102</id><published>2006-02-25T09:31:00.000-08:00</published><updated>2006-02-25T09:38:18.036-08:00</updated><title type='text'>Alternative to implementing js as jsp</title><content type='html'>Here is an idea that is not as simple as just directly implementing js as jsp, but is probably more performant and maintainable:  for each js, we also have a corresponding jsp.  For example&lt;br /&gt;&lt;br /&gt;Foo.js&lt;br /&gt;Foo.js.jsp&lt;br /&gt;&lt;br /&gt;Within Foo.js, it's pure static javascript, but optionally with "hook"'s that the Foo.js.jsp can fill in during runtime on the enclosing page.  For example:&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;Foo.js&lt;br /&gt;------&lt;br /&gt;// Constructor of the Javascript Foo class.&lt;br /&gt;function Foo() {}&lt;br /&gt;...&lt;br /&gt;// Anytime it needs to access a dynamic property that needs &lt;br /&gt;// to be determined by the Java App, or tag lib, or whatever, &lt;br /&gt;// use a class level variable.&lt;br /&gt;// For example, a i18n message to be displayed.&lt;br /&gt;alert(Foo.FOO_MESSAGE);&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Foo.js.jsp&lt;br /&gt;----------&lt;br /&gt;// Foo.js.jsp is included in the main page where the reference to Foo.js is made.&lt;br /&gt;// If there is no dynamic content, Foo.js.jsp just evaluates to do nothing.&lt;br /&gt;Foo.FOO_MESSAGE = "&amp;lt;c:out name="${fooMessage}" /&gt;"&lt;/pre&gt;&lt;/blockquote&gt;This way, all the dynamic content are included as Javascript class level variables in the main page, and the static Foo.js just refers to these variables.&lt;br /&gt;&lt;br /&gt;Now all the *.js can be pushed to the Web server front end (eg Apache) - solves the performance issue.  All the dynamic content is maintained in one single place: the respective jsp connected via a javascript class - solves the maintenance nightmare issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-114088904363316102?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/114088904363316102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=114088904363316102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114088904363316102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/114088904363316102'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/02/alternative-to-implementing-js-as-jsp.html' title='Alternative to implementing js as jsp'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113925266914039768</id><published>2006-02-06T11:03:00.000-08:00</published><updated>2006-02-06T11:09:51.436-08:00</updated><title type='text'>Replace tabs with spaces</title><content type='html'>&lt;blockquote&gt;&lt;pre&gt;# Replace tabs with 4 spaces in all java files&lt;br /&gt;for i in `find . -name '*.java'`; do sed -ie 's/\t/    /g' $i; done&lt;br /&gt;# Clean up left-over&lt;br /&gt;find . -name '*.javae' -exec rm -f {} \;&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113925266914039768?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113925266914039768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113925266914039768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113925266914039768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113925266914039768'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/02/replace-tabs-with-spaces.html' title='Replace tabs with spaces'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113886393157092972</id><published>2006-02-01T23:00:00.000-08:00</published><updated>2006-02-01T23:12:05.900-08:00</updated><title type='text'>Eclipse WTP rocks!</title><content type='html'>The Eclipse &lt;a href="http://www.eclipse.org/webtools/" target="_blank"&gt;Web Tools Platform&lt;/a&gt; Plugin Project is awesome!  Great for developing J2EE applications.  I particularly like the visual schema editors for xsd and wsdl files.&lt;br /&gt;&lt;br /&gt;Can be easily installed via the Eclipse Update Manager by entering this URL:&lt;blockquote&gt;&lt;pre&gt;http://download.eclipse.org/webtools/updates/&lt;/pre&gt;&lt;/blockquote&gt;Works like a charm with Eclipse 3.1.2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113886393157092972?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113886393157092972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113886393157092972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113886393157092972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113886393157092972'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/02/eclipse-wtp-rocks.html' title='Eclipse WTP rocks!'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113867947519285686</id><published>2006-01-30T19:46:00.000-08:00</published><updated>2006-01-30T20:09:13.146-08:00</updated><title type='text'>How to write a jaxb2 plugin ?</title><content type='html'>&lt;ol&gt;   &lt;li&gt;Subscribe to &lt;a target="_blank" href="mailto:users@jaxb.dev.java.net"&gt;users@jaxb.dev.java.net&lt;/a&gt;;&lt;/li&gt;   &lt;li&gt;Check out the JAXB2 RI workspace. See &lt;a target="_blank" href="https://jaxb2-sources.dev.java.net/"&gt;https://jaxb2-sources.dev.java.net/&lt;/a&gt; for the instruction;&lt;/li&gt;      &lt;li&gt;Consider looking at the "Developing on top of JAXB RI" section of &lt;a target="_blank" href="https://jaxb.dev.java.net/"&gt;https://jaxb.dev.java.net/&lt;/a&gt;.  The sample plugins in XJC should help you get started on how to write one;&lt;/li&gt;   &lt;li&gt;The &lt;a target="_blank" href="https://jaxb2-commons.dev.java.net/"&gt;jaxb2-commons&lt;/a&gt; project is intended to host plugins for JAXB 2;&lt;/li&gt;&lt;li&gt;For example, after writing to &lt;a target="_blank" href="mailto:users@jaxb.dev.java.net"&gt;users@jaxb.dev.java.net&lt;/a&gt;, I was added as a developer and directories "fluent-api" and "www/fluent-api" were created. I can put whatever I want there. Files in "www/fluent-api" can be served from &lt;a href="http://jaxb2-commons.dev.java.net/fluent-api/" target="_blank"&gt;http://jaxb2-commons.dev.java&lt;wbr&gt;.net/fluent-api/&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;Projects in &lt;a href="http://java.net/" target="_blank"&gt;java.net&lt;/a&gt; are encouraged to use "org.jvnet.&lt;projectname&gt;", so I used "org.jvnet.jaxb2_commons" as my plugin's package prefix.&lt;/projectname&gt;&lt;/li&gt;   &lt;li&gt;Feel free to update www/index.html with a link to www/fluent-api/&lt;/li&gt;   &lt;li&gt;Pick the license of your choice.&lt;/li&gt;  &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113867947519285686?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113867947519285686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113867947519285686' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113867947519285686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113867947519285686'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/how-to-write-jaxb2-plugin.html' title='How to write a jaxb2 plugin ?'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113867118441292378</id><published>2006-01-30T17:23:00.000-08:00</published><updated>2006-01-30T17:34:32.900-08:00</updated><title type='text'>Hsql File Locking failed in Ant + Windows</title><content type='html'>I had two junit tests using hsql to perform db operations. They were run using Ant 1.6.5 with hsql-1.8.0.2. When run on Linux 7.2, they worked fine. When run in Eclipse 3.1.1 (without using Ant), they also worked fine.&lt;br /&gt;&lt;br /&gt;However, when they were run in ant 1.6.5 + Cygwin on Windows, the 2nd test always failed saying it couldn't acquire the lock as another process already had it.&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a target="_blank" href="http://sourceforge.net/people/viewprofile.php?user_id=199381"&gt;Campbell Boucher-Burnet&lt;/a&gt;, the problem can be resolved via the shutdown=true connection property.  Details can be found &lt;a target="_blank" href="http://sourceforge.net/forum/forum.php?thread_id=1417547&amp;amp;forum_id=73674"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;More on hsql connection properties can be found &lt;a target="_blank" href="http://hsqldb.sourceforge.net/doc/guide/ch04.html#N109DA"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113867118441292378?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113867118441292378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113867118441292378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113867118441292378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113867118441292378'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/hsql-file-locking-failed-in-ant.html' title='Hsql File Locking failed in Ant + Windows'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113856552634294677</id><published>2006-01-29T12:10:00.000-08:00</published><updated>2006-02-25T09:43:20.246-08:00</updated><title type='text'>Comparing IDE's on support of Java 5 Generics</title><content type='html'>One interesting thing I've observed from building jaxb 2.0 (from source) is that if I set up a project in Netbeans (4.1.x) or IntelliJ (5.0.x) or just build it directly via Ant (1.6.5), the source code compiles just fine. But if I set up a project in Eclipse (3.1.2), a lot of source codes with Java 5 generics constructs are marked as errors by the IDE! (Example: ElementInfoImpl.java under package com.sun.xml.bind.v2.model.impl)&lt;br /&gt;&lt;br /&gt;This seems to indicate that as jar as Java generics goes Eclipse is not quite up to the task yet. &lt;img src="http://photos1.blogger.com/blogger/2093/377/1600/icon_sad.gif" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;I am not sure if they have anonymous cvs access, but if you subscribe to &lt;a href="http://www.dev.java.net" target="_blank"&gt;www.dev.java.net&lt;/a&gt; (which is free), you can check out the jaxb 2.0 cvs source tree and see the IDE differences (simply by importing the existing project config files set up for various IDE's including Eclipse, Netbeans and IntelliJ):&lt;blockquote&gt;&lt;pre&gt;cvs -d:pesrver:yourid@cvs.dev.java.net:/cvs co -d jaxb-ri jaxb2-sources/jaxb-ri&lt;/pre&gt;&lt;/blockquote&gt;I filed a bug report to Eclipse &lt;a target="_blank" href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=125956"&gt;https://bugs.eclipse.org/bugs/show_bug.cgi?id=125956&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update on 23Feb06: I received a email from Kent Johnson saying he has this bug fixed in Eclipse 3.2M6.  Thanks Kent!&lt;/i&gt; &lt;img src="http://photos1.blogger.com/blogger/2093/377/1600/icon_smile.gif" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113856552634294677?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113856552634294677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113856552634294677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113856552634294677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113856552634294677'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/comparing-ides-on-support-of-java-5.html' title='Comparing IDE&apos;s on support of Java 5 Generics'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113834499298148492</id><published>2006-01-26T22:50:00.000-08:00</published><updated>2006-01-30T12:01:34.926-08:00</updated><title type='text'>JAXB 2.0 XJC Fluent API Plugin launched!</title><content type='html'>As mentioned in my &lt;a href="http://hansonchar.blogspot.com/2006/01/jwsdp-wish-list.html"&gt;previous post&lt;/a&gt;, one thing I wish to have is the support of method chaining in JAXB.  It turns out it's really easy to write a JAXB 2.0 XJC plugin.  Indeed, you can now download it from &lt;a href="https://jaxb2-commons.dev.java.net/fluent-api/" target="_blank"&gt;https://jaxb2-commons.dev.java.net/fluent-api/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's also announced at the &lt;a href="http://blogs.sun.com/roller/page/theaquarium?entry=adding_support_for_methodchaining_to" target="_blank"&gt;acquarium&lt;/a&gt; and mentioned &lt;a href="http://weblogs.java.net/blog/kohsuke/archive/2006/01/jaxb_fluent_api.html" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Special thanks to &lt;a href="http://weblogs.java.net/blog/kohsuke/" target="_blank"&gt;Kohsuke Kawaguchi&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113834499298148492?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113834499298148492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113834499298148492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113834499298148492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113834499298148492'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/jaxb-20-xjc-fluent-api-plugin-launched.html' title='JAXB 2.0 XJC Fluent API Plugin launched!'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113812833977727024</id><published>2006-01-24T10:29:00.002-08:00</published><updated>2006-01-24T16:49:29.836-08:00</updated><title type='text'>Fibonacci Numbers in Scheme</title><content type='html'>A  Fibonacci number is basically the sum of the previous two.&lt;blockquote&gt;&lt;pre&gt;pos: 0 1 2 3 4 5 6 7  8  9  10 ...&lt;br /&gt;fib: 0 1 1 2 3 5 8 13 21 34 55 ...&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;Simple but slow version in Scheme:&lt;blockquote&gt;&lt;pre&gt;; Time is of exponential order of N; whereas&lt;br /&gt;; space is of linear order of N&lt;br /&gt;(define (fibslow N)&lt;br /&gt; (cond ((&lt; N 2) N)&lt;br /&gt;       (else (+ (fibslow (- N 1))&lt;br /&gt;                (fibslow (- N 2))))))&lt;/pre&gt;&lt;/blockquote&gt;&lt;i&gt;How can we make it faster ?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Warning: reading futher will reveal a faster version.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Fast version in Scheme:&lt;blockquote&gt;&lt;pre&gt;; Time is of linear order of N; whereas&lt;br /&gt;; space is of constant order of N&lt;br /&gt;(define (fibfast N)&lt;br /&gt; (cond ((&lt; N 2) N)&lt;br /&gt;       (else (fibup N 2 1 0))))&lt;br /&gt;&lt;br /&gt;(define (fibup MAX count n-1 n-2)&lt;br /&gt; (cond ((= MAX count) (+ n-1 n-2))&lt;br /&gt;       (else (fibup MAX (+ 1 count) (+ n-1 n-2) n-1))))&lt;/pre&gt;&lt;/blockquote&gt;To feel the performance difference, try: &lt;blockquote&gt;&lt;pre&gt;(fibslow 30)&lt;/pre&gt;&lt;/blockquote&gt; vs. &lt;blockquote&gt;&lt;pre&gt;(fibfast 30)&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113812833977727024?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113812833977727024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113812833977727024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113812833977727024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113812833977727024'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/fibonacci-numbers-in-scheme.html' title='Fibonacci Numbers in Scheme'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113808277831186937</id><published>2006-01-23T22:02:00.000-08:00</published><updated>2006-01-24T16:49:54.593-08:00</updated><title type='text'>Tower of Hanoi in Scheme</title><content type='html'>&lt;blockquote&gt;&lt;pre&gt;;Solving the Tower of Hanoi in Scheme&lt;br /&gt;(define (move N from to spare)&lt;br /&gt;  (if (= N 0)&lt;br /&gt;      (display "")&lt;br /&gt;      (begin &lt;br /&gt;        (move (- N 1) from spare to)&lt;br /&gt;        (display "move from ")(display from)(display " to ")(display to)(display "\n")&lt;br /&gt;        (move (- N 1) spare to from))))&lt;/pre&gt;&lt;/blockquote&gt;Sample run:&lt;blockquote&gt;&lt;pre&gt;&gt; (move 3 'start 'end 'spare)&lt;br /&gt;move from start to end&lt;br /&gt;move from start to spare&lt;br /&gt;move from end to spare&lt;br /&gt;move from start to end&lt;br /&gt;move from spare to start&lt;br /&gt;move from spare to end&lt;br /&gt;move from start to end&lt;/pre&gt;&lt;/blockquote&gt;&lt;i&gt;How can we solve it iteratively (ie via tail recursion) ?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Warning: reading futher will reveal an iterative version.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It requires a lot more code and not in any way faster.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;; Solving the Tower of Hanoi iteratively in Scheme&lt;br /&gt;(define (moveIter N from to spare)&lt;br /&gt;  (moveIterImpl N from to spare () ()))&lt;br /&gt;&lt;br /&gt;(define (moveIterImpl N from to spare displayList moveList)&lt;br /&gt;  (if (= N 0)&lt;br /&gt;      (if (null? displayList)&lt;br /&gt;         (display "")&lt;br /&gt;         (begin&lt;br /&gt;           (output (car displayList))&lt;br /&gt;           (if (null? moveList)&lt;br /&gt;               (display "")&lt;br /&gt;               (eval (toMoveIterCmd moveList displayList)))))&lt;br /&gt;      (moveIterImpl (- N 1) from spare to &lt;br /&gt;        (cons (toPair from to) displayList)&lt;br /&gt;        (cons (toMoveParam (- N 1) spare to from) moveList))))&lt;br /&gt;&lt;br /&gt;(define (toMoveIterCmd moveList displayList)&lt;br /&gt;  (cons 'moveIterImpl &lt;br /&gt;        (cons (car (car moveList))&lt;br /&gt;              (cons (cons 'quote (cons (car (cdr (car moveList))) ()))&lt;br /&gt;                    (cons (cons 'quote (cons (car (cdr (cdr (car moveList)))) ()))&lt;br /&gt;                          (cons (cons 'quote (cons (car (cdr (cdr (cdr (car moveList))))) ()))&lt;br /&gt;                                (cons (cons 'quote (cons (cdr displayList) ()))&lt;br /&gt;                                      (cons (cons 'quote (cons (cdr moveList) ()))&lt;br /&gt;                                            ()))))))))&lt;br /&gt;&lt;br /&gt;(define (toMoveParam N from to spare)&lt;br /&gt;  (cons N (cons from (cons to (cons spare ())))))&lt;br /&gt;&lt;br /&gt;(define (output displayItem)&lt;br /&gt;  (begin&lt;br /&gt;    (display "move from ")(display (car displayItem))&lt;br /&gt;    (display " to ")(display (car (cdr displayItem)))&lt;br /&gt;    (display "\n")))&lt;br /&gt;&lt;br /&gt;(define (toPair from to)&lt;br /&gt;  (cons from (cons to ())))&lt;/pre&gt;&lt;/blockquote&gt;To run, simply type:&lt;blockquote&gt;&lt;pre&gt;&gt; (moveIter 3 'start 'end 'spare)&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113808277831186937?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113808277831186937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113808277831186937' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113808277831186937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113808277831186937'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/tower-of-hanoi-in-scheme.html' title='Tower of Hanoi in Scheme'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113807398209237940</id><published>2006-01-23T19:39:00.000-08:00</published><updated>2006-01-23T19:39:42.103-08:00</updated><title type='text'>MIT Open Courseware</title><content type='html'>&lt;a target="_blank" href="http://ocw.mit.edu/index.html"&gt;http://ocw.mit.edu/index.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113807398209237940?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113807398209237940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113807398209237940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113807398209237940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113807398209237940'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/mit-open-courseware.html' title='MIT Open Courseware'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113790718785672517</id><published>2006-01-21T21:03:00.000-08:00</published><updated>2006-01-21T21:30:38.953-08:00</updated><title type='text'>Trivial Java Quiz</title><content type='html'>&lt;span style="font-style: italic;"&gt;Can you name a public method in JDK1.5 that exists in a class, but cannot be found declared or defined anywhere in the class (source file) ? In other words, you can invoke the method and it will behave as expected, but the method (and even the method name) cannot be found in the source code of the class (or it's super classes or super interfaces), nor in the respective javadoc.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 102, 102); font-weight: bold;"&gt;Warning: reading futher will reveal the answer.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is one answer:&lt;br /&gt;&lt;br /&gt;It appears there are two static methods generated for every enum class:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;method &lt;span style="font-family:courier new;"&gt;values()&lt;/span&gt;, which returns the full list of enum instances of the specific &lt;span style="font-family:courier new;"&gt;Enum &lt;/span&gt;class; and&lt;/li&gt;   &lt;li&gt;method &lt;span style="font-family:courier new;"&gt;valueOf(String)&lt;/span&gt;, which returns the respective enum instance with the same name as the input string.&lt;/li&gt; &lt;/ol&gt; For (2), interestingly there is also a public static method &lt;span style="font-family:courier new;"&gt;valueOf&lt;/span&gt; with 2 parameters defined in the source file of &lt;span style="font-family:courier new;"&gt;Enum&lt;/span&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;// existing method in Enum&lt;br /&gt;public static &amp;lt;T extends Enum&amp;lt;T&gt;&gt; T valueOf(Class&amp;lt;T&gt; enumType, String name);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;t extends="" enum=""&gt;&lt;t&gt;&lt;t&gt;For (1), it puzzles me why there isn't also a public static method like:&lt;br /&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;blockquote&gt;&lt;pre&gt;// why not&lt;br /&gt;public static &amp;lt;T extends Enum&amp;lt;T&gt;&gt; T[] values(Class&amp;lt;T&gt; enumType);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;t extends="" enum=""&gt;&lt;t&gt;&lt;t&gt;The &lt;span style="font-family:courier new;"&gt;Enum&lt;/span&gt; javadoc doesn't even mention the 2 generated static methods, although one can see them when using auto-completion in an IDE. Seems like an oversight to me.&lt;br /&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113790718785672517?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113790718785672517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113790718785672517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113790718785672517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113790718785672517'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/trivial-java-quiz.html' title='Trivial Java Quiz'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6715087.post-113786343554572607</id><published>2006-01-21T09:09:00.000-08:00</published><updated>2006-01-21T10:08:57.610-08:00</updated><title type='text'>Structure and Interpretation of Computer Programs</title><content type='html'>&lt;a href="http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/" target="_blank"&gt;http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The video is pretty cool, and the online book is free!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6715087-113786343554572607?l=hansonchar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hansonchar.blogspot.com/feeds/113786343554572607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6715087&amp;postID=113786343554572607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113786343554572607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6715087/posts/default/113786343554572607'/><link rel='alternate' type='text/html' href='http://hansonchar.blogspot.com/2006/01/structure-and-interpretation-of.html' title='Structure and Interpretation of Computer Programs'/><author><name>Hanson Char</name><uri>http://www.blogger.com/profile/17880352604016760155</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='18' src='http://1.bp.blogspot.com/_4vkc19A9SOE/TLvfPTVq9tI/AAAAAAAABHM/Bw-tZo_myR4/S220/Photo+on+2010-10-14+at+21.05.jpg'/></author><thr:total>0</thr:total></entry></feed>
