<?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-7502473886475526382</id><updated>2012-01-06T20:14:41.091+01:00</updated><category term='java parsing simple library jmte'/><category term='java simple library jmte bytecode'/><title type='text'>Programming Nerd</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-9185424405571753474</id><published>2011-02-01T23:29:00.003+01:00</published><updated>2011-02-01T23:52:24.367+01:00</updated><title type='text'>Test your shit</title><content type='html'>&lt;div&gt;I never even thought I would write a post about unit tests. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Why? Because it is such a dogmatic approach, invented by people far from practical experience. The dogmatic application of Test Driven Development would for sure have ruined my company and any single project that I worked on.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That was the disclaimer :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;when you have library that is actually easy to test because it has a relatively small and well defined interface, it might be a good idea to add unit tests. Even when you are in a hurry and just hack that shit away, a test driven approach might be useful (just notice my use of the word "might"). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you actually do so I'd advice to write tests for every &lt;b&gt;state&lt;/b&gt; (fuck 100% code coverage - it does not say anything and might even be misleading) that comes to your mind even if you think it is ridiculous. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let me give you an example from my current fun project the "Java Minimal Template Engine". &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I remember I was thinking about an else inside a foreach while I already had a test for an if without the else part inside a foreach. Obviously two different states. First: simple if inside foreach, second if with else block inside foreach. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I though, I know the code that evaluates that stuff and I know that it really does not make a difference if the else is inside a foreach or not. And I had a test for that else outside a foreach. And I was right. I skipped the test. Code worked. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Time passed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I refactored the complete core of the template engine. I felt save to do so as I had a good bunch of unit tests. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After the refactoring, it &lt;i&gt;did&lt;/i&gt; make a difference if that else was inside that foreach and - of course - I sill had no test for it. All tests passed after refactoring. But I made a really silly mistake in the refactored code and else inside foreach was broken. And it wasn't me who discovered that ;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See the point? Just because you know the code and you know it does not make a difference now, does not mean this will remain true when time passes and the code changes. It might not even be you who changes that code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Those tests are there to protect you, so either take them seriously or skip them completely.  So: Test all your states.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-9185424405571753474?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/9185424405571753474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=9185424405571753474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/9185424405571753474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/9185424405571753474'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2011/02/test-your-shit.html' title='Test your shit'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-7762005672397352391</id><published>2011-02-01T23:24:00.002+01:00</published><updated>2011-02-01T23:27:56.381+01:00</updated><title type='text'>Against any dogmatic approach</title><content type='html'>I am just against any dogmatic approach to anything. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because dogmatic approaches do not work. If they did even AI might eventually succeed (I no longer believe in it).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because it is arrogant and maybe ignorant to even suggest or advice a dogmatic approach to others.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is a dogmatic approach? Then this is the only viable exception :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-7762005672397352391?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/7762005672397352391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=7762005672397352391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/7762005672397352391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/7762005672397352391'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2011/02/against-any-dogmatic-approach.html' title='Against any dogmatic approach'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-1310832109442803469</id><published>2011-01-24T10:31:00.005+01:00</published><updated>2011-01-24T11:51:07.114+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java parsing simple library jmte'/><title type='text'>Parsing very simple expressions in Java</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;You might say parsing such a simple expression&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;function(param1, param2)&lt;/i&gt;&lt;/blockquote&gt;(and the like) is easy even if you want escaping of special characters and quoted parts. At least that's what I said. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Obvious approaches include using standard Java classes&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/StringTokenizer.html"&gt;StringTokenizer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/Scanner.html"&gt;Scanner&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html"&gt;Regular Expressions&lt;/a&gt; (sometimes coming in disguise as direct String methods like &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String)"&gt;String.split&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Use a lexer generator like &lt;a href="http://www.cs.princeton.edu/~appel/modern/java/JLex/"&gt;http://www.cs.princeton.edu/~appel/modern/java/JLex/&lt;/a&gt; or &lt;a href="http://jflex.de/"&gt;http://jflex.de/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Using a full parer generator like &lt;a href="http://www.antlr.org/"&gt;http://www.antlr.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;doing this by hand using low level &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/String.html"&gt;String&lt;/a&gt; functions, e.g. &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/String.html#indexOf(int)"&gt;indexOf&lt;/a&gt; and &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/String.html#substring(int, int)"&gt;substring&lt;/a&gt;&lt;/li&gt;&lt;li&gt;remember your C days and still do this by hand, but rather by iterating through the input character by character&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;What did I do? &lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Options (1) and (2) do not work as they are not powerful enough, especially when it comes to escaping. Besides they are slow&lt;/li&gt;&lt;li&gt;Option (3) might acutally work, but besides being slow, dealing with complex regular expressions and the Java API for it is something I can not recommend. Even after reading and groking this &lt;a href="http://download.oracle.com/javase/tutorial/essential/regex/"&gt;tutorial&lt;/a&gt; would you want to write and maintain regular expressions? Try it. I don't.&lt;/li&gt;&lt;li&gt;(4) and (5): Having the full burden of a generated lexer plus runtime libraries or even a full generated parser is hardly worth the effort considering the simplicity of the expressions, even though both approaches would solve the problem.&lt;/li&gt;&lt;/ul&gt;Which leaves my doing it by hand which I wound up doing. First using option (6) which did the job, but resulted in code very hard to read and very hard to maintain. &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I then turned to option (7) and things became both easy and fast. I even came up with a&lt;a href="http://code.google.com/p/jmte/source/browse/trunk/src/com/floreysoft/jmte/util/MiniParser.java"&gt; very simple utility class&lt;/a&gt; that not only handles the above case, but other similar inputs. This is a test case for that utility class&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;i&gt;@Test&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;public void scanAndSplit() throws Exception {&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;String input = "function(param1, param2)";&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;i&gt; &lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;List&lt;string&gt; segments = MiniParser.defaultInstance().scan(input, "(", ")");&lt;/string&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;assertEquals(2, segments.size());&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;String functionName = segments.get(0);&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;String parameterString = segments.get(1);&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;i&gt; &lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;assertEquals("function", functionName);&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;assertEquals("param1, param2", parameterString);&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;i&gt; &lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;List&lt;string&gt; parameters = MiniParser.trimmedInstance().split(parameterString, ',');&lt;/string&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;assertEquals(2, parameters.size());&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;assertEquals("param1", parameters.get(0));&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;assertEquals("param2", parameters.get(1));&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;}&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-1310832109442803469?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/1310832109442803469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=1310832109442803469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/1310832109442803469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/1310832109442803469'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2011/01/parsing-very-simple-expressions-in-java.html' title='Parsing very simple expressions in Java'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-8046462731421426331</id><published>2011-01-24T01:36:00.006+01:00</published><updated>2011-01-24T11:49:41.324+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java simple library jmte bytecode'/><title type='text'>Java byte code generation</title><content type='html'>To speed up template processing for our &lt;a href="http://code.google.com/p/jmte/"&gt;template engine&lt;/a&gt; I recently decided to optionally compile each template into byte code. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Looking for a library to help me I chose ASM, because it&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;is small with no dependencies&lt;/li&gt;&lt;li&gt;has been released lately&lt;/li&gt;&lt;li&gt;has decent documentation &lt;/li&gt;&lt;li&gt;has a tool (Eclipse plugin) that generates ASM API calls from existing byte code&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;Especially no 4 inspired me to do the following:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Create a fistful of hand crafted Java classes that do the same as some selected templates&lt;/li&gt;&lt;li&gt;Create ASM code that generates the same byte code as those Java classes by the tool described in no 4&lt;/li&gt;&lt;li&gt;Create a recursive descent compiler that calls the generalized ASM code derived from step 2 that generates the desired byte code&lt;/li&gt;&lt;li&gt;Load and cache the classes at runtime  &lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;It turned out to be a pretty viable approach and allowed me to finish my task without too much knowledge of Java byte code. And what I had to learn anyway was quite enlightening :) &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Even though a lot of code remains to be dynamic, because I do not know what will be in the model at run time, the caliper micro benchmarks comparing uncompiled reference code against the compiled version shows a 2.5x - 10x speedup:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: 'courier new'; "&gt;&lt;div&gt; &lt;span class="Apple-style-span"&gt;                         benchmark    ns logarithmic runtime&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;          SimpleExpressionReference  3367 ================&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;           SimpleExpressionCompiled   963 ==&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new'; "&gt;         ComplexExpressionReference  6721 =======================&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;          ComplexExpressionCompiled  1331 ======&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new'; "&gt;                                 If  7067 =======================&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;                         IfCompiled   805 =&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new'; "&gt;                            Foreach 12796 =============================&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;                    ForeachCompiled  5275 ====================&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new'; "&gt; &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new'; "&gt;  &lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-8046462731421426331?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/8046462731421426331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=8046462731421426331' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/8046462731421426331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/8046462731421426331'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2011/01/java-byte-code-generation.html' title='Java byte code generation'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-468223271506266534</id><published>2008-11-10T08:54:00.006+01:00</published><updated>2008-11-10T09:58:18.477+01:00</updated><title type='text'>Typedef in Java or Map&lt;String, List&lt;Map&lt;String, Object&gt;&gt;&gt;</title><content type='html'>Folks!&lt;br /&gt;&lt;br /&gt;Have you ever had generic types like these &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Map&amp;lt;String, List&amp;lt;Map&amp;lt;String, Object&gt;&gt;&gt;&lt;/span&gt;? If so this post might be interesting for you.&lt;br /&gt;&lt;br /&gt;I had to pass either&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Map&amp;lt;String,  Map&amp;lt;String, Object&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Map&amp;lt;String,  List&amp;lt;Map&amp;lt;String, Object&gt;&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;through a single method.&lt;br /&gt;&lt;br /&gt;As you may know, polymorphism does not work with generics as the generic type is erased at compile time and is thus not available at run time.&lt;br /&gt;&lt;br /&gt;So, I tried to have a decent signature for my method:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;public void doSomething(Map&amp;lt;String, Object&gt; data);&lt;/span&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;/span&gt;Which obviously works for both above types. Unfortunately, this signature works for many other types as well. Even worse, checking which type has been passed in, is really hard as the generic type has been erased. What you would have to do to really find out is to check the actual type of the map values. Really ugly. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What can you do then? Before doing Java programming I was a C++ programmer, so I remembered the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;typedef&lt;/span&gt; keyword. Giving a lengthy type descriptor a short name - that's what I would have used in the C++ world. However, in the C++ world generics - templates in C++ speak - where different in nature. Each generic parameter would actually create a new type - which is not the case for Java. Apart from the fact that there is no typedef in Java! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I finally did as &lt;a href="http://www.mernst.org/blog/rss.xml"&gt;Matthias&lt;/a&gt; advised me: Adding a thin wrapper around my two generic types that serves both as a short name as well as a type valid for run time:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A wrapper for &lt;span class="Apple-style-span" style="font-style: italic; "&gt;Map&amp;lt;String, Object&gt; &lt;span class="Apple-style-span" style="font-style: normal; "&gt;would look like this:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;public class DataProvider {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;public final Map&amp;lt;String, Object&gt; data;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;public DataProvider(Map &amp;lt;String, Object&gt; data) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;this.data = data;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;public DataProvider() {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;this(new HashMap&amp;lt;String, Object&gt;());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Such a wrapper even saves you from typing constructors having weird syntax all the time as the default constructor already does this for you.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Concerning public fields, I know some people do not like them - for whatever reason. Simply make that field private or protected and add a getter method.   &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-468223271506266534?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/468223271506266534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=468223271506266534' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/468223271506266534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/468223271506266534'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2008/11/typedef-in-java-or-map-list-object.html' title='Typedef in Java or Map&amp;lt;String, List&amp;lt;Map&amp;lt;String, Object&gt;&gt;&gt;'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-3719518004290011414</id><published>2008-09-29T09:54:00.002+02:00</published><updated>2008-09-29T10:08:30.138+02:00</updated><title type='text'>Your Daily Dog Picture (Google App Engine)</title><content type='html'>My &lt;a href="http://dailydogpicture.appspot.com/"&gt;latest piece of work&lt;/a&gt; allows users to upload and display self-made dog pictures. &lt;br /&gt;&lt;br /&gt;Right now only the latest 10 pictures will be displayed, but a tagging system to access older pictures is already on its way.   &lt;br /&gt;&lt;br /&gt;Technically, the site has been developed with the &lt;a href="http://code.google.com/appengine/"&gt;Google App Enginge&lt;/a&gt; and Python. On upload pictures are automatically rescaled to thumbnail size and are stored in &lt;a href="http://labs.google.com/papers/bigtable.html"&gt;Google Bigtable database&lt;/a&gt; along with the original.&lt;br /&gt;&lt;br /&gt;All in all the whole site require less than 200 lines of code and about the same amount of HTML. It took me less than two days - including learning Python - to have the site ready and online. This is not because I am a genius, but because the technique is so simple and straight forward. Just great!&lt;br /&gt;&lt;br /&gt;Why did I do it? Because I like dog pictures and I - of course - wanted to try out the Google stuff. You get free development and free hosting and there is &lt;a href="http://code.google.com/appengine/docs/gettingstarted/"&gt;much more&lt;/a&gt; available than I have shown on the dog site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-3719518004290011414?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/3719518004290011414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=3719518004290011414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/3719518004290011414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/3719518004290011414'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2008/09/your-daily-dog-picture.html' title='Your Daily Dog Picture (Google App Engine)'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-6621424117828081268</id><published>2007-11-19T20:42:00.000+01:00</published><updated>2007-11-19T20:44:00.885+01:00</updated><title type='text'>Google Android</title><content type='html'>If this &lt;a href="http://code.google.com/android/"&gt;http://code.google.com/android/&lt;/a&gt; isn't cool, I have got no clue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-6621424117828081268?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/6621424117828081268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=6621424117828081268' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6621424117828081268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6621424117828081268'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/11/google-android.html' title='Google Android'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-6412972638351302184</id><published>2007-11-09T15:40:00.000+01:00</published><updated>2007-11-09T15:46:57.423+01:00</updated><title type='text'>Is Spring Batch Vaporware?</title><content type='html'>I tried to figure out what Spring Batch can do for a customer. To my surprise I have not found a single source of practical use. No examples that made sense to me. Just a bounch of weird interfaces and some illustrations at the very high level. Could it be that Spring Batch is just Vaporware? That no one really has an idea what it should finally become? Announcements that went out a bit too early? Something like that?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-6412972638351302184?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/6412972638351302184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=6412972638351302184' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6412972638351302184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6412972638351302184'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/11/is-spring-batch-vaporware.html' title='Is Spring Batch Vaporware?'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-1697958089154330324</id><published>2007-09-05T17:38:00.000+02:00</published><updated>2007-09-05T17:40:03.446+02:00</updated><title type='text'>"Selling" Alfresco's CMS</title><content type='html'>&lt;a href="http://www.linuxworld.com/news/2007/081607-matt-asay-interview.html?page=1"&gt;Interview  with Matt Asay&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-1697958089154330324?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/1697958089154330324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=1697958089154330324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/1697958089154330324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/1697958089154330324'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/09/selling-alfrescos-cms.html' title='&quot;Selling&quot; Alfresco&apos;s CMS'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-5002167649728385020</id><published>2007-07-29T02:13:00.000+02:00</published><updated>2007-07-29T02:14:39.731+02:00</updated><title type='text'>Apache Commons Transaction 2.0</title><content type='html'>&lt;a href="http://wiki.apache.org/jakarta-commons/Brainstorm_Transaction_2%2e0"&gt;Most of the initial implementation work has been done. Interfaces should be more or less stable. &lt;/a&gt; Lots of detail work remains.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-5002167649728385020?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/5002167649728385020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=5002167649728385020' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/5002167649728385020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/5002167649728385020'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/apache-commons-transaction-20.html' title='Apache Commons Transaction 2.0'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-2562707191772385587</id><published>2007-07-25T20:53:00.000+02:00</published><updated>2007-07-25T21:02:59.884+02:00</updated><title type='text'>Testing concurrent software is hard</title><content type='html'>&lt;a href="http://www.theserverside.com/tt/knowledgecenter/knowledgecenter.tss?l=TestingConcurrent"&gt;How to do that.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-2562707191772385587?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/2562707191772385587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=2562707191772385587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/2562707191772385587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/2562707191772385587'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/testing-concurrent-software-is-hard.html' title='Testing concurrent software is hard'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-6618782760508808849</id><published>2007-07-25T20:51:00.000+02:00</published><updated>2007-07-25T20:52:50.918+02:00</updated><title type='text'>Concurrency using channels</title><content type='html'>&lt;a href="http://video.google.de/videoplay?docid=810232012617965344"&gt;Here is a Google video about concurrent programming using channels&lt;/a&gt;. I wonder if I can make any use it this concept.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-6618782760508808849?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/6618782760508808849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=6618782760508808849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6618782760508808849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6618782760508808849'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/concurrency-using-channels.html' title='Concurrency using channels'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-7737932784665898455</id><published>2007-07-25T20:41:00.000+02:00</published><updated>2007-07-25T20:43:26.045+02:00</updated><title type='text'>Designing a good Java API</title><content type='html'>&lt;a href="http://www.scribd.com/doc/33655/How-to-Design-a-Good-API-and-Why-it-Matters"&gt; Joshua Bloch tells us how and why to write good APIs&lt;/a&gt;. I tried to respect what he says in the redesign of Apache Commons Transaction. Let's see if I really did ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-7737932784665898455?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/7737932784665898455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=7737932784665898455' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/7737932784665898455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/7737932784665898455'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/designing-good-java-api.html' title='Designing a good Java API'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-3546573128573527187</id><published>2007-07-21T17:03:00.000+02:00</published><updated>2007-07-21T17:04:44.607+02:00</updated><title type='text'>Finally removed my old blog at JRoller...</title><content type='html'>... as it never really took off.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-3546573128573527187?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/3546573128573527187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=3546573128573527187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/3546573128573527187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/3546573128573527187'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/finally-removed-my-old-blog-at-jroller.html' title='Finally removed my old blog at JRoller...'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-407428596424225734</id><published>2007-07-21T16:47:00.001+02:00</published><updated>2007-07-21T16:49:44.863+02:00</updated><title type='text'>Parsing XML with ANTLR</title><content type='html'>A few years ago I had written a completely confusing article for German computer magazine iX. &lt;a href="http://www.antlr.org/wiki/display/ANTLR3/Parsing+XML"&gt;This is my second try to tell you how to work with ANTLR&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-407428596424225734?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/407428596424225734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=407428596424225734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/407428596424225734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/407428596424225734'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/parsing-xml-with-antlr.html' title='Parsing XML with ANTLR'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-4955285979885329994</id><published>2007-07-21T16:45:00.001+02:00</published><updated>2007-07-21T16:46:02.488+02:00</updated><title type='text'>Good software is not enough</title><content type='html'>&lt;a href="http://www.joelonsoftware.com/articles/DevelopmentAbstraction.html"&gt;http://www.joelonsoftware.com/articles/DevelopmentAbstraction.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-4955285979885329994?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/4955285979885329994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=4955285979885329994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/4955285979885329994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/4955285979885329994'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/good-software-is-not-enough.html' title='Good software is not enough'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7502473886475526382.post-6862258195273469105</id><published>2007-07-20T18:33:00.000+02:00</published><updated>2007-07-20T18:37:08.700+02:00</updated><title type='text'>Programming Nerd</title><content type='html'>Howdy!&lt;br /&gt;&lt;br /&gt;This is the new technical blog. &lt;a href="http://ozeigermann.blogspot.com/"&gt;Here you can find my personal one (in German)&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7502473886475526382-6862258195273469105?l=programmingnerd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingnerd.blogspot.com/feeds/6862258195273469105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7502473886475526382&amp;postID=6862258195273469105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6862258195273469105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7502473886475526382/posts/default/6862258195273469105'/><link rel='alternate' type='text/html' href='http://programmingnerd.blogspot.com/2007/07/programming-nerd.html' title='Programming Nerd'/><author><name>Oliver Zeigermann</name><uri>http://www.blogger.com/profile/12308781862122345234</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://3.bp.blogspot.com/_Ds0KG-Hi89A/SNZ7sBT-cdI/AAAAAAAAAEs/eChu3cPhFlE/S220/2006.jpg'/></author><thr:total>0</thr:total></entry></feed>
