<?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-3555300218296290557</id><updated>2012-02-02T04:38:14.058-05:00</updated><category term='mobile'/><category term='shell script'/><category term='android'/><category term='iPhone'/><category term='blackberry'/><category term='ant'/><category term='agile'/><category term='javascript'/><category term='build'/><category term='clojure'/><category term='Ruby'/><category term='functional programming'/><category term='mac'/><category term='Notes'/><category term='code craft'/><category term='software craftsman'/><category term='phonegap'/><category term='software design'/><category term='Groovy'/><category term='Qcon'/><category term='life'/><title type='text'>PURSUING THE TAO OF PROGRAMMING</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>80</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6518970539730891083</id><published>2011-12-22T21:45:00.002-05:00</published><updated>2011-12-22T21:47:35.812-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Why I decided to take Scrum training?</title><content type='html'>Yesterday I registered an Certified Scrum Master training. &amp;nbsp;I choose &lt;a href="http://www.worldmindware.com/CertifiedScrumMasterMarkhamJanuary2012"&gt;the seminar on Jan 12, 2012&lt;/a&gt; &amp;nbsp;from &lt;a href="http://www.berteigconsulting.com/"&gt;Berteig Consulting&lt;/a&gt;. &amp;nbsp;Actually I am not so interested in SCRUM, rather I am super fan of Lean/Kanban, XP and software craftsmanship.&lt;br /&gt;I have a bias on SCRUM because I feel its process is oversimplified, and focus on manager side only, ignores developer side; and it lack the whole picture of Lean and flexibility of Kanban. Another reason is so far I did not find a good SCRUM example in my past experience, so I really doubt the its performance.&lt;br /&gt;The third reason is recently I found many articles which pointed out the issues of SCRUM.&lt;br /&gt;&lt;br /&gt;As a many years of working experience as a software developer, I really doubt a certificate is useful. &amp;nbsp;I don't think that you will become an SCRUM master just for 2 days training, which means master Agile philosophy is too easy.&lt;br /&gt;&lt;br /&gt;But recently I changed my mind, and decided to get a SCRUM Master certificate. You may wonder why I changed my mind so quickly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why learn Scrum?&lt;/b&gt;&lt;br /&gt;1. I realized that the current IT situation is even though Lean/Kanban is really hot inside the Agile community, but outside of the community, Scrum is still the most popular one. I will say 90% of the IT managers does not know Kanban. They are &amp;nbsp;more familiar with SCRUM. &amp;nbsp;If you have a Scrum training or get a certificate, it will be helpful for your career path. My long term goal is Agile coach, so I hope I can use CSM as a business card to help me find better jobs.&lt;br /&gt;&lt;br /&gt;2. I hope the CSM certificate can help me make changes in my company. 6 month earlier, I tried to suggest to my managers thinking of using Lean/Kanban, they are familiar with Scrum, but not Kanban. I found I get stuck, because I don't know how to persuade them, since neither I have Kanban experience, nor I have Scrum certificate. Now there are 3 Scrum Master in our company. I hope if I have a Scrum certificate, then I could use their familiar "Scrum" language to communicate, then&lt;b&gt; it would be easier for me help the company to transform from Scrum to Lean/Kanban.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What do I want to know about Scrum?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Clear the misunderstandings about Scrum;&lt;/li&gt;&lt;li&gt;Focus on the principles and philosophy behind Scrum;&lt;/li&gt;&lt;li&gt;Figure out the fundamental assumption which support Scrum;&lt;/li&gt;&lt;li&gt;Find out the good and bad parts of Scrum;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6518970539730891083?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6518970539730891083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/12/why-i-decided-to-take-scrum-training.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6518970539730891083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6518970539730891083'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/12/why-i-decided-to-take-scrum-training.html' title='Why I decided to take Scrum training?'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1510993595239702680</id><published>2011-12-12T23:15:00.003-05:00</published><updated>2011-12-13T17:05:03.964-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Cynefin framework and software code</title><content type='html'>Recently I read some article about&lt;a href="http://en.wikipedia.org/wiki/Cynefin"&gt; Cynefin framework&lt;/a&gt;, it is really inspiring.&amp;nbsp;As the diagram shows, cynefin framework&amp;nbsp;categorize&amp;nbsp;the problems&amp;nbsp;in to 4 domains:&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-TvYmMMogpLk/TubLYRKsRzI/AAAAAAAAAEQ/I_6AvxnTdhQ/s1600/280px-Cynefin_framework_Feb_2011.jpeg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-TvYmMMogpLk/TubLYRKsRzI/AAAAAAAAAEQ/I_6AvxnTdhQ/s1600/280px-Cynefin_framework_Feb_2011.jpeg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;simple&lt;/li&gt;&lt;li&gt;complicated&lt;/li&gt;&lt;li&gt;complex&lt;/li&gt;&lt;li&gt;chaotic&lt;/li&gt;&lt;/ul&gt;For different domain, the approach and strategy are quite different.&lt;br /&gt;Today I would like to analyze the software code using cynefin framework.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Which domain does software belong to?&lt;/b&gt;&lt;br /&gt;In General I will say software belongs to complex domain. One reason is software product environment changes so fast, the other reason is its entropy nature: always grow from simple to complex. Software product is so hard to predict and plan. That is the reason why we choose agile methodology: we follow TDD, keep refactoring, iterative developing and continuous integration. These methods are to deal with rapid the software's rapid changing context.&lt;br /&gt;Let's compare the complex domain with agile practices:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;complex, in which the relationship between cause and effect can only be perceived in retrospect, but not in advance, the approach is to Probe - Sense - Respond and we can sense emergent practice.&lt;/blockquote&gt;Here The &lt;b&gt;probe - sense - Respond&lt;/b&gt; is same as TDD and iterative development, since we don't understand the domain, so we have to rely on immediate feedback.&lt;br /&gt;And the emergent practice and retrospection, which is the same as refactoring, refactoring itself is emergent practice.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;We can also conclude that&amp;nbsp;the reason why waterfall does not working is because they assume the problem domain in software is always in simple domain.&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How about other domains?&lt;/b&gt;&lt;br /&gt;If we don't care code base and let it grows, then code base will becomes more and more complex until it becomes chaotic. As a developer we all have the experience of working with messy legacy code base: the messy code is hared to understand, hard to maintain; you fix one issue, then will generate another issue unexpectedly; the software is unstable, a small change will cause a big issue; the issue is always unpredictable;nobody understand the system; we spent all the time putting fires. Which is totally unstable and uncontrollable. These symptoms fit nicely with the chaotic domain model.&lt;br /&gt;&lt;br /&gt;But if we keep writing clean code, the code are easy to understand, easy to maintain, easy to change. In agile world writing clean code also means simple design. So this &amp;nbsp;will fit nicely in simple or complicated domain. Since they are both ordered. so they are manageable and controllable. That is software's ultimate goal - &amp;nbsp;flexibility, maintainability and reusability. So we will say clean code will help the software reduce the complexity.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why clean code will help reduce the complexity?&lt;/b&gt;&lt;br /&gt;The following tools and method help us writing clean code:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SOLID principles&lt;/li&gt;&lt;li&gt;high cohesion/loose couple&lt;/li&gt;&lt;li&gt;Design patterns&lt;/li&gt;&lt;li&gt;DRY principle&lt;/li&gt;&lt;li&gt;LoD principle&lt;/li&gt;&lt;li&gt;Refactoring&lt;/li&gt;&lt;/ul&gt;Lets' dig them deeper:&lt;br /&gt;-&amp;nbsp;&lt;b&gt;Break the unnecessary dependencies&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp; &amp;nbsp;Uncle Bob once said writing software is all about dependency management. SOLID principle, high cohesion/loose couple means reducing dependencies. We all know that the more interactions between objects, the more complex the software will be, so reducing the dependencies means making the software simpler.&lt;br /&gt;- &lt;b&gt;Set Rules and Constraints&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Design patterns basically is describing the rules of the relationship between objects in a specific context. To make software reusable, stable and manageable, we do not allow objects interact each other randomly, they have to follow certain rules. This is quite similar in human society, we have to maintain the orders via laws, rules or regulations.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="text-align: -webkit-auto;"&gt;-&amp;nbsp;&lt;/span&gt;&lt;b style="text-align: -webkit-auto;"&gt;Encapsulate changes&lt;/b&gt;&lt;/div&gt;&amp;nbsp; &amp;nbsp;One of the advantage of design patterns is how it deals with change: encapsulate changes. Which means when we identify a concept which it changes, then we encapsulate it by putting it into a class. &amp;nbsp;we don't want them randomly change. we put them in a box, isolate them. Once we put those details evil in the box, then we can understand or control the system by using abstraction. Then the system becomes stable, manageable and controllable&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In General software belongs to complex domain. The agile practices are the right practices to solve the complex domain problems;&lt;/li&gt;&lt;li&gt;Writing clean code will help us reduce the complexity, will move from complex to simple/complicated domain;&lt;/li&gt;&lt;li&gt;Writing messy code will increase the complexity, will move from complex into chaotic domain, this is what we are trying to avoid.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Strategy&lt;/b&gt;&lt;br /&gt;So our strategy will be constantly refactoring our code base, keep code clean, avoid messy code.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Resources&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.cognitive-edge.com/index.php"&gt;Cognitive&amp;nbsp;Edge&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.jackvinson.com/docs/Systems-Thinking-and-the-Cynefin-Framework-Final.4.pdf"&gt;Systems Thinking and the Cynefin Framework&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://vimeo.com/30596502"&gt;Video by Dave Snowden - Practice without sound theory will not scale&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1510993595239702680?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1510993595239702680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/12/cynefin-framework-and-software-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1510993595239702680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1510993595239702680'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/12/cynefin-framework-and-software-code.html' title='Cynefin framework and software code'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-TvYmMMogpLk/TubLYRKsRzI/AAAAAAAAAEQ/I_6AvxnTdhQ/s72-c/280px-Cynefin_framework_Feb_2011.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8383111676604239237</id><published>2011-12-03T23:10:00.001-05:00</published><updated>2011-12-03T23:37:37.270-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='phonegap'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>How javascript call java in Phonegap android</title><content type='html'>&lt;br /&gt;&lt;a href="http://phonegap.com/"&gt;Phonegap&lt;/a&gt; is a great mobile solution, since I am working in &lt;a href="http://www.grapplemobile.com/"&gt;Grapple mobile&lt;/a&gt; now, our platform use quite similar solution with Phonegap, so I really want to learn Phonegap to see if we can steal some ideas from it.&lt;br /&gt;What troubled me a long time is in its android platform: I wonder how does its javascript code calls java native code? Before I tried to read its android source code, but did not find the answer. This week I spent some time on its source code, finally I find the answer. I would like to share this result with you, this might be valuable especially if you want to dig more to phonegap, since I seldom find the answer from google or books about phonegaps, none of them talks about this.&lt;br /&gt;&lt;br /&gt;The phonegap source code I checked out is from github, the current version is 1.2:&lt;br /&gt;1. phonegap android source code:&amp;nbsp;https://github.com/callback/callback-android&lt;br /&gt;2. phonegap platform sample code:&amp;nbsp;https://github.com/callback/phonegap&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Digging the source code&lt;/b&gt;&lt;br /&gt;From phonegap-1.2.0.js&lt;br /&gt;&lt;br /&gt;For example looking at accelerometer: &amp;nbsp;in javascript layer, the accelerometer is implemented by calling Phonegap.exec() method:&lt;br /&gt;&lt;script src="https://gist.github.com/1429149.js?file=gistfile1.js"&gt;&lt;/script&gt;The PhoneGap.exec() method will be like this:&lt;script src="https://gist.github.com/1429153.js?file=gistfile1.js"&gt;&lt;/script&gt;So the exec method will invoke a javascript prompt()- which is popping up an dialog, huh, it sounds weird.&lt;br /&gt;&lt;br /&gt;Let's look at the java code:&lt;br /&gt;Inside com.phonegap.DroidGap.java, find the inner class GapClient, which is a subclass of WebChromeClient, it override the following 3 methods:&amp;nbsp;onJsAlert(),&amp;nbsp;onJsConfirm() and&amp;nbsp;onJsPrompt()&lt;br /&gt;Here we only look at the onJsPrompt(), look at the &lt;a href="http://draft.blogger.com/:http://developer.android.com/reference/android/webkit/WebChromeClient.html#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult)"&gt;android API for onJsPrompt()&lt;/a&gt;:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Tell the client to display a prompt dialog to the user. If the client returns true, WebView will assume that the client will handle the prompt dialog and call the appropriate JsPromptResult method. If the client returns false, a default value of false will be returned to to javascript. The default behavior is to return false.&lt;/blockquote&gt;&lt;br /&gt;So it is quite clear that: if prompt() is called in javascript layer, then onJsPrompt() method will get invoked in java layer. Phonegap just uses this way to handle the javascript to java communication.&lt;br /&gt;&lt;br /&gt;Let's look at the onJsPrompt() method in details:&lt;script src="https://gist.github.com/1429158.js?file=gistfile1.java"&gt;&lt;/script&gt;&amp;nbsp;So here the phoneGap PluginManager will delegate the the javascript call to different native plugins.&lt;br /&gt;&lt;br /&gt;From the article of&amp;nbsp;&lt;a href="http://stackoverflow.com/questions/7251557/phonegap-and-prompt"&gt;http://stackoverflow.com/questions/7251557/phonegap-and-prompt&lt;/a&gt;&lt;br /&gt;and phonegap release note:&amp;nbsp;&lt;a href="http://phonegap.com/2011/04/28/phonegap-0-9-5-released/"&gt;http://phonegap.com/2011/04/28/phonegap-0-9-5-released/&lt;/a&gt;, it mentioned that&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Worked around JavaScript bridge exception for Android 2.3. Use “prompt” instead of calling objects directly.&lt;/blockquote&gt;So it seems that this is a workaround for an issue in Android 2.3.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;To recap, this is the flow of javascript call java in phonegap android is like this:&lt;br /&gt;1. in javascript layer, all the javascript method will finally delegate to Phonegap.exec() method&lt;br /&gt;2. PhoneGap.exec() will call prompt()&lt;br /&gt;3. In java layer, DriodGap.GapClient override onJsPrompt(), which will capture the prompt() method call in java, which then delegate to PluginManager to invoke the native java method call.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8383111676604239237?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8383111676604239237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/12/how-javascript-call-java-in-phonegap.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8383111676604239237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8383111676604239237'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/12/how-javascript-call-java-in-phonegap.html' title='How javascript call java in Phonegap android'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4565312901910437407</id><published>2011-11-25T21:39:00.001-05:00</published><updated>2011-11-26T13:41:06.794-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>3 types of work - yesterday, today and tomorrow</title><content type='html'>I found it is useful to describe software developer's daily job into 3 different types: yesterday, today and tomorrow.&lt;br /&gt;&lt;b&gt;Yesterday&lt;/b&gt;: bug fix, maintenance job. since this kind of job is based on the product which is supposed to be finished, so I describe it as yesterday.&lt;br /&gt;&lt;b&gt;Today&lt;/b&gt;: developing phase, the work on the product is under development,&lt;br /&gt;&lt;b&gt;Tomorrow&lt;/b&gt;: some research and R&amp;amp;D work.&lt;br /&gt;These 3 different type has different nature, and they need different mindset and strategy to deal with them.&lt;br /&gt;Let me dig them into deeper.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Yesterday's work&lt;/b&gt;&lt;br /&gt;Yesterday's work are bug fixing and maintenance job. This kind of job is putting off fire, they are urgent, and undeniable. We need to fix them ASAP.&lt;br /&gt;&lt;br /&gt;Yesterday's work has no value or negative value, because customer already paid us up front, this work is support and service. This kind of job is not adding value, but removing the negative value.&lt;br /&gt;The more time and effort we spend on the yesterday's work, the less value remained for us. The cost of fixing a bug in production phase is much expensive than fixing it in developing phase( today's work).&lt;br /&gt;&lt;br /&gt;Yesterday's work is quite stressful. A minor issue delayed in yesterday will cause higher priority work. Yesterday's job is quite critical for time. we just need the job get done, there is no time for refactoring, no time to focus on better design. There is no room for developer to improve the system (code base, design, code quality etc) at this stage.&lt;br /&gt;&lt;br /&gt;If there are too many yesterday's work, then this is not a good signal: It means we have a large amount of technical debts from today's work, it means bad design and careless decision.&lt;br /&gt;So yesterday's job is highly dependent on today's work.&lt;br /&gt;Ideally we should keep the number of yesterday's work as low as possible.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Today's work&lt;/b&gt;&lt;br /&gt;Today's work is about current realistic issues.&amp;nbsp;Today's work is the tasks which is belong to developing phase. We develop a new feature which is our customer wanted, so this job will bring values. They are urgent and important, but some features can be negotiable. Customer will focus on feature than time, so the time is not so critical as Yesterday's work.&lt;br /&gt;Developer has lots of room to improve the system, he can have time to improve the design, refactoring.&lt;br /&gt;&lt;br /&gt;The strategy of today's work will be - &lt;b&gt;Build quality in&lt;/b&gt;. Focus on quality over time. If we focus on quality at this phase, then time must be shorten on maintain phase.&lt;br /&gt;Quality means more than functionality, also means maintainability and readability. &amp;nbsp;We should focus on simple design, write clean code, keep refactoring. and do not easily leak the bug to maintenance phase.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tomorrow's work&lt;/b&gt;&lt;br /&gt;Tomorrow's work is focused on research and innovation. It will bring us potential value in future, so I call it tomorrow's work, means work for tomorrow.&lt;br /&gt;&lt;br /&gt;It for a long term goal, we might not realize its value at present. it's important but not so urgent.&lt;br /&gt;&lt;br /&gt;Tomorrow's job is like investment. there is a risk, we don't know how much value it will bring us.&lt;br /&gt;&lt;br /&gt;Usually the priority of tomorrow's work is less than yesterday and today, if there are too many work spending on yesterday and today, then there is no time for us on investment. But if we did a good job on today's work, then we need less time on yesterday, then we have more time spending on tomorrow.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mapping to First thing first&lt;/b&gt;&lt;br /&gt;I found these 3 types of work map perfectly with&lt;a href="http://en.wikipedia.org/wiki/First_Things_First_(book)"&gt; Stephen Covey's first thing first&lt;/a&gt;&amp;nbsp;:&lt;br /&gt;Yesterday - Urgent but not important&lt;br /&gt;today - Urgent and important&lt;br /&gt;tomorrow - Not urgent but important&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;Yesterday is your debt, today is your earning, tomorrow is your investment.&lt;br /&gt;We need to focus on today's work, keep improving the quality of today's work.&lt;br /&gt;If we want to be productive, we need to balance these 3 types of work wisely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4565312901910437407?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4565312901910437407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/11/3-types-of-work-yesterday-today-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4565312901910437407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4565312901910437407'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/11/3-types-of-work-yesterday-today-and.html' title='3 types of work - yesterday, today and tomorrow'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8107139220429222670</id><published>2011-11-06T21:09:00.000-05:00</published><updated>2011-11-06T21:09:10.668-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Be careful "this" in Javascript Object</title><content type='html'>Consider the following javascript code:&lt;script src="https://gist.github.com/1344027.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;What if I remove the &lt;b&gt;this&lt;/b&gt; in method increment()?, like this:&lt;script src="https://gist.github.com/1344033.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;I must admit at first I wrote the code like the second, But it was wrong.&lt;br /&gt;As a Java programmer, I thought keyword &lt;b&gt;this&lt;/b&gt; in javascript will like java this always refer to the object owner, so this can be omitted. But I was wrong, the code above is wrong, because javascript requires you to use this keyword explicitly, otherwise it will treat variable value as undefined. It seems javascript will treat variable value as local variable, except you specify this explicitly.&lt;br /&gt;&lt;br /&gt;From this mistake, I understand that the experience in java is not working in javascript, if you want to access the class level variable in javascript method, you have to explicitly using this. Be careful for "this"!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8107139220429222670?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8107139220429222670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/11/be-careful-this-in-javascript-object.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8107139220429222670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8107139220429222670'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/11/be-careful-this-in-javascript-object.html' title='Be careful &quot;this&quot; in Javascript Object'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3968447962165585316</id><published>2011-10-22T22:48:00.003-04:00</published><updated>2011-10-22T22:54:42.825-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>The function definition in Javascript</title><content type='html'>I highly recommended Douglas Crockford's book &lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&amp;amp;qid=1319337719&amp;amp;sr=8-1"&gt;"Javascript:The good parts"&lt;/a&gt;. In the page 133 of the book, the author mentioned 2 ways of defining a function:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;use function statement,&lt;/li&gt;&lt;li&gt;use function expression&lt;/li&gt;&lt;/ul&gt;Their results are exactly the same.&amp;nbsp;For example,&lt;br /&gt;Function statement:&lt;br /&gt;&lt;script src="https://gist.github.com/1306783.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;Function expression:&lt;br /&gt;&lt;script src="https://gist.github.com/1306785.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;The above two have the exactly same result. they will both define a function foo. But I found there are still one difference:&lt;b&gt; scope&lt;/b&gt;.&lt;br /&gt;&lt;b&gt;The function statement is globally scoped, it can be put anywhere in the javascript, and you can call the function before or after it is defined.&lt;/b&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;script src="https://gist.github.com/1306787.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;b&gt;But in function expression is different, the function call statement must be after the function is defined, otherwise the function call will be failed.&lt;/b&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;script src="https://gist.github.com/1306789.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;When you think a little deeper, the error of function expression make sense, because the function expression means first declare a variable, then assign it with a function object. Why it failed before the function defined is because the variable is not declared and assigned yet.&lt;br /&gt;&lt;br /&gt;So if you use the function expression to define a javascript function, you need to aware this issue.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-3968447962165585316?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3968447962165585316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/10/function-definition-in-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3968447962165585316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3968447962165585316'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/10/function-definition-in-javascript.html' title='The function definition in Javascript'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6046581761415228295</id><published>2011-10-16T23:32:00.002-04:00</published><updated>2011-10-16T23:35:12.457-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Learning javascript: understanding prototype property</title><content type='html'>&lt;br /&gt;Prototype in javascript is so important, because javascript implements the object inheritance via prototype delegation.&amp;nbsp;Here I tried to summarize what I found for the javascript property.&amp;nbsp;The examples I used are tested on&lt;a href="https://www.squarefree.com/shell/"&gt; Firefox Javscript shell&amp;nbsp;&lt;/a&gt;.&lt;br /&gt;Please note that in Javascript function is also an object, so here function and function object are interchangeable.&lt;br /&gt;&lt;br /&gt;1. Every function object is automatically created with its own prototype property, the prototype property itself is an javascript object.You can add property or functions to the prototype property via function object.&lt;br /&gt;Example:&lt;br /&gt;&lt;script src="https://gist.github.com/1291872.js?file=gistfile1.js"&gt;&lt;/script&gt;2. When a object is created by using new keyword, it will get the prototype object from the constructor function; &amp;nbsp;created object can not access prototype property directly like function object, but it can access the property of the prototype object:&lt;br /&gt;example:&lt;br /&gt;&lt;script src="https://gist.github.com/1291875.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;3. When the created object instance read a property of the prototype, which is directly linked to the prototype object of its function constructor; while you want to modify the property, you end up by creating a new property in the object itself, which will not impact the same property name in the original function prototype. I believe javascript in this way implements the OO inheritance and overriding.&lt;br /&gt;Example:&lt;br /&gt;&lt;script src="https://gist.github.com/1291876.js?file=gistfile1.txt"&gt;&lt;/script&gt;&lt;br /&gt;4. The function object prototype property, which itself is an object, its default value contains only one hidden property: constructor, whose value is the same as the function itself.&lt;br /&gt;Example:&lt;br /&gt;&lt;script src="https://gist.github.com/1291880.js?file=gistfile1.txt"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6046581761415228295?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6046581761415228295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/10/learning-javascript-understanding.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6046581761415228295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6046581761415228295'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/10/learning-javascript-understanding.html' title='Learning javascript: understanding prototype property'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4607578544994542462</id><published>2011-10-10T23:04:00.003-04:00</published><updated>2011-10-27T00:18:39.964-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Code is constraint</title><content type='html'>Last week I watched Michael Feathers presentation: &lt;a href="http://confreaks.net/videos/717-rockymtnruby2011-opening-keynote-code-blindness"&gt;Code blindness&lt;/a&gt;.This is a great presentation, and it inspired me to think deeper.&lt;br /&gt;&lt;br /&gt;Before I think code is important from the programmer's perspective: craftsmanship, and professionalism. But it seems quite far to the managers. They don't know understand it and don't know how to connect this with their daily management.&lt;br /&gt;&lt;br /&gt;Today I would try to think from manager's perspective: borrowing the idea from &lt;a href="http://en.wikipedia.org/wiki/Theory_of_Constraints"&gt;theory of constraints&lt;/a&gt;, I will say code is just another constraint, like other constraints manager usually considering: time, budget, people. More specifically code quality will impact developers productivity and on time delivery.&lt;br /&gt;&lt;br /&gt;We know that the clean code base will easier to understand, easy to make change, and easy to maintain,but bad code base will hard to understand, hard to change, and hard to maintain, which greatly slow down developer's productivity.To avoid this happens, we have to deliberately keep code lean.&lt;br /&gt;&lt;br /&gt;There are two main metaphor to support the clean code:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Metaphor of &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Technical_debt"&gt;technical debt&lt;/a&gt;&lt;/b&gt;: code base is like technical debt, we have to pay off first by taking effort to refactoring, otherwise it will become harder and harder to change and maintain in future, so refactoring is the interest we pay for the debt.&lt;/li&gt;&lt;li&gt;Metaphor of &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Software_entropy"&gt;software entropy&lt;/a&gt;&lt;/b&gt;: code base is like entropy, by nature it will gradually go to messy, we have to constantly refactoring and keep our codebase clean.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So we can get the conclusion: code can be asset if it is clean; and can be debt as well if it is messy.&lt;br /&gt;&lt;br /&gt;So far we know that code is very important to developer's productivity, it should be consider as a constraint by the manager.&amp;nbsp;But I found many managers are totally unaware of this issue:&lt;br /&gt;They just assume developers are all professional and their code will always good enough;&lt;br /&gt;They only care the schedule, only care something get done, but does not care if the code is well maintained or not.&lt;br /&gt;And since managers unaware or ignore this issue, they might make decisions to make code base even messier, for example,&lt;br /&gt;- they will pressure developer to push them make quick-and-dirty fix, which cause the long term issue;&lt;br /&gt;- They do not care for the code, so they measure the performance only by task been finished, not by how good the code is written, so we can imagine developer will not actively care for the code.&lt;br /&gt;&lt;br /&gt;Code is important, but if you unaware or ignore it, then you will not manage it.&lt;br /&gt;If you don't manage it, then you will finally lost the control and then we will get real problems.&lt;br /&gt;When you have the problems, but you don't understand the root cause is code quality, then you probably trying to solve the issue in a wrong way.&lt;br /&gt;I heard so many times from managers said something like "we need to work harder", "we should work more careful", which are totally useless slogans.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Suggestions&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Manager should aware the code quality's importance, bring the connection between good code quality to developer's productivity and developing schedule.&lt;/li&gt;&lt;li&gt;Manager should cover code quality into their daily management, right now there are so many different tools to do code analysis and measurement.&lt;/li&gt;&lt;li&gt;Manager should create a culture to encourage software craftsmanship, clean code is a foundation of good software product, &amp;nbsp;clean code fit nicely the "&lt;b&gt;build quality in&lt;/b&gt;" lean principle.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4607578544994542462?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4607578544994542462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/10/code-is-constraint.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4607578544994542462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4607578544994542462'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/10/code-is-constraint.html' title='Code is constraint'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5000298209729623177</id><published>2011-10-01T23:30:00.002-04:00</published><updated>2011-10-03T14:18:13.692-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Making developer multitasking is a bad idea</title><content type='html'>Following is copied from a&lt;a href="http://www.quickplay.com/2011/04/mobile-developers-blackberry-java-android-brew-iphone-windows-web-0s/"&gt; job description&lt;/a&gt;&amp;nbsp;for a mobile&amp;nbsp;software developer from my previous employer QuickPlay Media:&lt;br /&gt;&lt;blockquote&gt;"Well organized with the ability to effectively manage&lt;b&gt; multiple projects simultaneously&lt;/b&gt;. Extensive experience in a fast-paced deadline-oriented environment".&lt;/blockquote&gt;When I first look at it, I was really surprised by the word "&lt;b&gt;multiple&lt;/b&gt;" and "&lt;b&gt;simultaneously&lt;/b&gt;", it is pretty obvious that they requires developers to be able to do multitasking jobs. Today I would like to dig this topic a little bit.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What does "manage multiple projects simultaneously" exactly mean?&lt;/b&gt;&lt;br /&gt;- Working project A for 5 minutes, then working on prjoect B another 5 minutes, and project C for another 5 minutes?&lt;br /&gt;- Or when you are working on project A, then interrupt by project B, you have to suspend the project A, then switch to project B;&lt;br /&gt;- Does it mean the developer has more project working simultaneously, the better for his performance review?&lt;br /&gt;- Does multitasking really improve the productivity? get faster delivery?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;This idea is totally wrong&lt;/b&gt;&lt;br /&gt;In the last 2 years I read a lot books about agile and software craftsmanship, so I am quite confident to say this is totally wrong, it will only make things worst!&lt;br /&gt;&lt;br /&gt;Fist it is against human nature. Human is not machine, he is non-linear, a person can only focus on one thing at a time. Interrupt and context switching is very expensive. The book &lt;a href="http://www.amazon.com/Pragmatic-Thinking-Learning-Refactor-Programmers/dp/1934356050/ref=sr_1_1?ie=UTF8&amp;amp;qid=1317525433&amp;amp;sr=8-1"&gt;Pragmatic Thinking &amp;amp; learning&lt;/a&gt; and &amp;nbsp;&lt;a href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1317525472&amp;amp;sr=1-1"&gt;peopleware&lt;/a&gt; cover this topic, and explain why managing focus is so important to maintain a higher productivity. and that is the reason why &lt;a href="http://www.pomodorotechnique.com/"&gt;the Pomodoro technique&lt;/a&gt; will force you only focus on one task in each 25 minute session. Managing people's focus is the key of improving his productivity.&lt;br /&gt;&lt;br /&gt;Second it is against the agile principles and and other proven theories. The goal of agile is to deliver the product as fast as possible, but the interesting thing is the agile trying to reach this goal by limiting the &lt;b&gt;Working-In-Progress items (WIP)&lt;/b&gt;. &amp;nbsp;&lt;b&gt;Scrum&lt;/b&gt; is trying to limit WIP in one iteration, WIP is called inventory in &lt;b&gt;Lean&lt;/b&gt;, which is a waste and should be limited. Limiting WIP is the key concept of &lt;b&gt;Kanban&lt;/b&gt; technology. and in &lt;b&gt;theory of constraints&lt;/b&gt; also proved that putting to many task in the queue will only slow down the productivity.The reason is pretty obvious, think about this scenario, if you have 3 projects, each will take one week. If you work sequentially, you will deliver one project after 1 week, 2 projects after 2 weeks, and you will get 3 projects after 3 weeks. But if you work simultaneously, you will get any project done until after 3 weeks, but considering the context switch cost, it will take you longer time to finish all 3 projects.&amp;nbsp;So based on Scrum, or Lean/Kanban, or Theory of Contraints, &amp;nbsp;working simultaneously will not deliver fast, it will only delay the delivery time.&lt;br /&gt;&lt;br /&gt;Third is it is a shift burden to from mangers to developers. Managing backlog is manager's responsibility, but requiring developer multitasking means putting some more backlogs into developers. It might looks better for managers, but actually it is bad, since those extra backlogs are either under working or putting into developer's own backlog. This is actually hide the visibility, which is even harder for manager to track the progress. I can feel that the multitasking is a solution which managers are trying to solve too many backlogs, but it is a bad idea, since it only move the backlog from manager layer to developer layer, which making things even worse; the manager should figure out the root cause and find a true solution to increase the burden down rate or increasing the productivity. I like to call this issue is &lt;b&gt;leaky management &lt;/b&gt;issue(copied the idea from leaky abstraction from OO design), because it is supposed to be solved in the management layer, but it leaks to the developer layer.&lt;br /&gt;&lt;br /&gt;Based on the above analysis, I can feel multitasking will generate following result:&lt;br /&gt;developer will have low productivity, projects will get more delayed, developer have to work harder and over time; since more projects get delayed, so manger put more projects to developer to work simultaneously, then becomes a positive feedback loop, which will make things even worse...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;I feel very sad for my old colleagues, because they are not treated well; &amp;nbsp;and I feel sorry for my ex-managers, because they are unaware of the basic principle of agile. To make a developer working efficiently, the only thing is trying to make him to work on one thing only. I strongly suggest QuickPlay to remove multitasking in its job requirements, but removing that from managers minds are much harder.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5000298209729623177?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5000298209729623177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/10/making-developer-multitasking-is-bad.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5000298209729623177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5000298209729623177'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/10/making-developer-multitasking-is-bad.html' title='Making developer multitasking is a bad idea'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2462286045943902734</id><published>2011-09-13T22:13:00.002-04:00</published><updated>2011-09-13T22:13:21.429-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>learning clojure: how to compile clojure source code</title><content type='html'>Currently I am learning clojure now, I focused on the book &lt;a href="http://joyofclojure.com/"&gt;"The joy of Clojure"&lt;/a&gt;, but actually I did not enjoy the joy of clojure so far. For me the book is still difficult. As the author mentioned, this book is not for beginner. Most of my time I have to refer on the Clojure API document. Today I want to share my experience on learning chapter 10.2.1, how to compile a clojure source code.&lt;br /&gt;&lt;br /&gt;The source code is in page 212, listing 10.3, called DynaFrame.clj:&lt;br /&gt;&lt;script src="https://gist.github.com/427650.js"&gt; &lt;/script&gt;&lt;br /&gt;The author mentioned how to ompile the source code:&lt;br /&gt;&lt;blockquote&gt;&amp;nbsp;You can compile this namespace by saving it in a directory joy/gui, located on the classpath, in a file named DynaFrame.clj and executing the function (compile 'joy.gui.DynaFrame) in a fresh REPL.&lt;/blockquote&gt;&lt;br /&gt;As a clojure beginner, I found it is described not detailed enough, it took me almost a night to figure out how to build it successfully.&lt;br /&gt;After fixing different weird problems, finally I got it working. Here is what I found:&lt;br /&gt;&lt;br /&gt;1. Be careful clojure version: at first I use clojure 1.0 to launch the REPL to compile it, but I got Exception to complain not found java.lang. Later I realize the problem is in&lt;b&gt; ^{:static true}&lt;/b&gt;, you have to use clojure 1.2 to compile it; if you still want to use clojure 1.0, then use&lt;b&gt; #^{:static true}&lt;/b&gt; instead.&lt;br /&gt;&lt;br /&gt;2. Use &lt;a href="https://github.com/liebke/cljr"&gt;cljr&lt;/a&gt; tool, I found it is really handy to add classpath: just run &lt;b&gt;cljr add-classpath &amp;lt;your folder&amp;gt;&lt;/b&gt;; run&lt;b&gt; cljr list-classpath&lt;/b&gt; will display your classpath.&lt;br /&gt;&lt;br /&gt;3. Add source code folder in the classpath&lt;br /&gt;&amp;nbsp; &amp;nbsp;put DynaFrame.clj under joy/gui, and&lt;br /&gt;&amp;nbsp; &amp;nbsp;run &lt;b&gt;cljr add-classpath ./&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;4. Add *compile-path*&lt;br /&gt;&amp;nbsp; &amp;nbsp;create an directory called "classes", and&lt;br /&gt;&amp;nbsp; &amp;nbsp;run &lt;b&gt;cljr add-classpath classes/&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Based on the &lt;a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/*compile-path*"&gt;clojure API document&lt;/a&gt;:*compile-path* defaults to "classes", the directory must be in the classpath for 'compile' to work.&lt;br /&gt;&lt;br /&gt;5. run cljr repl to launch the REPL, &amp;nbsp;type&lt;br /&gt;&amp;nbsp; &amp;nbsp; (compile 'joy.gui.DynaFrame)&lt;br /&gt;&amp;nbsp; &amp;nbsp;and&lt;br /&gt;&amp;nbsp; &amp;nbsp; (joy.gui.DynaFrame. "1st")&lt;br /&gt;&lt;br /&gt;In summary, to&amp;nbsp;compile the clojure code successfully, you need:&lt;br /&gt;&amp;nbsp;- Add source folder in the classpath;&lt;br /&gt;&amp;nbsp;- Create and add "classes" folder in the classpath&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2462286045943902734?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2462286045943902734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/09/learning-clojure-how-to-compile-clojure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2462286045943902734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2462286045943902734'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/09/learning-clojure-how-to-compile-clojure.html' title='learning clojure: how to compile clojure source code'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-7257437560802018480</id><published>2011-09-06T22:14:00.000-04:00</published><updated>2011-09-06T22:17:21.356-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Developing Blackberry application using NetBeans Plugin - part 2, fixing debug issue</title><content type='html'>&lt;br /&gt;On my &lt;a href="http://code-dojo.blogspot.com/2011/08/developing-blackberry-application-using.html"&gt;previous post&lt;/a&gt;, I reviewed the new blackberry Netbeans Plugin. Latre I found Shai also published his &lt;a href="http://lwuit.blogspot.com/2010/12/better-way-to-blackberry-and-misc.html"&gt;post&lt;/a&gt; about how to use the new plugin in developing the LWUIT blackberry application.&lt;br /&gt;But I found the new plugin could not debug the blackberry application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reason&lt;/b&gt;&lt;br /&gt;The reason is if you want to debug your blackberry application, you have to copy all the .debug files into the blackberry simulator folder, include xxx.debug, xxx-1.debug, xxx-2.debug, ... etc. From the generated build-impl.xml script file, we know that blackberry plugin only copied the xxx.debug file and missing all other debug files.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;&lt;br /&gt;Add the following targets in the build.xml, which will override the same target in the build-impl.xml:&lt;br /&gt;1. &amp;nbsp;Update target &lt;b&gt;blackberry-pre-debug&lt;/b&gt;, it will copy all the debug files into the simulator folder.&lt;br /&gt;&lt;script src="https://gist.github.com/1199566.js?file=blackberry-pre-debug"&gt;&lt;/script&gt;&lt;br /&gt;2. &amp;nbsp;&amp;nbsp;Update target &lt;b&gt;clean-blackberry&lt;/b&gt;, it will delete all the files of the application in the simulator folder.&lt;br /&gt;&lt;script src="https://gist.github.com/1199569.js?file=clean-blackberrty-target"&gt;&lt;/script&gt;&lt;br /&gt;3. &amp;nbsp;If you want to build BlackBerry CLDC application, you need to add the target &lt;b&gt;create-cod&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1199572.js?file=create-cod"&gt;&lt;/script&gt;&lt;br /&gt;The only difference with build MIDlet application is in&lt;b&gt; &amp;lt;arg value="-cldc"/&amp;gt;&lt;/b&gt;, by default, the Blackberry plugin already choose MIDlet by using &lt;b&gt;&amp;lt;arg value="-midlet"/&amp;gt;.&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-7257437560802018480?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/7257437560802018480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/09/developing-blackberry-application-using.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7257437560802018480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7257437560802018480'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/09/developing-blackberry-application-using.html' title='Developing Blackberry application using NetBeans Plugin - part 2, fixing debug issue'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2200247780217045855</id><published>2011-08-10T22:31:00.005-04:00</published><updated>2011-12-21T10:34:03.363-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Developing Blackberry application using NetBeans Plugin - part 1, first impression</title><content type='html'>Updates: I got some feedbacks that the download link in Netbeans is not working anymore, I uploaded the plugin binary into my google doc, please try &lt;a href="https://docs.google.com/open?id=0B3TGMRuLRen_ZjI2ZmVkYzYtMDU5Ny00NjA3LTk1MDYtOTBhNDcxOGQ2ZjI0"&gt;my link&lt;/a&gt; if you have problem to download.&lt;br /&gt;&lt;br /&gt;Recently when I checked out the latest version of the source code of LWUIT, I realized that LWUIT used a new solution of developing blackberry application - using Netbeans Blackberry plugin. So today I tried to give an review about this new tool.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Plugin Installation&lt;/b&gt;&lt;br /&gt;1. go to &lt;a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=11194"&gt;this link&lt;/a&gt;&amp;nbsp;(or&lt;a href="https://docs.google.com/open?id=0B3TGMRuLRen_ZjI2ZmVkYzYtMDU5Ny00NjA3LTk1MDYtOTBhNDcxOGQ2ZjI0"&gt; my link&lt;/a&gt;)to download the blackberry netbeans plugin, save it in your local drive.&lt;br /&gt;2. In your Netbeans IDE, choose Tools - Plugins, click Downloaded tab, press "Add Plugins..." button, choose the downloaded blackberry plugin .nbm file,&lt;br /&gt;3. Restart your Netbeans IDE, the thing is it seems the blackberry plugin has an issue, you can not see it under the Installed tab of the Plugins UI Form. I was confused it at the beginning as well.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add BlackBerry SDK platforms&lt;/b&gt;&lt;br /&gt;&lt;a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=11194"&gt;The plugin download link&lt;/a&gt;&amp;nbsp;(or &lt;a href="https://docs.google.com/open?id=0B3TGMRuLRen_ZjI2ZmVkYzYtMDU5Ny00NjA3LTk1MDYtOTBhNDcxOGQ2ZjI0"&gt;here)&lt;/a&gt;gives some screen shots about how to add blackberry SDK platform into your NetBeans IDE environment, here I just give an rough description, if you are familiar with the steps of adding other J2ME SDK into the NetBeans IDE, you will know it is the exactly the same steps.&lt;br /&gt;Compare this step with &lt;a href="http://www.naviina.eu/wp/blackberry/blackberry-api-in-netbeans-6-7/"&gt;the older solution&lt;/a&gt;, you will feel how easy it is.&lt;br /&gt;&lt;br /&gt;After Adding the BlackBerry SDKs in your NetBeans IDE, you can use the same way as J2ME Mobility package for blackberry development. Really Nice!!! Good job for the author!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test&lt;/b&gt;&lt;br /&gt;To test how the Plugin works, I choose 2 tests, one is for MIDlet and the other is for CLDC application (RIMlet).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test1 - build an BlackBerry MIDlet application&lt;/b&gt;&lt;br /&gt;I imported an JavaME SDK sample application - SunSamples-Demos into my NetBeans IDE, then add another configuration, choose an BlackBerry platform, I just choose JDE 4.5, then everything else is copied from the default configuration. &lt;br /&gt;1. Test Build&lt;br /&gt;Click "Clean and Build", the IDE build successfully and generate .cod file and bunch of .debug files. &lt;br /&gt;So Build test passes.&lt;br /&gt;2. Test Run&lt;br /&gt;When I click "Run", the IDE launches BlackBerry simulator, then I found the several applications (since SunSamples-Demos contains multiple MIDlets), I choose some apps, they work perfectly.&lt;br /&gt;Application Running also passed.&lt;br /&gt;3. Test Debug &lt;br /&gt;I set several break points in the IDE, then I click "Debug", the IDE launches the BlackBerry JDWP application and the blackberry simulator, when choose an application, the application did not stop at a specific break point.&lt;br /&gt;The debug test failed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test2 - build an BlackBerry CLDC application&lt;/b&gt;&lt;br /&gt;This time I choose a LWUIT blackberry port demo application - LWUITDemoRIM, just check out the LWUIT source code from its SVN, open the LWUITDemoRIM project. If you installed the plugin and added the blackBerry SDK properly, it is very easy to configure the project in the NetBeans.&lt;br /&gt;Here I would like to mention, for native CLDC application, you need to do a little extra work in your build script. Check this link for details: http://forums.netbeans.org/topic24475.html&lt;br /&gt;&lt;br /&gt;1. Test Build&lt;br /&gt;Click "Clean and Build", the IDE build successfully and generate .jad file, .cod file and bunch of .debug files. If you open the jad file, it will tell you the application is CLDC application.&lt;br /&gt;So Build test passes.&lt;br /&gt;2. Test Run&lt;br /&gt;When I click "Run", the IDE launches BlackBerry simulator, you will find the familiar LWUIT demo icon, the application works perfectly as I saw before.&lt;br /&gt;So running test passed.&lt;br /&gt;3. Test Debug &lt;br /&gt;When I click "Debug", I saw the same behaviour as the MIDlet application test, the application never stops at the break point.&lt;br /&gt;Debug test failed as well.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;Pros:&lt;br /&gt;- The Blackberry Plugin for NetBeans is pretty easy to install and use. The developer will feel it looks pretty same as other J2ME SDK. &lt;br /&gt;- The Build process is really simple and almost same as regular J2ME application, it will convert jar file into blackberry .cod file.&lt;br /&gt;- The IDE can launch Blackberry native simulator and can run the application successfully.&lt;br /&gt;- The plugin built-in support MIDlet build, need a little work for RIMlet.&lt;br /&gt;&lt;br /&gt;Cons:&lt;br /&gt;- Debug is not working, after I read the build script, I know why: based on my experience, you need to copy all the .debug files into the simulator folder, but in build-impl.xml, the target "blackberry-pre-debug" only copied 1 .debug file but missing others.&amp;nbsp; I will post the detailed solution in future.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Next Action&lt;/b&gt;&lt;br /&gt;In future, I will continue post my investigation about this plugin, includes:&lt;br /&gt;- How to build the MIDlet and RIMlet&lt;br /&gt;- Dig deeper on how it implement the blackberry build&lt;br /&gt;- How to fix the debug issue&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2200247780217045855?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2200247780217045855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/08/developing-blackberry-application-using.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2200247780217045855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2200247780217045855'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/08/developing-blackberry-application-using.html' title='Developing Blackberry application using NetBeans Plugin - part 1, first impression'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5153964845103910749</id><published>2011-07-17T00:20:00.007-04:00</published><updated>2011-07-17T00:22:11.413-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Becoming generalist - dealing with constraints in software development</title><content type='html'>&lt;br /&gt;Recently I read the fascinating book - &lt;a href="http://www.amazon.com/gp/product/0884271781/ref=s9_simh_gw_p14_d2_i2?pf_rd_m=ATVPDKIKX0DER&amp;amp;pf_rd_s=center-2&amp;amp;pf_rd_r=0MPNWB5PHSE4F70SPZJ0&amp;amp;pf_rd_t=101&amp;amp;pf_rd_p=470938631&amp;amp;pf_rd_i=507846"&gt;the goal&lt;/a&gt;, it is really an eye opener for me. I learned the&lt;a href="http://en.wikipedia.org/wiki/Theory_of_Constraints"&gt; theory of constraints&lt;/a&gt; from the book.&amp;nbsp;Everything of TOC looks like common sense, but the conclusion is really striking.&lt;br /&gt;&lt;br /&gt;TOC tells us the importance of bottle neck (constraint). We need to identify it, and protect it. In the example of manufacturing assembly line, to make sure the task in bottle neck is the highest priority, other jobs even have to be idle instead of working, otherwise it will make the whole productivity even worse!&lt;br /&gt;&lt;br /&gt;I believe TOC can apply to software development as well: because the software developing also needs a series dependent activities. And similar to manufacturing, software development also has constraints(bottlenecks), it might be in: test,coding,deploy,maintenance. On the other side, compared to manufacturing, software development is people centered vs. machine centered; most of the constraints is about people; software process is lot easier to change compare to assembly line.&lt;br /&gt;In software industry, we could have a big advantage over manufacturing: to deal with bottleneck, we don't need put other people to sit in idle, we can put more people working on the bottle neck! But this advantage depends on a requirement - if our developers are generalists.&lt;br /&gt;&lt;br /&gt;If every developer in a team is a generalist, which would be a great help to maintain a high productivity, then we can deal with almost any constraint, since when there is a bottleneck, we can put more people on it. So the developing flow will be well controlled in a high productivity speed.&lt;br /&gt;&lt;br /&gt;Becoming a generalist raise the bar for developers: we are not just a geek who focus on a single area, we are not only J2EE developers, but we also need to fix the bug of a J2ME application; we might need to mange data base as DBA; or improve the build system by writing Ant or shell script.&lt;br /&gt;&lt;br /&gt;Becoming a generalist is really challenging, and much harder than focusing on one single area. But based on my experience, software developing job is not a rocket science, every technology can be learned if given an enough time. Technology is not a problem for becoming a generalist, the problem is attitude and mindset. We need to be open minded, be flexible, and ready to wear different hat at different context.&lt;br /&gt;&lt;br /&gt;A generalist has following benefits:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Doing different jobs, give developer a chance to learn different new technology and tools, learn by doing will make you learn faster.&lt;/li&gt;&lt;li&gt;Have chance to know the big picture of your work.&lt;/li&gt;&lt;li&gt;Better for team work and collaboration&lt;/li&gt;&lt;li&gt;Improve your competence and marketability, since you can put more stuff on your resume.&lt;/li&gt;&lt;li&gt;More changes to become linchpin and less likely being laid off, who wants to fire a developer who can do multiple jobs?&lt;/li&gt;&lt;/ul&gt;I will suggest our managers should encourage developers to become generalist. For example, he can deliberately assign different jobs for one developer; rotate developer to another team; foster pair programming and mentoring, etc.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5153964845103910749?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5153964845103910749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/07/becoming-generalist-dealing-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5153964845103910749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5153964845103910749'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/07/becoming-generalist-dealing-with.html' title='Becoming generalist - dealing with constraints in software development'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6292755361851989834</id><published>2011-07-10T23:09:00.003-04:00</published><updated>2011-07-10T23:13:51.654-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Can software be estimated?</title><content type='html'>As a software developer, I am always asked by project managers:How long do you think you need to finish project X or fix &amp;nbsp;issue Y? Most of the time I feel annoyed and guilty, because usually I don't really know the answer but I have to give them &amp;nbsp;a number - which is far from accurate.&lt;br /&gt;&lt;br /&gt;I believe how to get a good estimation is one of the major issue for all the developer and managers. An accurate estimation help manager control and plan the project, which make sense. But it is based on an assumption: the software can be estimated.&amp;nbsp;Is this assumption really true? Let's investigate it.&lt;br /&gt;First, if we assume software is estimatable, =&amp;gt; then we can see software is predictable, =&amp;gt; then we can plan ahead, =&amp;gt; waterfall model. We all know that waterfall and CMM is not workable, try to harden the software project is myth.&lt;br /&gt;Next, let's check the software development model. From Lean/Agile software development we know that software is a discovery process, an explorative process, a theory building process, an process of reducing ignorance level. In summary, it is a learning process, the problem solving process itself is also a learning process. &amp;nbsp;That is why agile uses iterative, feedback process. Which means at the beginning you know very little, you only understand the problem when you solve the problem at the end. So how could you estimate or predict at the beginning? How could you give an accurate estimation at the beginning? You can predict only if you know all the variables, but in software development, there are so many unknown variables: third party library issues, platform compatible issues, IDE, target constraints, etc and other issues you might not aware(you don't know you don't know). So based on analysis the above , &lt;b&gt;we can say estimation in software is impossible.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let's look at another question: can we estimate bug fix? Bug fix is also a learning process, especially when you are assigned a bug which code base is not written by you. You need to take time to understand the bug, reproduce the issue, understand the code base, familiar with the context, all this stuff are learning process and takes time. How can we estimate this time, because this is really case by case. And we all know that bug fix is actually we spend 90% of time on finding the bug, another 10% time on fixing the bug. Once we found the bug, we know how to fix it. So we can only see we can estimate the bug only after we found the bug, but at this moment it is pointless to give an estimation since we already solve the 90% of the problem.&lt;br /&gt;&lt;br /&gt;I would like to share my own experience:&lt;b&gt;In an iterative development process, &amp;nbsp;there is no need to estimate&lt;/b&gt;, just do it. Before I start fixing a bug, I knew nothing; the time I know the estimation answer is when I solve the issue, so the process of finding the answer of estimation is the same process of solving the problem. So at this case why we need the estimation?&lt;br /&gt;&lt;br /&gt;&amp;nbsp;So we know that software nature is impossible to estimate and needless to estimate. But why project managers need it?&amp;nbsp;Maybe they don't have technical background and still trying to use the concept of waterfall methodology; or maybe the psychological reason: human usually not comfortable with uncertainty and &lt;a href="http://pragprog.com/magazines/2011-01/guru-meditation"&gt;needs for closure&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;Forcing estimation cause some worse consequences:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Force developer to plan up front, which will fallback to waterfall;&lt;/li&gt;&lt;li&gt;Developer faces the pressure to lie, and give the wrong number, which cause,&lt;/li&gt;&lt;li&gt;Wrong measurement is worse than no measurement. Like weather forecast.&lt;/li&gt;&lt;/ul&gt;What can we do when the project manager ask you estimation next time:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;Live with the uncertainty, that is the nature of the software development;&lt;/li&gt;&lt;li&gt;To be honest, tell them you don't know yet, you only estimate what you can deliver after the current iteration;&lt;/li&gt;&lt;li&gt;Timebox the estimation, spend 30 minutes to investigate the problem, you should know if you can finish it by the end of the day or not. Avoid yak-shaving.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6292755361851989834?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6292755361851989834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/07/can-software-be-estimated.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6292755361851989834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6292755361851989834'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/07/can-software-be-estimated.html' title='Can software be estimated?'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5793491734744362481</id><published>2011-07-03T23:18:00.001-04:00</published><updated>2011-07-03T23:20:40.025-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Learning the theory of Constraint - "The goal" Review</title><content type='html'>Yesterday I finished the book:&lt;a href="http://www.amazon.com/Goal-Process-Ongoing-Improvement/dp/0884271781?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;The Goal: A Process of Ongoing Improvement&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0884271781" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;. The book is so fascinating, when I read it, I can not put it down, just like reading one of Agatha Christine's books. I never imagine that a business book can be written like this.&lt;br /&gt;What I am most interested is the principle described in book: the theory of constrains. Here I copied some key points from the &lt;a href="http://en.wikipedia.org/wiki/Theory_of_Constraints"&gt;TOC WIKI&lt;/a&gt;:&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Key assumption&lt;/b&gt;&lt;br /&gt;The underlying premise of Theory of Constraints is that organizations can be measured and controlled by variations on three measures: throughput, operational expense, and inventory.&lt;br /&gt;Throughput is the rate at which the system generates money through sales.&lt;br /&gt;Inventory is all the money that the system has invested in purchasing things which it intends to sell.&lt;br /&gt;Operational expense is all the money the system spends in order to turn inventory into throughput.&lt;br /&gt;"The Goal" itself is to "make money". All other benefits are derived, in one way or another, from that single primary goal.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The five focusing steps&lt;/b&gt;&lt;br /&gt;Theory of Constraints is based on the premise that the rate of goal achievement is limited by at least one constraining process. Only by increasing flow through the constraint can overall throughput be increased.Assuming the goal of the organization has been articulated (e.g., "Make money now and in the future") the steps are:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Identify the constraint (the resource or policy that prevents the organization from obtaining more of the goal)&lt;/li&gt;&lt;li&gt;Decide how to exploit the constraint (get the most capacity out of the constrained process)&lt;/li&gt;&lt;li&gt;Subordinate all other processes to above decision (align the whole system or organization to support the decision made above)&lt;/li&gt;&lt;li&gt;Elevate the constraint (make other major changes needed to break the constraint)&lt;/li&gt;&lt;li&gt;If, as a result of these steps, the constraint has moved, return to Step 1. Don't let inertia become the constraint.&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;Applying to software development&lt;/b&gt;&lt;br /&gt;This book is about manufacturing, but I found it can be easily applied to the software development. And I found it is very similar with Kanban method: Kanban help us visualize the bottleneck, improve the productivity by limiting the Work-In-Progress. Which is exactly the same as the theory of constraints. I feel that the TOC can be regarded as the scientific theory behind the Kanban system. Before when I learn Kanaban, I just accept the principles and conclusion from the Kanban, but I never thought of why it is like this or that, &amp;nbsp;Since this book uses lots of examples and step by step from question to conclusion. Now I understand more about Kanban. So&amp;nbsp;I can say Kanban is an implementation of TOC.&lt;br /&gt;If you knows Lean/Agile, you will find there are lots of concepts shared between lean and TOC:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;lead time&lt;/li&gt;&lt;li&gt;Inventory is bad&lt;/li&gt;&lt;li&gt;WIP (Work-In-Progress)&lt;/li&gt;&lt;li&gt;small batch increase the productivity&lt;/li&gt;&lt;li&gt;local optimization is not working only optimize the whole works.&lt;/li&gt;&lt;li&gt;The dependent event queue can be mapped to the value stream map, or Kanban Queue.&lt;/li&gt;&lt;/ul&gt;Even the subtitle of the book - "A Process of Ongoing Improvement", which is perfectly match one of the lean philosophy - Kaizen, which means continuous improvement.&lt;br /&gt;&lt;br /&gt;I just found David J. Anderson's book: &lt;a href="http://www.amazon.com/Agile-Management-Software-Engineering-Constraints/dp/0131424602?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Agile Management for Software Engineering: Applying the Theory of Constraints for Business Results&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0131424602" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;. I haven't read that, but based on the title, it must be about applying the TOC into software development. In his recent blog post: &lt;a href="http://agilemanagement.net/index.php/Blog/reflections_on_the_passing_of_eli_goldratt/"&gt;REFLECTIONS ON THE PASSING OF ELI GOLDRATT&lt;/a&gt;, &amp;nbsp;he describe how TOC inspired him for his book and Kanban system.&lt;br /&gt;Actually when I read this article from twitter last week, and this is the reason to let me read the book of "The goal".&lt;br /&gt;&lt;br /&gt;And I found this youtube video is interesting:&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=C3RPFUh3ePQ"&gt;Standing on the Shoulder of Giants by Eliyahu M. Goldratt&lt;/a&gt;, Godratt talks about the TOC, Kanban and Toyota Production System.&lt;br /&gt;&lt;br /&gt;I realized I need to read this book one more time. the TOC is so powerful, but I still have lots of questions, like:&lt;br /&gt;- How can we apply it into our daily software development?&lt;br /&gt;- How to find the bottleneck?&lt;br /&gt;- What are the measurements we need?&lt;br /&gt;&lt;br /&gt;Hope I can find the answers from the goal, kanban and Lean.&lt;br /&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/3555300218296290557-5793491734744362481?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5793491734744362481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/07/learning-theory-of-constraint-goal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5793491734744362481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5793491734744362481'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/07/learning-theory-of-constraint-goal.html' title='Learning the theory of Constraint - &quot;The goal&quot; Review'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6561239654122236360</id><published>2011-06-20T16:19:00.005-04:00</published><updated>2011-08-06T22:27:47.744-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><title type='text'>NoClassDefFoundError in Blackberry</title><content type='html'>&lt;b&gt;Background&lt;/b&gt;&lt;br /&gt;Since lastweek I spent couple of days trying to fix an issue: The application keep throwing NoClassDefFoundError Exception in a callback method. Through JDE debugger, I can figure out exactly where the exception is threw and which object cause the exception, but when I check the code back and forth, I could not find the problem, since the class file is there. Finally I realized that I also changed the build script: before I use antenna wtkbuild task to generate the library, the new build I use regular javac task, since I used the blackberry native API. Will it cause the problem? It does not make any sense to me. I tried to switch back the build script using twkbuild task and adding the rim api in the class path, this time everything works! No more NoClassDefFoundError any more!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Finding the root cause&lt;/b&gt;&lt;br /&gt;I compared the wtktask and the javac task with blackberry build script:&lt;br /&gt;&lt;br /&gt;build target(with issue):&lt;br /&gt;&lt;div style="overflow: auto;"&gt;&lt;div class="geshifilter"&gt;&lt;pre class="r geshifilter-R" style="font-family: monospace;"&gt;&amp;lt;target name=&lt;span style="color: blue;"&gt;"compile_rim"&lt;/span&gt; depends=&lt;span style="color: blue;"&gt;"init"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;  &amp;lt;javac destdir=&lt;span style="color: blue;"&gt;"${outputclasses}"&lt;/span&gt; encoding=&lt;span style="color: blue;"&gt;"${src.encoding}"&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/source"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;source&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: blue;"&gt;"1.3"&lt;/span&gt; srcdir=&lt;span style="color: blue;"&gt;"${src.dir}:${rim.src.dir}"&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;classpath location=&lt;span style="color: blue;"&gt;"${rimlib.loc}"&lt;/span&gt;/&amp;gt;&lt;br /&gt;   &amp;lt;/javac&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt; &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;a href="http://www.inside-r.org/pretty-r" title="Created by Pretty R at inside-R.org"&gt;Created by Pretty R at inside-R.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;wtk build ( no issue)&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1129991.js?file=ant%20sample1"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Form the above, I can not tell the difference, and can not figure out why there is an issue. So I have to look at the antenna source code. When I looked at the WtkBuild.java, I noticed that &lt;b&gt;antenna sets the javac target to 1.1 by default!&lt;/b&gt; This is interesting.&lt;br /&gt;&lt;br /&gt;Check the ant document for &lt;a href="http://ant.apache.org/manual/Tasks/javac.html"&gt;javac task&lt;/a&gt;, for target attribute, it says:&lt;br /&gt;&lt;blockquote&gt;Generate class files for specific VM version (e.g., 1.1 or 1.2). Note  that the default value depends on the JVM that is running Ant. In  particular, if you use JDK 1.4+ the generated classes will not be usable  for a 1.1 Java VM unless you explicitly set this attribute to the value  1.1 (which is the default value for JDK 1.1 to 1.3). We highly  recommend to always specify this attribute.&lt;/blockquote&gt;So based on the above statement, I suspect that the Ant require us to specify the target version, if we don't specify ant will use the default version.and the default target version cause the blackberry device throws the exception.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is the target version for J2ME and Blackberry&lt;/b&gt;&lt;br /&gt;In Antenna, the target is set to 1.1, is this the correct value for J2ME and Blackberry? To prove this, I googled and find some articles:&lt;br /&gt;&lt;a href="http://developers.sun.com/mobility/midp/articles/ant/"&gt;Managing Wireless Builds with Ant&lt;/a&gt;, this article from oracle mentioned that J2ME build requires target value to be 1.1:&lt;br /&gt;&lt;pre&gt;&amp;lt;javac bootclasspath="${midp_lib}" destdir="build/classes" srcdir="src" target="1.1"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and I found this article in BlackBerry forum:&lt;a href="http://supportforums.blackberry.com/t5/Java-Development/javac-target-parameter-used-by-the-rapc-exe-tool/ta-p/520761"&gt;javac -target parameter used by the rapc.exe tool&lt;/a&gt;&lt;br /&gt;It shows that you need to use target 1.1 to build blackberry compatible application:&lt;br /&gt;&lt;blockquote&gt;Rapc.exe automatically ensures that these .class files are targeted for  BlackBerry® Java® Virtual Machine (BlackBerry JVM) 1.1 or later. This is  done to maintain compatibility on the BlackBerry smartphones when the  .class files are actually packaged in a .cod file.&lt;br /&gt;&lt;br /&gt;If you are  using a custom script that calls javac.exe and rapc.exe separately to  package your application, you will have to make sure that you are  calling javac.exe with -target option so that all generated .class files  are compatible. This is a requirement to make sure that the generated  .class files are consistent with Connected Limited Device configuration  (CLDC) 1.1 BlackBerry JVM implementation.&lt;/blockquote&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;Based on what I found, I know that Both J2ME and Blackberry Build need target option to 1.1. otherwise the blackberry application might have a weird issue like NoClassDefFoundError.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6561239654122236360?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6561239654122236360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/06/noclassdeffounderror-in-blackberry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6561239654122236360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6561239654122236360'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/06/noclassdeffounderror-in-blackberry.html' title='NoClassDefFoundError in Blackberry'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-9053648722700422201</id><published>2011-06-11T23:50:00.003-04:00</published><updated>2011-07-17T00:39:41.743-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='build'/><title type='text'>How I improved my company's build system - build automation</title><content type='html'>Last 2 weeks I haven't check twitter, did not go to infoQ, all my spare time is focused on one thing: improve the build system, the goal - one button click triggered the build and deploy automation.&lt;br /&gt;This goal is finally achieved last week. Now the build system is scheduled deployment once a day, the automation jobs include following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;check out source code from CVS;&lt;/li&gt;&lt;li&gt;build client and server artifacts;&lt;/li&gt;&lt;li&gt;generate the change log&lt;/li&gt;&lt;li&gt;update the wiki and download page&lt;/li&gt;&lt;li&gt;upload the artifact into server and downloading repository&lt;/li&gt;&lt;li&gt;execute the server deploy script&lt;/li&gt;&lt;li&gt;send new release email&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;Before only step 1) and 2) are automatic using the ANT script. All other steps are manual, I found this kind of job is boring,painful and quit easy to make mistakes.&lt;br /&gt;&lt;br /&gt;I have the idea for build automation for a long time, especially I was inspired by the book "&lt;a href="http://www.amazon.com/Continuous-Delivery-Deployment-Automation-Addison-Wesley/dp/0321601912?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Continuous Delivery&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0321601912" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;" and "&lt;a href="http://www.amazon.com/Pragmatic-Project-Automation-Deploy-Monitor/dp/0974514039?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Pragmatic Project automation&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0974514039" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;". &amp;nbsp;My plan to implement the build automation is pretty simple: simulate the human deployment behaviour, implement an ANT target for each manual step. It sound easy, but when I actually did it, it was harder than imagined. But I finally I made it. &lt;br /&gt;Right now everyday we will automatically release a new build, this is a milestone and a great improvement. I feel so happy and so proud of it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The tools I used&lt;/b&gt;&lt;br /&gt;- ANT, &amp;nbsp;I used scp, filterset, filterchain, sshexec, cvschangelog, I found Ant has lots of gem.&lt;br /&gt;- Groovy, I used AntBuilder to integrate with the existing ANT task, parsing XML, generating text file, quite neat.&lt;br /&gt;- &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt;, &amp;nbsp;everyone recommend Hudson/Jenkins CI server, when I used it, it is so easy to use, and has lots of useful plugins. I use Jenkins to schedule and trigger the build.&lt;br /&gt;- &lt;a href="http://www.viewvc.org/"&gt;ViewVC&lt;/a&gt;, a very good tool to browse CVS source code from web, I configure the ViewVC in Jenkins, Jenkins will provide the actually source code link in the changes page.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What I learned&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pay more attention to your feeling. If you feel boring and painful, don't just complain, try to find a way to improve it. This is a good chance to improve your self, my &lt;a href="http://code-dojo.blogspot.com/2010/12/use-your-pain-to-measure-your-ignorance.html"&gt;previous blog&lt;/a&gt; describe this.&lt;/li&gt;&lt;li&gt;A good developer must be able to delegate the dirty jobs to the computers, it would be shame for a good developer to do the repetitive manual jobs over and over.&lt;/li&gt;&lt;li&gt;I implemented the automatic build script based on the manual process, so I learned: &lt;b&gt;if you can define a repeatable step by step manual process, then you can automate it by program.&lt;/b&gt;&lt;/li&gt;&lt;li&gt;I finished this job usually in down time, I finished one small piece each time, so the improvement for the legacy system has to be emergent.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Next Actions&lt;/b&gt;&lt;br /&gt;This is only the first step, there are way more things needs to be done, my next steps will be:&lt;br /&gt;- Add Unit Test and Regression test automation&lt;br /&gt;- Add the code quality analysis report&lt;br /&gt;- Use Ivy for dependency management&lt;br /&gt;- Use Puppet to manage the configuration&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-9053648722700422201?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/9053648722700422201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/06/how-i-improved-my-companys-build-system.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/9053648722700422201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/9053648722700422201'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/06/how-i-improved-my-companys-build-system.html' title='How I improved my company&apos;s build system - build automation'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6030688291200306277</id><published>2011-05-28T23:35:00.002-04:00</published><updated>2011-05-28T23:38:28.745-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Ant mail task issue in Mac</title><content type='html'>Last week I get stuck again when using the Ant mail task, based on &lt;a href="http://ant.apache.org/manual/install.html#librarydependencies"&gt;the document from Ant site&lt;/a&gt;,&amp;nbsp;the mail task requires the following 2 jar files:&lt;br /&gt;&amp;nbsp;- mail.jar from &lt;a href="http://www.oracle.com/technetwork/java/javamail-138606.html"&gt;JavaMail API&amp;nbsp;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;- activation.jar from &amp;nbsp;&lt;a href="http://www.oracle.com/technetwork/java/javase/jaf-135115.html"&gt;JAF API&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I already downloaded and copied them into /usr/share/ant/lib folder, but still I got the error.&lt;br /&gt;After google a while, I realized that Mac missed another jar file in its ant package, this time it is &lt;b&gt;ant-javamail.jar&lt;/b&gt;! So when I just copied the ant-javamail.jar from the downloaded ant package into /usr/share/ant/lib folder, then every thing worked perfectly.&lt;br /&gt;&lt;br /&gt;In summary, to make the mail task work in Mac, you need 3 jar files:&lt;br /&gt;&amp;nbsp;- mail.jar&lt;br /&gt;&amp;nbsp;- activation.jar&lt;br /&gt;&amp;nbsp;- ant-javamail.jar&lt;br /&gt;&lt;br /&gt;Ant target to send email example (using gmail smtp server):&lt;br /&gt;&lt;pre&gt;&amp;lt;target name="sendmail" description="send email"&amp;gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;mail mailhost="smtp.gmail.com"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mailport="25"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;user="${your.gmail.account}"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;password="${your.gmail.password}"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ssl="true"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;from="${your.email.address}"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;tolist="${mail.recipient}"&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;subject="Results of nightly build"&amp;gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;message&amp;gt;This is a test email&amp;lt;/message&amp;gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/mail&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6030688291200306277?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6030688291200306277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/05/ant-sendmail-task-issue-in-mac.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6030688291200306277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6030688291200306277'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/05/ant-sendmail-task-issue-in-mac.html' title='Ant mail task issue in Mac'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8809053547936341962</id><published>2011-05-28T23:10:00.000-04:00</published><updated>2011-05-28T23:10:10.386-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Ant scp and sshexec task issues in Mac</title><content type='html'>Last week when I tried to run my ant target using scp and sshexec task in my macbook pro, I got the following issues:&lt;br /&gt;&lt;br /&gt;1) scp task issue&lt;br /&gt;Problem: failed to create task or type scp&lt;br /&gt;Cause: the class org.apache.tools.ant.taskdefs.optional.ssh.Scp was not found.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;This looks like one of Ant's optional components.&lt;br /&gt;Action: Check that the appropriate optional JAR exists in&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-/usr/share/ant/lib&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-/Users/steve/.ant/lib&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-a directory added on the command line with the -lib argument&lt;br /&gt;&lt;br /&gt;Do not panic, this is a common problem.&lt;br /&gt;The commonest cause is a missing JAR.&lt;br /&gt;&lt;br /&gt;2) sshexec task issue&lt;br /&gt;Problem: failed to create task or type sshexec&lt;br /&gt;Cause: the class org.apache.tools.ant.taskdefs.optional.ssh.SSHExec was not found.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;This looks like one of Ant's optional components.&lt;br /&gt;Action: Check that the appropriate optional JAR exists in&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-/usr/share/ant/lib&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-/Users/steve/.ant/lib&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-a directory added on the command line with the -lib argument&lt;br /&gt;&lt;br /&gt;Do not panic, this is a common problem.&lt;br /&gt;The commonest cause is a missing JAR.&lt;br /&gt;&lt;br /&gt;I already download the jsch-0.1.44.jar from &lt;a href="http://www.jcraft.com/jsch/"&gt;Jcraft&lt;/a&gt;,&amp;nbsp;&amp;nbsp;and copied the jar file into folder&amp;nbsp;/usr/share/ant/lib, and I also tried to put the jar file into different folder as the error suggested, but no help.&lt;br /&gt;Finally I found this &lt;a href="http://myvirtual-lab.blogspot.com/2009/07/ant-scp-and-ec2.html"&gt;article&lt;/a&gt;:, it mentioned that&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; in Mac,&lt;/span&gt; the ant-jsch.jar is missing&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;!&lt;/span&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;and when I look at the /usr/share/ant/lib folder, yes there is no ant-jsch.jar file! &amp;nbsp;So I downloaded the ant 1.8.2 from ant website, unpack it, and copy&amp;nbsp;it into the /usr/share/ant/lib folder, it just works!&lt;br /&gt;&lt;br /&gt;In summary, to make the ant scp and sshexec task work in Mac, you need to do 2 things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install ant-jsch.jar file: download the ant package from ant website, then copy the ant-jsch.jar into /usr/shar/ant/lib folder&lt;/li&gt;&lt;li&gt;Go to&amp;nbsp;&lt;a href="http://www.jcraft.com/jsch/"&gt;Jcraft&lt;/a&gt;&amp;nbsp;website, download the latest version of jsch jar file, copy it into /usr/share/ant/lib&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/3555300218296290557-8809053547936341962?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8809053547936341962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/05/ant-scp-and-sshexec-task-issues-in-mac.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8809053547936341962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8809053547936341962'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/05/ant-scp-and-sshexec-task-issues-in-mac.html' title='Ant scp and sshexec task issues in Mac'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5317596504569582558</id><published>2011-05-21T21:28:00.002-04:00</published><updated>2011-05-21T21:31:54.803-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Handling incoming call interruption in BlackBerry audio player</title><content type='html'>Last week I spent two days to fix an issue of blackberry audio player: the audio stream need to pause the player during incoming call interruption, and resume when call is finished.&lt;br /&gt;At the beginning, I feel it is easy to fix, because I fixed this kind of issue many times before for blackberry platform.&lt;br /&gt;So I just program based on my old experiences, but it did not working.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;My Mistake&lt;/b&gt;&lt;/div&gt;&lt;div&gt;At first I use BlackBerry API &lt;a href="ttp://www.blackberry.com/developers/docs/4.0.2api/net/rim/blackberry/api/phone/PhoneListener.html"&gt;PhoneListener&lt;/a&gt; to register the call interruption event. But it did not work, I found some issues:&lt;/div&gt;&lt;div&gt;- If you use PhoneListener, the application will prompt use to agree to use Phone API, which is annoying.&lt;/div&gt;&lt;div&gt;- When you delete the application, you have to restart the phone.&lt;/div&gt;&lt;div&gt;- The application can get the incoming call event via callIncoming() method, but some time the application get exception;&lt;/div&gt;&lt;div&gt;- The application get the call end event via callDisconnected() method, but when you call MMAPI player play() method, it always throws MediaException.&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;It seems the application the the event earlier than the voice call app release the resource.&lt;/div&gt;&lt;div&gt;- I found the Phone already stop the media player before it send the incoming call event the the application, so you have to use a workaround to deal with this issue.&lt;/div&gt;&lt;div&gt;I tried the different workarounds, but none of them working, it seems the PhoneListener solution is not reliable, and even not working. I don't remember why it works before.&lt;/div&gt;&lt;div&gt;maybe because of current phone is 5.0 while before are 4.3 or 4.6? Actually I don't know.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;New solution&lt;/b&gt;&lt;/div&gt;&lt;div&gt;After I googled and I found a really simple solution: handle the DEVICE_AVAILABLE and DEVICE_UNAVAILABLE event in the playerListener. Based on &lt;a href="http://www.informit.com/articles/article.aspx?p=375708"&gt;this article&lt;/a&gt;:&lt;/div&gt;&lt;div&gt;&lt;b&gt;The DEVICE_UNAVAILABLE event occurs when there is an incoming call. The DEVICE_AVAILABLE event occurs when the call is ended.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;So all you need to do is pause the player in DEVICE_UNAVAILABLE, and resume when DEVICE_AVAILABLE event comes.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Code snippet like this:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;playerUpdate(Player player, String event, Object eventData) &lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    if(event == PlayerListener.DEVICE_UNAVAILABLE)&lt;br /&gt;    {&lt;br /&gt;        if(player.getState() == Player.STARTED)&lt;br /&gt;        {&lt;br /&gt;              player.stop();&lt;br /&gt;              bPausedByIncomingCall = true;&lt;br /&gt;        } &lt;br /&gt;    }&lt;br /&gt;    else if(event == PlayerListener.DEVICE_AVAILABLE)&lt;br /&gt;    { &lt;br /&gt;        if(bPausedByIncomingCall)&lt;br /&gt;        {&lt;br /&gt;            player.start();&lt;br /&gt;            bPausedByIncomingCall = false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The solution is very easy and it really works. I tested it when the DEVICE_UNAVAILABLE event comes, the player is still playing, which means the event is sent before the incoming call interruption.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Retrospection&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I checked the MMAPI API and Blackberry API document, I found this event is not new (Blackberry support this since 4.0!), but I did not notice this until now. Why I did not notice these two events before? I did not find them in the books, nor I did not heard from them from previous colleagues. This is my another blind spot and it exposed my ignorance of MMAPI. This issue tells me: sometime your old experience is unreliable; you still need to empty your mind, like Andy Hunt said: &lt;b&gt;always have beginner's mind!&lt;/b&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/3555300218296290557-5317596504569582558?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5317596504569582558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/05/handling-incoming-call-interruption-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5317596504569582558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5317596504569582558'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/05/handling-incoming-call-interruption-in.html' title='Handling incoming call interruption in BlackBerry audio player'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3823222088359785540</id><published>2011-05-07T23:02:00.003-04:00</published><updated>2011-05-07T23:10:05.761-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><title type='text'>Functional programming in OO languages</title><content type='html'>Yesterday I watch the presentation: &lt;a href="http://www.infoq.com/presentations/Functional-Programming-A-Pragmatic-Introduction"&gt;Functional Programming: A Pragmatic Introduction&lt;/a&gt; in Infoq.com. Jim Duey explains functional programming through &lt;a href="http://intensivesystems.net/tutorials/code/intro-fp.java"&gt;Java code samples&lt;/a&gt;. He covers 3 parts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;high order functions&lt;/li&gt;&lt;li&gt;&amp;nbsp;laziness&lt;/li&gt;&lt;li&gt;&amp;nbsp;composing&lt;/li&gt;&lt;/ul&gt;I am more interested in the first part - high order functions. Jim shows 3 important functions:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&amp;nbsp;reduce,&amp;nbsp;filter and&amp;nbsp;map.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Comparing with the java code, Jim describes how these 3 methods can help us reduce the duplicated boilerplate java code: like loop, iteration. He even emphasizes that these 3 methods - &lt;b&gt;reduce, filter and map can reduce 90% of the loop code! &amp;nbsp;&lt;/b&gt;&lt;br /&gt;Copied from his slide, the benefits of the high order functions are: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Allows common code structures to reused&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Abstracts away details&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Isolates the essential parts of the code&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Allows easier unit testing&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Lets you think at a higher level&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;Allows easy parallelism&lt;/li&gt;&lt;/ul&gt;If you don't want to watch the video, then I found &lt;a href="http://www.ugrad.cs.jhu.edu/%7Ewsix/collections.pdf"&gt;this article&lt;/a&gt; is really great to explain the map, filter and reduce method, also gives Java implementation.&lt;br /&gt;As a java developer, the implementation code is not new to me, mostly the template method pattern is used. Actually I already saw the similar benefit in Spring framework: it is so amazing the JdbcTemplate can removed lots of the JDBC boilerplate code! But I did not aware that it shares the same idea with the function programming.&lt;br /&gt;Since I learned that high order functions are so important, so I decide to investigate more and see how to implement them in other OO languages beside Java.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Javascript&lt;/b&gt;&lt;br /&gt;Joel has a nice article about function programming using javascript: &lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html"&gt;Can Your Programming Language Do This?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Groovy&lt;/b&gt;&lt;br /&gt;I checked the Groovy API and recalled what I learned before, so I found the equivalent methods for reduce, filter and map in Collection API are:&lt;br /&gt;&amp;nbsp;&amp;nbsp; reduce &amp;nbsp;=&amp;gt; inject()&lt;br /&gt;&amp;nbsp;&amp;nbsp; filter &amp;nbsp;=&amp;gt; findAll()&lt;br /&gt;&amp;nbsp;&amp;nbsp; map &amp;nbsp; &amp;nbsp; =&amp;gt; collect()&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/Functional+Programming+with+Groovy"&gt;Groovy functional programming link&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Ruby&lt;/b&gt;&lt;br /&gt;Groovy is very similar with Ruby, especially when I learned Groovy, I suspect if Groovy copies some concept from Ruby, since the collection API is so similar.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;reduce &amp;nbsp;=&amp;gt; reduce(), inject()&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;map &amp;nbsp; &amp;nbsp; =&amp;gt; map(), collect()&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;filter &amp;nbsp; &amp;nbsp;=&amp;gt; select(), find_all()&lt;br /&gt;&lt;br /&gt;&lt;a href="http://billsix.blogspot.com/2008/03/functional-collection-patterns-in-ruby.html"&gt;This article&lt;/a&gt; is really great to explain them more in Ruby&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Other resources&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf"&gt;Why functional programming matters&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;- To use functional programming, it would be better to use the language that support functional programming in first class. I have to say Java implementation is too ugly, Groovy and Ruby are much better.&lt;br /&gt;- Changing mindset to functional programming is hard but really important. Functional programming is another way of programming to elevate your abstraction layer.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Next Action&lt;/b&gt;&lt;br /&gt;To pursue the way of Functional Programming, you need to pick up a new Functional Programming language ASAP, since I learned LISP through SICP, so Clojure would be my next choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-3823222088359785540?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3823222088359785540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/05/functional-programming-in-oo-languages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3823222088359785540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3823222088359785540'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/05/functional-programming-in-oo-languages.html' title='Functional programming in OO languages'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5104457275267919260</id><published>2011-04-30T21:11:00.004-04:00</published><updated>2011-07-17T00:40:11.104-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><title type='text'>Rediscover the power of Ant</title><content type='html'>My &lt;a href="http://code-dojo.blogspot.com/2011/04/invoke-groovy-script-from-ant-or-gant.html"&gt;last post&lt;/a&gt; talks about using groovy template to generate a text file, but I did not realize it can be done in Ant until reading the book- &lt;a href="http://www.amazon.com/Ant-Action-Manning-Steve-Loughran/dp/193239480X?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;"Ant in action"&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=193239480X" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;.&lt;br /&gt;Recently when I refactored the ant build script of our comany's build system, I realize I need to learn ant systematically to improve my skills in Ant, so I choose this famous book.&lt;br /&gt;When I learned the "filterset" datatype, I realize I can use that to generate the text file from a template, for example the last example can be written in Ant:&lt;br /&gt;&lt;pre&gt;&amp;lt;copy file="test2.template" toFile="test2.txt" overwrite="true"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;lt;filterset begintoken="%" endtoken="%"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp; &amp;nbsp;&amp;lt;filter token="firstname" value="Steve"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp; &amp;nbsp;&amp;lt;filter token="lastname" value="Zhang"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp; &amp;nbsp;&amp;lt;filter token="city" value="Toronto"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;lt;/filterset&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/copy&amp;gt;&lt;br /&gt;&lt;/pre&gt;It is even simpler than Groovy in this case, right?&lt;br /&gt;This example exposes my ignorance level of Ant, I realize that there a still lots of Gems in Ant. As Douglas Crockford said most language contains good parts and bad parts, we need to use only good parts and avoid bad parts, I think what he said also can apply to Ant. So don't easily discard a tool or a language, right now in my case, I love Groovy, I love Gant, they look so cool, but I am not 100% precent for sure Groovy/Gant can fully replace our build script. I have to rely on Ant now.&lt;br /&gt;I start understand the reason why our build script is a kind of ugly: probably we did not fully use the good parts of ant and too much bad parts instead.&lt;br /&gt;So my next step is start reading Ant in Action!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5104457275267919260?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5104457275267919260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/04/revisit-power-of-ant.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5104457275267919260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5104457275267919260'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/04/revisit-power-of-ant.html' title='Rediscover the power of Ant'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-7776998527841880956</id><published>2011-04-22T23:06:00.002-04:00</published><updated>2011-04-22T23:12:17.211-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Invoke Groovy script from Ant or Gant</title><content type='html'>Recently I tried to use groovy script to improve our build system. I found Groovy TemplateEngine is so powerful and very easy to use, quite similar to erb in Ruby. I want to use it to generate a text file. The following example shows how to generate a text file based on a template.&lt;br /&gt;&lt;br /&gt;file test.template&lt;br /&gt;&lt;pre&gt;Dear "$firstname $lastname",&lt;br /&gt;So nice to meet you in &amp;lt;% out &amp;lt;&amp;lt; (city == "New York" ? "\"The Big Apple\"" : city) %&amp;gt;.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;file test.groovy&lt;br /&gt;&lt;pre&gt;import groovy.text.SimpleTemplateEngine&lt;br /&gt;import groovy.text.GStringTemplateEngine&lt;br /&gt;&lt;br /&gt;def f = new File(this.args[0])&lt;br /&gt;def binding = ["firstname":args[1], "lastname":args[2], "city":args[3]]&lt;br /&gt;engine = new GStringTemplateEngine()&lt;br /&gt;template = engine.createTemplate(f).make(binding)&lt;br /&gt;println template.toString()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If in a terminal if I type: &amp;nbsp;groovy test.groovy Steve Zhang Toronto, and I will get output&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Dear "Steve Zhang",&lt;br /&gt;So nice to meet you in Toronto.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Invoke Groovy from Ant&lt;/b&gt;&lt;br /&gt;I followed &lt;a href="http://groovy.codehaus.org/The+groovy+Ant+Task"&gt;this article&lt;/a&gt; from Groovy site&lt;br /&gt;Following is the ant script:&lt;br /&gt;build.xml&lt;br /&gt;&lt;pre&gt;&amp;lt;project&amp;gt;&lt;br /&gt; &amp;lt;taskdef name="groovy"&lt;br /&gt;          classname="org.codehaus.groovy.ant.Groovy"&lt;br /&gt;          classpath="lib/groovy-all-1.7.10.jar"/&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;target name="helloGroovy"&amp;gt;&lt;br /&gt;    &amp;lt;groovy&amp;gt;&lt;br /&gt;     println "hello world"&lt;br /&gt;    &amp;lt;/groovy&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;   &lt;br /&gt;    &amp;lt;target name="testTemplate"&amp;gt;&lt;br /&gt;   &amp;lt;groovy src="test.groovy"&amp;gt;&lt;br /&gt;    &amp;lt;arg line="test.template"/&amp;gt;&lt;br /&gt;    &amp;lt;arg line="Steve" /&amp;gt;&lt;br /&gt;    &amp;lt;arg line="Zhang"/&amp;gt;&lt;br /&gt;    &amp;lt;arg line="Toronto"/&amp;gt;&lt;br /&gt;    &amp;lt;/groovy&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt; &lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;It pretty straight forward, first declare &amp;lt;taskdef&amp;gt;, you need to put groovy-all-version.jar in the class path, but it took me a while to figure out where the groovy-all-xxx.jar is, finally I got it: when you download the binary zip file, unzip it, find &lt;b&gt;embeddable&lt;/b&gt; folder, inside this folder you will find the groovy-all-1.7.x.jar!&lt;br /&gt;Then you can put any kind of groovy code inside &amp;lt;groovy&amp;gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Invoke Groovy Script from Gant&lt;/b&gt;&lt;br /&gt;Gant is a great tool to replace Ant, I can definitely convert the above build.xml to build.gant, but I realize it is a kind of weird, since Gant is already based on Groovy, it already depends on Groovy jars, why we still need to declare the dependency in groovy-all-xxx.jar? There must be a better solution. Through my exploration, I found two ways to call Groovy script from Gant:&lt;br /&gt;&lt;br /&gt;A)&lt;b&gt; Use GroovyShell&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;target( runGroovy:"run a groovy script") {&lt;br /&gt; def shell = new GroovyShell()&lt;br /&gt;    shell.run(new File("test.groovy"),&lt;br /&gt;               ["test.template","Steve","Zhang","Toronto"] as String[])&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above gant script also tells you how to invoke a groovy script from another Groovy script file. GroovyShell can do this for us.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;B) Embed the groovy source code directly in the Gant script file&lt;/b&gt;&lt;br /&gt;During the exploration, I have some feeling that Gant script might can be thought of Groovy code, what if we add the groovy source code directly into the Gant script, so I did this:&lt;br /&gt;&lt;pre&gt;import groovy.text.GStringTemplateEngine&lt;br /&gt;&lt;br /&gt;target( hello: "hello") {&lt;br /&gt;  println "hello"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;target( runGroovy:"run a groovy script") {&lt;br /&gt; def shell = new GroovyShell()&lt;br /&gt;    shell.run(new File("test.groovy"),&lt;br /&gt;               ["test.template","Steve","Zhang","Toronto"] as String[])&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;target(runTemplate :"run a groovy template") {&lt;br /&gt; def f = new File('test.template')&lt;br /&gt; def binding = ["firstname":"Steve", "lastname":"Zhang", "city":"Toronto"]&lt;br /&gt; engine = new GStringTemplateEngine()&lt;br /&gt; template = engine.createTemplate(f).make(binding)&lt;br /&gt;    println template.toString()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The target runTemplate will have the same result output, when you look at the import statement at the top, and the groovy code inside the target, &lt;b&gt;I realize that Gant script is actually Groovy code!, the Gant target can be regarded as Groovy method&lt;/b&gt;. This conclusion is so important, because it means you can easily integrate the Groovy(or Java) code in the build script, I am sure it will definitely improve developer's productivity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-7776998527841880956?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/7776998527841880956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/04/invoke-groovy-script-from-ant-or-gant.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7776998527841880956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7776998527841880956'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/04/invoke-groovy-script-from-ant-or-gant.html' title='Invoke Groovy script from Ant or Gant'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8886808285688988240</id><published>2011-04-17T18:06:00.001-04:00</published><updated>2011-04-17T18:07:30.545-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Foscam FI8918W wireless IP camera review</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-fd6Tx29CXtw/TatiujBCRnI/AAAAAAAAADw/6fKCNbSq72I/s1600/IMG_0312.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-fd6Tx29CXtw/TatiujBCRnI/AAAAAAAAADw/6fKCNbSq72I/s320/IMG_0312.JPG" width="239" /&gt;&lt;/a&gt;&lt;/div&gt;I am looking for a video camera as baby monitor for a while. Currently all the baby video cameras in the market are too expensive, over $200 - $300, even that the features are quite limited. So I start looking for the replacement: the IP camera, and finally in Amazon I found &lt;a href="ttp://www.amazon.ca/Foscam-FI8918W-Wireless-Camera-Viewing/dp/B0046710G6/ref=pd_rhf_p_t_4"&gt;FOSCAM FI8918W&lt;/a&gt;, it has almost all the features I need: pan/tilt remote control, wireless-IP, info-red, built-in micro phone and speaker. The most feature attract me is the wireless-IP, you can watch your camera anywhere over the internet through your browser or iPhone!&lt;br /&gt;&lt;br /&gt;Yesterday I finally got my Foscam wireless IP camera from amazon.ca.  I can't wait to unpack it start setting up. I just followed the manual step by step, it did not take me any longer to watch the video over the IE browser; but the hard part is making it work from the internet:&lt;br /&gt;&amp;nbsp;- At first I choose UPnP, but it did not work, this took me a while;&lt;br /&gt;&amp;nbsp;- Then I choose forward port as the manual suggested, configure the camera address and port number in my router, tried several times, finally get it working;&lt;br /&gt;&amp;nbsp;- Last I went to dyndns.org to create an free domain, then configure the parameters in the camera. finally I got it working. &lt;br /&gt;&lt;br /&gt;There is another issue: as the manual mentioned, the camera only support IE to get the audio working, but there is no audio on my windows 7, after I followed &lt;a href="http://foscam.us/blog/foscamipcameras/setting-up-ie-on-windows-7-to-view-the-foscam-fi8908w-wireless-camera-enabling-the-activex-control-module"&gt;this article&lt;/a&gt;, finally I got it working. Since the camera relies on ActiveX to make audio working, so currently audio does not support on other browsers: Firefox, Chrome, Safari.&lt;br /&gt;&lt;br /&gt;Overall the camera does exactly what it mentioned. I like this camera:&lt;br /&gt;Pros:&lt;br /&gt;- info-red feature is awesome, I can see the picture clearly at night when I turned on the info-red;&lt;br /&gt;- remote control is very handy, you can control the camera in 8 direction via browser or iPhone application.&lt;br /&gt;- I just found the motion detection feature, when it detects the motion, the computer will beep and automatically record the video.&lt;br /&gt;&lt;br /&gt;Cons:&lt;br /&gt;- No audio output on non IE browser or iPhone application, I heard it due to the video output is Microsoft ASF format.&lt;br /&gt;- No Zoom support&lt;br /&gt;- Only support Wireless b/g, not support wireless-N network&lt;br /&gt;- Picture quality is OK, you can see the pause, quite similar to the web cam &lt;br /&gt;&lt;br /&gt;Comparing its feature and the price $100 in amazon.ca, less than the half of the regular video monitor, I think it is a good choice for a baby monitor.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The iPhone application&lt;/b&gt;&lt;br /&gt;I downloaded the &lt;a href="http://itunes.apple.com/ca/app/foscam-surveillance-pro/id373509500?mt=8"&gt;foscam surveillance pro application&lt;/a&gt; in my iPhone, iPod touch and iPad, it costs me $5, the app is really good, except no audio output. And at first I found the left/right control is reversed, after searching the support forum, the solution is choose FI8918W-reversed, then every thing is perfect.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Other resources&lt;/b&gt;&lt;br /&gt;watch video with audio (works in vlc player):&lt;br /&gt;&amp;nbsp;http://[your ip]/videostream.asf?user=[your_user]d&amp;amp;pwd=[your_pass]&lt;br /&gt;&lt;br /&gt;watch video without audio(works in the browser):&lt;br /&gt;&amp;nbsp;http://[your ip]/videostream.cgi?user=[your_user]&amp;amp;pwd=[your_pass]&lt;br /&gt;&lt;br /&gt;watch video with camera in vertical stroll mode:&lt;br /&gt;&amp;nbsp;http://[your ip]/decoder_control.cgi?user=[your_user]&amp;amp;pwd=[your_pass]&amp;amp;command=25  &lt;br /&gt;&lt;br /&gt;Foscam surveillance application support forum:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;a href="http://www.ruwebit.net/smf/index.php?topic=257.0"&gt;Faq&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;a href="http://www.ruwebit.net/smf/index.php?board=30.0"&gt;forum&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gadgetvictims.com/search/label/Foscam"&gt;foscam in gadget victims&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8886808285688988240?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8886808285688988240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/04/foscam-fi8918w-wireless-ip-camera.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8886808285688988240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8886808285688988240'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/04/foscam-fi8918w-wireless-ip-camera.html' title='Foscam FI8918W wireless IP camera review'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-fd6Tx29CXtw/TatiujBCRnI/AAAAAAAAADw/6fKCNbSq72I/s72-c/IMG_0312.JPG' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5934134957542855497</id><published>2011-04-03T22:05:00.004-04:00</published><updated>2011-04-03T22:27:37.963-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Deming's philosophy - the root of Lean</title><content type='html'>In the Agile community, almost every one talking about Toyota's Lean technology. When we talking about lean, we can not ignore &lt;a href="http://en.wikipedia.org/wiki/W._Edwards_Deming"&gt;Deming&lt;/a&gt;, since Japanese learned a lot from Deming and goes further and have today's Lean.&lt;br /&gt;Yesterday I spent some time watch Deming's videos on youtube:&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=GHvnIm9UEoQ"&gt;W. Edwards Deming - Part 1&lt;/a&gt;, &amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=mKFGj8sK5R8&amp;amp;feature=related"&gt;Part 2&lt;/a&gt;, &amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=6WeTaLRb-Bs&amp;amp;feature=related"&gt;Part 3&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=ehMAwIHGN0Y"&gt;Dr. Deming - The 5 Deadly Diseases 1984&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From these videos, you will easily find some of the lean principles do get from Deming, like: continuous improvement, eliminate wast, build quality in, respect people, optimize whole, focus on long-term goal, etc.I realize that the core of his philosophy is: &lt;b&gt;respecting people, people first.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Here I copied his 14 points and 5 deadly diseases about management.&lt;br /&gt;&lt;b&gt;Deming's 14 points:&lt;/b&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Create constancy of purpose.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Adopt the new philosophy.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Cease dependence on mass inspection.Eliminate the need for massive inspection by building quality into the product in the first place.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Minimize total cost when dealing with suppliers.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Improve continuously products, services, and processes.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Institute training on the job.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Adopt and institute leadership.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Drive out fear.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Break down barriers between departments.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Eliminate management by slogan and exhortation.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Eliminate numerical quotas and goals.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Eliminate barriers to joy in work.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Institute a program of education and self-improvement for everyone.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Put everyone to work on the transformation of the organization.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;b&gt;&lt;div style="display: inline !important;"&gt;&lt;div style="display: inline !important;"&gt;Deming's Five Deadly Diseases&lt;/div&gt;&lt;/div&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;1) Lack of Constancy of Purpose&lt;br /&gt;- No planning for the future&lt;br /&gt;- Lack of short term definition and goals&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;2) Emphasis on Short Term Profits&lt;br /&gt;- Worship of the quarterly dividends&lt;br /&gt;- Sacrificing long term growth of the organization&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;3) Annual Rating of Performance&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; - Arbitrary and unjust system&lt;br /&gt;- Demoralizing to employees&lt;br /&gt;- Nourishes short term performance&lt;br /&gt;- Annihilates team work, encourages fear&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;4) Mobility of Management&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; - No roots in the company&lt;br /&gt;- No Knowledge of the company&lt;br /&gt;- No understanding of problems of company&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;5) Use of Visible Figures Only&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; - No use of figures that are unknown or unknowable, i.e., customer or employee satisfaction&lt;br /&gt;- Encouraged by business schools&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;From the above, you will find these problems are quite common today, we need a long time to go to adopted his philosophy, this is why I am pessimistic about lean, because I feel the largest problem for lean is coming from managers, not from software developers.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why learning philosophy is so important?&lt;/b&gt;&lt;br /&gt;Some one might ask: we can just follow the practices or process, why we need to learn the philosophy?&lt;br /&gt;I think if technology is good and worth doing, it must have some good principles or philosophy behind the concrete technologies. Once you understand the behind philosophy, you can master the technology, you will not be confused by the different variation or context. And also the detailed technologies or practices are context based, they are easily changed or deprecated with the time and context change; but principle/philosophy is different, they are abstract and can transcend the detailed context, the philosophy can be so powerful that they can apply to different context without change. That is why the art of war and the book of five ring is still useful today, because their principles are general and timeless. This is the meaning of Tao, that is why I am so obsessed by the principle and philosophy. The philosophy is hard to mastered, I remembered the author of The Toyota Way once mentioned, many companies adopted the Toyota production System, but Toyota find few companies really understand the behind philosophy. That is my suggestion, when you learn lean, you still need to understand the behind philosophy. If you just do the lean practices without knowing the philosophy, I am sure you will not do Lean correctly; you can do lean correctly only if you fully understand the lean philosophy.&lt;br /&gt;&lt;b&gt;&lt;/b&gt;Here I would like Quote What Deming said:(from his&lt;a href="http://en.wikipedia.org/w/index.php?title=W._Edwards_Deming#The_Deming_System_of_Profound_Knowledge"&gt; wiki&lt;/a&gt;)&lt;br /&gt;&lt;blockquote&gt;&lt;blockquote&gt;"Once the individual understands the system of profound knowledge, he will apply its principles in every kind of relationship with other people. He will have a basis for judgment of his own decisions and for transformation of the organizations that he belongs to. The individual, once transformed, will:&lt;/blockquote&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Set an example;&lt;/li&gt;&lt;li&gt;Be a good listener, but will not compromise;&lt;/li&gt;&lt;li&gt;Continually teach other people; and&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Help people to pull away from their current practices and beliefs and move into the new philosophy without a feeling of guilt about the past."&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5934134957542855497?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5934134957542855497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/04/demings-philosophy-root-of-lean.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5934134957542855497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5934134957542855497'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/04/demings-philosophy-root-of-lean.html' title='Deming&apos;s philosophy - the root of Lean'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6878916357344660998</id><published>2011-03-11T15:02:00.003-05:00</published><updated>2011-03-11T15:14:05.713-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Blackberry trick: retrieving the MNC correctly</title><content type='html'>Recently I need to retrieve the &lt;a href="http://en.wikipedia.org/wiki/Mobile_Network_Code"&gt;MNC&lt;/a&gt; value from the blackberry device, but though the real network testing, I realize that the value might not be correct for some cases.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The 3 different solutions of retrieving the MNC&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;via GPRSInfo&lt;/li&gt;&lt;pre&gt;int mnc = GPRSInfo.getHomeMNC(); &lt;/pre&gt;&lt;li&gt;via RadioInfo&lt;/li&gt;&lt;pre&gt;int currentIndex = RadioInfo.getCurrentNetworkIndex();  &lt;br /&gt;      int mnc = RadioInfo.getMNC(currentIndex); &lt;/pre&gt;&lt;li&gt;via GPRSCellInfo&lt;/li&gt;&lt;pre&gt;GPRSInfo.GPRSCellInfo cellInfo = GPRSInfo.getCellInfo();  &lt;br /&gt;       int mnc = cellInfo.getMNC(); &lt;/pre&gt;&lt;/ol&gt;&lt;div&gt;Note:in blackberry the returned MNC value is decimal, which is different with the MNC standard, which is hexadecimal.&lt;br /&gt;&lt;br /&gt;I found  that solution 1-2 are always consistent, they are always same if you are not in the roaming network. But in solution 3, in some cases you will get the wrong value. For example I tested the following UK carriers, the retrieved mnc values are all wrong:&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;th&gt;Carrier Name&lt;/th&gt; &lt;th&gt;MNC(Hex)&lt;/th&gt; &lt;th&gt;retrieved(dec)&lt;/th&gt; &lt;th&gt;retrieved(hex)&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt; &lt;td&gt;3 UK&lt;/td&gt; &lt;td&gt;20&lt;/td&gt; &lt;td&gt;527&lt;/td&gt; &lt;td&gt;20F&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Orange UK&lt;/td&gt;&lt;td&gt;33&lt;/td&gt;&lt;td&gt;831&lt;/td&gt;&lt;td&gt;33F&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Vodafone UK&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;351&lt;/td&gt;&lt;td&gt;15F&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;T-Mobile&lt;/td&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;783&lt;/td&gt;&lt;td&gt;30F&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;O2&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;271&lt;/td&gt;&lt;td&gt;10F&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;From the above table, we can tell that all the mnc values are appended letter F at the end, if we removed the F, then the value is correct. This is the first time I have ever met. Actually I found &lt;a href="http://supportforums.blackberry.com/t5/Java-Development/Determine-the-MCC-and-MNC-of-the-current-network/ta-p/443039"&gt;this article&lt;/a&gt; mentioned this issue a little bit:&lt;br /&gt;&lt;blockquote&gt;...therefore the corresponding hexadecimal value returned by getMCC()or getMNC()may contain the letter F as padding. For example, for T-Mobile®, the MCCs can be identified as either 260 or 26F.&lt;/blockquote&gt;If you want to use cellInfo ( ex. MCC, MNC, LAC, cellID) to get the current location via &lt;a href="http://www.opencellid.org/api"&gt;openCellID&lt;/a&gt; for example, then you need to be careful for this issue.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;So the solution to get the correct MNC value from blackberry API should be: &lt;b&gt;first check the last 4 bits value, if it is F (or more than 9), then right shift 4 bits&lt;/b&gt;, that is it!&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/3555300218296290557-6878916357344660998?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6878916357344660998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/03/blackberry-trick-retrieving-mnc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6878916357344660998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6878916357344660998'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/03/blackberry-trick-retrieving-mnc.html' title='Blackberry trick: retrieving the MNC correctly'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2835075544336542326</id><published>2011-02-16T01:51:00.001-05:00</published><updated>2011-02-16T01:56:07.056-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software craftsman'/><title type='text'>Learning SICP: resources and tool</title><content type='html'>I started learning &lt;a href="http://mitpress.mit.edu/sicp/"&gt;SICP &lt;/a&gt;since the beginning this year. The reason why I learn SICP is because I was inspired by Michael Feathers and Uncle Bob. In 2009, I watched the Michael Feathers presentation &lt;a href="http://scna.softwarecraftsmanship.org/media/michaelfeathers"&gt;"Self-education and the craftsman"&lt;/a&gt; for SCNA 2009, he mentioned the SICP book, I did look at it at first, but LISP's lots of parenthesis scared me. Then last year when I read Uncle Bob's blog post &lt;a href="http://thecleancoder.blogspot.com/2010/08/why-clojure.html"&gt;"Why Clojure?"&lt;/a&gt;, he recommend this book, and I also listened his &lt;a href="http://pragprog.com/podcasts/show/32"&gt;podcast&lt;/a&gt; and watched &lt;a href="http://cleancoder.posterous.com/stub-1-sicp-assignment"&gt;his video about SICP&lt;/a&gt;, finally &amp;nbsp;make to decide to start learning it.&lt;br /&gt;&lt;br /&gt;Here I would like to share What I found the useful resources and tools to learn SICP. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;SICP text book&lt;/b&gt;&lt;br /&gt;Official Web site:&amp;nbsp;&lt;a href="http://mitpress.mit.edu/sicp/"&gt;http://mitpress.mit.edu/sicp/&lt;/a&gt;&lt;br /&gt;You can also get PDF file from &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=4FF96B60F4EDDE3D39FCF7BAC7A6D79B?doi=10.1.1.98.7506&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SICP Video&lt;/b&gt;&lt;br /&gt;&lt;a href="http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/"&gt;MIT open course ware&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IDE&lt;/b&gt;&lt;br /&gt;I tried several LISP IDE, but finally I found &lt;b&gt;DrScheme&lt;/b&gt; is the best one. &lt;b&gt;DrScheme&lt;/b&gt; is included in the software called Racket, it is formally called PLT scheme. You can download Racket software from &lt;a href="http://racket-lang.org/"&gt;this site.&lt;/a&gt;&amp;nbsp;It works on my Mac Pro, I haven't tried it on the Windows environment.&lt;br /&gt;&lt;br /&gt;To run the program and exercises on the book, you need to download the package for SICP,&lt;br /&gt;&lt;a href="http://www.neilvandyke.org/sicp-plt/"&gt;SICP support in PLT scheme&lt;/a&gt;.&amp;nbsp;Just follows the installation instruction step by step. The latest version is SICP (PLaneT 1.13)&lt;br /&gt;&lt;br /&gt;To use the SICP language in DrScheme, first choose Language|Choose Lanuage..., in Teaching language, choose SICP(PLneT 1.13),&lt;br /&gt;and another most important thing: click "Show Details" Button, in "Output Syntax" group, under "Output Style", choose "write" radio button, then select OK.&lt;br /&gt;I found if you use default selection, which "print" is selected, the output for list is quite annoying.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SICP exercise solutions&lt;/b&gt;&lt;br /&gt;I found following two sites are pretty good:&lt;br /&gt;&lt;a href="http://community.schemewiki.org/?SICP-Solutions"&gt;http://community.schemewiki.org/?SICP-Solutions&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wqzhang.wordpress.com/sicp-solutions/"&gt;http://wqzhang.wordpress.com/sicp-solutions/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Uncle bob's blog post about SICP&lt;/b&gt;&lt;br /&gt;why clojure? &lt;br /&gt;&lt;a href="http://thecleancoder.blogspot.com/2010/08/why-clojure.html"&gt;http://thecleancoder.blogspot.com/2010/08/why-clojure.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;STUB1: SICP &amp;amp; Assignment&lt;br /&gt;&lt;a href="http://cleancoder.posterous.com/stub-1-sicp-assignment"&gt;http://cleancoder.posterous.com/stub-1-sicp-assignment&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Robert Matin interview in The Pragmatic BookShelf&lt;br /&gt;&lt;a href="http://pragprog.com/podcasts/show/32"&gt;http://pragprog.com/podcasts/show/32&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;michael feathers&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;SCNA 2009 presentation:Self-education and the craftsman&lt;br /&gt;&lt;a href="http://scna.softwarecraftsmanship.org/media/michaelfeathers"&gt;http://scna.softwarecraftsmanship.org/media/michaelfeathers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;About DrScheme&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&amp;nbsp;&lt;a href="http://linuxgazette.net/119/pramode.html"&gt;Learning to Program with DrScheme&lt;/a&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://linuxgazette.net/119/pramode.html"&gt;&lt;/a&gt;I am interested in the chaos graphs in this article.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2835075544336542326?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2835075544336542326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/02/learning-sicp-resources-and-tool.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2835075544336542326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2835075544336542326'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/02/learning-sicp-resources-and-tool.html' title='Learning SICP: resources and tool'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4711523253650063782</id><published>2011-01-17T19:54:00.002-05:00</published><updated>2011-01-17T20:06:12.161-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>The Facebook login &amp; logout flow for Android platform</title><content type='html'>Recently I am working on a mobile application project using the FaceBook API. I never touched Facebook API before, for me the first thing is to understand how the Facebook login/logout works on the mobile apps, so I spent some time on figure out how does it work on the Android platform.&lt;br /&gt;&lt;br /&gt;I just summarized the login and logout flow based on the &lt;a href="https://github.com/facebook/facebook-android-sdk"&gt;Facebook android SDK source code&lt;/a&gt; and its sample app log output.&lt;br /&gt;&lt;br /&gt;First you need to register your application and get your application ID from the facebook website.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Login Flow&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Request format:&lt;br /&gt;&lt;pre&gt;https://m.facebook.com/dialog/oauth?client_id=xxxx&amp;amp;redirect_uri=fbconnect://success&amp;amp;display=touch&amp;amp;type=user_agent&lt;br /&gt;&lt;/pre&gt;example:&lt;br /&gt;&lt;pre&gt;https://m.facebook.com/dialog/oauth?client_id=175729095772478&amp;amp;redirect_uri=fbconnect://success&amp;amp;display=touch&amp;amp;type=user_agent&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here,&lt;br /&gt;&lt;b&gt;client_id&lt;/b&gt; is your application id.&lt;br /&gt;&lt;b&gt;display=touch&lt;/b&gt; means the device smart phone (android or iphone)&lt;br /&gt;&lt;br /&gt;response:&lt;br /&gt;&lt;pre&gt;fbconnect://success/#access_token=xxxxx&amp;amp;expires_in=xxxxx&lt;/pre&gt;example:&lt;br /&gt;&lt;pre&gt;fbconnect://success/#access_token=175729095772478%7C2.vQIILuM8Bu_9nLKrl4yIew__.3600.1294938000-100000460660639%7Ch9OreeWmU4iUMB47UKwl20H64Gg&amp;amp;expires_in=4593&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You need to launch a browser inside your app to send the login the request, browser will display a login dialog let input the facebook account and password, then if login successful, the browser will return the redirected URL(fbconnect://success) with the access_token and expired value.&lt;br /&gt;&lt;br /&gt;To retrieve these values, you need to intercept the redirected URL: check if it starts with fbconnect://success, then parse the response, get the access_token and expire value.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Logout Flow&lt;/b&gt;&lt;br /&gt;format:&lt;br /&gt;&lt;pre&gt;https://api.facebook.com/restserver.php?access_token=[your access_token]&lt;br /&gt;                                       &amp;method=auth.expireSession&amp;format=json&lt;br /&gt;&lt;/pre&gt;example:&lt;br /&gt;&lt;pre&gt;https://api.facebook.com/restserver.php?access_token=175729095772478%7C2.mJlReipn5lu6jEJrKU2D6w__.3600.1295024400-100000460660639%7CE7f8hi-RkJtxOoJmGTyaWFgXHfI&amp;amp;method=auth.expireSession&amp;amp;format=json&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If logout successfully, the response will return text "&lt;b&gt;true&lt;/b&gt;",&lt;br /&gt;otherwise it will return a JSON text contains the detailed error message.&lt;br /&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/3555300218296290557-4711523253650063782?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4711523253650063782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2011/01/facebook-login-logout-flow-for-android.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4711523253650063782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4711523253650063782'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2011/01/facebook-login-logout-flow-for-android.html' title='The Facebook login &amp; logout flow for Android platform'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5988084995645452264</id><published>2010-12-28T21:36:00.002-05:00</published><updated>2010-12-28T21:38:19.910-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>The power of Groovy - notes of "Transforming to Groovy"</title><content type='html'>Yesterday I watched a video presentation from infoQ:&lt;a href="http://www.infoq.com/presentations/Transforming-to-Groovy"&gt;"Transforming to Groovy"&lt;/a&gt;, presented by Venkat Subramaniam, I read his book: &lt;a href="http://www.amazon.com/Programming-Groovy-Productivity-Developer-Programmers/dp/1934356093?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Programming Groovy&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=1934356093" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;. The presentation is really great, the author used lots of code examples to explain the power of groovy: first he provided the java code, then refactored it into groovy code, so you will find out how concise the Groovy is compare to Java. The whole presentation is 1.5 hour, but I did not feel it is quite long.&amp;nbsp; I remembered the author describe the Groovy using the term "&lt;b&gt;less ceremony&lt;/b&gt;", Which reminds me the how to describe the power of Groovy: "Accomplish more by doing less". And when he refactored java code to Groovy code, he described it as "&lt;b&gt;reducing the noise&lt;/b&gt;".&amp;nbsp; I like the word "noise" to describe Java code, since Groovy is quite expressive, concise, and its dynamic nature allow developer to focus more on their core business problems (&lt;b&gt; essential problem&lt;/b&gt;), and spend less time to deal with the language issues (&lt;b&gt;accidental problem&lt;/b&gt;), which is noise compare to the business problem. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;What I learned&lt;/b&gt;&lt;br /&gt;&lt;b&gt;AST transformation&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; Before I did not aware the feature of &lt;a href="http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations"&gt;AST transformation&lt;/a&gt; in Groovy, probably this is the new feature,&amp;nbsp; because I did not find this topic in the book.&lt;br /&gt;&amp;nbsp; The author covered @Immutable, @Newify, and @Delegate&lt;br /&gt;&lt;br /&gt;&lt;b&gt;@Immutable&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;@Immutable class Person {&lt;br /&gt;   String firstName;&lt;br /&gt;   String lastName;&lt;br /&gt;   int age;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;@Immutable annotation applies to class level only, it does not support on the field level.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;@Newify&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;@Newify def createPerson {&lt;br /&gt;    Person.new("John", "Smith", 28)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Newify(Person)&lt;br /&gt;def createPerson {&lt;br /&gt;   Person("John", "Smith", 28)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;@Delegate&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;class TirelessWorker {&lt;br /&gt;   public void work() {}&lt;br /&gt;   public void report() {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Manager {&lt;br /&gt;   @Delegate employee = new TirelessWorker();&lt;br /&gt;   public void schedule() {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here the Manager class can use all the methods of TirelessWorker class, if you add/modify method of class Tirelessworker, you don't have to modify the Manager class, it follows the OCP principle.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Multimethods&lt;/b&gt;&lt;br /&gt;Multimethods is one of the major difference between Groovy and Java. Multimethod means the method call depends on the target and the parameter type, which reminds me the &lt;a href="http://en.wikipedia.org/wiki/Multiple_dispatch"&gt;multiple dispatch&lt;/a&gt;, Java does not support mutlimethod, it only support single dispatch, I remember when I learn the Visitor pattern, I learned the multiple dispatch term, I am sure the Visitor pattern will be much easier to understand if the language support multiple dispatch, cool.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ArrayList&lt;/b&gt;&lt;br /&gt;use &lt;b&gt;spread-dot&lt;/b&gt; operator to access ArrayList&lt;br /&gt;*.&amp;nbsp; is called spread-dot operator, for example:&lt;br /&gt;&lt;pre&gt;list*.member  =  list.collect { item -&amp;gt; item?.member }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It means given a list, iterate each item's specific method, form the return value as a collection.&lt;br /&gt;get each item's first name: list*.firstName&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Groovy follows the Kanban principle&lt;/b&gt;&lt;br /&gt;I think Groovy is a good example of evolutionary and emergent design, since you can begin with purely java code, then migrate with Groovy, and even more you can mix with java and Groovy code in your project. Let's look at the &lt;a href="http://agilemanagement.net/index.php/Blog/the_principles_of_the_kanban_method/"&gt;Kanban's 2 foundational principles&lt;/a&gt;: Start with what you do now; Agree to pursue incremental, evolutionary change. Pretty similar.&lt;br /&gt;&lt;br /&gt;Based on this, I think Groovy is an important language that worth every Java developer to looking at.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5988084995645452264?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5988084995645452264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/12/power-of-groovy-notes-of-transforming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5988084995645452264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5988084995645452264'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/12/power-of-groovy-notes-of-transforming.html' title='The power of Groovy - notes of &quot;Transforming to Groovy&quot;'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-695861045440157712</id><published>2010-12-15T23:06:00.001-05:00</published><updated>2010-12-15T23:07:45.536-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Try Pomodoro</title><content type='html'>Today I finished the book of &lt;a href="http://draft.blogger.com/goog_274786635"&gt;"Pomodoro Technique Illustrated&lt;/a&gt;&lt;iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=p0da-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=bpl&amp;amp;asins=1934356506&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"&gt;&lt;/iframe&gt;&lt;a href="http://www.amazon.com/Pomodoro-Technique-Illustrated-Minutes-Pragmatic/dp/1934356506"&gt;"&lt;/a&gt;. Actually I heard of the Pomodoro in last year, but I did not think it seriously, until recently Dan North recommend it in his last two talks, so I decided to look at it. Through over a week's learning and practicing, I like it, it is simple, straight forward, and powerful.&lt;br /&gt;&lt;br /&gt;The Pomodoro technique is pretty simple:&lt;br /&gt;- Choose one single activity from your TO DO List;&lt;br /&gt;- Set clock to 25 minutes focused on a single activity for 25 minutes, during this time-boxed 25 minutes, &amp;nbsp;you only have one activity, and one goal: finish it.&lt;br /&gt;- After 25 minutes, take 5 minutes break;&lt;br /&gt;- Choose the next most important activity, start again; &lt;br /&gt;&lt;br /&gt;The Pomodoro is timeboxed, focus on single activity and single goal. It helps you prioritize your task, help you keep focused and remain high productivity.&lt;br /&gt;It emphasize on execution, getting things done, and NOW. I found it is similar as Getting Things Done, but comparing with GTD, I like Pomodoro because it is quite hands on and easy to implement, &amp;nbsp;actually I have not finished the GTD book &amp;nbsp;yet. It focus on only one thing at a time, and its emphasize on NOW remind me the ZEN philosophy.&lt;br /&gt;&lt;br /&gt;From Agile perspective, Pomodoro like a personal agile methodology, or specifically it very similar as SCRUM, I would rather say it as personal SCRUM, because you can treat each Pomodoro as SCRUM sprint, and the inventory as SCRUM backlog. And quite similar, in SCRUM, you can not change your task during each sprint; while you can not change your task during each Pomodoro. Pomodoro also focus on planning,processing, tracking,retrospective, so it is really agile.&lt;br /&gt;&lt;br /&gt;I only started Pomodoro for only a week, I like it because it provide you the awareness the time,prioritizing and single minded;&amp;nbsp;before it is quite easy to yak shaving, or get distracted. The Pomodoro provides a mechanism to let you get focused and remain higher rhythm, then improve your productivity.&lt;br /&gt;&lt;br /&gt;Some notes from the book:&lt;br /&gt;&lt;br /&gt;- time-boxed, single activity,single goal&lt;br /&gt;- 5 stages: Planing, Tracking, Processing, Visualizing - retrospective&lt;br /&gt;- Deming-Shewart cycle: plan, do, check, act&lt;br /&gt;- Tools: TODO Today Sheet, Activity Inventory,Record Sheet&lt;br /&gt;- Pomodoro will first Prioritize, then focus on the most important activity (like scrum)&lt;br /&gt;- Pomodoro need to see the big picture before you decide what to do&lt;br /&gt;- it is goal oriented&lt;br /&gt;- it has immediate feedback&lt;br /&gt;&lt;br /&gt;I&lt;b&gt;nterruptions&lt;/b&gt;&lt;br /&gt;- &lt;i&gt;principle: neither switch activities nor stop an activity in the middle of a Pomodoro.&lt;/i&gt;&lt;br /&gt;- avoid LIFO&lt;br /&gt;- avoid BPUF&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Deal with internal interruptions&lt;/b&gt;&lt;br /&gt;- Strategy: Accept, Record and continue&lt;br /&gt;- Write it into Unplanned &amp;amp; Urgent&lt;br /&gt;- &lt;i&gt;never switch activities in the middle of Pomodoro: "Once a Pomodoro begins, it has to ring.&lt;/i&gt;"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Deal with external interruptions&lt;/b&gt;&lt;br /&gt;- Strategy: inform, negotiate,schedule,call back&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Resources:&lt;/b&gt;&lt;br /&gt;I use my iphone as a timer, but I want to use it as vibrate only, but I could not find a vibrate only ringtone, try this &lt;a href="http://richardkmiller.com/702/iphone-tip-use-a-silent-ringtone-to-screen-calls-in-your-sleep"&gt;link&lt;/a&gt;, it tells you how to set the silence only ringtone&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-695861045440157712?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/695861045440157712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/12/try-pomodoro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/695861045440157712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/695861045440157712'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/12/try-pomodoro.html' title='Try Pomodoro'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1783642299959191424</id><published>2010-12-12T23:02:00.001-05:00</published><updated>2010-12-12T23:04:27.950-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Some thoughts about Conway's law</title><content type='html'>One of my best learned from QCon San Francisco is&lt;a href="http://en.wikipedia.org/wiki/Conway's_Law"&gt; Conway's Law&lt;/a&gt;, I heard it at least 3 times from different talks, especially from Michael Feather's talk. It is so striking, I never aware this before. Here is the definition of the Conway's law:&lt;br /&gt;&lt;blockquote&gt;organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations&lt;/blockquote&gt;In short, you can understand Conway's law like this:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The software design structure is constrained or shaped by the company's physical structure;&lt;/li&gt;&lt;li&gt;Your code structure mirrors your organization's structure.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;This concept is quite interesting and so striking, it forced me into further thinking:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Constraints&lt;/b&gt;&lt;br /&gt;Based on Conway's law, we can conclude:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Good organization's structure generate good software architecture, bad organization's structure generates bad software architecture;&lt;/li&gt;&lt;li&gt;The messy code base reflect its organization's messy management, the clean code base reflects the organization's clear structure;&lt;/li&gt;&lt;li&gt;Management structure is quite similar as the code structure, for example, some manager like to control everything and focused on details, he does not know how to delegate, just like the "GOD Object" anti-pattern in the software development.&lt;/li&gt;&lt;li&gt;The software manager's style, like/dislike and skills may also constraints the software product;&lt;/li&gt;&lt;li&gt;Developer's own skills, knowledge, communication skills and ignorance level, etc, may also constraint the software product. We need to be aware of these constraints.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Conway's law in the other way&lt;/b&gt;&lt;br /&gt;Can we good developer influence/improve organization by applying the good practices/patterns/principles? &amp;nbsp;For example, As a developer we knows how powerful the design patterns and SOLID principles to the OO design, and manager can apply those patterns to improve/refactoring the organization structure. Actually I have the idea long time ago: &lt;b&gt;manage a company is like managing software,&lt;/b&gt;&amp;nbsp;&lt;b&gt;if you are a good developer you can be a good CEO or manager&lt;/b&gt;. We can use the software technologies to manage the company team. Although the context is quite different, they both solve the similar problems: &lt;b&gt;How to manage dependency, how to make the team or software product more adaptable.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;This seems has a higher requirement for the manager,&amp;nbsp;since I seldom see a manager who has a strong developer background. I really experienced how difficult it is to communicate with a non-technical background manager, it is really frustrating, and so hard to explain the issue, some time you have to translate it into an real life example to make it easy to understand. Think about it, it is so hard to let the manager to understand an issue, how could he actively find out the issue that developer himself does not aware? This is definitely an example of the Conway's law.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1783642299959191424?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1783642299959191424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/12/some-thoughts-about-conways-law.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1783642299959191424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1783642299959191424'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/12/some-thoughts-about-conways-law.html' title='Some thoughts about Conway&apos;s law'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3336229870333496101</id><published>2010-12-02T23:57:00.001-05:00</published><updated>2010-12-03T12:32:26.661-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell script'/><title type='text'>Use your pain point to measure your incompetence</title><content type='html'>Corey Haines's presentation &lt;a href="http://www.infoq.com/presentations/Software-Craftsmanship-Beyond-The-Hype"&gt;Software Craftsmanship, Beyond the Hype &lt;/a&gt;is interesting.&lt;br /&gt;What I get most impressed is what he mentioned a simple way to measure your level of incompetence:&lt;br /&gt;&lt;b&gt;Picture your mind what's your ideal of programming, then picture what you do when deadline comes, the difference is how much you suck is.&lt;/b&gt;&lt;br /&gt;In short, the difference between your ideal and your reality is the measuring of your suck.&lt;br /&gt;&lt;br /&gt;I totally agree with what he said. Because right now it really applies my situation: I am thinking a long time to improve our build system, &amp;nbsp;I took the training of "Continuous Delivery" in Qcon, I know what is the ideal, but in reality it is really painful, and I don't know where to start, use what tools, it really measures my skills and knowledge for the build process is really low. I have to acknowledge this.&lt;br /&gt;&lt;br /&gt;Here I would like to share my experience about measuring my incompetence:&lt;br /&gt;Yesterday I tried to follow &lt;a href="http://blog.fedecarg.com/2009/11/14/managing-multiple-build-environments/"&gt;this article&lt;/a&gt; to improve our build script, we have 3 different environments: local test, stage box and product box. The first thing I need to do is put the parameters in the build script into 3 different property file, like: local.properties, stage.properties, and prod.properties. then in ant build.xml will read different property file based on the different server environment variables; what we need to do is in different build script, passing its own server environment variable, for example:&lt;br /&gt;inside local.sh, &amp;nbsp;call ant -Dbuild.env=local&lt;br /&gt;inside stage.sh, &amp;nbsp;call ant -Dbuild.env=stage&lt;br /&gt;&lt;br /&gt;This's change is not hard, it did not take me a long time to do that. Then I noticed that in 3 different build script are quite duplicated: the major difference is the build.env value, others are pretty similar, can we refactor the shell script like refactoring the java code? Or can we apply the OO concept to the shell script? Till now I realized that I actually I did not do too much shell script programming: most of the time I just read and copy &amp;amp; past. Then when I googled, I just know that unix shell also support function, you can pass arguments, and even it can return values, this is cool! I did some test, it works!&lt;br /&gt;But I need another feature: inside one script, call the methods in another script file. &amp;nbsp;Basically I want to put the common methods into another file, and so that 3 different script files call the methods in this common file; just like parent class and child class in java, which can make the script file much simple and reusable. After googling, I found the solution again, here I would like to post the sample code and show how it works.&lt;br /&gt;&lt;br /&gt;In build-common.sh, define 3 functions:&lt;br /&gt;&amp;nbsp;process_arguments()&lt;br /&gt;&amp;nbsp;set_ant_env()&lt;br /&gt;&amp;nbsp;call_ant()&lt;br /&gt;&lt;br /&gt;buildlocal.sh&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;. ./build-common.sh &amp;nbsp; # this is how to import another file&lt;br /&gt;&amp;nbsp;&amp;nbsp;set_ant_env&lt;br /&gt;&amp;nbsp;&amp;nbsp;process_arguments $*&lt;br /&gt;&amp;nbsp;&amp;nbsp;call_ant local&lt;br /&gt;&lt;br /&gt;buildstage.sh&lt;br /&gt;&amp;nbsp;&amp;nbsp; . ./build-common.sh&lt;br /&gt;&amp;nbsp;&amp;nbsp;set_ant_env&lt;br /&gt;&amp;nbsp;&amp;nbsp;process_arguments $*&lt;br /&gt;&amp;nbsp;&amp;nbsp;call_ant stage&lt;br /&gt;&lt;br /&gt;buildprod.sh&lt;br /&gt;&amp;nbsp;&amp;nbsp;. ./build-common.sh&lt;br /&gt;&amp;nbsp;&amp;nbsp;set_ant_env&lt;br /&gt;&amp;nbsp;&amp;nbsp;process_arguments $*&lt;br /&gt;&amp;nbsp;&amp;nbsp;call_ant local&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Actually I still can improve the build script by passing an extra argument, but I am afraid we get used to use different shell to manage different environment, so I just leave it now.&lt;br /&gt;&lt;br /&gt;The most important thing is how to import another shell into your shell script:&lt;br /&gt;&lt;br /&gt;1.&lt;br /&gt;. ./buld-common.sh&lt;br /&gt;&lt;br /&gt;2. then you can the function, like calling the local function:&lt;br /&gt;&amp;nbsp;&amp;nbsp; set_ant_env&lt;br /&gt;&lt;br /&gt;From this small improvement, I learned some thing about the unix shell, not bad. And more important what I learned is whenever you feel the pain, especially it will be painful over and over, do not just let it control you, you should to face it and think about how to solve it. Because it is good chance to measure you incompetence and a good chance for you to improve your skills.&lt;br /&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/3555300218296290557-3336229870333496101?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3336229870333496101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/12/use-your-pain-to-measure-your-ignorance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3336229870333496101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3336229870333496101'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/12/use-your-pain-to-measure-your-ignorance.html' title='Use your pain point to measure your incompetence'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4128837776888148864</id><published>2010-11-30T21:55:00.002-05:00</published><updated>2010-12-03T00:03:38.716-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Hacking the Wireless Toolkit for Mac</title><content type='html'>Today I spend a whole day trying to fix an J2ME build issue: the build script works on windows, but failed on Mac. My working environment is:&lt;br /&gt;WTK&lt;br /&gt;&amp;nbsp;&amp;nbsp; - Windows PC: WTK 2.5.2&lt;br /&gt;&amp;nbsp;&amp;nbsp; - &amp;nbsp;Mac: &amp;nbsp; &amp;nbsp; WTK 2.5.2 Linux version, copied preverify from JavaME SDK 3.0 Mac &lt;br /&gt;Build tool is Antenna&lt;br /&gt;&amp;nbsp;&amp;nbsp; - Windows: antenna 1.1.0&lt;br /&gt;&amp;nbsp;&amp;nbsp; - Mac: &amp;nbsp;antenna 1.2.1 ( the earlier versions have preverify issue on Mac )&lt;br /&gt;&lt;br /&gt;Actually we usually build J2ME application on windows or Linux box, this is the first time to build on Mac. I checked the build log, the log shows the preverify error.&lt;br /&gt;Since I used Sun's latest version of preverify file for Mac, I never suspect it might have issue. I thought issue might due to Mac is picky with the Antenna build script, so I spent lots of time trying to tweaking the build script, but no luck. So I started to thinking the problem might be the preverify file I used for Mac.&lt;br /&gt;&lt;br /&gt;Finally I have to google and I was so lucky that I found Sam's blog post: &lt;a href="http://javablog.co.uk/2008/01/17/j2me-development-on-os-x-revisited/"&gt;J2ME Development on OS X, revisited&lt;/a&gt;. This is a fantastic article, the most important for me is he tells me how to get the Mac version of preverify: &amp;nbsp;&lt;b&gt;Download the &lt;a href="https://phoneme.dev.java.net/"&gt;phoneME&lt;/a&gt; project source code, and the preverify for mac is under phoneme_feature/cldc/build/share/bin/darwin_powerpc/&lt;/b&gt;, as the author suggested, I downloaded the PhoneME feature M2 source code, and I did found the preverify, and after I copied the preverify in my &amp;nbsp;WTK /bin folder of my mac machine, then when I run the build script, it works, awesome. I really admire this guy, how could he find out this tool!&lt;br /&gt;&lt;br /&gt;Now let me describe how to install WTK 2.5.2 on Mac in step by step, please note this only works if you still use WTK 2.5.x, and it is only useful for building the application, the emulator and other tools are not working, you can use JavaME SDK 3.0 for Mac, but based on my today's experience, its preverify still has issues:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Download and Install the WTK 2.5.2&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Goto &lt;a href="http://www.oracle.com/technetwork/java/download-135801.html"&gt;here&lt;/a&gt; to download the Sun's WTK 2.5.2 for Linux, file is called sun_java_wireless_toolkit-2_5_2-linux.bin&lt;/li&gt;&lt;li&gt;Execute the downloaded file (sh sun_java_wireless_toolkit-2_5_2-linux.bin)&lt;/li&gt;&lt;li&gt;When asked for a path to JDK, enter “/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin/”&lt;/li&gt;&lt;li&gt;Follow the instructions, probably best to install into /Applications/WTK2.5.2&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Get the preverify binary&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Download the &lt;a href="https://phoneme.dev.java.net/downloads_previous.html#feature"&gt;PhoneME project feature source code&lt;/a&gt;, &amp;nbsp;choose t&lt;a href="http://download.java.net/mobileembedded/phoneme/feature/phoneme_feature-mr2-rel-src-b23-08_may-2007.zip"&gt;he M2 source bundle&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Extract phoneME build, it creates a directory called “phoneme_feature”&lt;/li&gt;&lt;li&gt;Copy /phoneme_feature/cldc/build/share/bin/darwin_powerpc/preverify and overwrite the preverify binary in your WTK bin folder.&lt;/li&gt;&lt;li&gt;You might need to change the permission to w+x of preverify.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;You might need to install Rosetta before running preverify&lt;/b&gt;&lt;br /&gt;Today one of my colleague found this issue on this macbook, when I give him a copy of preverify binary file, &amp;nbsp;when he run it on his machine, it prompt need to install &lt;a href="http://www.apple.com/rosetta/"&gt;Rosetta &lt;/a&gt;to run it. &amp;nbsp;it said the Rosetta comes with the MacOS installation CD, so if you have the similar issue, then install it first.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Other tools:&lt;/b&gt;&lt;br /&gt;&lt;a href="http://antenna.sourceforge.net/"&gt;Antenna&lt;/a&gt;: &amp;nbsp;please use the latest version for Mac (1.2.1).&lt;br /&gt;&lt;a href="http://gant.codehaus.org/"&gt;Gant&lt;/a&gt;: &amp;nbsp;the groovy based DSL for build script, it built-in support all the ant tasks, but you don't need to write XML any more, I just started using it, and I love it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4128837776888148864?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4128837776888148864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/11/hacking-wireless-toolkit-for-mac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4128837776888148864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4128837776888148864'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/11/hacking-wireless-toolkit-for-mac.html' title='Hacking the Wireless Toolkit for Mac'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4746399217515770427</id><published>2010-11-17T21:52:00.000-05:00</published><updated>2010-11-17T21:52:09.325-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Review of BlackBerry Eclipse Plugin for Mac OS X</title><content type='html'>Today I have a chance to look at BlackBerry's &lt;a href="http://us.blackberry.com/developers/javaappdev/macosx.jsp"&gt;Eclipse Plugin for Mac OS X.&lt;/a&gt;&amp;nbsp;&amp;nbsp;Since it is only a preview version, I did not expect too much. After install and play a while, my excitement vs. disappointment is half and half.&lt;br /&gt;&lt;br /&gt;The software contains the full Eclipse 3.5 and it's Eclipse Plugin, like the windows version of earlier this year. It requires to install the &lt;a href="http://us.blackberry.com/support/software/mac.jsp"&gt;BlackBerry Desktop manager for Mac&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What I don't like:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;Does not support simulator yet. &amp;nbsp;From the IDE menu, I could not find the where I can launch the BlackBerry simulator, &amp;nbsp;then when I read the manual document, I realize this feature is not supported, it only support running/debug on the actual device via USB cable. &amp;nbsp;&lt;/li&gt;&lt;li&gt;On-device debugging is kind of working. It takes a long time to connect the device, it can stop at the break point, but &amp;nbsp;the variable value is wrong, always 0 or null.&lt;/li&gt;&lt;li&gt;Support BlackBerry OS 6 only.&lt;/li&gt;&lt;li&gt;Signing is more restricted, in windows version you can hack the signing tool by putting the file &amp;nbsp;sigtool.csk and sigtool.db in the \bin folder of blackberry SDK component folder. &amp;nbsp;It does not working on Mac version now.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Now I understand why it is called a preview version.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I like most is the blackberry tool "javaloader" is &amp;nbsp;now supported in Mac, I tested it works on Mac, you can install/remove an application using &amp;nbsp;javaloader via USB cable. Really nice! &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The javaloader file is under the folder like:&lt;/div&gt;&lt;div&gt;BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/bin&lt;/div&gt;&lt;div&gt;If you are familiar with the Blackberry Windows version of Eclipse Plugin, you will find they have the same folder structure. &lt;b&gt;Just remember you have to manually change the permission to make sure it is executable. &lt;/b&gt;&amp;nbsp;You can also find the &lt;b&gt;preverify &lt;/b&gt;tool in the same folder, and &lt;b&gt;fledge&lt;/b&gt; tool in the simulator folder, which is supposed to launch the simulator, unfortunately it does not working right now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another interesting thing is I wonder how it build the application in the IDE. &amp;nbsp;From the console window I got following output:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Compiling CLDC Application:&lt;/div&gt;&lt;pre&gt;java -jar /Users/steve/Desktop/BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/bin/rapc.jar -convertpng -quiet codename=deliverables/Standard/6.0.0/HelloWorldDemo deliverables/Standard/6.0.0/HelloWorldDemo.rapc -exepath=/Users/steve/Desktop/BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/bin/ -sourceroot=/Users/steve/dev/workspace/HelloWorldDemo/src:/Users/steve/dev/workspace/HelloWorldDemo/res -import=/Users/steve/Desktop/BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/lib/net_rim_api.jar /Users/steve/dev/workspace/HelloWorldDemo/bin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Compiling MIDlet application:&lt;/div&gt;&lt;pre&gt;java -jar /Users/steve/Desktop/BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/bin/rapc.jar -convertpng -quiet codename=deliverables/Standard/6.0.0/MIDletDemo -midlet deliverables/Standard/6.0.0/MIDletDemo.rapc -exepath=/Users/steve/Desktop/BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/bin/ -sourceroot=/Users/steve/dev/workspace/MIDletDemo/src:/Users/steve/dev/workspace/MIDletDemo/res -import=/Users/steve/Desktop/BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/lib/net_rim_api.jar /Users/steve/dev/workspace/MIDletDemo/bin&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;Now we understand that in Mac, &amp;nbsp;it uses java to launch rap compiler, and it has some option I never seen before: like &amp;nbsp;-convertpng, -exepath, etc. &amp;nbsp;I wonder RIM might upgrade it new version of RAPC compiler.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4746399217515770427?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4746399217515770427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/11/review-of-blackberry-eclipse-plugin-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4746399217515770427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4746399217515770427'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/11/review-of-blackberry-eclipse-plugin-for.html' title='Review of BlackBerry Eclipse Plugin for Mac OS X'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1650268976786150734</id><published>2010-11-14T14:01:00.001-05:00</published><updated>2010-11-14T14:04:46.416-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>More about "Drive"</title><content type='html'>I just by accident read Martin&amp;nbsp;Fowler's&amp;nbsp;article:&lt;a href="http://martinfowler.com/bliki/CannotMeasureProductivity.html"&gt; Can Not Measure Productivity.&lt;/a&gt;&amp;nbsp;&amp;nbsp;The author concluded that you can not measure developer's productivity, because the output is not measurable. Even if you try to measure the performance by using the wrong metrics, things even become worse. In the article, he recommend a book&amp;nbsp;called&amp;nbsp;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;a href="http://www.amazon.com/Measuring-Managing-Performance-Organizations-Robert/dp/0932633366/ref=ntt_at_ep_dpt_6"&gt;Measuring and Managing Performance in Organizations&lt;/a&gt;, written by Robert Austin. but it seems it is not published any more, I just found&amp;nbsp;&lt;a href="http://www.diag.com/ftp/Measurement_Dysfunction.pdf"&gt;a slide of the book.&lt;/a&gt;, and&amp;nbsp;&lt;a href="http://www.dorsethouse.com/pdf/Dorset-House-mmpo.pdf"&gt;a brief introduction of the book.&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Quotes from the book introduction:&lt;br /&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;b&gt;Because people often react with unanticipated sophistication when they are being measured,measurement-based management&amp;nbsp;systems can become dysfunctional,interfering with achievement of intended results. Fortunately, as the author shows, measurement dysfunction&amp;nbsp;follows a pattern that can be identified and avoided.&lt;/b&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&amp;nbsp;Here&amp;nbsp;I got some quotes from the slide:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt; &amp;nbsp;"A system of incentives is dysfunctional if the resulting effort allocation provides less value to the customer&amp;nbsp;than when there is no supervision.” (Austin)&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Measurement versus Delegation&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• Full Supervision: incentives via measurement&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– Relies on extrinsic motivators&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;• Money&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;• Continued employment&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;• “Forcing Contract”&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• No Supervision: incentives via “delegation”&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– Relies on intrinsic motivators&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;• Pride of workmanship, joy in being part of the team&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;• Identification with the company’s values and goals&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;• Desire to please the customer&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Intrinsic versus Extrinsic Motivators&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• &lt;b&gt;Intrinsic motivators are much more powerful&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• But appear to be overridden by extrinsic motivators&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• Japanese versus American management styles&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– Japanese rely heavily on delegation&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– But it is cheaper for them&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– It is both a strength and a weakness&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• Delegation may not be cost effective either&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• Sometimes neither style works&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– “Large software development firm”&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Summary&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• You may think you have full supervision&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• But you are almost certainly wrong&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• The ship’s wheel is not directly connected to the rudder&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;• Austin versus Deming&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– W. Edwards Deming, Out of the Crisis, MIT Press, 2000&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– Former BTL lead Japanese quality movement in 1980s&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;&amp;nbsp;– Methodology summarized in his “Fourteen Points”&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So based on the text above, we can conclude that the book of "&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;a href="http://www.amazon.com/Measuring-Managing-Performance-Organizations-Robert/dp/0932633366/ref=ntt_at_ep_dpt_6"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Measuring and Managing Performance in Organizations&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;" share the same concept with the book of "Drive", use different perspective, it proves that people's performance and productivity is&amp;nbsp;unmeasurable, the manager should not rely on external performance incentive, but should rely on people's intrinsic motive. It also proved that this idea share with Deming's 14 point. Interesting.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Another useful link:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;http://www.slideshare.net/RobMyers64/metrics-in-an-agile-world&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&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/3555300218296290557-1650268976786150734?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1650268976786150734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/11/thoughts-about-performance-measurement.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1650268976786150734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1650268976786150734'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/11/thoughts-about-performance-measurement.html' title='More about &quot;Drive&quot;'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-861160787073421252</id><published>2010-11-13T23:22:00.003-05:00</published><updated>2010-11-13T23:28:17.522-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Manage Change by Managing Unchanged</title><content type='html'>As a software developer, we have to deal with different changes:&lt;br /&gt;&amp;nbsp;- &amp;nbsp;The changing requirements, which means change code, bug fix, revers engineering...&lt;br /&gt;&amp;nbsp;- &amp;nbsp;The changing technologies, you have to deal with new buzz, new API, new languages...&lt;br /&gt;&lt;br /&gt;How can we deal with these changing? because chasing change is really hard, because:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;New stuff in software industry are too much, they are out of control, every year there are so many buzz, languages and SDKs waiting for you;&lt;/li&gt;&lt;li&gt;Some new stuffs are quite easy to obsolete, some time even when you try to start learning it, it is just gone.&lt;/li&gt;&lt;li&gt;Understand too many details in short time is really stressful&lt;/li&gt;&lt;li&gt;They are quite context specific, they will be useless in different area.&lt;/li&gt;&lt;/ul&gt;Since human's time and energy is limited, how can we manage these changes properly? Why not focus on unchanged stuff instead of changing stuff?&amp;nbsp;What I mean the unchanged is something behind the detailed technologies. For example, like principles, rules, patterns, philosophy etc.&amp;nbsp;They are more general which means last longer, they are also the high level abstract knowledge which easier to transfer another area, so based on these 2 characteristics, they are manageable.&lt;br /&gt;&lt;br /&gt;Another interesting characteristic about unchanged is they are meta level of details. For example, measure an object's change of position, then we use velocity, which is can be thought of meta position: the change of position; if we want to measure the change of velocity, then we use accelerator. This example means the higher meta level, the less likely to change and easier to manage. &amp;nbsp;Another example is in software developing, in object oriented developing, the object's meta level is class, the class's meta level is meta class, we manage the class to make the code more reusable, we manage the meta class to make the code more dynamic and more adaptable.&lt;br /&gt;&lt;br /&gt;So how does the concept of "Manage change by manage unchanged" help in the software development?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;We should focus more on classics, like algorithm, data structure, fundamental computer theory, OO design patterns, OO SOLID principles, etc. because they are fundamental and general, they are powerful, they are going to still valid for a long time;&lt;/li&gt;&lt;li&gt;When you learn a new technology, or a new SDK or even a new language, don't try to remember every details, which will overkill you, but you should focus more on the principles, rules or philosophy, since detailed technologies are easy to forget, but when you understand the principles behind the details, it is much easier to memorize, and much easier to transfer to another area;&lt;/li&gt;&lt;li&gt;It help you to identify which technology is worth learning by analyzing its unchanged properties&lt;/li&gt;&lt;li&gt;In software design, when we design an adaptive software system, first we need to identify the changed stuff and unchanged, then design the structure based on unchanged, then isolate and encapsulate the changed stuff; make sure the system depends on unchanged, not on changed, this is the famous &lt;a href="http://en.wikipedia.org/wiki/Dependency_inversion_principle"&gt;Dependency Inversion Principle&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-861160787073421252?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/861160787073421252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/11/manage-change-by-managing-unchanged.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/861160787073421252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/861160787073421252'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/11/manage-change-by-managing-unchanged.html' title='Manage Change by Managing Unchanged'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2443054719430447819</id><published>2010-11-11T23:12:00.003-05:00</published><updated>2010-11-11T23:52:37.318-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Qcon'/><category scheme='http://www.blogger.com/atom/ns#' term='Notes'/><title type='text'>Mind map: Continuous Delivery Notes</title><content type='html'>In QCon San Francisco, I attended the tutorial -"Continuos Delivery", it is a great training. I learned a lot, then&amp;nbsp;I realized I have to record and organize what I learned - which is the part of the GTD principle. Also at the meeting I noticed that Dan North used a Mind Map for his presentation, which is awesome. The software he used is called &lt;a href="http://freemind.sourceforge.net/wiki/index.php/Main_Page"&gt;FreeMind&lt;/a&gt;, &amp;nbsp;so I just tried to use this tool to take my notes in the mind map format.&amp;nbsp;The notes like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lxmigwrwDfI/TNzIA0nwS2I/AAAAAAAAADg/XvoUoTp47HY/s1600/Coninuous_Delivery_Notes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_lxmigwrwDfI/TNzIA0nwS2I/AAAAAAAAADg/XvoUoTp47HY/s640/Coninuous_Delivery_Notes.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Since this is my first time to use it, it is pretty basic, but it is good enough for me right now. It is a good starting point. FreeMind provide lots of nice features, please check &lt;a href="http://www.scribd.com/doc/6492990/FreeMind-Manual"&gt;the pdf manual&lt;/a&gt;&amp;nbsp;for details.&lt;br /&gt;&lt;br /&gt;I realize that using Mind map to take notes and posted on the website is a great idea. I already use mind map to take notes, but just manually drawing, this is a great tool.&lt;br /&gt;&lt;br /&gt;The next step I need to figure out how to embed the actual map on the website.&lt;a href="http://freemind.sourceforge.net/docs/Serving%20Freemind%20maps%20in%20a%20browser/freemind%20applet.html"&gt; This article&lt;/a&gt; tells you how to install and use the FreeMind Applet on your website, then it seems I need to have my own website, so right now it is time for me to build my own website.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2443054719430447819?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2443054719430447819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/11/mind-map-continuous-delivery-notes.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2443054719430447819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2443054719430447819'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/11/mind-map-continuous-delivery-notes.html' title='Mind map: Continuous Delivery Notes'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lxmigwrwDfI/TNzIA0nwS2I/AAAAAAAAADg/XvoUoTp47HY/s72-c/Coninuous_Delivery_Notes.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6731883316926995274</id><published>2010-11-06T22:15:00.002-04:00</published><updated>2010-11-06T22:17:50.094-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Qcon'/><title type='text'>Impressions of Qcon San Francisco 2010 conference</title><content type='html'>My journey of 5-day &lt;a href="http://qconsf.com/"&gt;Qconsf&lt;/a&gt; 2010 is just finished, now I am on the plane flying back to Toronto. This my first time to attend Qcon conference, the whole conference is so nice, I really enjoyed the whole conference. Now I am trying to write down what I thought about this conference. It will be just an overview, I will give more detailed post for each interesting talks in future.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2 Days tutorial: fantastic&lt;/b&gt;&lt;br /&gt;1. &lt;a href="http://qconsf.com/sf2010/speaker/Joseph+Yoder"&gt;Joseph Yoder &lt;/a&gt;and &lt;a href="http://qconsf.com/sf2010/speaker/Rebecca+Wirfs-Brock"&gt;Rebecca Wirfs-Brock&lt;/a&gt;'s Adaptive Object Model is really nice, actually I supposed to take Dan North's architect course, but I changed my mind in the last minute. I really missed Dan North's course, but AOM is really good. because it provide several patterns to make the application architecture more flexible, which is really important for using static language like Java. I think it is really useful to use this model in my current java application development.&lt;br /&gt;&lt;br /&gt;2. Continuous Delivery&lt;br /&gt;I am Martin Fowler's follower, finally I have a chance to listen to Martin Fowler training. My current build process is really painful, I think I have an idea to improve my current build system, including:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; break down one big build script to several pieces,&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; create dependency&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; use code analysis&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; use build server like Hudson&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; use Junit test&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; set up build artifact&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; unify configuration of developing environment and deploy environment&amp;nbsp;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; decouple the dependency of developing build script from deploy build script.&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; use puppet and cucumber&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; simplify the ant build script: use gradle or gant&lt;/li&gt;&lt;/ul&gt;My goal: shorten the deploy build time, shorten the developing unit test build time, try to automate every thing, shorten feedback, improve productivity&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;Martin's Friday's Keynote is also fantastic, I bought his latest book: Domain Specific Language, my suggestion is just to buy any of his book, you will not be disappointed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;overview of 3-day talks&lt;/b&gt;&lt;br /&gt;The 3 days talks are really good, every day I feel struggle to choosing which one I should choose. I choose Java track (wednesday), NoSQL(Thursday), Parallelism programming(Friday). I will say most talks are really good, some talks you will find which is not you expected. My most favourite is Michael Feather's talk:the most important part is about conway's law: your code structure mirror your organization structure, wow!, totally striking, before I have some kind of impression, but I did not aware this rule, fantastic! Michael's talk is so important because it gives your insight to deeper thinking. like zen medication, action of awaken and awareness. Thank you Michael!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My favorite speakers&lt;/b&gt;&lt;br /&gt;I am so happy that I have chance to meet following famous speakers:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Martin Fowler&lt;/li&gt;&lt;li&gt;Dan North&lt;/li&gt;&lt;li&gt;Ralph Johnson&lt;/li&gt;&lt;li&gt;Dan Ingalls&lt;/li&gt;&lt;li&gt;Erik Meijer&lt;/li&gt;&lt;li&gt;Michael Feathers&lt;/li&gt;&lt;/ul&gt;Some speakers I am not familiar, they give really wonderful talking:&lt;br /&gt;&amp;nbsp;&amp;nbsp; Joe and rebecca&lt;br /&gt;&amp;nbsp;&amp;nbsp; Stuart Halloway&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What I learned&lt;/b&gt;&lt;br /&gt;NoSQL, Concurrency &amp;amp; parallel programming and functional programming are my blind spots. Thorough 3 ays conference, &amp;nbsp;I just get some concepts, since they are all very good speakers, I know what I am going to learn next steps.&lt;br /&gt;Especially when I attended two talks by Stuart Halloway about Clojure, I learned that clojure is such a elegant beautiful language, and the more important is closure defines/redefines the concepts about value, time, perception, which are totally different with traditional object oriented model. OO is not the only thing to observe the world. This is big mindset change. Stuart's second talk about time model in clojure is brilliant, pretty philosophy, it will take me longer time to fully understand them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;who I meet&lt;/b&gt;&lt;br /&gt;&amp;nbsp;Mark: &amp;nbsp;I talked to him a lot, who is a ruby guy, I got lots of information about tools of ruby from him.&lt;br /&gt;&amp;nbsp;Jai: &amp;nbsp;Java guy, I found we read quite similar computer books,&lt;br /&gt;&amp;nbsp;Wei: java guy, I learned some form him about NoSQL.&lt;br /&gt;&amp;nbsp;Daniel: .NET guy, I am so impressed by his productivity of blogging, &amp;nbsp;I noticed he just he keep writing in a Martin Fowler's keynotes talking, &amp;nbsp;I thought he might do something else,like checking email, but when after the talk, he told me he just finished his another blog post about the talk, oh my god! Compare to him, usually I take notes on my notebook, then later type them on the computer; it always take a longer time to write a blog post, I need to learn this skill. how to blog your thought easier and faster.&lt;br /&gt;&lt;br /&gt;And I talked many other guys I forget their names, &amp;nbsp;I found we almost read same books, shared same vision, like "learn a new language every year",&amp;nbsp;it is a very good chance to learn, get feedback, you will aware your ignorance, your blind spot, you need to learn more !&lt;br /&gt;&lt;br /&gt;It is really interesting that a group of people come from different country, with different back ground, share the same philosophy.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Next actions&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Am I going to come QCon next year? Maybe, it depends on my own budget.&lt;br /&gt;&amp;nbsp;&amp;nbsp;Get more involved in infoq.com? I talked to Floyd about submitting articles to infoq, which is a good idea, but you have to commit to submit at least one article each week, which is sound stressful to me right now, it is challenge you have to overcome. Do it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6731883316926995274?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6731883316926995274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/11/impressions-of-qcon-san-francisco-2010.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6731883316926995274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6731883316926995274'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/11/impressions-of-qcon-san-francisco-2010.html' title='Impressions of Qcon San Francisco 2010 conference'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-7808765152455374467</id><published>2010-10-16T23:25:00.001-04:00</published><updated>2010-10-16T23:28:59.130-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Gant Script: print ant default properties</title><content type='html'>If you want to know exactly what kind of ant properties in your environment, try the following gant target:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;target(properties : "print ant default properties") {&lt;br /&gt;     println "ant properties are:"&lt;br /&gt;     ant.project.properties.each { key, value -&amp;gt;&lt;br /&gt;         println "${key} = ${value}"&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here are some of the out put:&lt;br /&gt;&lt;pre&gt;ant properties are:&lt;br /&gt;ant.version = Apache Ant version 1.8.1 compiled on April 30 2010&lt;br /&gt;sun.os.patch.level = unknown&lt;br /&gt;java.vm.vendor = Apple Inc.&lt;br /&gt;environment.HOME = /Users/steve&lt;br /&gt;environment.TERM_PROGRAM = Apple_Terminal&lt;br /&gt;file.encoding = MacRoman&lt;br /&gt;user.language = en&lt;br /&gt;java.class.path = /opt/local/share/java/gant/lib/groovy-all-1.7.3.jar&lt;br /&gt;file.separator = /&lt;br /&gt;java.runtime.name = Java(TM) SE Runtime Environment&lt;br /&gt;basedir = /Users/steve/dev/gant&lt;br /&gt;java.vm.specification.version = 1.0&lt;br /&gt;awt.nativeDoubleBuffering = true&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Look how easy it work in the Groovy/Gant script, I am sure it is much harder to write in ant xml build script, and you have to use ant-contrib to implement the for loop! &amp;nbsp;Byebye XML!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-7808765152455374467?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/7808765152455374467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/10/gant-script-print-ant-default.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7808765152455374467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7808765152455374467'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/10/gant-script-print-ant-default.html' title='Gant Script: print ant default properties'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6234928810350305651</id><published>2010-10-16T23:11:00.004-04:00</published><updated>2011-06-05T11:00:09.195-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Build J2ME app using Gant</title><content type='html'>These days I spent some time learning &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;. Why I learn Groovy? Because I want to use &lt;a href="http://gant.codehaus.org/"&gt;Gant&lt;/a&gt;. &amp;nbsp;Gant = Groovy + Ant.&amp;nbsp;Gant is really powerful, since you can use Groovy script and Ant API to write your build script instead of XML.&amp;nbsp;I struggle a long time in Ant, because I have to use Ant-Contrib plugin, and it is so hard to write an condition block and even for loop, &amp;nbsp;it is much easier to do that in Gant script.&lt;br /&gt;&lt;br /&gt;Now I am going to share the gant script of building J2ME app, this is just basic, but you can see the power of Gant.&lt;br /&gt;&lt;br /&gt;Requirement:&lt;br /&gt;1. You need to install Groovy and Gant, &lt;a href="http://gant.codehaus.org/Prepackaged+Distributions"&gt;here is the link&lt;/a&gt;, I used 1.9.3 in Mac.&lt;br /&gt;2. download the latest version of antenna, &lt;a href="http://sourceforge.net/projects/antenna/files/"&gt;here&lt;/a&gt; is the download link, &amp;nbsp;I used 1.2.1-beta.&lt;br /&gt;3. install the JavaME SDK, &amp;nbsp;I choose &amp;nbsp;JavaME SDK 3, since it works on Mac.&lt;br /&gt;&lt;br /&gt;The J2ME MIDlet class source code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import javax.microedition.midlet.*;&lt;br /&gt;import javax.microedition.lcdui.*;&lt;br /&gt; &lt;br /&gt;public class HelloWorld extends MIDlet implements CommandListener {&lt;br /&gt;    private final Command exitCommand;&lt;br /&gt;    private final Form form;&lt;br /&gt; &lt;br /&gt;    public HelloWorld() {&lt;br /&gt;        exitCommand = new Command("Exit", Command.EXIT, 1);&lt;br /&gt;        form = new Form("Hello World!");&lt;br /&gt;        form.append("from Steve");&lt;br /&gt;        form.addCommand(exitCommand);&lt;br /&gt;        form.setCommandListener(this);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    protected void startApp() {&lt;br /&gt;        Display.getDisplay(this).setCurrent(form);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    protected void pauseApp() {}&lt;br /&gt;    protected void destroyApp(boolean force) {}&lt;br /&gt; &lt;br /&gt;    public void commandAction(Command cmd, Displayable disp) {&lt;br /&gt;        if (cmd == exitCommand) {&lt;br /&gt;            destroyApp(false);&lt;br /&gt;            notifyDestroyed();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The Ant script looks like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;project name="antenna-test" default="jar" basedir="."&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;taskdef resource="antenna.properties" classpath="./antenna-bin-1.2.1-beta.jar" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="wtk.home" value="/Users/Steve/dev/wtk252" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="wtk.midp.version" value="2.0" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="wtk.cldc.version" value="1.1" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="src.dir" location="src" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="out.dir" location="out" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="dist.dir" location="dist" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;property name="preverified.dir" location="preverified" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;!-- Regular targets --&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;target name="clean" description="cleans the target directory"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;delete dir="${out.dir}"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;delete dir="${dist.dir}"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;delete dir="${preverified.dir}"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;target name="compile" depends="init"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;wtkbuild source="1.3" srcdir="${src.dir}" destdir="${out.dir}"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/wtkbuild&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;target name="preverify" depends="compile"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;wtkpreverify srcdir="${out.dir}" destdir="${preverified.dir}"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/wtkpreverify&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;target name="jar" depends="compile,jad,preverify"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;wtkpackage jarfile="${dist.dir}/helloworld.jar"&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;jadfile="${dist.dir}/helloworld.jad"&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;obfuscate="false"&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;preverify="false"&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${out.dir}"/&amp;gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/wtkpackage&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;target name="jad" depends="compile"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;wtkjad &amp;nbsp;version="0.01" name="hello" vendor="foo" jadfile="${dist.dir}/helloworld.jad" jarfile="${dist.dir}/helloworld.jar"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt; &amp;nbsp;&amp;lt;midlet name="hello" class="HelloWorld"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt; &amp;nbsp;&amp;lt;/midlet&amp;gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/wtkjad&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/target&amp;gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;target name="init" description="initialization for properties and paths" depends="clean"&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;buildnumber/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;mkdir dir="${out.dir}"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;mkdir dir="${dist.dir}"/&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;mkdir dir="${preverified.dir}" /&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the build script build.gant:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ant.taskdef(resource:"antenna.properties", classpath:"./antenna-bin-1.2.1-beta.jar")&lt;br /&gt;&lt;br /&gt;ant.property(name:"wtk.home", value:"/Applications/Java_ME_SDK_3.0.app/Contents/Resources")&lt;br /&gt;ant.property(name:"wtk.midp.version", value:"2.0")&lt;br /&gt;ant.property(name:"wtk.cldc.version", value:"1.1")&lt;br /&gt;&lt;br /&gt;final srcDir = "src"&lt;br /&gt;final outDir = 'out'&lt;br /&gt;final distDir = 'dist'&lt;br /&gt;final preverifiedDir = 'preverified'&lt;br /&gt;&lt;br /&gt;//clean target&lt;br /&gt;includeTargets &amp;lt;&amp;lt; gant.targets.Clean&lt;br /&gt;cleanPattern &amp;lt;&amp;lt; '**/*~'&lt;br /&gt;cleanDirectory &amp;lt;&amp;lt; [ outDir, distDir, preverifiedDir]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;target(name:"init", description:"initialization") {&lt;br /&gt; depends(clean)&lt;br /&gt; /*buildnumber() */&lt;br /&gt; mkdir(dir:outDir)&lt;br /&gt; mkdir(dir:distDir)&lt;br /&gt; mkdir(dir:preverifiedDir)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;target(name:"compile", description:"compile") {&lt;br /&gt; depends(init)&lt;br /&gt; wtkbuild( source:"1.3", srcdir:srcDir, destdir:outDir)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;target(name:"preverify", description:"preverify") {&lt;br /&gt; depends(compile)&lt;br /&gt; wtkpreverify(srcdir:outDir, destdir:preverifiedDir)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//target jad file&lt;br /&gt;&lt;br /&gt;target(name:"jad", description:"generate jad file") {&lt;br /&gt;    depends(compile)&lt;br /&gt; wtkjad( version:"0.01", name:'hello', vendor:"foo", jadfile:"${distDir}/helloworld.jad", jarfile:"${distDir}/helloworld.jar" ) {&lt;br /&gt;  midlet(name:"hello", class:"HelloWorld")&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//target jar&lt;br /&gt;target(name:"jar", description:"generating jar file") {&lt;br /&gt; depends(compile,jad)&lt;br /&gt; wtkpackage( jadfile:"${distDir}/helloworld.jad", jarfile:"${distDir}/helloworld.jar", obfuscate:"false", preverify:"false")  {&lt;br /&gt;  fileset(dir:outDir)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//target obfuscate&lt;br /&gt;&lt;br /&gt;//target all&lt;br /&gt;target(name:"all", description: "build the whole app") {&lt;br /&gt; depends(jar)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;setDefaultTarget(all)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;From the above script, you can see how easy to write gant build script.&lt;br /&gt;This is only the basic implementation, I am going to post more Gant based script in future.&lt;br /&gt;&lt;br /&gt;In future I am going to consider:&lt;br /&gt;1. How to integrate with ANT script;&lt;br /&gt;2. How import multiple Gant script file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6234928810350305651?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6234928810350305651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/10/build-j2me-app-using-gant.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6234928810350305651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6234928810350305651'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/10/build-j2me-app-using-gant.html' title='Build J2ME app using Gant'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1332626481966223768</id><published>2010-09-26T22:57:00.002-04:00</published><updated>2010-11-13T19:22:44.221-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Use the BlackBerry Issue Tracker to find bugs</title><content type='html'>I don't know when BlackBerry start opening their issue list for the developers, recently I just know this service. This is a great service, you can browse, search and submit the Blackberry issues.&lt;br /&gt;&lt;br /&gt;Here I would like to share my experience how to use the Issue tracker:&lt;br /&gt;&lt;br /&gt;First go to BlackBerry Developer Zone, register an account, use this link:&lt;br /&gt;&lt;i&gt;&amp;nbsp;&amp;nbsp;&lt;a href="https://www.blackberry.com/bdsc/?lang=na#login"&gt;https://www.blackberry.com/bdsc/?lang=na#login&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;After login in, in the left part of the portal, click Resources tab, it will expand several sub links, then select "Developer Issue Tracker", &amp;nbsp;then click &amp;nbsp;link "Submit an Issue", finally your will enter the BlackBerry Issue Tracker portal.&lt;br /&gt;&lt;br /&gt;For example, to identify an BlackBerry OS 5 SMS issue, I found a bug which reported the exact same issue, which is very helpful.&lt;br /&gt;&lt;b&gt;JAVAAPI-553:&lt;/b&gt;&lt;br /&gt;Java APIs&lt;br /&gt;&amp;nbsp;&amp;nbsp; invokeApplication() Ignores PayloadText for Populating SMS Text Message&lt;br /&gt;Created: 19/Oct/09 10:44 PM &amp;nbsp; Updated: 07/Jun/10 05:50 AM&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;DevTrack ID:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; 360769&lt;br /&gt;Fix Version/s:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; None&lt;br /&gt;App Build Number:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; 5.0.0.224&lt;br /&gt;Device:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; Bold 9000&lt;br /&gt;Component:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; --&lt;br /&gt;Description: When calling Invoke.invokeApplication() and passing TextMessage arguments, the PayloadText is ignore when it should be used to populate the body of a new SMS message.&lt;br /&gt;&lt;br /&gt;You will be&amp;nbsp;surprised&amp;nbsp;that there are some many open issues for different blackberry OS.&lt;br /&gt;So I will suggest you to go to the Issue Tracker if you want to confirm a BlackBerry device issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1332626481966223768?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1332626481966223768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/09/use-blackberry-issue-tracker-to-find.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1332626481966223768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1332626481966223768'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/09/use-blackberry-issue-tracker-to-find.html' title='Use the BlackBerry Issue Tracker to find bugs'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-159448441341331348</id><published>2010-09-26T22:18:00.001-04:00</published><updated>2010-09-26T22:23:12.387-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>The incompatible issues of BlackBerry OS 5</title><content type='html'>Recently I realize that BlackBerry OS 5 has more and more incompatible issues with 4.x, usually  a feature works on pearl, curve, bold (4.6), but does not working on bold 5.0, which is very disappointing.&lt;br /&gt;&lt;br /&gt;Here I just make a list of incompatible issues that I found recently:&lt;br /&gt;&lt;br /&gt;1. BACK key issue&lt;br /&gt;In 4.x, the BACK key value mapped in MIDlet is 27, I tested on 8100/8300/8900, this key value is the same: 27.  But I just found in Bold with OS 5.0, the BACK key is not mapped into MIDlet at all, the MIDlet can not get the BACK key event.&lt;br /&gt;&lt;br /&gt;2. SMS send issue.  When you launch the BlackBerry native Message application to send SMS using Invoke class, you can pre-populate with phone number and text message, it works in 4.x, but does not work on 5.0, it is a know issue of blackberry 5.0, the message body is empty. Please check this &lt;a href="http://supportforums.blackberry.com/t5/Java-Development/Invoke-Message-application/m-p/418965/highlight/true"&gt;link&lt;/a&gt; for details.&lt;br /&gt;&lt;br /&gt;3. Retrieving CellID issue.  We know that using GPRSInfo we can get phone's Cell-ID, but in 5.0 you will get the wrong id if you use the same method, this is because for 3G network, you need to use different method, how complicated it is!&lt;br /&gt;&lt;br /&gt;4. Icon issue, I found in OS 5.0, you can set the rollover icon the jad file, and blackberry will recognize it even if your application is MIDlet, but I found you need to use JDE 5.0 to build your app; if you use JDE 4.x, it does not work.&lt;br /&gt;&lt;br /&gt;I feel disappointed about BlackBerry platform, since I feel 4.2 - 4.6 even 4.7, the OS are quite consistent with each version, but in OS 5.0, it seems this is a big difference with previous ones. If OS 5 look like this, how can we trust OS 6?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-159448441341331348?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/159448441341331348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/09/incompatible-issues-of-blackberry-os-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/159448441341331348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/159448441341331348'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/09/incompatible-issues-of-blackberry-os-5.html' title='The incompatible issues of BlackBerry OS 5'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3272956002071289487</id><published>2010-09-05T23:50:00.003-04:00</published><updated>2010-09-05T23:58:24.827-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Be careful to use "Class.forName()" in J2ME</title><content type='html'>A couple weeks ago, I made another mistake: I tried to use&lt;b&gt; Class.forName()&lt;/b&gt; method to solve the multiple platform issue, but unfortunately it did not work on the actual devices due to the issue caused by the obfuscation. This is my another blind spot, because of my ignorance of J2ME obfuscation.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Scenario&lt;/b&gt;&lt;br /&gt;I need to provide an API to support multiple mobile platform, for example: Nokia, Blackberry, and simulator, etc.&lt;br /&gt;What I implement is pretty easy:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;define an interface: Service&lt;/li&gt;&lt;li&gt;Implement the Service interface for each mobile platform, for example:&amp;nbsp;NokiaService, BlackBerryService, SimualtorService&lt;/li&gt;&lt;li&gt;At the build time, inject different Service class file in the package.&lt;/li&gt;&lt;li&gt;At the run time, the application use the Class.forName() to create the Service objects.&lt;/li&gt;&lt;/ul&gt;The snippet code looks like this:&lt;br /&gt;&lt;pre&gt;public Service createService(int device)&lt;br /&gt; {&lt;br /&gt;    Service service = null;&lt;br /&gt;&lt;br /&gt;    if( device == NOKIA)&lt;br /&gt;    {&lt;br /&gt;        service = Class.forName("NokiaService").newInstance();&lt;br /&gt;    }&lt;br /&gt;    else if( device == BLACKBERRY)&lt;br /&gt;    {&lt;br /&gt;        service = Class.forName("BlackBerryService").newInstance();&lt;br /&gt;    }&lt;br /&gt;    else if(device == SIMULATOR)&lt;br /&gt;    {&lt;br /&gt;        service = Class.forName("SimulatorService").newInstance();&lt;br /&gt;    }&lt;br /&gt;    else &lt;br /&gt;        service = Class.forName("GenericService").newInstance();&lt;br /&gt;&lt;br /&gt;     return service;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here I use a factory pattern to support multiple platform, no need to use preprocess, sound pretty simple, right?&lt;br /&gt;But I found the above solution only works on BlackBerry platform, on other J2ME platform, the application will throw the ClassNotFound Exception.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The reason of failure&lt;/b&gt;&lt;br /&gt;&lt;b&gt;The problem is in obfuscation phase&lt;/b&gt;, we usually use&lt;b&gt; Proguard&lt;/b&gt; to do preverification and obfuscation for the J2ME application. The proguard will remove the unused class file. (for detail please check this &lt;a href="http://proguard.sourceforge.net/index.html#/FAQ.html"&gt;link&lt;/a&gt; )&amp;nbsp;In my solution above use class.forName() by passing different string values, which is not recognized in Proguard. For example: in Nokia platform, the NokiaService.class is used, but Proguard did not find the NokiaService.class is explicitly reference in the java code, so it think it is unused class file, then remove it from the final package. Then it cause the ClassNotFoundException.If you don't use obfuscation, the application works, but it is really rarely the commercial application does not have obfuscated.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;But why it works on BlackBerry platform?&lt;/b&gt;&lt;br /&gt;Because Blackberry is quite different with other J2ME platforms, it requires it own preverification and obfuscation using its own RAPC compiler. And I found that in Blackberry application package it usually keep all the class files in the package, which is different with the Proguard. That is the reason why it works in BlackBerry platform&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;&lt;br /&gt;I have to rewrite the above code, remove all the Class.forName(), replaced with the explicit method call.&lt;br /&gt;To support multiple platform, I use &lt;a href="http://www.csg.is.titech.ac.jp/~chiba/javassist/"&gt;javaassit&lt;/a&gt; to adjust the createService() method for different platform, while you can use pre-process if you want, even I really don't like the J2ME pre-process, because it will bring other more complicated issue in your application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Class.forName()&lt;/b&gt; seems the only reflection that is support in the J2ME platform, but actually it will cause the problem during obfuscation phase, try not to use the Class.forName() in your J2ME application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-3272956002071289487?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3272956002071289487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/09/be-careful-to-use-classforname-in-j2me.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3272956002071289487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3272956002071289487'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/09/be-careful-to-use-classforname-in-j2me.html' title='Be careful to use &quot;Class.forName()&quot; in J2ME'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5041435180015522038</id><published>2010-08-19T23:41:00.001-04:00</published><updated>2010-11-14T14:09:52.550-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Aspire to be agile missionary</title><content type='html'>In an evening of earlier this week, when I went out for a walk near my house, I met 2 young Christian missionaries. From their eyes, I can feel their passion and ideal. They want to help people, and enjoy seeing how they can make changes to them. They did that all for free, they have a mission to transfer what the God said to other people. I was totally impressed by their passion, although I don't believe in God.&lt;br /&gt;&lt;br /&gt;I was inspired by these 2 young missionary: we might need missionaries in the software industry. I love to be a missionary if there is a similar group about software development which share a unique vision about software developing, like software craftsmanship for example. &amp;nbsp;I would love to share my knowledge and experience; I would love to transfer to other developer that what I believe the right thing, right principle; I love to pursue the way of software development, find the philosophy behind the principles. I love to do that for free, and I am sure I will enjoy what I am doing and seeing the changes I made.&lt;br /&gt;&lt;br /&gt;What is the reason that I want to be agile missionary? During year 2002, at that time I had been a software engineer for about 10 years, I became confused about my career as software developer: should I continue my career as developer or change to a manager? Why programmer's job is so hard, so boring, so messy? It doesn't make sense! And in that year, occasionally I began to know about Agile movement, it totally changed my mindset of software developing. Agile is like philosophy: it tells you the right way beyond the detailed technology, computer language and tools. Since then I read lots of books from Kent beck, Martin Fowler, Uncle Bob, Dave Thomas ... etc.&amp;nbsp;Since then I found the answer of my career path: continue my career as software developer, because there so many good stuff you need to know, there are lots of potentials for to improve yourself. Then I started learning Design patterns, doing refactoring, investigate new tools. Gradually I realized that I can feel the difference between me and my colleagues: not because of my experience, but because I have the deeper knowledge of agile and the right way of programming. I really love to share my experiences, because I learned a lot from agile. Before I just unconsciously shared my experiences and knowledge, from now I need to do that consciously and deliberately.&lt;br /&gt;&lt;br /&gt;Being agile missionary is not easy. First, you need to keep improving your skills, then you can lead by example; second, you need passion and strong vision; third, you need to know some knowledge of psychology, because different person has different background and different mindset, you need to aware that and use different strategy; fourth, the communication skills is definitely important, you need to keep improving it.&lt;br /&gt;&lt;br /&gt;I already set my goal: pursuing the right way of software of development, finding the true principles, strategy and philosophy, attain mastery. Right now I feel I just enter the gate to that road, there is till a long journey to go. I hope at this journey, when I work as a missionary by help other developers, I can improve myself and find other missionaries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5041435180015522038?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5041435180015522038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/08/aspire-to-be-agile-missionary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5041435180015522038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5041435180015522038'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/08/aspire-to-be-agile-missionary.html' title='Aspire to be agile missionary'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6680619089431818468</id><published>2010-08-08T22:57:00.001-04:00</published><updated>2010-08-08T23:10:46.764-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Is it possible for a developer to become an artist?</title><content type='html'>I am still reading the book: &lt;a href="http://www.amazon.com/Linchpin-Are-Indispensable-Seth-Godin/dp/1591843162?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Linchpin&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=1591843162" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;. &amp;nbsp;I am interested with the author's definition about art:&lt;br /&gt;Art is a personal gift that changes the recipient. Art is something creative, passionate and personal, which can bring some change and make the difference.&lt;br /&gt;The author expanded the &amp;nbsp;definition of art , it focuses on "making changes".This idea share the similar idea of software crafsmanship.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where is the art in software developing?&lt;/b&gt;&lt;br /&gt;The developer's daily job can be boring, repetitive instead of creative.&amp;nbsp;For example:&lt;br /&gt;you can just copy and paste from the old code; or just use google check some API usage;&lt;br /&gt;You don't need to care the code quality, don't need to care about the maintainability.&lt;br /&gt;you can also finsih the job. You can do like that everyday.&lt;br /&gt;But this job is not art,&amp;nbsp;you will not make the difference,&amp;nbsp;any one with the similar knowledge can do it.&lt;br /&gt;then your job are easily been replaced.&lt;br /&gt;&lt;br /&gt;But the developer's job can be a kind of art if you choose to do in different way:&lt;br /&gt;&amp;nbsp;&amp;nbsp; there is the art of making simple design;&lt;br /&gt;&amp;nbsp;&amp;nbsp; there is the art of wrting clean code;&lt;br /&gt;&amp;nbsp;&amp;nbsp; there is the art of refactoring;&lt;br /&gt;&amp;nbsp;&amp;nbsp; there is the art of maintaining;&lt;br /&gt;&amp;nbsp;&amp;nbsp; there is the art of debugging;&lt;br /&gt;&amp;nbsp;&amp;nbsp; there is the art of communciation and interaction;&lt;br /&gt;&lt;br /&gt;Anything which can make things better and make some difference is the art of programming.&lt;br /&gt;if you bring your passion, and make some difference, then that is art;&lt;br /&gt;if you do that day by day, keep improving yourself, then you will become a master, which is also an artist of software.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The road to become artist&lt;/b&gt;&lt;br /&gt;I like the concept of &lt;a href="http://www.aikidofaq.com/essays/tin/shuhari.html"&gt;Shu-Ha-Ri&lt;/a&gt;, it can be treated as a path from an average developer to a master developer:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;In Shu Level, the point is "following, copying", all you need to do is learning, so there is no art behaviour at this level;&lt;br /&gt;&amp;nbsp;&amp;nbsp;In Ha Level, &amp;nbsp;the key point is "detaching, breaking", you try to bring some change, bring what you learned into different context, you will have some art behavior in this stage;&lt;br /&gt;&amp;nbsp;&amp;nbsp;In Ri Level, the key point is "transcending", you becomes master, everything you do is from your intuition, you are freely to express your idea,which is the artists behaviour.&lt;br /&gt;&lt;br /&gt;So I believe the truly artist is only existed in Ri level, which needs years of the deliberate practice, it should be an ultimate goal for any serious software developer. You will become master and artist at the same time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6680619089431818468?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6680619089431818468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/08/is-it-possible-for-developer-to-become.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6680619089431818468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6680619089431818468'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/08/is-it-possible-for-developer-to-become.html' title='Is it possible for a developer to become an artist?'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1314601445151286937</id><published>2010-08-02T22:59:00.003-04:00</published><updated>2010-08-04T00:50:15.509-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Linchpin: to be or not to be?</title><content type='html'>Are you a cog or lincphin? Every employee has to answer this question.&lt;br /&gt;&lt;br /&gt;In your team, you work hard, show up on time, folllow the order, try to fit in the team, compliance to your boss, always say "yes", finished what you've been told.If you are lucky, you might be given some bonus. But if you only just did that, then you are just an average developer, will be no difference with other colleague, you are just an interchangable component, like a cog in a machine, which are easily to be replaced.&lt;br /&gt;The problem in IT industry, average and mediocrity can not survive, whether a company or a developer. &amp;nbsp;If you are just an average cog, then you are easily to be replaced, you have to compete with other lower priced developer; and even more finally your job might be outsourced to India or China.&lt;br /&gt;&lt;br /&gt;So if you want to survive, secure your job, &amp;nbsp;you have to be lincpin: you are indespnesible. Make sure you stand out, remarkable, quite different with others average people; you have passion, you are emotional labour.&amp;nbsp;If you are linchpin, you will become independent and get freedom, you don't need to worry about job, job is always looking for you. Since you are linchpin, you deserve the high pay because you bring much more value to the company.The difference productivity between a great software developer and average one is 10:1, think about how much you can earn if you are linchpin.&amp;nbsp;Think about Apple, how the iPhone makes such difference with other regular phones.&lt;br /&gt;&lt;br /&gt;You have to make a choice between these two: to be linchpin or not to be. It is up to you.&lt;br /&gt;If you want more details about linchpin, please read the book:&lt;a href="http://www.amazon.com/Girl-Dragon-Tattoo-ebook/dp/B0015DROBO?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt; Linchpin: Are you indispensable?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Girl-Dragon-Tattoo-ebook/dp/B0015DROBO?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=B0015DROBO" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;&lt;br /&gt;&lt;iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=p0da-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=bpl&amp;amp;asins=0307705501&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Also check this article:&lt;a href="http://www.pragprog.com/magazines/2010-06/the-indispensable-developer"&gt; The indispensable Developer&lt;/a&gt;&lt;br /&gt;And this: &lt;a href="http://agilewarrior.wordpress.com/2010/05/06/you-are-not-your-role/"&gt;You are not your role&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1314601445151286937?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1314601445151286937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/08/linchpin-to-be-or-not-to-be.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1314601445151286937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1314601445151286937'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/08/linchpin-to-be-or-not-to-be.html' title='Linchpin: to be or not to be?'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6370599985479209866</id><published>2010-07-25T01:45:00.009-04:00</published><updated>2011-07-12T12:49:22.273-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>What drive you work? - The review of book Drive</title><content type='html'>Today I finish reading the book &lt;a href="http://www.amazon.com/Drive-Surprising-Truth-About-Motivates/dp/1594488843?ie=UTF8&amp;amp;tag=p0da-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Drive-The surprising Truth About What Motivates Us&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=p0da-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=1594488843" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;". I knew this book from this &lt;a href="http://www.youtube.com/watch?v=u6XAPnuFjJc"&gt;10 minutes cartoon&lt;/a&gt; on twitter, and&lt;a href="http://www.youtube.com/watch?v=_mG-hhWL_ug"&gt; the author's video about drive&lt;/a&gt;.The topic sound interesting to me, so I started to read the book. To my surprise, the book is quite easy to read, I was so absorbed in it,&amp;nbsp; most of the book was finished on the flight trip to London.This is very unusual to me, since I seldom finishing a English book in such a short time, except Agatha Christie's&amp;nbsp; novel.&lt;br /&gt;The core concept of the book: The traditional external carrot &amp;amp; stick motivator does not work on 21 century; we need to upgrade to intrinsic motivator: autonomy, mastery, &amp;amp; purpose.&lt;br /&gt;This concept is not new to me, it reminds me some other books which share the similar theory behind:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Maslow's self realization theory;&lt;/li&gt;&lt;li&gt;Lean Technology and Deming's theory;&lt;/li&gt;&lt;li&gt;Seven Habits&lt;/li&gt;&lt;li&gt;Maverick&lt;/li&gt;&lt;li&gt;The passionate programmer&lt;/li&gt;&lt;li&gt;The fifth discipline&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This book drives me into deep thinking about the 3 factors:&lt;b&gt; autonomy, mastery and purpose&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What I learned from the book&lt;/b&gt;&lt;br /&gt;&amp;nbsp;- Autonomy, mastery and purpose are correlated, and each of them supports each other.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Good example: Since I have the mastery in my mind, I have the passion to do things better; if I get the autonomy, I get trust, I am allowed to do my job on my way, then I will focus entirely on the job, and try to doing my job better, since I know the purpose of my job, I know the whole picture, and I enjoy the whole process.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Bad example: In the command &amp;amp; control hierarchy, I am just a interchangable resource, I can not control what I am going to do; I have to follow the order from my boss; my job is make my boss happy, I don't care job itself. I don't know the my job related to any purpose, I just know get my job done, make my boss happy and get my money. It is impossible to get highly motivated.&lt;br /&gt;&amp;nbsp; - The road to "go independent" is the right way to me, I get this idea from the book of "the Passionate programmer".This is the only thing that can guarantee you to get autonomy. You can not control your company, you can not decide who is your boss, but at least you can control your self if you are independent software developer.&lt;br /&gt;&amp;nbsp;-&amp;nbsp; Reinforce my goal to mastery.&lt;br /&gt;&amp;nbsp; I feel lucky that I am still a programmer instead of manager, this give me a chance to become a master in future.Keep improve yourself, love your job, treat your career as an infinite game, keep challenge your self.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;b&gt;Next step thinking:&lt;/b&gt;&lt;br /&gt;- Compare drive with Lean technology&lt;br /&gt;- Investigate the "flow" concept&lt;br /&gt;- If you are a Type I person, how can you do in a Type X organization, how to deal with your Type X boss?&lt;br /&gt;- What kind of Type I organization should be? How to migrate from Type X to Type I organization?&lt;br /&gt;- Why we should focus Type I behavior in software industry?&lt;br /&gt;- Why manager need to give up control?&lt;br /&gt;- use the theory in "drive" to explain the "three stone cutter stories"&lt;br /&gt;- Read the book of "the fifh discipline".&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Resources:&lt;/b&gt;&lt;br /&gt;1. &lt;a href="http://www.youtube.com/watch?v=u6XAPnuFjJc"&gt;10 minutes video link&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://www.youtube.com/watch?v=_mG-hhWL_ug"&gt;author Daneil Pink's presentation&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://www.danpink.com/"&gt;Dan pink's website&lt;/a&gt;&lt;br /&gt;4.&amp;nbsp;&lt;a href="http://www.worldcat.org/profiles/dcornwall/lists/1834257"&gt;The reading list of drive&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6370599985479209866?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6370599985479209866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/07/what-drive-you-work-review-of-book.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6370599985479209866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6370599985479209866'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/07/what-drive-you-work-review-of-book.html' title='What drive you work? - The review of book Drive'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3778006851132357166</id><published>2010-07-04T20:47:00.009-04:00</published><updated>2010-08-31T19:11:04.505-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Time Machine Wireless backup using your own network drive</title><content type='html'>Last Friday My Macbook is broken again, this is the third time since this year, I don't know why I am so unlucky and I love my macbook so much! I really worried about my hard drive because the computer could not recognize the hard drive, and I never backup my hard drive data before! Finally the issue was resolved in the Apple Store, the problem is in the harddrive cable.&lt;br /&gt;This time it gave me a lesson:&lt;b&gt; I need to backup my hard drive ASAP.&lt;/b&gt;&lt;br /&gt;But when I started to use the time machine for the first time, I got stuck: the Time Machine requires the Time Capusle and Apple airport, while I want to backup into my own NAS drive. To solve this issue, I spent &amp;nbsp;almost half a day on google and trying out back and forth. Finally I made it, I can use time machine to backup my harddrive into my own network drive.&lt;br /&gt;Here I would like to share my experience about how I solve it. Basically I referred &lt;a href="http://adamcohenrose.blogspot.com/2008/02/time-machine-wireless-backup-without.html"&gt;this blog&lt;/a&gt;, it is so great, I could not able to finish it without this article.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Goal&lt;/b&gt;&lt;br /&gt;Backup my mac hard drive into my own NAS via wireless network.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Environment&lt;/b&gt;&lt;br /&gt;Computer: MacBook Pro&lt;br /&gt;OS: Snow Leopard&lt;br /&gt;Wireless Router: Netgear WNDR3700&lt;br /&gt;Network drive: West Digit MyBook Essential&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Steps&lt;/b&gt;&lt;br /&gt;1. Setup network drive, create a network shared folder for time machine. For example, I called the folder "\mac".&lt;br /&gt;2. Connect the NAS storage, for example in my netgeare wireless network, I type following in Finder:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;smb://readyshare/mac&lt;br /&gt;3. Enable time machine to use your network drive, run following command in the terminal:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1&lt;/pre&gt;&lt;br /&gt;4. Find out your computer name and Ethernet ID.&lt;br /&gt;&amp;nbsp;&amp;nbsp; To get the computer name, go to "System Preferences" - "Sharing" , then you will see the computer name at the top, and you can change to any name without restarting the mac computer.&lt;br /&gt;&amp;nbsp;&amp;nbsp; For example, my computer name is: steve_zhang_mac. &amp;nbsp;The name contains space and other special characters should be fine, but I prefer to make it simple.&lt;br /&gt;&amp;nbsp;&amp;nbsp; For the Ether ID, go to "System Preferences" - "Network" - "Ethernet" - "Advanced" - "Ethernet". The ethernet ID in my computer is: d4:9a:20:04:65:34&lt;br /&gt;&amp;nbsp;&amp;nbsp; Or you can try to type following command in the terminal:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;ifconfig en0 | grep ether | sed s/://g | sed s/ether//&lt;/b&gt;&lt;br /&gt;&amp;nbsp;Please remeber: it requires the computer's MAC address regardless if you use wireless or wired connection.&lt;br /&gt;&amp;nbsp;&amp;nbsp; If you use Wi-Fi, you will find another different ethernet ID under the &amp;nbsp;"Airport" configuration, don't use this value.&lt;br /&gt;5. Create the disk image file&lt;br /&gt;&amp;nbsp;&amp;nbsp; Create the disk image file locally, the file name is like computername_MACaddrss.sparsebundle&lt;br /&gt;&amp;nbsp;&amp;nbsp; based on the information from step 4), run following in the terminal:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;pre&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DISK_IMAGE_NAME="steve_zhang_macbook_d49a20046534.sparsebundle"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DISK_SIZE=200000&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;hdiutil create -library SPUD -megabytes $DISK_SIZE -fs HFS+J -type SPARSEBUNDLE -volname "$DISK_IMAGE_NAME" "$DISK_IMAGE_NAME"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;Copy the created image file into the NAS storage folder.&lt;br /&gt;6. &amp;nbsp;Run Time Machine, choose your NAS box, &amp;nbsp;if everything is OK, then the time machine will start working.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Some Erorrs I met&lt;/b&gt;&lt;br /&gt;-&lt;b&gt; Error 45&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;This is because the time machine could not create the .sparsebundle file, in your NAS storage folder, you might find a file name and folder called like coputerName_tmp.sparsebundle, please follow step 4 and 5, &amp;nbsp;copy the generated file into the specific shared folder.&lt;br /&gt;&amp;nbsp;&amp;nbsp;I met this issue twice, one is I did not create the image file, the other is since I use the wrong ehternet ID which I got from the "airport" configuration. After I used the correct ehternet ID,this error does not happened again.&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;Error of" .....sparsebundle is already been used."&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;The .spasebundle file is used by another process, please restart the computer to run the Time machine again, this issue will solved.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Other tricks&lt;/b&gt;&lt;br /&gt;1. For the first time backup, it is better to use LAN instead of Wi-Fi, for example, it took me about 14 hours to backup 113G data using LAN mode.&lt;br /&gt;2. How to check the connected NAS in terminal:&lt;br /&gt;&amp;nbsp;&amp;nbsp; All the harddrives are under folder /Volumes, so if you type cd /Volumes in terminal, you will see your hard drive and your network drive.&lt;br /&gt;3. How to check the system log:&lt;br /&gt;&amp;nbsp;&amp;nbsp; System log is in /var/log/system.log&lt;br /&gt;4. If you don't like the time machine to backup every hour, please try the Time Machine Editor, you can customize your own backup schedule with this free app.&lt;br /&gt;5. If you use Parallels virtual machine, then it is better to turn off the backup for parallels virtual machine file, &amp;nbsp;go to Parallels Desktop - Virtual Machine - Configure... , choose "General" tab, check the "Do not back up with time machine." For example, before my computer needs about 120G, right now it only needs to backup 59G data. &amp;nbsp;Or you can open the Time Machine Preferences, choose options, &amp;nbsp;add exclude the Virtual machine file: it is in /Users/Shared/Parallels/Windows XP.pvm&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;1. &amp;nbsp;&lt;a href="http://appleclinic.wordpress.com/2008/10/30/time-machine-on-nas/"&gt;Getting Time Machine to work on an Unsupported NAS&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://adamcohenrose.blogspot.com/2008/02/time-machine-wireless-backup-without.html"&gt;Time Machine Wireless Backup without Time Capsule&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://timesoftware.free.fr/timemachineeditor/"&gt;Time Machine Editor&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-3778006851132357166?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3778006851132357166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/07/time-machine-wireless-backup-using-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3778006851132357166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3778006851132357166'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/07/time-machine-wireless-backup-using-your.html' title='Time Machine Wireless backup using your own network drive'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-879309585074523010</id><published>2010-06-27T20:49:00.003-04:00</published><updated>2010-06-29T15:52:25.527-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Debug BlackBerry Application Inside NetBeans</title><content type='html'>This post continues the my &lt;a href="http://code-dojo.blogspot.com/2010/05/lwuit-blackberry-ant-script-refactored_27.html"&gt;last post&lt;/a&gt;&amp;nbsp;&amp;nbsp;about blackberry application development.&lt;br /&gt;&lt;br /&gt;I added the ANT target to launch the blackberry JDWP debugger from these two articles: &lt;a href="http://www.xenglobaltech.com/blackberry/index.php?option=com_content&amp;amp;view=article&amp;amp;id=45&amp;amp;Itemid=40"&gt;1)&lt;/a&gt; and &lt;a href="http://supportforums.blackberry.com/t5/Java-Development/Building-Blackberry-apps-with-Netbeans/td-p/431612"&gt;2)&lt;/a&gt;.&amp;nbsp;I can launch the BlackBerry JDWP and simulator, but unfortunately the app did not stopped at the break point.&lt;br /&gt;I googled a lot, but it seems none of the post tells you that debugging blackberry successfully inside the NetBeans IDE, I did not find any tutorial about using JDWP in blackberry development document either.&lt;br /&gt;So I have to figure out by myself by using reverse engineering again.&lt;br /&gt;&lt;br /&gt;First I set up the BlackBerry project in the JDE environment, and it launched the debugger successfully, can stop at the break point, and can single step;&lt;br /&gt;then I go to the simulator folder of the BlackBerry ( in my pc is C:\Program Files\Research In Motion\BlackBerry JDE 4.5.0\simulator), I found there not only .cod file and .jad file, but also found&lt;br /&gt;&amp;nbsp;.debug, .jar, and .alx file. &lt;b&gt;I realize this might be the reason: you need to copy .debug files in the simulator! &lt;/b&gt;In my old build script, I only copied jad and cod files, did not copy .debug files into the simulator.&lt;br /&gt;&lt;br /&gt;So I modified my ant build script, make sure it will copy all the rapc generated files into the simulator folder, which includes:&lt;br /&gt;&amp;nbsp;&amp;nbsp;- .jad and .jar file, I don't know why JDWP needs jar file, but it works any way;&lt;br /&gt;&amp;nbsp;&amp;nbsp;- debug file, like .debug and xxx-1.debug, xxx-2.debug, etc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;- .cod file&lt;br /&gt;&amp;nbsp;&amp;nbsp;- .alx file&lt;br /&gt;&lt;br /&gt;The ant script snippet look like this:&lt;br /&gt;1.&amp;nbsp;&amp;nbsp;ANT target: copy files.&amp;nbsp;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&amp;nbsp;&lt;/a&gt;Since I used bb-ant, this target means copy all the file contains the project name under \bbant folder to the simulator folder.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;target name="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy todir="${platform.home}/simulator" verbose="true"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;fileset dir="${dist.dir}/bbant"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name="**/${name}*"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/copy&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;ANT target: launch blackerry debugger, this target will launch the blackberry JDWP remote server and blackberry simulator.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;target name="bb-debug" depends="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;delete file="${preprocessed.dir}/.timestamp"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;parallel&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;java jar="${platform.home}/bin/JDWP.jar" fork="true" dir="${platform.home}/bin"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;jvmarg value="-Xmx128M"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/java&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sequential&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sleep seconds="5"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;antcall target="nbdebug"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/sequential&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/parallel&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At this time I use the new ant script and press the debu button in NetBeans, this time it works!!! It takes a longer time to launch the debugger and simualtor, but finally the app stops at the break point, and it allows me to step in and step out.&lt;br /&gt;Another thing I like to mention is for the system outputs, you can only see them from the BlackBerry JDWP output window, you can not see them from the NetBeans output window.&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;For your reference, I post the whole build script and source code:&lt;br /&gt;1. bb-build.xml&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;target name="post-init"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;available file="${platform.home}/bin/rapc.exe" property="do.rapc" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;condition property="jpda.port" value="8000"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;isset property="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/isset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/condition&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="post-jar" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;lt;antcall target="bbbuild" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="run" depends="init,jar,bb-run,cldc-run" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="debug" depends="init,jar, bb-debug, cldc-debug" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="cldc-run" unless="do.rapc" &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;nb-run jadfile="${dist.dir}/${dist.jad}" jarfile="${dist.dir}/${dist.jar}" jadurl="${dist.jad.url}" device="${platform.device}" platformhome="${platform.home}" platformtype="${platform.type}" execmethod="${run.method}" securitydomain="${evaluated.run.security.domain}" commandline="${platform.runcommandline}" classpath="${platform.bootclasspath}:${dist.dir}/${dist.jar}" cmdoptions="${run.cmd.options}"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="cldc-debug" unless="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;delete file="${build.dir}/.timestamp"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;parallel&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;nb-run debug="true" debugsuspend="true" debugserver="true" debuggeraddressproperty="jpda.port" platformtype="${platform.type}" platformhome="${platform.home}" device="${platform.device}" jadfile="${dist.dir}/${dist.jad}" jarfile="${dist.dir}/${dist.jar}" execmethod="${run.method}" securitydomain="${evaluated.run.security.domain}" commandline="${platform.debugcommandline}" classpath="${platform.bootclasspath}:${dist.dir}/${dist.jar}" cmdoptions="${run.cmd.options}"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sequential&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sleep seconds="5"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;antcall target="nbdebug"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/sequential&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/parallel&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="post-clean"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;delete failonerror="false"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${platform.home}/simulator"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;include name="**/${name}*"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/include&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/delete&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;typedef resource="bb-ant-defs.xml" classpath="bb-ant-tools.jar" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;target name="bbbuild" description="blackberry build" depends="init" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;echo message="rapc build, dir=${dist.dir}"&amp;gt;&amp;lt;/echo&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir="${dist.dir}/bbant" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${dist.dir}/bbant/" noconvert="true"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;src&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;fileset file="${dist.dir}/${dist.jar}" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/src&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;jdp title="${app.title}" vendor="${app.vendor}" version="${app.version}" type="cldc" icon="${app.icon}" runonstartup="false" &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/jdp&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/rapc&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!-- sigtool jdehome="C:Program FilesResearch In MotionBlackBerry JDE 4.7.0" codfile="${dist.dir}/bbant/${name}.cod" password="" / --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;alx destdir="${dist.dir}/bbant" filename="${name}.alx"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;application id="${app.title}"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;codset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/codset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/application&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/alx&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;mkdir dir="${dist.dir}/bbant-final" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;jadtool input="${dist.dir}/bbant/${dist.jad}" destdir="${dist.dir}/bbant-final"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/jadtool&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy todir="${platform.home}/simulator" verbose="true"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;fileset dir="${dist.dir}/bbant"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name="**/${name}*"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/copy&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="bb-run" depends="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows XP"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dir="${platform.home}/simulator"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;executable="${platform.home}/simulator/${platform.device}.bat"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;failonerror="true" resolveExecutable="true"/&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="bb-debug" depends="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;delete file="${preprocessed.dir}/.timestamp"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;parallel&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;java jar="${platform.home}/bin/JDWP.jar" fork="true" dir="${platform.home}/bin"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;jvmarg value="-Xmx128M"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/java&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sequential&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sleep seconds="5"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;antcall target="nbdebug"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/sequential&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/parallel&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;/pre&gt;&lt;br /&gt;2. build.xml&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE project [&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!ENTITY bb-common SYSTEM "bb-build.xml"&amp;gt;&lt;br /&gt;]&amp;gt;&lt;br /&gt;&amp;lt;project name="helloLWUIT" default="jar" basedir="."&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;description&amp;gt;Builds, tests, and runs the project .&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;import file="nbproject/build-impl.xml"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.title" value="helloLWUIT" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.version" value="1" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.icon" &amp;nbsp; value="/icon.png" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.vendor" value="foo" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;amp;bb-common;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;/a&gt;&lt;/pre&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;3. source code project: helloLWUIT:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;a href="http://docs.google.com/leaf?id=0B3TGMRuLRen_NTJmNTYxOWUtYmJhYi00MDY4LWEyNTEtMjEzZGU3YzA2N2I3&amp;amp;hl=en&amp;amp;authkey=CLqUuuAH"&gt;Here&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;Environment requirements: please refer &lt;a href="http://lwuit.blogspot.com/2009/11/building-project-on-blackberry.html"&gt;Shai's blog for blackberry&lt;/a&gt; to set up the project environment&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=3555300218296290557&amp;amp;postID=879309585074523010" name="ref"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Next Steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Figure out how to debug blackberry application on the actual device inside NetBeans;&lt;/li&gt;&lt;li&gt;Make sure how to read attribute in the jad file in the BlackBerry CLDC application;&lt;/li&gt;&lt;li&gt;How to easier copy the customized attribute in the midlet jade file to the BlackBerry CLDC jad file.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;http://www.xenglobaltech.com/blackberry/index.php?option=com_content&amp;amp;view=article&amp;amp;id=45&amp;amp;Itemid=40&lt;/li&gt;&lt;li&gt;http://supportforums.blackberry.com/t5/Java-Development/Building-Blackberry-apps-with-Netbeans/td-p/431612&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-879309585074523010?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/879309585074523010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/06/debug-blackberry-application-inside.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/879309585074523010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/879309585074523010'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/06/debug-blackberry-application-inside.html' title='Debug BlackBerry Application Inside NetBeans'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-161771055486057714</id><published>2010-06-21T22:52:00.002-04:00</published><updated>2010-11-17T22:06:06.992-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Professional Devlelopers require professional managers</title><content type='html'>I realize that there are similarities between software developers and software managers:&lt;br /&gt;- Developers manage codes, managers manage people;&lt;br /&gt;- Developers resolve bugs in the codes, managers resolve bugs among the people;&lt;br /&gt;- A developer has to make decisions all the time, compromise his solution with different constraints; A manager has to make decision all the time based on people, schedule and budget;&lt;br /&gt;- A professional developer always choose the right framework and right tool for the task, a professional manager choose the right person to do the&amp;nbsp; right thing;&lt;br /&gt;- A professional developer improves his code by keep constantly refactoring and reflection, a professional manager keep improving his team;&lt;br /&gt;- A professional developer always follows the software principles and design patterns to guide his work, deliberately improve his skills, keep finding new tools;&amp;nbsp; A professional manager will follow the agile patterns and other principles and philosophy (ex. The Art Of War) to guide his work, his has the clear picture of his vision, and keep finding the new process to improve the productivity of his team.&lt;br /&gt;&lt;br /&gt;But in reality,&amp;nbsp; unfortunately in my career so far I haven't found a manager which I can regard as a professional manager.&amp;nbsp; Most of them I call them "event dispatcher". They&amp;nbsp; care more about passing the command down to developers, focus more on his boss instead of developers, they don't care how developer finish it nor be interested in it. I even could not find his strategy of management. I really want he can show me how he solved a difficult issue creatively and beautifully, just like I saw my coworker solve an issue by using a pattern or a tool, but so far I haven't seen once.&lt;br /&gt;&lt;br /&gt;Right now I know the reason why software industry is still primitive, why there are so many unprofessional developers, because most of our managers are unprofessional.&amp;nbsp; If a manger dos not know the principles and rules of software, how can he manage well for his team?&amp;nbsp; If a manager does not care his developer, how can his developer has motivation to become better?&lt;br /&gt;&lt;br /&gt;A good manager for a software team just as a good coach for a soccer team. Professional developers do require professional managers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-161771055486057714?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/161771055486057714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/06/professional-devlelopers-require.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/161771055486057714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/161771055486057714'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/06/professional-devlelopers-require.html' title='Professional Devlelopers require professional managers'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8192541391504942879</id><published>2010-05-27T23:03:00.006-04:00</published><updated>2010-06-02T23:51:17.598-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>LWUIT blackberry ANT script refactored 2</title><content type='html'>Last time I posted the &lt;a href="http://code-dojo.blogspot.com/2010/05/lwuit-blackberry-ant-script-refactored.html"&gt;refactored blackberry build script&lt;/a&gt;, today I made some other small improvements:&lt;br /&gt;&lt;br /&gt;1. Add a "run" target, support running both blackberry and regular J2ME simulator.&lt;br /&gt;&lt;pre&gt;&amp;lt;target name="run" depends="init,jar,bb-run,cldc-run"&amp;gt;&lt;br /&gt;     &lt;br /&gt;    &amp;lt;target name="cldc-run" unless="do.rapc" &amp;gt;&lt;br /&gt;       &amp;lt;nb-run jadfile="${dist.dir}/${dist.jad}" &lt;br /&gt;                  jarfile="${dist.dir}/${dist.jar}" jadurl="${dist.jad.url}" &lt;br /&gt;                  device="${platform.device}" platformhome="${platform.home}" &lt;br /&gt;                  platformtype="${platform.type}" &lt;br /&gt;                  execmethod="${run.method}" &lt;br /&gt;                  securitydomain="${evaluated.run.security.domain}" &lt;br /&gt;                  commandline="${platform.runcommandline}" &lt;br /&gt;                  classpath="${platform.bootclasspath}:${dist.dir}/${dist.jar}" &lt;br /&gt;                  cmdoptions="${run.cmd.options}"/&amp;gt;&lt;br /&gt;    &amp;lt;/target&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;target name="bb-run" depends="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;     &amp;lt;exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows XP"&lt;br /&gt;             dir="${platform.home}/simulator"&lt;br /&gt;            executable="${platform.home}/simulator/${platform.device}.bat"&lt;br /&gt;        failonerror="true" resolveExecutable="true"/&amp;gt;&lt;br /&gt;   &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&amp;nbsp;&amp;nbsp; The above code snipplet means, when user press "run" button in NetBeans IDE, if the current configuration is blackberry, then launch the blackberry simulator,&amp;nbsp;else launch the regular J2ME simulator.&lt;br /&gt;&lt;br /&gt;2. Separate the blackberry specific ant targets into aother build script file, make the build file generic and easier to use.&lt;br /&gt;At the beginning I tried to put all the targets in a separate file: bb-build.xml, then import it in the build.xml, but I found the netbeans custom targets&amp;nbsp;like post-init, post-jar are not called, it seems these targets needs to be explicit specified in the build.xml.&lt;br /&gt;I found another solution - embedding the xml snippet in the build.xml using XML entity, based on this &lt;a href="http://ant.apache.org/faq.html#xml-entity-include"&gt;link&lt;/a&gt;:&lt;br /&gt;&amp;nbsp;for exmaple, like this:&lt;br /&gt;&lt;pre&gt;&amp;lt;!DOCTYPE project [&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!ENTITY bb-common SYSTEM "bb-build.xml"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;]&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;amp;bb-common;&lt;br /&gt;&lt;/pre&gt;&amp;nbsp;The above snippet is equivlent of copying the code from bb-build.xml into build.xml. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Benefits:&lt;/b&gt;&lt;br /&gt;The new refactored build script becomes generic, does not specific to lwuit project, can apply to any blackberry CLDC app.&lt;br /&gt;&lt;br /&gt;I attach the full build script here, and you can use them as template for your blackberry build script in your NetBeans project.&lt;br /&gt;1) build.xml&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE project [&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!ENTITY bb-common SYSTEM "bb-build.xml"&amp;gt;&lt;br /&gt;]&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;project name="myApp" default="jar" basedir="."&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;description&amp;gt;Builds, tests, and runs the project .&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;import file="nbproject/build-impl.xml"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.title" value="myApp" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.version" value="1" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.icon" &amp;nbsp; value="/icon.png" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name="app.vendor" value="foo" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;amp;bb-common;&lt;br /&gt;&amp;nbsp;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2) bb-build.xml, the&amp;nbsp;blackberry build script snippet&lt;br /&gt;&lt;pre&gt;&amp;lt;target name="post-init"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;available file="${platform.home}/bin/rapc.exe" property="do.rapc" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;condition property="jpda.port" value="8000"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;isset property="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/isset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/condition&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="post-jar" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;lt;antcall target="bbbuild" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="run" depends="init,jar,bb-run,cldc-run"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;target name="cldc-run" unless="do.rapc" &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;nb-run jadfile="${dist.dir}/${dist.jad}" jarfile="${dist.dir}/${dist.jar}" jadurl="${dist.jad.url}" device="${platform.device}" platformhome="${platform.home}" platformtype="${platform.type}" execmethod="${run.method}" securitydomain="${evaluated.run.security.domain}" commandline="${platform.runcommandline}" classpath="${platform.bootclasspath}:${dist.dir}/${dist.jar}" cmdoptions="${run.cmd.options}"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="post-clean"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;delete failonerror="false"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${platform.home}/simulator"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;include name="**/${name}.*"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/include&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/delete&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;typedef resource="bb-ant-defs.xml" classpath="bb-ant-tools.jar" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;target name="bbbuild" description="blackberry build" depends="init" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;echo message="rapc build, dir=${dist.dir}"&amp;gt;&amp;lt;/echo&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir="${dist.dir}/bbant" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${dist.dir}/bbant/" noconvert="true"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;src&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;fileset file="${dist.dir}/${dist.jar}" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/src&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;jdp title="${app.title}" vendor="${app.vendor}" version="${app.version}" type="cldc" icon="${app.icon}" &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/jdp&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/rapc&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!-- sigtool jdehome="C:Program FilesResearch In MotionBlackBerry JDE 4.7.0" codfile="${dist.dir}/bbant/${name}.cod" password="" / --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;alx destdir="${dist.dir}/bbant" filename="${name}.alx"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;application id="${app.title}"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;codset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/codset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/application&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/alx&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;mkdir dir="${dist.dir}/bbant-final" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;jadtool input="${dist.dir}/bbant/${dist.jad}" destdir="${dist.dir}/bbant-final"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/jadtool&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy todir="${platform.home}/simulator" verbose="true"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset dir="${dist.dir}/bbant"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name="*.cod"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name="*.jad" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/copy&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="bb-run" depends="copyBBSimulator" if="do.rapc"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows XP"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dir="${platform.home}/simulator"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;executable="${platform.home}/simulator/${platform.device}.bat"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;failonerror="true" resolveExecutable="true"/&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Next Step:&lt;/b&gt;&lt;br /&gt;Add a target support debugging blackberry Application inside the NetBeans IDE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8192541391504942879?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8192541391504942879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/05/lwuit-blackberry-ant-script-refactored_27.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8192541391504942879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8192541391504942879'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/05/lwuit-blackberry-ant-script-refactored_27.html' title='LWUIT blackberry ANT script refactored 2'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6463774218075380485</id><published>2010-05-18T17:59:00.006-04:00</published><updated>2010-06-27T21:51:50.733-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>LWUIT BlackBerry ANT script refactored</title><content type='html'>My &lt;a href="http://code-dojo.blogspot.com/2010/05/ant-build-script-for-lwuit-blackberry.html"&gt;last article&lt;/a&gt; about using ANT script to build LWUIT blackberry application was intereted by some people, which is encouraging.&amp;nbsp;I spent some time to review the ant script again and made some improvements. Here I posted my updated build script, it is cleaner and easier to use,&amp;nbsp;you can just use it as template, copy and paste it in your NetBeans project by just configure some parameters.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;property name="app.title" value="helloLWUIT" /&amp;gt;&lt;br /&gt;    &lt;b&gt;&amp;lt;property name="app.version" value="1" /&amp;gt;&lt;br /&gt;    &amp;lt;property name="app.icon"   value="/icon.png" /&amp;gt;&lt;br /&gt;    &amp;lt;property name="app.vendor" value="foo" /&amp;gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;target name="post-init"&amp;gt;&lt;br /&gt;          &amp;lt;available file="${platform.home}/bin/rapc.exe" property="do.rapc" /&amp;gt;&lt;br /&gt;          &amp;lt;condition property="jpda.port" value="8000"&amp;gt;&lt;br /&gt;              &amp;lt;isset property="do.rapc"&amp;gt;&lt;br /&gt;              &amp;lt;/isset&amp;gt;&lt;br /&gt;         &amp;lt;/condition&amp;gt;&lt;br /&gt;    &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;   &amp;lt;target name="post-jar" if="do.rapc"&amp;gt;&lt;br /&gt;     &amp;lt;antcall target="bbbuild" /&amp;gt;&lt;br /&gt;   &amp;lt;/target&amp;gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&amp;lt;target name="post-clean"&amp;gt;&lt;br /&gt;   &amp;lt;delete failonerror="false"&amp;gt;&lt;br /&gt;      &amp;lt;fileset dir="${platform.home}/simulator"&amp;gt;&lt;br /&gt;       &amp;lt;include name="**/${name}.*"&amp;gt;&lt;br /&gt;       &amp;lt;/include&amp;gt;&lt;br /&gt;      &amp;lt;/fileset&amp;gt;&lt;br /&gt;   &amp;lt;/delete&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;typedef resource="bb-ant-defs.xml" classpath="bb-ant-tools.jar" /&amp;gt;&lt;br /&gt;  &amp;lt;target name="bbbuild" description="blackberry build" depends="init"&amp;gt;&lt;br /&gt;          &amp;lt;echo message="rapc build, dir=${dist.dir}"&amp;gt;&amp;lt;/echo&amp;gt;&lt;br /&gt;          &amp;lt;mkdir dir="${dist.dir}/bbant" /&amp;gt;&lt;br /&gt;          &amp;lt;rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${dist.dir}/bbant/" noconvert="true"&amp;gt;&lt;br /&gt;          &amp;lt;src&amp;gt;&lt;br /&gt;             &amp;lt;fileset file="${dist.dir}/${dist.jar}" /&amp;gt;&lt;br /&gt;          &amp;lt;/src&amp;gt;&lt;br /&gt;          &amp;lt;jdp title="&lt;b&gt;${app.title}&lt;/b&gt;" vendor="${&lt;b&gt;app.vendor}&lt;/b&gt;" version="&lt;b&gt;${app.version}&lt;/b&gt;" type="cldc" icon="&lt;b&gt;${app.icon}&lt;/b&gt;" &amp;gt;&lt;br /&gt;          &amp;lt;/jdp&amp;gt;&lt;br /&gt;          &amp;lt;/rapc&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;!-- sigtool jdehome="C:Program FilesResearch In MotionBlackBerry JDE 4.7.0" codfile="${dist.dir}/bbant/${name}.cod" password="" / --&amp;gt;&lt;br /&gt;        &amp;lt;alx destdir="${dist.dir}/bbant" filename="${name}.alx"&amp;gt;&lt;br /&gt;            &amp;lt;application id="${app.title}"&amp;gt;&lt;br /&gt;               &amp;lt;codset&amp;gt;&lt;br /&gt;                    &amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;                   &amp;lt;/fileset&amp;gt;&lt;br /&gt;               &amp;lt;/codset&amp;gt;&lt;br /&gt;           &amp;lt;/application&amp;gt;&lt;br /&gt;       &amp;lt;/alx&amp;gt;&lt;br /&gt;       &amp;lt;mkdir dir="${dist.dir}/bbant-final" /&amp;gt;&lt;br /&gt;       &amp;lt;jadtool input="${dist.dir}/bbant/${dist.jad}" destdir="${dist.dir}/bbant-final"&amp;gt;&lt;br /&gt;        &amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;        &amp;lt;/fileset&amp;gt;&lt;br /&gt;       &amp;lt;/jadtool&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="copyBBSimulator" depends="bbbuild" if="do.rapc"&amp;gt;&lt;br /&gt;    &amp;lt;copy todir="${platform.home}/simulator" verbose="true"&amp;gt;&lt;br /&gt;            &amp;lt;fileset dir="${dist.dir}/bbant"&amp;gt;&lt;br /&gt;                  &amp;lt;include name="*.cod"/&amp;gt;&lt;br /&gt;                  &amp;lt;include name="*.jad" /&amp;gt;&lt;br /&gt;            &amp;lt;/fileset&amp;gt;&lt;br /&gt;    &amp;lt;/copy&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="bb-run" depends="copyBBSimulator"&amp;gt;&lt;br /&gt;    &amp;lt;exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows XP"&lt;br /&gt;             dir="${platform.home}/simulator"&lt;br /&gt;            executable="${platform.home}/simulator/${platform.device}.bat"&lt;br /&gt;        failonerror="true" resolveExecutable="true"/&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It has following improvements:&lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;ol&gt;&lt;li&gt;Separate out the customized parameters in the build scriciptThen entire build script only needs following customized parameters: app.title, app.version, app.icon, app.vendor. You only need to configure them with your own application parameters.&lt;/li&gt;&lt;li&gt;Simplify the build script. &amp;nbsp;In the old build script, you have to use target "copyBBTouchSources" and "copyBBSources" to copy and update the LWUIT library source code&amp;nbsp;into specific folder, then call rapc compiler to build the entire application.&amp;nbsp;But when you investigate a little bit deeper, since NetBeans IDE already generate jar file for you, which already included the preprocessed application&amp;nbsp;and the LWUIT blackbery library class files, why not just pass this jar file to rapc and then generate the cod file?&amp;nbsp;based on this idea, I modified the target "bbbuild" and it works.&lt;/li&gt;&lt;li&gt;One build script supports both BlackBerry touch and non-touch build. since the build script is simplified and only use jar file to generate cod file,the touch or non-touch specific files are already embedded in the jar file, the build script itself becomes generic.&amp;nbsp;To tested it, I installed JDE 4.5 and JDE 4.7 two different JDE in the NetBeans, and set up 4.5 and 4.7 different configurations in my project,&amp;nbsp;and I found both works.&lt;/li&gt;&lt;li&gt;Added the ant target "bb-run", which allow you run the application in the blackberry simulator.&amp;nbsp;To make it work, you had better to check the&lt;b&gt; nbproject\project.properties&lt;/b&gt; file, if the simualtor device name is configured properly, In JDE 4.7, the device name is 9500, like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;configs.BlackBerryTouch.platform.device=9500&lt;/pre&gt;In 4.5, the device name is 8320, like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;configs.BlackBerry.platform.device=8320&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Update: Sample project&lt;br /&gt;Please click &lt;a href="http://docs.google.com/leaf?id=0B3TGMRuLRen_NTJmNTYxOWUtYmJhYi00MDY4LWEyNTEtMjEzZGU3YzA2N2I3&amp;amp;hl=en&amp;amp;authkey=CLqUuuAH"&gt;here&lt;/a&gt; to download the sample project.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6463774218075380485?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6463774218075380485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/05/lwuit-blackberry-ant-script-refactored.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6463774218075380485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6463774218075380485'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/05/lwuit-blackberry-ant-script-refactored.html' title='LWUIT BlackBerry ANT script refactored'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1345845185340355357</id><published>2010-05-04T20:58:00.002-04:00</published><updated>2010-11-17T22:08:23.588-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Why should managers embrace agile?</title><content type='html'>When you look at the articles about Agile/Scrum/Lean, they are all about &lt;b&gt;self-organizing, decentralized, democracy&lt;/b&gt;, etc.Those are welcomed by the developers but conflict with managers benefit, because our conventional management is about hierarchy, command and control, chasing the power, the manager cares more about how his boss think instead of how his subordinates think. For managers, embracing agile means loosing power, weaken their benefit, that is why manager don't like agile.&lt;br /&gt;On the other hand, agile is about changing, changing means risky, but the managers care more about the stability of their position, their power, they don't have much enthusiasm to make changes. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;So we have a conclusion that developer and manager like two different classes, developers like agile because it brings them benefits; managers dislike agile because it will lose managers' benefit. The progress of agile movement is quite similar with the progress of human's democracy movement. &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This sounds discouraging, but this is the fact, that will explain why agile has not become mainstream after 10 years of its movement.Then what can we do? Try to educate as many developers as possible, gradually if agile principles are accepted by most people, then it is quite possible to force the managers make changes. This will take time, but please remember that the manager won't truely embrace agile,just like no ruler will truely embrace democracy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1345845185340355357?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1345845185340355357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/05/why-should-managers-embrace-agile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1345845185340355357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1345845185340355357'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/05/why-should-managers-embrace-agile.html' title='Why should managers embrace agile?'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8831769887919846945</id><published>2010-05-01T22:49:00.003-04:00</published><updated>2011-11-01T10:17:55.009-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>ANT build script for LWUIT blackberry application</title><content type='html'>&lt;b&gt;Update:&lt;/b&gt;&lt;br /&gt;&amp;nbsp; This article is more than a year old, now LWUIT project uses a new tool to build BlackBerry application - NetBeans BlackBerry Plugin, please refer my two latest post:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #222222; font-family: Georgia, Utopia, 'Palatino Linotype', Palatino, serif; line-height: 19px;"&gt;&lt;a href="http://code-dojo.blogspot.com/2011/08/developing-blackberry-application-using.html"&gt;Developing Blackberry application using NetBeans Plugin - part 1, first impression&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #222222; font-family: Georgia, Utopia, 'Palatino Linotype', Palatino, serif; line-height: 19px;"&gt;&lt;a href="http://code-dojo.blogspot.com/2011/09/developing-blackberry-application-using.html"&gt;Developing Blackberry application using NetBeans Plugin - part 2, fixing debug issue&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lwuit.blogspot.com/2009/11/building-project-on-blackberry.html"&gt;Shai's article&lt;/a&gt; about build script for LWUIT in BlackBerry is great, but it has so many errors,I spend two days trying to fix the errors, and finally make it work.&lt;br /&gt;&lt;br /&gt;Here I posted my modified ant buil.xml and application source code. The application is very simple, just display a "Hello World" text.&amp;nbsp;Since this article is based on &lt;a href="http://lwuit.blogspot.com/2009/11/building-project-on-blackberry.html"&gt;Shai's article&lt;/a&gt;, for details such as project set up, configuration and tools installation etc, please check his article.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;application source code&lt;/b&gt;&lt;br /&gt;HelloLWUITMidlet.java&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import com.sun.lwuit.Display;&lt;br /&gt;import com.sun.lwuit.Form;&lt;br /&gt;import com.sun.lwuit.Label;&lt;br /&gt;import com.sun.lwuit.layouts.BorderLayout;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class HelloLWUITMidlet extends&lt;br /&gt;//#ifdef RIM&lt;br /&gt;     net.rim.device.api.ui.UiApplication&lt;br /&gt;//#else&lt;br /&gt;//#      javax.microedition.midlet.MIDlet&lt;br /&gt;//#endif&lt;br /&gt; {&lt;br /&gt;    public void startApp() {&lt;br /&gt;&lt;br /&gt;        Display.init(this);&lt;br /&gt;        Form f = new Form();&lt;br /&gt;        f.setTitle("Hello World");&lt;br /&gt;        f.setLayout(new BorderLayout());&lt;br /&gt;        f.addComponent("Center",&lt;br /&gt;        new Label("I am a Label"));&lt;br /&gt;        f.show();&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;//#ifdef BlackBerry&lt;br /&gt;   public static void main(String[] argv)&lt;br /&gt;   {&lt;br /&gt;       new HelloLWUITMidlet().startApp();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void notifyDestroyed()&lt;br /&gt;   {&lt;br /&gt;       System.exit(0);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void platformRequest(String s) {&lt;br /&gt;      net.rim.blackberry.api.browser.Browser.getDefaultSession().displayPage(s);&lt;br /&gt;     }&lt;br /&gt;//#endif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    public void pauseApp() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void destroyApp(boolean unconditional) {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;ANT build script&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;!-- You may freely edit this file. See commented blocks below for --&amp;gt;&lt;br /&gt;&amp;lt;!-- some examples of how to customize the build. --&amp;gt;&lt;br /&gt;&amp;lt;!-- (If you delete it and reopen the project it will be recreated.) --&amp;gt;&lt;br /&gt;&amp;lt;project name="helloLWUIT" default="jar" basedir="."&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;Builds, tests, and runs the project .&amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;import file="nbproject/build-impl.xml"/&amp;gt;&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;   &lt;br /&gt;     &amp;lt;target name="post-init"&amp;gt;&lt;br /&gt;        &amp;lt;available file="${platform.home}/bin/rapc.exe" property="do.rapc" /&amp;gt;&lt;br /&gt;        &amp;lt;available file="${platform.home}/simulator/9500.bat" property="bbtouch" /&amp;gt;&lt;br /&gt;        &amp;lt;condition property="jpda.port" value="8000"&amp;gt;&lt;br /&gt;           &amp;lt;isset property="do.rapc"&amp;gt;&lt;br /&gt;           &amp;lt;/isset&amp;gt;&lt;br /&gt;        &amp;lt;/condition&amp;gt;&lt;br /&gt;     &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;br /&gt;        &amp;lt;target name="post-preprocess" depends="copyBBSources,copyBBTouchSources"&amp;gt;&lt;br /&gt;        &amp;lt;/target&amp;gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;       &amp;lt;typedef resource="bb-ant-defs.xml" classpath="bb-ant-tools.jar" /&amp;gt;&lt;br /&gt;       &amp;lt;target name="bbbuild" description="blackberry build" depends="init,copyBBSources,copyBBTouchSources"&amp;gt;&lt;br /&gt;          &amp;lt;echo message="Compiling ${preprocessed.dir}"&amp;gt;&amp;lt;/echo&amp;gt;&lt;br /&gt;          &amp;lt;mkdir dir="${dist.dir}/bbant" /&amp;gt;&lt;br /&gt;          &amp;lt;rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${dist.dir}/bbant/" noconvert="true"&amp;gt;&lt;br /&gt;          &amp;lt;src location="${basedir}/${preprocessed.dir}"&amp;gt;&lt;br /&gt;          &amp;lt;/src&amp;gt;&lt;br /&gt;          &amp;lt;jdp title="&lt;b&gt;helloLWUIT&lt;/b&gt;" version="1" type="cldc" icon="/icon.png" &amp;gt;&lt;br /&gt;          &amp;lt;/jdp&amp;gt;&lt;br /&gt;          &amp;lt;/rapc&amp;gt;&lt;br /&gt;          &lt;br /&gt;        &amp;lt;!-- sigtool jdehome="C:\Program Files\Research In Motion\BlackBerry JDE 4.7.0" codfile="${dist.dir}/bbant/${name}.cod" password="" / --&amp;gt;&lt;br /&gt;        &amp;lt;alx destdir="${dist.dir}/bbant" filename="${name}.alx"&amp;gt;&lt;br /&gt;        &amp;lt;application id="&lt;b&gt;helloLWUIT&lt;/b&gt;"&amp;gt;&lt;br /&gt;       &amp;lt;codset&amp;gt;&lt;br /&gt;        &amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;       &amp;lt;/fileset&amp;gt;&lt;br /&gt;       &amp;lt;/codset&amp;gt;&lt;br /&gt;       &amp;lt;/application&amp;gt;&lt;br /&gt;       &amp;lt;/alx&amp;gt;&lt;br /&gt;&lt;br /&gt;      &lt;br /&gt;       &amp;lt;mkdir dir="${dist.dir}/bbant-final" /&amp;gt;&lt;br /&gt;       &amp;lt;jadtool description="&lt;b&gt;desc&lt;/b&gt;" id="&lt;b&gt;appId&lt;/b&gt;" input="${dist.dir}/bbant/${dist.jad}" destdir="${dist.dir}/bbant-final"&amp;gt;&lt;br /&gt;        &amp;lt;fileset dir="${dist.dir}/bbant" includes="*.cod"&amp;gt;&lt;br /&gt;        &amp;lt;/fileset&amp;gt;&lt;br /&gt;       &amp;lt;/jadtool&amp;gt;&lt;br /&gt;       &lt;br /&gt;      &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="copyBBTouchSources" if="bbtouch"&amp;gt;&lt;br /&gt; &amp;lt;echo message="Copying blackberry touch sources"&amp;gt;&amp;lt;/echo&amp;gt;&lt;br /&gt; &amp;lt;copydir forceoverwrite="true" src="${project.BlackberryPort}/build/touch/preprocessed" dest="${basedir}/${preprocessed.dir}" /&amp;gt;&lt;br /&gt; &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/M3G.java" /&amp;gt;&lt;br /&gt; &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/SVGImage.java" /&amp;gt;&lt;br /&gt; &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/animations/Transition3D.java" /&amp;gt;&lt;br /&gt; &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/impl/midp/SVGImplementation.java" /&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="copyBBSources" if="do.rapc"&amp;gt;&lt;br /&gt;   &amp;lt;echo message="Copying blackberry sources ${preprocessed.dir}"&amp;gt;&amp;lt;/echo&amp;gt;&lt;br /&gt;   &amp;lt;copydir src="${project.LWUIT}/src" dest="${basedir}/${preprocessed.dir}" /&amp;gt;&lt;br /&gt;   &amp;lt;copydir forceoverwrite="true" src="${project.BlackberryPort}/build/preprocessed" dest="${basedir}/${preprocessed.dir}" /&amp;gt;&lt;br /&gt;   &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/M3G.java"/&amp;gt;&lt;br /&gt;   &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/SVGImage.java"/&amp;gt;&lt;br /&gt;   &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/animations/Transition3D.java"/&amp;gt;&lt;br /&gt;   &amp;lt;touch file="${basedir}/${preprocessed.dir}/com/sun/lwuit/impl/midp/SVGImplementation.java"/&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;target name="post-jar" if="do.rapc"&amp;gt;&lt;br /&gt;   &amp;lt;rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${platform.home}/simulator/" noconvert="true"&amp;gt;&lt;br /&gt;     &amp;lt;src location="${basedir}/${preprocessed.dir}"&amp;gt;&lt;br /&gt;     &amp;lt;/src&amp;gt;&lt;br /&gt;     &lt;br /&gt;     &amp;lt;jdp title="&lt;b&gt;helloLWUIT&lt;/b&gt;" version="&lt;b&gt;1&lt;/b&gt;" type="cldc" icon="/icon.png" &amp;gt;&lt;br /&gt;     &amp;lt;/jdp&amp;gt;&lt;br /&gt;   &amp;lt;/rapc&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;target name="post-clean"&amp;gt;&lt;br /&gt;    &amp;lt;delete failonerror="false"&amp;gt;&lt;br /&gt;       &amp;lt;fileset dir="${platform.home}/simulator"&amp;gt;&lt;br /&gt;        &amp;lt;include name="**/${name}.*"&amp;gt;&lt;br /&gt;        &amp;lt;/include&amp;gt;&lt;br /&gt;       &amp;lt;/fileset&amp;gt;&lt;br /&gt;    &amp;lt;/delete&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note:&lt;br /&gt;This build script is for touch screen build, for non touch sreen build you need to&lt;br /&gt;1.Comment out "bbtouch" property in target "post-init" :&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&amp;lt;!-- &amp;lt;available file="${platform.home}/simulator/9500.bat" property="bbtouch"&amp;gt; &amp;nbsp;--&amp;gt; &amp;lt;/available&amp;gt;&lt;/span&gt;&lt;br /&gt;2.Remove the "copyBBTouchSources" dependency in target &amp;nbsp;"bbbuild".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8831769887919846945?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8831769887919846945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/05/ant-build-script-for-lwuit-blackberry.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8831769887919846945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8831769887919846945'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/05/ant-build-script-for-lwuit-blackberry.html' title='ANT build script for LWUIT blackberry application'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6724850660975963637</id><published>2010-04-21T22:39:00.002-04:00</published><updated>2010-07-05T22:54:13.509-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Build LWUIT BlackBerry CLDC application</title><content type='html'>Last week finally I have time to review the &lt;a href="http://lwuit.blogspot.com/2009/11/building-project-on-blackberry.html"&gt;Shai's blog&lt;/a&gt; &amp;nbsp;about building LWUIT project on Blackberry platform.&amp;nbsp;At first I tried to follow the step by step in his article, but I am &amp;nbsp;disappointed because of so many errors of his build.xml.&amp;nbsp;After a couple hours fix, I still could not make the build, so I decided to give up Shai's script,&amp;nbsp;and choose an easier way.&lt;br /&gt;My solution is just using NetBeans and BlackBerry JDE, it is much easier to build a demo.&lt;br /&gt;Here is the step by step description:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Build LWUIT BlackBerry library&lt;/span&gt;&lt;br /&gt;1. Checkout the LWUIT source code from SVN, (https://lwuit.dev.java.net/svn/lwuit/trunk),&amp;nbsp;the LWUIT source includes the NetBeans BlackBerry port project.&lt;br /&gt;2. Install JDE 4.7 and Configure BlackBerry support in NetBeans, you can follow this &lt;a href="http://www.naviina.eu/wp/blackberry/blackberry-api-in-netbeans-6-7/"&gt;link&lt;/a&gt;&amp;nbsp;to configure;&lt;br /&gt;3. Start NetBeans, open the "BlackBerryPort" poject under the "BlackBerry" sub folder of lwuit project source,&amp;nbsp;there are two configuration for this project, the default is for non touch screen build, the "touch" configuration is for touch screen device like STORM.for non touch device, just choose DefaultConfiguration, build the project, you will see BlackberryPort.jad and BlackberryPort.jar in \dist folder, they are the LWUIT library for&amp;nbsp;BlackBerry devices;&lt;br /&gt;&lt;br /&gt;B&lt;b&gt;uild LWUIT Demo into BlackBerry CLDC application&lt;/b&gt;&lt;br /&gt;1. Open Blackberry JDE, create a new workspace, called "lwuitdemo.jdw";&lt;br /&gt;2. add a new project under the workspace, name it "lwuit", &amp;nbsp;choose its Application type as "Library", import the BlackberryPort.jad and BlackBerryPort.jar file into the project. then&amp;nbsp;build it, the JDE will generate lwuit.cod and update BlackBerryPort.jad file. &amp;nbsp; &lt;br /&gt;3. download LWUIT 1.3 from &lt;a href="http://java.sun.com/javame/technology/lwuit/"&gt;sun website&lt;/a&gt;, it comes with the famous LWUITDemo source code, open the LWUITDemo project using NetBeans,&amp;nbsp;build it;&lt;br /&gt;4. add another new project in the JDE workspace, name it "lwuitdemo", choose application type as "CLDC Application";&lt;br /&gt;&amp;nbsp;&amp;nbsp; set up the correct value with title, version and Vendor information;&lt;br /&gt;&amp;nbsp;&amp;nbsp; next you need to add project dependency to "lwuit" project, right click project, choose "Project Dependencies..", choose "lwuit project";&lt;br /&gt;&amp;nbsp;&amp;nbsp; copy all the java source code from LWUITDemo src folder, add them into the project, ignore those png files and .res files;&lt;br /&gt;&amp;nbsp;&amp;nbsp; go to &amp;nbsp;build\preverified folder, copy all the png files and .res files, add them into your JDE project;&lt;br /&gt;&amp;nbsp;&amp;nbsp; right click icon.png, choose "use as application icon";&lt;br /&gt;5.Modify the UIDemoMIDlet.java&lt;br /&gt;Made following changes:&lt;br /&gt;make sure the UIDemoMIDlet extends from uiApplication, like this:   &lt;br /&gt;&lt;pre&gt;public class UIDemoMIDlet extends net.rim.device.api.ui.UiApplication  {...}&lt;br /&gt;&lt;/pre&gt;Add the following methods, copied from Shai's blog:&lt;br /&gt;&lt;pre&gt;public static void main(String[] argv)&lt;br /&gt;    {&lt;br /&gt;        new UIDemoMIDlet().startApp();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public void notifyDestroyed()&lt;br /&gt;    {&lt;br /&gt;        System.exit(0);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public void platformRequest(String s) {&lt;br /&gt;       net.rim.blackberry.api.browser.Browser.getDefaultSession().displayPage(s);&lt;br /&gt;    }&lt;br /&gt;    &lt;/pre&gt;In startApp() method, comment out the following statement, because non touch device need to disable the virtual keypad:&lt;br /&gt;&lt;pre&gt;// VKBImplementationFactory.init();&lt;br /&gt;&lt;/pre&gt;6. Build the lwuitdemo project.&lt;br /&gt;7. Sign both lwuitdemo.cod and lwuit.cod fle, load them both into your blackberry device.&lt;br /&gt;8. If you want to provide OTA download, that is a litttle bit tricky:&lt;br /&gt;&amp;nbsp;&amp;nbsp; You need to download two artifacts, one for lwuit libray, the other for lwuitdemo, which means user need to download two links:&lt;br /&gt;&amp;nbsp;&amp;nbsp; 1) lwuti library:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;BlackBerryPort.jad&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;lwuit.cod&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;lwuit-1.cod&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp; 2) lwuitdemo application:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;lwuitdemo.jad&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;lwuitdemo.cod&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;lwuitdemo-1.cod&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can download the whole source code of the JDE project from &lt;a href="http://docs.google.com/leaf?id=0B3TGMRuLRen_NDQyNmQ1Y2QtZmExMi00ZTEwLWFiZDYtMDE2NzU5YjM0NDA0&amp;amp;hl=en"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In future I would like to share:&lt;br /&gt;&amp;nbsp;&amp;nbsp;1. Provide an updated build.xml based on Shai's blog;&lt;br /&gt;&amp;nbsp;&amp;nbsp;2. provide how to build LWUITDemo MIDlet project for BlackBerry device.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-6724850660975963637?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6724850660975963637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/04/build-lwuit-blackberry-cldc-application.html#comment-form' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6724850660975963637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6724850660975963637'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/04/build-lwuit-blackberry-cldc-application.html' title='Build LWUIT BlackBerry CLDC application'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8025106451182140976</id><published>2010-04-08T22:00:00.050-04:00</published><updated>2010-04-08T22:50:19.455-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>How to send email  in BlackBerry Simulator</title><content type='html'>Recently I am working on a BlackBerry Email app, I need to setup a test environment so I can test mail send in the BlackBerry simulator.&lt;br /&gt;I did some research, I read the RIM related document it does not help, then I find a solution from a good book about blackberry - &lt;a href="http://www.amazon.com/Advanced-BlackBerry-Development-Chris-King/dp/1430226560/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1270694756&amp;amp;sr=8-1"&gt;Advanced BlackBerry Development&lt;/a&gt;, by Chris King.&lt;br /&gt;I just follow the method from the book , and finally get it working, the solution is quite straight forward.&lt;br /&gt;&lt;br /&gt;You need BlackBerry ESS ( Email Server Simulator) in order to simulate mail from your simulator, it comes with the JDE SDK and JDE component, currently I used JDK 4.5 , I prefer it because it's simulator is much faster to launch.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_lxmigwrwDfI/S76UyY3mjHI/AAAAAAAAAC8/jwEpc99li0s/s1600/ess.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_lxmigwrwDfI/S76UyY3mjHI/AAAAAAAAAC8/jwEpc99li0s/s320/ess.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There are two mode you can choose - Connected mode or Standalone mode.&lt;br /&gt;I tired the connected mode, it does not working.&lt;br /&gt;The book recommend using the Standalone mode: &amp;nbsp;ESS will listen the localhost port, send out email to your smtp email client. If you set up your email client, choose localhost as server address, and configure the same pop3 and smtp port as ESS configured, your email client will receive the email.&lt;br /&gt;&amp;nbsp;Choose "Standandalone mode", &amp;nbsp;set Pop3 port and Smtp port, &amp;nbsp;I choose default value, which are 995 and 465.&lt;br /&gt;Click Launch, the ESS will start, and you will say a dos command window displaying the server log information.&lt;br /&gt;&lt;br /&gt;Then we need to configure your email client, &amp;nbsp;I choose OutLook Express.&lt;br /&gt;Add a new account, &amp;nbsp;you can set up any email address,&lt;br /&gt;Set localhost &amp;nbsp;for both SMTP and POP3 server.&lt;br /&gt;for POP3 port number ,use the same value of ESS: 465&lt;br /&gt;for SMTP port number, use the same value of ESS:995&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lxmigwrwDfI/S76U0wa6oPI/AAAAAAAAADE/fDNPgHtkek8/s1600/outlook_express_1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_lxmigwrwDfI/S76U0wa6oPI/AAAAAAAAADE/fDNPgHtkek8/s320/outlook_express_1.PNG" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_lxmigwrwDfI/S76U34WizsI/AAAAAAAAADM/1x4K1UyEFew/s1600/outlook_express_2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_lxmigwrwDfI/S76U34WizsI/AAAAAAAAADM/1x4K1UyEFew/s320/outlook_express_2.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;So far the configuration is finished, all you can do is launching the simulator.&lt;br /&gt;You can start the blackberry email client, type any address, &amp;nbsp;then send. &amp;nbsp;Check your OutLook Express, you will find an incoming email.&lt;br /&gt;And you can write an email from your outlook express, type any address, then send it. &amp;nbsp;You will find the email in your blackberry simulator.&lt;br /&gt;The only drawback is you can only send and receive email from your local machine. which is not real, but it is good enough to test the mail function in the simulator.&lt;br /&gt;It is really good, I tested over 100 email using the solution above.&lt;br /&gt;Finally I want to talk about a little about the book, it covers many good topics, such as BES, BIS which confuses me for a long time. &amp;nbsp;Even I haven't finished it, but I think it is one of the best &amp;nbsp;blackberry book so far.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8025106451182140976?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8025106451182140976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/04/how-to-send-email-in-blackberry.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8025106451182140976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8025106451182140976'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/04/how-to-send-email-in-blackberry.html' title='How to send email  in BlackBerry Simulator'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lxmigwrwDfI/S76UyY3mjHI/AAAAAAAAAC8/jwEpc99li0s/s72-c/ess.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4156601696237546190</id><published>2010-03-15T23:40:00.000-04:00</published><updated>2010-03-15T23:40:35.135-04:00</updated><title type='text'>My mistakes to the J2ME Location API</title><content type='html'>Last week when I tried to test the location API for J2ME devices, I made big mistakes.&lt;br /&gt;The 2 devices I tested are: NOKIA N93 and BlackBerry 8320. Actually I don't have any experience for J2ME location API before.Before testing, I checked the spec of these two devices, they both support Location API - JSR 179, so I thought they both have GPS receiver,but when I tested several location applications on theses two devices and even simple demos, none of them works on either devices: N93 keep looking for Blue tooth devices, and then pop up Location exception or pop up timeout exception; while the applications in blackberry keep hanging no response.&lt;br /&gt;&lt;br /&gt;I spent the whole afternoon trying to make them works, but no luck. Finally I googled them again, then I found that these two devices do not have internal GPS receiver! They support location API means they need external blue tooth GPS receiver!!! Which explains why N93 keeps looking for blue tooth devices.&lt;br /&gt;&lt;br /&gt;So I learned that even if a device supports Location API does not means it has GPS, then it means there is no way to check a device supports GPS or not via programmatic way, because it is impossible to distinguish if a device has built-in GPS with a device without GPS.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;A solution for non GPS Blackberry devices&lt;/b&gt;&lt;br /&gt;Another reason I made the mistakes is because I saw the Google Map works perfectly in my 8320 devices. Now I understand it might use cell id to get the location information.This will give the developer another hint to enable the loation service to the non GPS blackberry phones.&lt;br /&gt;&lt;br /&gt;I found a open source project: &lt;a href="http://www.opencellid.org/"&gt;OpenCellId&lt;/a&gt;, which maintain a cell id database, so you can query your location by providing your device's cell id.&lt;br /&gt;Here is the &lt;a href="http://www.opencellid.org/api"&gt;API&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I checked the &lt;a href="http://www.blackberry.com/developers/docs/4.3.0api/net/rim/device/api/system/GPRSInfo.html"&gt;BlackBerry API&lt;/a&gt;, it has a GPRSInfo class, which provides the GPRSCellInfo class,  GPRSCellInfo contains all the cell id information you have.&lt;br /&gt;You can use the following code snippet to get the cell id:&lt;br /&gt;&amp;nbsp;&amp;nbsp; import net.rim.device.api.system.GPRSInfo;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ... &lt;br /&gt;&amp;nbsp;&amp;nbsp; int cellId = GPRSInfo.getCellInfo().getCellId();&lt;br /&gt;You can also get MNC, MCC, LAC, RAC etc. &lt;br /&gt;With these information, you can use OpenCellId to retrieve your location. &lt;br /&gt;&lt;br /&gt;This sounds interesting, I haven't try it yet, I am sure I will check it in future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4156601696237546190?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4156601696237546190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/03/my-mistakes-to-j2me-location-api.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4156601696237546190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4156601696237546190'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/03/my-mistakes-to-j2me-location-api.html' title='My mistakes to the J2ME Location API'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2300152640490734509</id><published>2010-02-07T22:25:00.007-05:00</published><updated>2010-02-07T22:31:02.459-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Software Quality:  internal vs. external</title><content type='html'>Let's check following questions:&lt;br /&gt;1)How to define the quality of a software product?&lt;br /&gt;2)Is a bug free software a high quality software?&lt;br /&gt;3)Is software quality determined by QA testing?&lt;br /&gt;4)Can QA testing help improve the quality?&lt;br /&gt;&lt;br /&gt;The software quality can be divided into two parts: &lt;b&gt;external and internal.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;External quality&lt;/b&gt; is explicit, transparent and easy for user to experience, easy to test, the bug can be easily found;&lt;br /&gt;&lt;b&gt;Internal quality&lt;/b&gt; is implicit, it is hard to describe and visualize by the end user, but it is the true quality of the software, usually related clarity, flexibility, maintainability, readability etc, it is a gene of a software.&lt;br /&gt;&lt;b&gt;The relationship between external and internal quality like a iceberg: external quality is above the water, while most of the stuff under the water are belong to internal quality.&lt;/b&gt;&lt;br /&gt;We say that Internal quality determines the external quality:&lt;br /&gt;If internal quality is good, then external quality are also good,&lt;br /&gt;If we found more external bugs, then there must be more internal bugs, we just haven't found them yet.&lt;br /&gt;&lt;br /&gt;Now we can answer question 1) and 2):&lt;br /&gt;To determine a software is high quality or not, the most important is how much it can add value to customer, which is based on its internal quality; if it does not bring much value, even if it is no bug, still it can not be treated as a high quality software, because it is useless.&lt;br /&gt;&lt;br /&gt;To answer question 3) and 4), Let's check another metaphor:&lt;br /&gt;A human being is healthy is determined by his internal physical condition,or his gene, not by the physical examination. The annual checkup will give you a feedback of your body. The testing itself does not improve your body condition.&lt;br /&gt;So the answer will be: the internal quality determine the software quality; the QA testing just give the feedback of the quality, itself can not improve the quality.&lt;br /&gt;&lt;br /&gt;We just pay too much attention on the external quality, but ignore the internal quality; &lt;b&gt;if we want to truly improve the software quality, we need to pay more attention on the internal quality, pay attention on external quality is too late and not efficient.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to measure the internal quality? How to improve the transparency and visualize the internal quality?&lt;/b&gt;&lt;br /&gt;Static analysis tool can tell you how good your code is.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to improve the internal quality?&lt;/b&gt;&lt;br /&gt;Use iterative development process, encourage team reflection, keep constantly refactoring, code review, use design patterns, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2300152640490734509?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2300152640490734509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/02/software-quality-internal-vs-external.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2300152640490734509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2300152640490734509'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/02/software-quality-internal-vs-external.html' title='Software Quality:  internal vs. external'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1174185654715286396</id><published>2010-01-30T23:04:00.002-05:00</published><updated>2010-01-30T23:11:15.952-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Focus on Workflow instead of plans</title><content type='html'>Recently I watch the Mary Poppendieck's video&lt;a href="http://www.infoq.com/presentations/tyranny-of-plan"&gt; "The tyranny of the plan"&lt;/a&gt;, which is another good video about agile. The key point of the presentation is - &lt;b&gt;Focus on the workflow instead of the detailed plans&lt;/b&gt;&lt;br /&gt;I put some of the notes here:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3 main principles:&lt;/b&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&amp;nbsp;Design the system to&lt;b&gt; meet the constraints&lt;/b&gt;; do not derive constraints from the design.&lt;/li&gt;&lt;li&gt;&amp;nbsp;Decouple workflows; break dependencies!&lt;/li&gt;&lt;li&gt;Workflows are easier to control &amp;amp; more predictable than a schedules.&lt;/li&gt;&lt;/ol&gt;Mary used the Empire building example is used to support the principles:&lt;br /&gt;&amp;nbsp;&amp;nbsp; Start with the constraints, then design the system to meet the constraints;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;design based on the schedule (constraints);&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;schedule does not depend on the detailed design.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;What I learned is that the system design depends on constraints, which might be resource, schedule and cost, etc. while schedule should not depend on design. This is a 180 degree reverse of the mindset change.&lt;br /&gt;&amp;nbsp;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;The problems of the schedules.&lt;/b&gt;&lt;br /&gt;We need schedules because:&lt;br /&gt;&amp;nbsp;-&amp;nbsp; To control when things happen, but&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Detailed schedules are &lt;b&gt;deterministic&lt;/b&gt; and do not allow for &lt;b&gt;normal variation&lt;/b&gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Managing a level workflow is a lot easier than following a deterministic schedule.&lt;br /&gt;&amp;nbsp;-&amp;nbsp; To predict when things will happen, but&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Schedules based on experience are reliable; if it is based on &lt;b&gt;wishful thinking&lt;/b&gt; are not&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; When reality does not match the schedule -&amp;nbsp; &lt;b&gt;the schedule hypothesis was dis-proven!&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;The workflow is more flexible, always updated based on the situation, &lt;b&gt;"plan is bad, planning is good"&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pull scheduling&lt;/b&gt;&lt;br /&gt;&amp;nbsp;Mary also mentioned the pull scheduling, pull scheduling is time-boxed:&lt;br /&gt;&amp;nbsp;don't scope box,&amp;nbsp; &lt;b&gt;don't ask how long will this take, ask what can we done by this date?&lt;/b&gt;&lt;br /&gt;&amp;nbsp;I think which is the concept from Lean/Kanban. I will check it in detail later.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Resources:&lt;br /&gt;&amp;nbsp;1. &lt;a href="http://www.infoq.com/presentations/tyranny-of-plan"&gt;Presentation video&lt;/a&gt;&lt;br /&gt;&amp;nbsp;2.&lt;a href="http://www.ukleanconference.com/files/mary_presentation.pdf"&gt; PPT&lt;/a&gt;, which is different from the presentation, but actual concepts are same.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1174185654715286396?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1174185654715286396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/01/focus-on-workflow-instead-of-plans.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1174185654715286396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1174185654715286396'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/01/focus-on-workflow-instead-of-plans.html' title='Focus on Workflow instead of plans'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8131095272472682307</id><published>2010-01-26T22:22:00.004-05:00</published><updated>2010-02-10T18:28:06.381-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><title type='text'>My Vision of the future mobile platform framework</title><content type='html'>Develop a mobile application is painful, develop a portable mobile application is really hard. I've been a mobile developer for many years, and I am struggling many years to make them portable to different platforms. To deal with fragmentation, which is the nature of mobile platform, my vision of the future mobile platform framework would be:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Support multiple platforms&lt;/b&gt;&lt;br /&gt;support J2ME, iPhone, android, blackberry, Windows Mobile, etc. One solution supports multiple platform, which will makes our life much easier.&amp;nbsp; I hope new new framework will provide a more abstraction layer, then developer can only write one piece of code can support all.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Separation of concerns&lt;/b&gt;&lt;br /&gt;- Separate platform independent logic from platform specific logic&lt;br /&gt;- Separate application logic from specific user interface&lt;br /&gt;The platform specific logic should be encapsulated as component modules, and developer should not care more about their details. Think about the IC and drivers, our mobile application is like a computer mother board which plug different cards and installing different drivers.&lt;br /&gt;The concept of separation of concern reminds me of how GIS works, GIS map is composed of maps in different layer, each layer map focuses on a specific concern, same as the mobile application, the mobile app will be composed of different layers, UI layer, business logic layer, model layer, etc. And each layer can be easily modified and plug-in. Then graphic designer can focus UI, generate the rendering logic; BA focuses on business rules, generate business logic, then developer integrate them all into one application, and each layer can be easily changed and upgraded.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Easy to customization&lt;/b&gt;&lt;br /&gt;The mobile framework should takes the advantage of different platforms technologies. we should not do the way of common denominator, like J2ME MIDP widget, which is a bad example.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Open and easy to integrate with other libraries &lt;/b&gt;&lt;br /&gt;The new mobile platform should be open to other framework or library, it should be easily to integrate with other libraries. for example, developer can integrate different UI libray easily, like LWUIT, SVG, oepnGL, etc. and the mobile platform does not want to reinvent the wheels, it focuses on integration.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Follow agile&lt;/b&gt;&lt;br /&gt;The mobile framework should be agile, which means&lt;br /&gt;- support TDD, provide a mobile unit test framework or support 3rd party test framework&lt;br /&gt;- Encourage short feedback, the mobile framework provides powerful simulator which can simulate different platforms, developer can easily to know what is going on for his application, and it is also a good demo and presentation to our costumer, the simulator can be run inside the browser so that it is a good demo for end users.&lt;br /&gt;- provide build and deploy automation, since different platform has different SDK and build tools, manage them is a nightmare, having a build automation tool will greatly improve the developer's productivity and speed up the application development cycle.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Several possible technical paths:&lt;/b&gt;&lt;br /&gt;- &lt;b&gt;DSL/Code generation&amp;nbsp; &lt;/b&gt;&lt;br /&gt;&amp;nbsp; Define a mobile Domain Specific Language,&amp;nbsp; then generate the native source code for different platform. we can use Ruby or ANTLR. I like the idea of code generation, because it can meet the needs of different platform, and can easily to implement the AOP&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;Use web based script languages&lt;/b&gt;&lt;br /&gt;&amp;nbsp; Using html, xml, CSS, java script, then render in the browser or using parser to generate the native source code. This is also a good concept, actually there are already have several open source project doing like this, for example PhoneGap,but what I really worry about are: 1) How to address the fragmentation for each platform; 2) to solve the question 1, may leads to common denominator issue. For this reason, I really doubt the JavaFX Mobile framework, because there is no way to handle the fragmentation issue in script language level.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;I hope in the near future, I can do something for the new mobile platform. I have a dream, in future: UI designer, BA, developer and QA will share the same framework, each works on his own part, then developer integrates them by pressing a button, then generate mobile applications for different platforms, hope this won't take long.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8131095272472682307?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8131095272472682307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/01/my-vision-of-future-mobile-platform.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8131095272472682307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8131095272472682307'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/01/my-vision-of-future-mobile-platform.html' title='My Vision of the future mobile platform framework'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5588107101382498298</id><published>2010-01-21T21:53:00.008-05:00</published><updated>2010-02-10T18:25:57.053-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><title type='text'>How to add a J2ME 3rd party library into your NetBeans project</title><content type='html'>&lt;b&gt;Scenario&lt;/b&gt;&lt;br /&gt;You need to port our J2ME application to a specific platform, either Nokia, Samsung or LG, etc. You have to use OEM's specific API to implement a feature, but that special API is not included J2ME standard library, nor included in the OEM's J2ME SDK. You got an ZIP or jar file of the API library, but mostly it they are just stub classes, the only real implementations are inside the actual devices. &lt;b&gt;What you need to do is adding the library in your project class path, but without including them into the J2ME jar file.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;&lt;br /&gt;In NetBeans IDE, You can add the libray of zip/jar file in your J2ME project without including in the packaged jar file. Here are the steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Select your project, right click mouse, choose "Properties"&lt;/li&gt;&lt;li&gt;Select Build - Libraries &amp;amp; Resources, click button "Add Jar/Zip ...", then select the libray file you want to add, press "Open"&lt;/li&gt;&lt;li&gt;You will see the library file is included the file/folder list, pleases make sure uncheck the "Package" checkbox, this is the most important step, it will tell IDE don't include this jar/zip file into your J2ME jar file, or IDE will not build successfully, because it can not find dependencies packages for the libraries. The screen shot is attached at the end of this article.&lt;/li&gt;&lt;li&gt;Select OK, and build your J2ME application&lt;b&gt;&amp;nbsp;&lt;/b&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/3555300218296290557-5588107101382498298?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5588107101382498298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/01/how-to-add-j2me-3rd-party-library-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5588107101382498298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5588107101382498298'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/01/how-to-add-j2me-3rd-party-library-in.html' title='How to add a J2ME 3rd party library into your NetBeans project'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-6300099352334530896</id><published>2010-01-21T21:43:00.000-05:00</published><updated>2010-01-21T21:43:17.824-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><title type='text'>Java ME SDK 3.0 review</title><content type='html'>Last week I spent some time on Java ME SDK 3.0. One of my application need to support both landscape mode and portrait mode, currently J2ME wireless toolkit does not support the feature of changing the screen orientation, I heard that Sun's new JavaME SDK V3.0 emulator support changing the screen orientation, so I installed it and hope it will help my work. but unfortunately I feel disappointed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Issue of integration with NetBeans IDE&lt;/b&gt;&lt;br /&gt;After installing it successfully on my windows machine, I tried to add the SDK into My NetBeans 6.1 IDE, and then later I realize that the all the tools and Prefrence setting of the SDK 3.0 are disabled in my NetBeans IDE. which means you can not profile, clear database, change emulator settings inside the NetBeans IDE.&lt;br /&gt;At first I thought maybe due to my NetBeans version is old, so I installed the Netbeans 6.8, which integrates the Java ME SDK 3.0, but I found the same thing; and I also tried the NetBeans 6.5.1, it is still not working. I also found &lt;a href="http://forums.netbeans.org/ptopic19465.html"&gt;this thread in a forum&lt;/a&gt; about the same issue I found in NetBeans 6.7. I don't know when Sun will fix this issue, but I do know that if this issue is not fixed, then few developer will use the new SDK, since so many mobile developers are tied with the NetBeans IDE.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lack of the options to launch the emulator&lt;/b&gt;&lt;br /&gt;For the emulator, I need a scenario that my application launched in a landscape mode, but I did not find there is any setting in the SDK allow you to do that, it always start as portrait mode.While Nokia S60 3rd SDK already supports this feature. Sun should provide this feature both in GUI menu settings and command line.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Failed to debug&lt;/b&gt;&lt;br /&gt;I tried to debug my application by setting a break point using the SDK 3.0,I tried twice, but no luck.&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;No document to describe how to customize the emulator&lt;/b&gt;&lt;br /&gt;&amp;nbsp;Compare to WTK 2.5.x, the SDK 3 changed a lot for the emulator file structures, I realize it becomes much more complicated than before. For WTK 2.5.x, it is really easy to customize the emulator, I now how to change screen size, how to enable touch screen; but for SDK 3, I don't where I can start,I hope Sun could provide an official document to describe the architecure of the new emulator. I found &lt;a href="http://blogs.sun.com/javamesdk/entry/how_to_create_a_custom"&gt;this article &lt;/a&gt;about customizing the emulator in SDK 3 in Java ME SDK team blog&lt;b&gt;,&amp;nbsp; &lt;/b&gt;it might be useful.&lt;br /&gt;&lt;br /&gt;Based on the reasons of above, I don't think the current version of the JavaME SDK can help me for my application development, so I have to change back to WTK 2.5, and use Nokia's S60 emulator, even if it is slow,but at least it works. It seems Sun has a long way to improve its new mobile SDK.&lt;br /&gt;&lt;br /&gt;This artcile is based on windows version, I haven't touch the Mac version and Linux version yet.&lt;br /&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;Related links:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://forums.netbeans.org/ptopic19465.html"&gt;Java ME SDK integration in NetBeans 6.7&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/javamesdk/entry/how_to_create_a_custom"&gt;How to create a custom device&amp;nbsp;&lt;/a&gt;&lt;b&gt; &lt;br /&gt;&lt;/b&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/3555300218296290557-6300099352334530896?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/6300099352334530896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/01/java-me-sdk-30-review.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6300099352334530896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/6300099352334530896'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/01/java-me-sdk-30-review.html' title='Java ME SDK 3.0 review'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3951717708179710962</id><published>2010-01-17T21:33:00.004-05:00</published><updated>2010-01-17T21:40:43.054-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><title type='text'>Ruby and AOP</title><content type='html'>Right now I am learning Ruby, I focus on Dave Thomas' famous &lt;a href="http://pragprog.com/titles/ruby3/programming-ruby-1-9"&gt;pickaxe Ruby book&lt;/a&gt;, last week I just finished the chapter 24: "Metaprogramming".Now I learn the power of Ruby Metaprogramming, right now it is still quite difficult for me, I am sure I will read this chapter over and over in future.&lt;br /&gt;&lt;br /&gt;Today I want to discuss my impression of AOP concept in Ruby.&lt;br /&gt;I learned AOP from java, in java you have to use AspectJ or Dynamic Proxy implement AOP. But comapre to Java, I realize Ruby support AOP in the lanuage level:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Classes are open: you add new method or attribute for any existing class, or replace the method with new one.&lt;/li&gt;&lt;li&gt;Module and Mixin: you can easily add new functionalities by Mixin the module.&lt;/li&gt;&lt;li&gt;MetaProgramming: you can dynamically define a method on the fly, using hook method as call back, easily implement before, after and around advice&lt;/li&gt;&lt;/ul&gt;I feel by using the above technologies, it is quite easy using AOP concept in Ruby, for example you can easily implement a Logging Aspect in a Module, then get it mixin in your application code.That is separating of concern, which is the essence of AOP.&lt;br /&gt;So I will say AOP is built in support in Ruby language level. &lt;br /&gt;&lt;br /&gt;Today I found a blog called &lt;a href="http://debasishg.blogspot.com/2006/06/does-ruby-need-aop.html"&gt;"Does Ruby need AOP?"&lt;/a&gt;, the author argue that Ruby metaprogramming is not AOP,because he think AOP is all about semantics, while Ruby metaprogramming is too low level. I feel this argument is too academic, from the pragmatic perspective, I think as long as Ruby can do the job of separation of concern, then it is AOP, then who care about the semantics?&lt;br /&gt;&lt;br /&gt;Here are some useful links:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://4loc.wordpress.com/2008/10/07/ruby-and-aop/"&gt;another blog about ruby and APO at 4 line of code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.slideshare.net/deimos/aspect-orientated-programming-in-ruby"&gt;slide: AOP of Ruby&lt;/a&gt;&lt;br /&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/3555300218296290557-3951717708179710962?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3951717708179710962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/01/ruby-and-aop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3951717708179710962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3951717708179710962'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/01/ruby-and-aop.html' title='Ruby and AOP'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8069150879027715991</id><published>2010-01-10T19:38:00.013-05:00</published><updated>2010-02-10T18:30:38.449-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><title type='text'>Customize Your J2ME Emulator</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;b&gt;Why do we need to customize J2ME emulator ?&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;As a J2ME mobile developer, you have to port application to different devices,&amp;nbsp; while the J2ME default emulator only provide 4 different profiles, which can not meet our needs, and also some platforms like BlackBerry, Nokia S60 etc, the J2ME emulator they provided are really slow to launch, which is really inconvenient. If you can customize the emulator to support the device you are porting, which will improve your developing productivity.&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Where are the emulator device profiles located?&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;For example, if you installed wireless toolkit 2.5 in c:\WTK25, then the device folder is:&lt;/div&gt;&lt;div class="MsoNormal"&gt;C:\WTK25\wtklib\devices&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The mobility package is included in the NetBeans 6.5 or later version, the wireless toolkit folder is like this:&lt;/div&gt;&lt;div class="MsoNormal"&gt;C:\Program Files\NetBeans 6.x\mobility8\Java_ME_platform_SDK_x.x&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Create a new emulator device profile&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;I like to choose Sun Wireless Toolkit 2.5, because its Qwerty Device emulator looks better.&amp;nbsp;&amp;nbsp; For example, if I want to create a device for Black Berry 9000:&lt;/div&gt;&lt;div class="MsoNormal"&gt;1. &amp;nbsp;Copy the entire folder of &amp;nbsp;“QwertyDevice” to a new folder, rename the new folder name to “BlackBerry9000”&lt;/div&gt;&lt;div class="MsoNormal"&gt;2.&amp;nbsp; Go inside the folder, rename the Qwerty.properies file to BlackBerry9000.properties&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Enable the touch screen&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The touch screen feature is disabled for J2ME default emulators. If you want to enable it, you need to modify the .properties file. In properties file, find following statement:&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; touch_screen=false&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Change false to true will enable the touch screen.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Change the screen size&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;For example, for BlackBerry 9000, its screen size is 480x320, then go to .prperties file, update the following values:&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; screenPaintableRegion.width=480&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; screenPaintableRegion.height=320&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; and .. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.width=480&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.height=332&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Please note that you need to make sure:&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp; screen.height &amp;gt;&amp;nbsp; screenPaintableRegion.height + screenPaintableRegion.y&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp; In the properties file, screenPaintableRegion.y=11, so the screen.height value is 332. &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp; If you don’t put the correct value, the emulator will throw exception once it is launched.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Make your customization available in NetBeans IDE&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Once You finished the customization, you need to update your NetBeans IDE environment:&lt;/div&gt;&lt;ol start="1" style="margin-top: 0in;" type="1"&gt;&lt;li class="MsoNormal"&gt;Select      Tools – Java Platform,&amp;nbsp; choose Sun      wireless toolkit 2.5, click Refresh button&lt;/li&gt;&lt;li class="MsoNormal"&gt;You      will see the device names&amp;nbsp; you added      in the device folder&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;You can easily customize J2ME emulator by modifying the .properties file, even it is really simple, it can improve your productivity considerably.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Further steps&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;This article is only focused on Wireless Toolkit 2.5.x , Sun released the new wireless toolkit 3.0,&amp;nbsp; the device emulators are changed a lot. I need to do more investigation on 3.0 emulator in future..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8069150879027715991?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8069150879027715991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2010/01/customize-your-j2me-emulator.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8069150879027715991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8069150879027715991'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2010/01/customize-your-j2me-emulator.html' title='Customize Your J2ME Emulator'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2589057329635633769</id><published>2009-12-30T20:43:00.011-05:00</published><updated>2010-02-10T18:31:48.074-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software craftsman'/><title type='text'>Book Review: Apprenticeship Patterns</title><content type='html'>I finally finished reading the book &lt;a href="http://oreilly.com/catalog/9780596518387"&gt;“Apprenticeship Patterns – Guidance for the aspiring Software Craftsman”.&lt;/a&gt; It took me about 2 months to finish it, because I don’t have enough time to read it, usually I read it at waiting time for the Go train.&lt;br /&gt;&lt;br /&gt;This book changes my strategy of my career path. If you want to become a master of software craftsman, then you should focus on improving your craft, not on promotion, not on money.  This is a long road.&lt;br /&gt;&lt;br /&gt;“sustainable motivations”  &lt;br /&gt;You need to keep motivate yourself, nurture your passion, beware don’t let yourself trapped into Golden Lock:" I'd like to learn something new ,but what I already know pays too well." &lt;br /&gt;&lt;br /&gt;You need to find a better company, better job, team and co-worker. Love your job, do what your love, then money will follow. Money itself is not the goal, it is just the byproduct along the road to master. It gives me an insight that you should focus on finding the job that you truly love and passionate, even if it is low pay, because once you have the passion, you will generate creativity and energy, then it will generate the money for you. Another great example is Steve Jobs, in &lt;a href="http://news.stanford.edu/news/2005/june15/jobs-061505.html"&gt;his commencement address to Standford’s class of 2005&lt;/a&gt;, he said: “&lt;b&gt;You've got to find what you love &lt;/b&gt;“..., “Don't let the noise of others' opinions drown out your own inner voice. And most important, &lt;b&gt;have the courage to follow your heart and intuition.&lt;/b&gt; They somehow already know what you truly want to become. Everything else is secondary.”&lt;br /&gt;&lt;br /&gt;This book helps me reinforce the understanding of the patterns, the author draws quite a few maps, connecting different patterns, then I realize the importance of the map, because it reveals the connections and relationship of each pattern. It inspire me that pattern itself is important, but also the connections. We should not only focus on each pattern itself, but also their relationship to other patterns.&lt;br /&gt;Those patterns seems simple, it give ms an insight that yourself can find your own pattern if you think deliberately.&lt;br /&gt;&lt;br /&gt;My favorite patterns in the book are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Be the worst&lt;/li&gt;&lt;li&gt;The white belt&lt;/li&gt;&lt;li&gt;Nurture your passion&lt;/li&gt;&lt;/ul&gt;My personal goal is finding the Tao of programming, which is the right way of software developing, so go from apprentice to master is a must path for me.&lt;br /&gt;&lt;br /&gt;I have another blog about this book: &lt;a href="http://code-dojo.blogspot.com/2009/12/my-personal-practices-map.html"&gt;My personal practice map. &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2589057329635633769?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2589057329635633769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/12/book-review-apprenticeship-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2589057329635633769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2589057329635633769'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/12/book-review-apprenticeship-patterns.html' title='Book Review: Apprenticeship Patterns'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-1635438555505745064</id><published>2009-12-22T23:14:00.006-05:00</published><updated>2010-02-10T18:35:17.855-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><title type='text'>The Evil of Java ME preprocess</title><content type='html'>Developing Java ME application is painful, because of Java ME's own fragmentation in nature. Java Mobile developers have to deal with different devices, and each device or platform has different implementation. Writing a portable application to support different devices is really hard, and some time it is really a torture. &lt;br /&gt;&lt;br /&gt;To solve the fragment issue, NetBeans IDE provides a solution - Preprocess, it is similar to pre-compile in C and C++. Actually preprocess in NetBeans is quite perfect, quite powerful. When I first use it, I feel it is so powerful, so easy to use.&amp;nbsp; Several years later, when I look at our code, which have #if, #else every where, I just feel the code are so ugly, seems to return to the c code era. I really feel preprocess is an evil! Following are my reasons.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Violate OO Principles&lt;/b&gt;&lt;br /&gt;Since preprocess is so easy to use, just add something like comments, it gives developer a backdoor to break OO principles easily and brutally. It is so easy to hack the program, so there is no need to care about abstraction, no need to care about design patterns. And the problem is my colleagues like to overuse preprocess, mostly even use preprocess for constants!&amp;nbsp; I saw so many code full of magic numbers, and so many preprocess directive scattered every where to change those values.&lt;br /&gt;&lt;br /&gt;It also violates OCP principle, OCP means "Open for extension, closed for modification". But preprocess is modifying the existing source code when you add new preprocess configuration. It is quite common that the change works for the new configuration, but will break the old ones.&lt;br /&gt;&lt;br /&gt;I found if we use more design patterns deliberately, like strategy pattern, abstract factory pattern etc, and use constant class instead of magic number directly, we can minimize the preprocess greatly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hard to Refactor&lt;/b&gt;&lt;br /&gt;Refactoring the preprocessed code is really difficult, for example when you rename a method name or variable name, you can only refactor the current active preprocessed code, because others are commented out. If in your project need&amp;nbsp; 4 different devices type, so every time when&amp;nbsp; you refactor, you have to test 4 times to make sure the change is working. It is really painful!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hard to Reuse&lt;/b&gt;&lt;br /&gt;If you want to reuse a class or a component to another project, but when you see so many preprocess scattered in the code, probably you will not use it.&amp;nbsp; Either you have to add all those preprocess into your new project which might does not make any sense, or you have to manually remove them, which is even harder to test.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hard to understand&lt;/b&gt;&lt;br /&gt;When you read the code has so many #if #else statement, it is ugly to read, more difficult to understand, code is not clean.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hard to maintain&lt;/b&gt;&lt;br /&gt;When you want to port the current application to a new device, you have to understand how the previous preprocess work; when you want to fix a bug for specific device, you have to make sure it won't break the others. Manage so many preprocess configuration is really painful. So preprocess is good for short-term, but really painful for long term.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IDE Lock-in&lt;/b&gt;&lt;br /&gt;Because of widely use of preprocess, our projects are locked in NetBeans IDE, we can not use other IDE, like Eclipse.&amp;nbsp; For my experience, NetBeans IDE has some problems for example:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;you can't use different source code folder for different configuration, you can easily do that in Eclipse MTJ;&lt;/li&gt;&lt;li&gt;Build automation is difficult, I don't understand the NetBeans generated build xml, I have to build inside the IDE, I never tried to run build file outside the IDE, and I don't know how create a customized ant build file, I think it is really hard;&lt;/li&gt;&lt;li&gt;Difficult for team work. NetBeans project use absolute path, and private project properties. Which means it works in your computer, but might not work in your co-workers environment, or you have to take a while to set up the environment correctly.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Conclusions&lt;/b&gt;&lt;br /&gt;Java ME preprocess is easy for short-term, but painful for long term, it solves one issue by generating more issues in future; it delay your pain in a short term, but you will be more painful for long term.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Suggestions for anti-preprocess&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Try to minimize the use of preprocess, we can't 100% percent remove the preprocess, but be ware to use it, only use it when no other options.&lt;/li&gt;&lt;li&gt;Have the discipline of writing clean code, readable code and maintainable code, before you use preprocess, think it carefully, if there is better solution;&lt;/li&gt;&lt;li&gt;Use OO design patterns, for example strategy pattern and abstract factory can remove lots of preprocess;&lt;/li&gt;&lt;li&gt;Try to use configuration file instead of preprocess, if we put the constant value into resource property file instead of hardcoded using preprocess, we can also make the code cleaner;&lt;/li&gt;&lt;li&gt;Centralize the preprocess, if you have to use preprocess, don't allow them scattering every where in the code, try to put those preprocess specific logic together, even better to put them into one class, it would be easier to read, understand and maintain;&lt;/li&gt;&lt;li&gt;DSL/Meta programming, if fragmentation is unavoidable, why not use code generation technology to generate source code for each specific platform for us? This needs compiler skills and Domain Specific Language knowledge, it is really an interesting topic. &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-1635438555505745064?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/1635438555505745064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/12/evil-of-java-me-preprocess.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1635438555505745064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/1635438555505745064'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/12/evil-of-java-me-preprocess.html' title='The Evil of Java ME preprocess'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-929263613049083062</id><published>2009-12-13T00:04:00.012-05:00</published><updated>2009-12-13T23:15:38.529-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>My Personal Practices Map</title><content type='html'>Currently I am reading the book called &lt;a href="http://www.amazon.com/Apprenticeship-Patterns-Guidance-Aspiring-Craftsman/dp/0596518382/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1260678126&amp;amp;sr=8-1"&gt;Apprenticeship Patterns – Guidance for the Aspring Software Craftsman.&lt;/a&gt;&lt;o:p&gt; &lt;/o:p&gt;In page 85, the pattern “Reflect As You Work”, it mentions a technology called “Personal Practices Map”. You can use this technology to analyze and reflect your idea and what you did.&lt;br /&gt;&lt;div class="MsoNormal"&gt;This idea originally comes from &lt;st1:place w:st="on"&gt;&lt;st1:city w:st="on"&gt;London&lt;/st1:city&gt;&lt;/st1:place&gt;’s Extreme Tuesday Club. The page &lt;a href="http://www.xpdeveloper.net/xpdwiki/Wiki.jsp?page=MapsOfPeoplesPersonalPractices"&gt;"Maps of People’s Personal Practices".&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;This is my Personal Practices Map.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_lxmigwrwDfI/SyRzuYpooHI/AAAAAAAAABg/1bekkvgpGKE/s1600-h/personalPracticeMap.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_lxmigwrwDfI/SyRzuYpooHI/AAAAAAAAABg/1bekkvgpGKE/s640/personalPracticeMap.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Using map to reflect ideas reminds me the book of GoF design patterns.&amp;nbsp; In that book, the authors draw a map of all 23 patterns and their relationships. &amp;nbsp;The book Apprenticeship patterns draw lots of map to connect each pattern.&lt;br /&gt;&lt;div class="MsoNormal"&gt;This is a great technology. In future I will draw more maps:&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;“Draw your own map” (Page 47), draw a map of your career path.&lt;/li&gt;&lt;li&gt;Draw the map of reading list&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-929263613049083062?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/929263613049083062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/12/my-personal-practices-map.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/929263613049083062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/929263613049083062'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/12/my-personal-practices-map.html' title='My Personal Practices Map'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lxmigwrwDfI/SyRzuYpooHI/AAAAAAAAABg/1bekkvgpGKE/s72-c/personalPracticeMap.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-2873264524822622525</id><published>2009-12-05T23:40:00.002-05:00</published><updated>2010-02-10T22:51:41.600-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Agile meeting notes at Toronto JUG Dec 1, 2009</title><content type='html'>&lt;meta content="text/html; charset=utf-8" http-equiv="Content-Type"&gt;&lt;/meta&gt;&lt;meta content="Word.Document" name="ProgId"&gt;&lt;/meta&gt;&lt;meta content="Microsoft Word 11" name="Generator"&gt;&lt;/meta&gt;&lt;meta content="Microsoft Word 11" name="Originator"&gt;&lt;/meta&gt;&lt;link href="file:///C:%5CDOCUME%7E1%5CSteve%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" rel="File-List"&gt;&lt;/link&gt;&lt;style&gt;&lt;!-- /* Font Definitions */ @font-face	{font-family:Wingdings;	panose-1:5 0 0 0 0 0 0 0 0 0;	mso-font-charset:2;	mso-generic-font-family:auto;	mso-font-pitch:variable;	mso-font-signature:0 268435456 0 0 -2147483648 0;}@font-face	{font-family:宋体;	panose-1:2 1 6 0 3 1 1 1 1 1;	mso-font-alt:SimSun;	mso-font-charset:134;	mso-generic-font-family:auto;	mso-font-pitch:variable;	mso-font-signature:3 135135232 16 0 262145 0;}@font-face	{font-family:"\@宋体";	panose-1:2 1 6 0 3 1 1 1 1 1;	mso-font-charset:134;	mso-generic-font-family:auto;	mso-font-pitch:variable;	mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal	{mso-style-parent:"";	margin:0in;	margin-bottom:.0001pt;	mso-pagination:widow-orphan;	font-size:12.0pt;	font-family:"Times New Roman";	mso-fareast-font-family:宋体;}@page Section1	{size:8.5in 11.0in;	margin:1.0in 1.25in 1.0in 1.25in;	mso-header-margin:.5in;	mso-footer-margin:.5in;	mso-paper-source:0;}div.Section1	{page:Section1;} /* List Definitions */ @list l0	{mso-list-id:43599118;	mso-list-type:hybrid;	mso-list-template-ids:155888428 67698703 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}@list l0:level1	{mso-level-tab-stop:21.0pt;	mso-level-number-position:left;	margin-left:21.0pt;	text-indent:-.25in;}@list l1	{mso-list-id:362944916;	mso-list-type:hybrid;	mso-list-template-ids:1547971932 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}@list l1:level1	{mso-level-tab-stop:39.0pt;	mso-level-number-position:left;	margin-left:39.0pt;	text-indent:-.25in;}@list l2	{mso-list-id:882713065;	mso-list-type:hybrid;	mso-list-template-ids:306450100 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}@list l2:level1	{mso-level-number-format:bullet;	mso-level-text:;	mso-level-tab-stop:39.0pt;	mso-level-number-position:left;	margin-left:39.0pt;	text-indent:-.25in;	font-family:Symbol;}@list l3	{mso-list-id:1628077984;	mso-list-type:hybrid;	mso-list-template-ids:440725080 -306775774 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}@list l3:level1	{mso-level-start-at:0;	mso-level-number-format:bullet;	mso-level-text:-;	mso-level-tab-stop:21.0pt;	mso-level-number-position:left;	margin-left:21.0pt;	text-indent:-.25in;	font-family:"Times New Roman";	mso-fareast-font-family:宋体;}ol	{margin-bottom:0in;}ul	{margin-bottom:0in;}--&gt;&lt;/style&gt;  &lt;br /&gt;&lt;div class="MsoNormal"&gt;I attended the Toronto JUG meeting on December 1. This time it is about Agile, the presentato is Jack Milunsky from agilebuddy.com. His topic covered agile, SCURM and lean.&amp;nbsp; &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;I put my notes here:&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Adopting agile is hard&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp; Agile requires both bottom up and top down.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp; Applying agile practices is easy, but the hard part is new mindset and new philosophy, which is quite different with traditional waterfall methodology&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp; Agile/Scrum is pervasive; it involves all different teams to change&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Lean software technology&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Jack spent lots of time on Lean.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Lean’s two pillars&lt;/b&gt;:&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;1.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Just-In-Time Flow&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt;"&gt;Eliminate inventory, &lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt;"&gt;Do things in batches, which is similar with SCRUM&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;2.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Autonomation: &lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stop the line,&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Built-in reflex&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Just In Time Flow&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;-&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;inventory is waste&amp;nbsp; =&amp;gt; partial done software&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;-&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Moving in Just in time&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt;"&gt;Uncover waste&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Focus on overall concept&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Focus on value&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;7 principles of lean software development&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;1.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Eliminate waste&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt;"&gt;Any partial done software is waste&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;2.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Build Quality in&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; don’t test it in, prevent defect in the first place&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; avoid creating defects&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stop the line, automation, unit test&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;3.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;create knowledge&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; knowledge create process&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; don’t lock down&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;4.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Defer commitment&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 3pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; “Planning is good, plans are bad”&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;5.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Deliver fast&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Lean focus on time&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Don’t equate fast with hacking&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Expose issues&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Build quality in&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Quality is the first priority&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;6.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Respect people&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Self organizing team&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Trust over command and control&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;7.&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Optimize the whole&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Mindset is important, not just practice&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Transfer ownership&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Focus on the whole value stream, the big picture&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 0.5in;"&gt;Focus on value, eliminate waste&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Waste&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;span style="font-family: Symbol;"&gt;·&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Extra features&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Justify every feature, limit features&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Extra features are waste, &amp;gt; 60% are extra features.&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;span style="font-family: Symbol;"&gt;·&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Relearning&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Task switching drops the productivity&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Undocumented code&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;No wiki&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;span style="font-family: Symbol;"&gt;·&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Handoff&lt;/div&gt;&lt;div class="MsoNormal" style="text-indent: 12pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Transition point are waste point, knowledge degrades&lt;/div&gt;&lt;div class="MsoNormal" style="text-indent: 12pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Delays&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 39pt; text-indent: -0.25in;"&gt;&lt;span style="font-family: Symbol;"&gt;·&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Defects&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Increasing speed helps the absence of waste&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cycle Time =&amp;nbsp; things in process / average completion rate&lt;/div&gt;&lt;div class="MsoNormal"&gt;How to reduce the cycle time:&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;-&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;minimize the number of things in process&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;-&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;minimize the size of the things&lt;/div&gt;&lt;div class="MsoNormal" style="margin-left: 21pt; text-indent: -0.25in;"&gt;-&lt;span style="font-family: &amp;quot;Times New Roman&amp;quot;; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Recommend small batches, which is similar as sprint in SCRUM&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;80% rule: if the task load is over 80%, the cost, defect rate increase dramatically&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&lt;br /&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Agile in AgileBuddy&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Agile buddy spends 20% time for refactoring, (which is very good, they know how important refactoring is, they do it deliberately, very nice!)&lt;/div&gt;&lt;div class="MsoNormal"&gt;Discipline:&amp;nbsp; set the dial to 11( 80% rule)&lt;/div&gt;&lt;div class="MsoNormal"&gt;Sprint length: 2 weeks&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;My thoughts&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;After the meeting, I talked to Jack, and we exchanged the idea, I believe that SCRUM mainly focuses on management side, it only focuses on what to do, but does not cover how to do, if you look at the SCRUM, there is no TDD, refactoring, pair programming, etc. I always have the question: do they need to be added in the SCRUM sprint practices? How? So I think SCRUM only is not enough, SCRUM should work with XP. So I asked Jack his idea about SCRUM vs. XP. He replied me that SCRUM only definitely not enough, it has to work with XP, because some of the XP practices are really fundamental, like TDD, refactoring. That what they are doing in agilebuddy.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;He also suggest me to organize a lunch and learn meeting, just watch this &lt;a href="http://www.youtube.com/watch?v=IyNPeTn8fpo%29"&gt;video&lt;/a&gt; by Ken Schwaber about SCRUM..This meeting let think more about agile.Thanks Jack.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;You can visit Jack's blog at &lt;a href="http://blog.agilebuddy.com/"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-2873264524822622525?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/2873264524822622525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/12/agile-meeting-notes-at-toronto-jug-dec.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2873264524822622525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/2873264524822622525'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/12/agile-meeting-notes-at-toronto-jug-dec.html' title='Agile meeting notes at Toronto JUG Dec 1, 2009'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5935478129914516654</id><published>2009-11-26T22:41:00.027-05:00</published><updated>2011-08-06T22:38:42.142-04:00</updated><title type='text'>Code Kata: SuDoKu Solver</title><content type='html'>This week I am interested in the Sudoku puzzle, I am thinking how to use program to solve the SuDoKu. I almost spent a week for it. At first I was inspired the a book called &lt;a href="http://www.amazon.com/Wicked-Cool-Ruby-Scripts-Difficult/dp/1593271824/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1259289439&amp;amp;sr=8-1"&gt;“Wicked Cool Ruby Scripts”&lt;/a&gt;in chapter 5, it provides a ruby source code for the SuDoKu solver. I spent two days to understand the code. The problem is the book does not describe the algorithm in details, and I don’t know how to debug the ruby code in TextMate. So it took me a longer time to finally understand the whole logic.&lt;br /&gt;&lt;br /&gt;Actually it uses the brutal backtrack method.  Try fill a number in one cell, then recursively call itself, if it works, continue, then return, try another, until it fills all the 81 cells. I made some changes based on the original code,  the major changes once the solver find the solution then exit the loop, while in the original code the program will continue loop until the end, I compare my changes with the original code, the total times executed and execution time both drops about 50%.&lt;br /&gt;&lt;br /&gt;Here is my modified code:&lt;br /&gt;&lt;script src="https://gist.github.com/1129998.js?file=sudoku_solver.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;The logic is really simple:  first reads the puzzle, construct the one dimension array.&lt;br /&gt;The key is in Solver method:  &lt;br /&gt;From 81 cells, pick one empty cell, calculate the candidate numbers of this cell,&lt;br /&gt;Pick one number, fill the cell,  &lt;br /&gt;Recusively call itself, continue try to fill another empty cell.&lt;br /&gt;If the program could not find the candidate for the cell, or the program iterate all the cell’s candidate number, then erase the number, backtrack;&lt;br /&gt;If the program fills all the 81 cells, return true&lt;br /&gt;&lt;br /&gt;The algorithm of getCanidates(j) is easy:&lt;br /&gt;Build an array of 1-9&lt;br /&gt;Find each cell with the same row, erase the number in the cell from the array;&lt;br /&gt;Find each cell with the same column,   erase the number in the cell from the array;&lt;br /&gt;Find each cell with the same sub block, erase the number in the cell from the array.&lt;br /&gt;The left in the array are candidates&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;From this code, I understand more about the backtrack and recursive method. This code belongs to the depth-first backtrack search.&lt;br /&gt;&lt;br /&gt;Donald Knuth’s Dancing Link algorithm is quite interesting, there are lots of articles and blog about using it solving the SuDoKu. But right now for me it is really hard to understand. &lt;br /&gt;&lt;br /&gt;For SuDoKu, there are following thins to do in future:&lt;br /&gt;1. Implement the SuDoKu solver using Dancing Link algorithm&lt;br /&gt;2. Find out the algorithm of SuDoKu Generator, like how to generate a puzzle based on difficulty, and how to find out there is only one solution.&lt;br /&gt;3. How to implement an algorithm that simulate human's solving logic?&lt;br /&gt;&lt;br /&gt;Here are several link about dancing link and SoDuKu:&lt;br /&gt;&lt;a href="http://cgi.cse.unsw.edu.au/%7Exche635/dlx_sodoku/"&gt;Dancing Link C implementation&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ocf.berkeley.edu/%7Ejchu/publicportal/sudoku/sudoku.paper.html"&gt;Dancing link for Java&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www-cs-faculty.stanford.edu/%7Eknuth/index.html"&gt;Donald Knuth Home page&lt;/a&gt;&lt;br /&gt;&lt;a href="http://arxiv.org/PS_cache/cs/pdf/0011/0011047v1.pdf"&gt;Donald Knuth's Dancing links paper(pdf)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5935478129914516654?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5935478129914516654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/11/code-kata-sudoku-solver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5935478129914516654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5935478129914516654'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/11/code-kata-sudoku-solver.html' title='Code Kata: SuDoKu Solver'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-5444282482661358418</id><published>2009-11-13T22:34:00.001-05:00</published><updated>2009-11-13T22:37:30.959-05:00</updated><title type='text'>code Kata 3,   How many n-digit binary numbers are there that don't have two adjacent 1 bits?</title><content type='html'>Today I read a new Kata from Dave's CodeKata&lt;a href="http://codekata.pragprog.com/2007/01/code_kata_fifte.html"&gt;CodeKata fifteen: A diversion&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Question:&lt;br /&gt;Think of binary numbers: sequences of 0's and 1's. How many n-digit binary numbers are there that don't have two adjacent 1 bits? For example, for three-digit numbers, five of the possible eight combinations meet the criteria: 000, 001, 010, &lt;strike&gt;011&lt;/strike&gt;, 100, 101, &lt;strike&gt;110&lt;/strike&gt;, &lt;strike&gt;111&lt;/strike&gt;. What is the number for sequences of length 4, 5, 10, n?&lt;br /&gt;&lt;br /&gt;Having worked out the pattern, there's a second part to the question: can you prove why that relationship exists?&lt;br /&gt;&lt;br /&gt;The answer is in the replied comments, it is a fibonacci series: &lt;br /&gt;f(1) = 2  =&gt; 0,1&lt;br /&gt;f(2) = 3  =&gt; 00, 01, 10&lt;br /&gt;f(n) = f(n-1) + f(n-2)&lt;br /&gt;&lt;br /&gt;Now I will try to explain why it is like this using my own thoughts:&lt;br /&gt;f(3) can be thought of 2 groups, one is begin with 0, and the other is begin with 1&lt;br /&gt;begin with 0 group:  0 + xx, =&gt; f(2)&lt;br /&gt;begin with 1 group:  since it begins with 1, it must be followed by 0, so it becomes 10 + x , =&gt;f(1)&lt;br /&gt;&lt;br /&gt;so f(3) = f(2) + f(1)&lt;br /&gt;&lt;br /&gt;same thing with f(n)&lt;br /&gt;begins with 0: 0 + xxx...x ( n-1 digit) =&gt; f(n-1)&lt;br /&gt;begins with 1: 10 + xxx..x ( n-2 digit) =&gt; f(n-2)&lt;br /&gt;&lt;br /&gt;so f(n) = f(n-1) + f(n-2)&lt;br /&gt;&lt;br /&gt;Now I will give the solution in Ruby:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def non_adjacent_one_array(n)&lt;br /&gt;if(n == 1)&lt;br /&gt;["0", "1"]&lt;br /&gt;elsif (n== 2)&lt;br /&gt;["00", "01", "10"]&lt;br /&gt;else&lt;br /&gt;array1 = non_adjacent_one_array(n-1).collect { |i| "0"+i}&lt;br /&gt;array2 = non_adjacent_one_array(n-2).collect { |i| "10"+i}&lt;br /&gt;array1+array2   &lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;s=non_adjacent_one_array(5)&lt;br /&gt;puts "n=5, number is #{s.length}\n"&lt;br /&gt;puts s&lt;br /&gt;puts "\n"&lt;br /&gt;&lt;br /&gt;1.upto(10) do |i|&lt;br /&gt;s = non_adjacent_one_array(i)&lt;br /&gt;puts "n=#{i}  number=#{s.length}\n"&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And the results are:&lt;br /&gt;&lt;br /&gt;n=5, number is 13&lt;br /&gt;00000&lt;br /&gt;00001&lt;br /&gt;00010&lt;br /&gt;00100&lt;br /&gt;00101&lt;br /&gt;01000&lt;br /&gt;01001&lt;br /&gt;01010&lt;br /&gt;10000&lt;br /&gt;10001&lt;br /&gt;10010&lt;br /&gt;10100&lt;br /&gt;10101&lt;br /&gt;&lt;br /&gt;n=1  number=2&lt;br /&gt;n=2  number=3&lt;br /&gt;n=3  number=5&lt;br /&gt;n=4  number=8&lt;br /&gt;n=5  number=13&lt;br /&gt;n=6  number=21&lt;br /&gt;n=7  number=34&lt;br /&gt;n=8  number=55&lt;br /&gt;n=9  number=89&lt;br /&gt;n=10  number=144&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-5444282482661358418?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/5444282482661358418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/11/code-kata-3-how-many-n-digit-binary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5444282482661358418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/5444282482661358418'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/11/code-kata-3-how-many-n-digit-binary.html' title='code Kata 3,   How many n-digit binary numbers are there that don&apos;t have two adjacent 1 bits?'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3448166719022818981</id><published>2009-11-12T23:14:00.006-05:00</published><updated>2009-11-12T23:35:29.528-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><title type='text'>Build an iPhone application without Interface Builder</title><content type='html'>I am still a beginner of iPhone developer. I finished a tutorial book.  Right now I am trying to read another one. But I found my problem:  I only know how to build the application using the Interface Builder, but I don’t know the underlying mechanism of the application, for example; what is the life cycle of the application, how does the application delegate, ViewController and View interact each other?&lt;br /&gt;&lt;br /&gt;Using Interface Builder makes the application developing very easy, it separate out the presentation logic with the application logic. I like this idea, but for beginner only know the Interface Builder is not enough: &lt;br /&gt;- It makes your job easier, but also hides the application information, and blocks you to understand the underlying mechanism. For example, When I investigate the sample code LocateMe, it uses UITabBarController and NavigationgController for each tab, when I read the source code, I don’t know the where the variable navigationController come from, I don’t know how it created. It is set in the nib file, and you have to read the reference document to see how it works.&lt;br /&gt;&lt;br /&gt;-  Sometime you need to customize your app, Interface Builder will not help you, you have to do it programmatically. For example,  I tried to add a UIScrollView using the interface builder, but I found it does not scroll as I expected.&lt;br /&gt;&lt;br /&gt;I google the solution and found this video is helpful:&lt;br /&gt;&lt;object width="400" height="251"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=3363949&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=3363949&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="251"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/3363949"&gt;Building iPhone Applications without Interface Builder&lt;/a&gt; from &lt;a href="http://vimeo.com/mcilvena"&gt;Troy Mcilvena&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;And this blog:&lt;a href="http://blog.shinetech.com/?p=195"&gt;Why would you use Interface Builder for iPhone Development?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I just summarize the detailed steps:&lt;br /&gt;&lt;br /&gt;1. In Xcode wizard, choose Window-based Application, then delete the MainWindow.xib,  remove the property with the key ‘Main nib file base name’ (the raw key name is ‘NSMainNibFile’) from your Info.plist file.&lt;br /&gt;&lt;br /&gt;2. In main.m, add your AppDelegate class name in the last argument of the UIApplicationMain method.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;int main(int argc, char *argv[]) {&lt;br /&gt;    &lt;br /&gt;    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];&lt;br /&gt;    int retVal = UIApplicationMain(argc, argv, nil, @"NoNibAppDelegate");&lt;br /&gt;    [pool release];&lt;br /&gt;    return retVal;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;3.  In AppDelegate class, initialize and configure the window and Controller object. &lt;br /&gt;&lt;br /&gt;   For example: NoNibAppDelegate.m&lt;br /&gt;&lt;blockquote&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {    &lt;br /&gt;&lt;br /&gt;    // Override point for customization after application launch&lt;br /&gt; window = [[UIWindow alloc] initWithFrame:[ [UIScreen mainScreen] bounds]];&lt;br /&gt;  &lt;br /&gt; RootViewController *root = [[RootViewController alloc] init];&lt;br /&gt; [window addSubview:root.view];&lt;br /&gt;             [window makeKeyAndVisible];&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;4.  In your ViewController class, implement the loadView()  method &lt;br /&gt;From UIViewController Reference document: If you create your views manually, you must override this method and use it to create your views&lt;br /&gt;&lt;blockquote&gt;- (void)loadView&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; UIView *contentView = [[ButtonView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];&lt;br /&gt; &lt;br /&gt; self.view = contentView;&lt;br /&gt;           [contentView release];&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;5. In View class,  implement the initWithFrame: method&lt;br /&gt;“If you create a view object programmatically, this method is the designated initializer for the UIView class.”  - From UIView reference document.&lt;br /&gt;&lt;blockquote&gt;- (id)initWithFrame:(CGRect)frame {&lt;br /&gt;    if (self = [super initWithFrame:frame]) {&lt;br /&gt;        &lt;br /&gt;  self.backgroundColor = [UIColor lightGrayColor];&lt;br /&gt;  &lt;br /&gt;  UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 30.0f)];&lt;br /&gt;  label.text = @"Hello World";&lt;br /&gt;  label.center = self.center;&lt;br /&gt;  label.backgroundColor = [UIColor clearColor];&lt;br /&gt;  label.textAlignment = UITextAlignmentCenter;&lt;br /&gt;  &lt;br /&gt;  [self addSubview:label];&lt;br /&gt;    }&lt;br /&gt;    return self;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;6.  You might want to register an UIControl event listener:&lt;br /&gt;  - Intitialize the UIControl object, for example a UIButton:&lt;br /&gt;&lt;blockquote&gt;[buttonPress addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;   -  implement the event call back method:&lt;br /&gt;&lt;blockquote&gt;-(void)buttonClicked:(id)sender&lt;br /&gt;{&lt;br /&gt; UIButton *button = (UIButton *)sender;&lt;br /&gt; NSString *text = button.currentTitle;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; NSString *string = [ [NSString alloc] initWithFormat:@"Button %@ pressed.",text];&lt;br /&gt; &lt;br /&gt;     NSLog(@"button clicked. button title:%@", text);&lt;br /&gt; &lt;br /&gt; self.label.text = string;&lt;br /&gt; [string release];&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;You can download my sample code from &lt;a href="http://www.4shared.com/file/151158285/50366f50/NoNib.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;From this investigation, I understand the iPhone application life cycle and event flow; know the underlying mechanism and get the confidence to customize application in future.&lt;br /&gt;&lt;br /&gt;For learning iPhone, I am trying to follow the &lt;a href="http://www.shuhari.com/site/view/ShuharisMeaning.pml"&gt;Shu-Ha-Ri&lt;/a&gt; learning model:  at the Shu level, which is called following and copying, so I just follow one book: &lt;a href=" http://www.amazon.com/Beginning-iPhone-Development-Exploring-SDK/dp/1430224592/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1258084158&amp;sr=1-1"&gt;Beginning iPhone 3 Development: Exploring the iPhone SDK&lt;/a&gt;. I just follow step by step, copy every line of the code from the book. This is a very good book for the beginner who never touch the apple development environment like me, but it does not cover the deeper information, which I am really want to understand now.&lt;br /&gt;&lt;br /&gt;So I think it is time for me to go to Ha level: which is breaking, it means trying to collecting different information and trying to read different article and books, Now I learned that it is time for me and I am ready to read Apple reference document, read advanced iPhone books, investigate the sample code, joining the forum, and practice.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tutorial gives you a starting point, Interface Builder is a crutch, it is time for you to remove them if you want to get improved.&lt;br /&gt;&lt;br /&gt;Here is my reading list for iPhone in fufure:&lt;br /&gt; -  Apple iPhone reference documents and API documents&lt;br /&gt; -  Apple iPhone sample codes&lt;br /&gt; -  &lt;a href="http://www.amazon.com/iPhone-Developers-Cookbook-Building-Applications/dp/0321555457/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1258083608&amp;sr=8-1-spell"&gt;The iPhone Developer's Cookbook: Building Applications with the iPhone SDK&lt;/a&gt;&lt;br /&gt;     This is a really good book, but not for beginner, it tells your more detailed information which is not covered in other books. I am waiting for the 2nd edtion.&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;- &lt;a href="http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40007072-CH8-SW1"&gt;iPhone Application Programming Guide&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.amazon.com/iPhone-Developers-Cookbook-Building-Applications/dp/0321555457/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1258083608&amp;sr=8-1-spell"&gt;The iPhone Developer's Cookbook: Building Applications with the iPhone SDK&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-3448166719022818981?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3448166719022818981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/11/build-iphone-application-without.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3448166719022818981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3448166719022818981'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/11/build-iphone-application-without.html' title='Build an iPhone application without Interface Builder'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-7210103008765410821</id><published>2009-11-08T22:55:00.004-05:00</published><updated>2011-08-06T22:33:31.860-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code craft'/><title type='text'>Code Kata 2 - Reverse words in a string  using Ruby</title><content type='html'>Last time I posted the blog &lt;a href="http://code-dojo.blogspot.com/2009/10/code-kata-reverse-word-in-string.html"&gt;&lt;span style="font-weight: bold;"&gt;Code Kata - Reverse words  in a string&lt;/span&gt;&lt;/a&gt;, in that blog I provided the java solution. Today I will try to solve this problem using Ruby.&lt;br /&gt;&lt;br /&gt;Question: How to reverse words in a string? &lt;br /&gt;For example, given a string "The quick brown fox jumped over the lazy dog", reversed string needs to be “dog lazy the over jumped fox brown quick The”. &lt;br /&gt;And this time there is no memory constraint, we just focus on providing an elegant and concise code.&lt;br /&gt;&lt;br /&gt;The algorithm has two steps:&lt;br /&gt;1. First reverse the entire string by character&lt;br /&gt;For example: "The quick brown fox jumped over the lazy dog" becomes&lt;br /&gt;“god yzal eht revo depmuj xof nworb kciuq ehT”&lt;br /&gt;2. Then reverse each word by character&lt;br /&gt;For example: “god yzal eht revo depmuj xof nworb kciuq ehT” becomes&lt;br /&gt;“dog lazy the over jumped fox brown quick The”&lt;br /&gt;&lt;br /&gt;The ruby code would be:&lt;br /&gt;&lt;script src="https://gist.github.com/1129996.js?file=reverse_string.rb"&gt;&lt;/script&gt;&lt;br /&gt;The method reverse_string() will return an array instead of a string, but it does not matter here. You can see how easy to implement using Ruby compare to Java!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-7210103008765410821?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/7210103008765410821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/11/code-kata-2-reverse-words-in-string.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7210103008765410821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7210103008765410821'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/11/code-kata-2-reverse-words-in-string.html' title='Code Kata 2 - Reverse words in a string  using Ruby'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8523332506307959365</id><published>2009-11-04T23:34:00.007-05:00</published><updated>2010-02-10T18:37:38.463-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software design'/><title type='text'>My Presentation: The OO design principles</title><content type='html'>&lt;div id="__ss_2426183" style="text-align: left; width: 425px;"&gt;&lt;a href="http://www.slideshare.net/intellizhang/the-oo-design-principles" style="display: block; font-family: Helvetica,Arial,Sans-serif; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; margin: 12px 0pt 3px; text-decoration: underline;" title="The OO Design Principles"&gt;The OO Design Principles&lt;/a&gt;&lt;object height="355" style="margin: 0px;" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=theoodesignprinciplesv2-091104223017-phpapp01&amp;stripped_title=the-oo-design-principles" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=theoodesignprinciplesv2-091104223017-phpapp01&amp;stripped_title=the-oo-design-principles" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="font-family: tahoma,arial; font-size: 11px; height: 26px; padding-top: 2px;"&gt;View more &lt;a href="http://www.slideshare.net/" style="text-decoration: underline;"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/intellizhang" style="text-decoration: underline;"&gt;Steve Zhang&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;This is my presentation about OO software design principles: &lt;a href="http://www.slideshare.net/intellizhang/the-oo-design-principles"&gt;http://www.slideshare.net/intellizhang/the-oo-design-principles&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The whole slide is copied from the following two books:&lt;br /&gt;1. &lt;a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257397088&amp;amp;sr=8-1"&gt;Agile Software Development: Principles, Patterns, and Practices&lt;/a&gt;, by Uncle Bob&lt;br /&gt;&lt;br /&gt;2. &lt;a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257397164&amp;amp;sr=8-1"&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/a&gt;, by Dave Thomas and Andy Hunt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-8523332506307959365?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/8523332506307959365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/11/my-presentation-oo-design-principles.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8523332506307959365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/8523332506307959365'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/11/my-presentation-oo-design-principles.html' title='My Presentation: The OO design principles'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4055810109273645829</id><published>2009-10-26T22:02:00.011-04:00</published><updated>2009-10-26T22:18:23.505-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code craft'/><title type='text'>Code Kata – Reverse words  in a string</title><content type='html'>Dave Thomas creates a website called &lt;a href=" http://codekata.pragprog.com/"&gt;&lt;span style="font-weight:bold;"&gt;Code Kata&lt;/span&gt;&lt;/a&gt;, Who encourage developers improve their skills by keep practicing coding, trying to find better solutions for some questions.&lt;br /&gt;&lt;br /&gt;Today I met an interesting question: &lt;span style="font-weight:bold;"&gt;How to reverse words in a string?&lt;/span&gt; &lt;br /&gt;For example, given a string "The quick brown fox jumped over the lazy dog", reversed string needs to be “dog lazy the over jumped fox brown quick The”. The thing is you can not use extra memory to do it, you had better manipulate the reverse logic in the original text string.&lt;br /&gt;&lt;br /&gt;To solve this question, I remembered I read a good book several years ago, it is called &lt;a href="http://www.amazon.com/Programming-Pearls-2nd-Jon-Bentley/dp/0201657880/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1256607122&amp;sr=8-1"&gt;&lt;span style="font-weight:bold;"&gt;Programming Pearls&lt;/span&gt;&lt;/a&gt; ,written by John Bentley.&lt;br /&gt;&lt;br /&gt;In chapter 2, section “The power of Primitive”, the author gives the solution of transform an array vector, which is clean, elegant and efficient. I used this solution to solve this problem.&lt;br /&gt;The algorithm has two steps:&lt;br /&gt;1. First reverse the entire string by character&lt;br /&gt;For example:  "The quick brown fox jumped over the lazy dog" becomes&lt;br /&gt;             “god yzal eht revo depmuj xof nworb kciuq ehT”&lt;br /&gt;2. Then reverse each word by character&lt;br /&gt;For example:   “god yzal eht revo depmuj xof nworb kciuq ehT” becomes&lt;br /&gt;              “dog lazy the over jumped fox brown quick The”&lt;br /&gt;&lt;br /&gt;You see it is pretty easy, right?  No need extra memeory, no need substring.This is the power of the algorithm.&lt;br /&gt;&lt;br /&gt;Here I post the java version of the solution, you can easily implement this algorithm in C or other language.&lt;br /&gt;&lt;br /&gt;public class StringRerverse {&lt;br /&gt; &lt;br /&gt; private int wordStartIndex;&lt;br /&gt; private int wordEndIndex;&lt;br /&gt; private StringBuffer sBuffer;&lt;br /&gt;   &lt;br /&gt; String reverse(String string)&lt;br /&gt; {&lt;br /&gt; &lt;br /&gt;  this.sBuffer = new StringBuffer(string); &lt;br /&gt;&lt;br /&gt;  sBuffer.reverse();&lt;br /&gt;  &lt;br /&gt;  int size = sBuffer.length();&lt;br /&gt;  int pos = 0;&lt;br /&gt;  &lt;br /&gt;  while(pos &amp;lt; size)&lt;br /&gt;  {&lt;br /&gt;   if(findNextWord(pos) == true)&lt;br /&gt;   {&lt;br /&gt;      reverseWord(sBuffer,wordStartIndex,wordEndIndex);&lt;br /&gt;      pos = wordEndIndex+1;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    break;&lt;br /&gt;   }&lt;br /&gt;  }  &lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  return sBuffer.toString();&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; boolean findNextWord(int startFrom)&lt;br /&gt; {&lt;br /&gt;        int start = startFrom;&lt;br /&gt;                &lt;br /&gt;        while (start&amp;lt; sBuffer.length()-1 &amp;&amp; sBuffer.charAt(start) == ' ')&lt;br /&gt;        {&lt;br /&gt;         start++;&lt;br /&gt;        }&lt;br /&gt;        if(start == sBuffer.length() -1 )&lt;br /&gt;        {&lt;br /&gt;         return false;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        wordStartIndex = start;&lt;br /&gt;        &lt;br /&gt;        int end = start+1;        &lt;br /&gt;        while(end &amp;lt; sBuffer.length()-1 &amp;&amp; sBuffer.charAt(end) != ' ' )&lt;br /&gt;        {&lt;br /&gt;         end++;&lt;br /&gt;        }&lt;br /&gt;        if(end == sBuffer.length() -1 )&lt;br /&gt;        {&lt;br /&gt;         wordEndIndex = end;&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {        &lt;br /&gt;          wordEndIndex= end-1;&lt;br /&gt;        }        &lt;br /&gt;        return true;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; void reverseWord(StringBuffer sBuffer,int wordStartIndex, int wordEndIndex)&lt;br /&gt; {&lt;br /&gt;  int length = wordEndIndex - wordStartIndex + 1;&lt;br /&gt;  for(int j = 0; j&amp;lt;length/2; j++)&lt;br /&gt;  {&lt;br /&gt;   &lt;br /&gt;   int startIndex = wordStartIndex + j;&lt;br /&gt;   int endIndex = wordEndIndex - j; &lt;br /&gt;   char c = sBuffer.charAt(startIndex);&lt;br /&gt;   sBuffer.setCharAt(startIndex, sBuffer.charAt(endIndex));&lt;br /&gt;   sBuffer.setCharAt(endIndex, c);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;      public static void main(String[] args)&lt;br /&gt;      {&lt;br /&gt;       StringRerverse reverse = new StringRerverse();&lt;br /&gt;       &lt;br /&gt;       String string = new String("The quick brown fox jumped over the lazy dog");&lt;br /&gt;       String reverseString = reverse.reverse(string);&lt;br /&gt;       System.out.println("reversed String: "+reverseString);&lt;br /&gt;       &lt;br /&gt;      }&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4055810109273645829?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4055810109273645829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/10/code-kata-reverse-word-in-string.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4055810109273645829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4055810109273645829'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/10/code-kata-reverse-word-in-string.html' title='Code Kata – Reverse words  in a string'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-3205826090635895359</id><published>2009-10-25T15:01:00.006-04:00</published><updated>2010-02-10T18:41:07.863-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>From Good to Great Developer</title><content type='html'>Last week I watch a presentation called “From good to great developer“ from &lt;a href="http://www.infoq.com/"&gt;www.infoq.com&lt;/a&gt;.&lt;br /&gt;Here is the link : &lt;a href="http://www.infoq.com/presentations/Good-to-Great-Developer-Chris-Hedgate"&gt;http://www.infoq.com/presentations/Good-to-Great-Developer-Chris-Hedgate&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Chris Hedgate made a really great presentation. He pointed out that good developer writes code quickly but hard to maintain; but great developer has long term goal and try to write clean code and make it easier to maintain.&lt;br /&gt;&lt;br /&gt;He also gave the advices how to become a great developer. I really like the 4-stage learning model he introduced: unconscious incompetence, conscious incompetence, conscious competence and unconscious competence. The learner in different stage will take different actions: inspiration, training, practice and reflection.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Talking about becoming a great developer, which is the same idea coming from Agile. It means craftsmanship, professionalism, discipline, and mastery. I think every serious developer should have a goal to become a great developer or master programmer, just like kong-fu master or samurai. It is a whole life’s practice.&lt;br /&gt;&lt;br /&gt;Being a great developer is not an easy job. You need to understand the agile principles, understand design patterns, have disciplines and patience to write clean codes and keep refactoring; you have to constantly reflect yourself; you need to keep learning new technologies. And you need to help other people and try to motivate and inspire them. This is raising the bar, it is hard, but this is the only way to create a remarkable career for you, the only way to give you a passion, and the only way to transcend yourself.&lt;br /&gt;&lt;br /&gt;Here I add some other videos which share the same philosophy:&lt;br /&gt;&lt;br /&gt;1. &lt;span style="font-weight: bold;"&gt;Craftsmanship and Ethics&lt;/span&gt;, by Robert Martin:&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/craftmanship-ethics"&gt;http://www.infoq.com/presentations/craftmanship-ethics&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2. &lt;span style="font-weight: bold;"&gt;Developing Expertise: Herding Racehorses, Racing Sheep&lt;/span&gt;, by Dave Thomas&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/Developing-Expertise-Dave-Thomas"&gt;http://www.infoq.com/presentations/Developing-Expertise-Dave-Thomas&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dave Thomas is the author of “Pragmatic Programmer, from journeyman to master”. This video talks about the Dreyfus model, which is 5-stage learning model. The details about it is in the Book “Pragmatic learning and thinking” by Andy Hunt.&lt;br /&gt;&lt;br /&gt;3.&lt;span style="font-weight: bold;"&gt; I Come to Bury Agile, Not to Praise It&lt;/span&gt;, by Alistar CockBurn&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/cockburn-bury-not-praise-agile"&gt;http://www.infoq.com/presentations/cockburn-bury-not-praise-agile&lt;/a&gt;&lt;br /&gt;This video talks about a Shu-Ha-Ri, a 3-stage learning model, I first learned Shu-Ha-Ri from his book “Agile Software Development”&lt;br /&gt;&lt;br /&gt;4. &lt;span style="font-weight: bold;"&gt;Deliberate Practice in Software Development&lt;/span&gt;, by Marry Poppendieck,&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/poppendieck-deliberate-practice-in-software-development"&gt;http://www.infoq.com/presentations/poppendieck-deliberate-practice-in-software-development&lt;/a&gt;&lt;br /&gt;Marry Poppendieck is regarded the first person who apply Toyota’s Lean technology into software development, this video she provide the 10-year rule theory, emphasizes the craftsmanship and clean code.&lt;br /&gt;&lt;br /&gt;5. &lt;span style="font-weight: bold;"&gt;Productive Programmer: On the Lam from the Furniture Police&lt;/span&gt;, by Neal Ford&lt;br /&gt;&lt;a href="http://library.theserverside.com/detail/RES/1242309506_447.html?asrc=vcatssc_sitepost_05_14_09"&gt;http://library.theserverside.com/detail/RES/1242309506_447.html?asrc=vcatssc_sitepost_05_14_09&lt;/a&gt;&lt;br /&gt;The author of “Productive programmer”, he talked about the principles in his book, the book of “Peopleware” and “pragmatic learning and thinking”&lt;br /&gt;&lt;br /&gt;6. &lt;span style="font-weight: bold;"&gt;Transcendence and Passing Through the Gate&lt;/span&gt;, by Dave West&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/transcendence-gate-dave-west"&gt;http://www.infoq.com/presentations/transcendence-gate-dave-west&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This video is really interesting, it talks about agile, but he use the concept of Zen. He mentioned the famous 10 Bulls pictures which describe 10 different stages of a human being to describe the agile development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-3205826090635895359?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/3205826090635895359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/10/from-good-to-great-developer.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3205826090635895359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/3205826090635895359'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/10/from-good-to-great-developer.html' title='From Good to Great Developer'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-9012049164104339620</id><published>2009-10-12T16:58:00.004-04:00</published><updated>2009-10-12T17:03:14.930-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Learning from the Book Of Five Rings</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lxmigwrwDfI/StOY3XQtTcI/AAAAAAAAAAM/wx4WbgBDHG0/s1600-h/Thebookof5rings.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://4.bp.blogspot.com/_lxmigwrwDfI/StOY3XQtTcI/AAAAAAAAAAM/wx4WbgBDHG0/s320/Thebookof5rings.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5391821255796936130" /&gt;&lt;/a&gt;&lt;br /&gt;Miamoto Musashi was a very famous Japanese saumari, who wrote a book called The book of Five Rings. I first heard of him by Alistir CockBurn’s book – Agile Software Devleopment. &lt;br /&gt;&lt;br /&gt;The good thing is Alistair pointed out what we can learn from his book into our software development. Here is what Alistair pointed out:&lt;br /&gt;&lt;br /&gt;• Do not develop an attachment to any one weapon or anyone school of fighting.&lt;br /&gt;Use the rang of them without getting stuck in anyone.&lt;br /&gt;• Practice and observe reflectively.   &lt;br /&gt;Practice hard, win big (pointed out by Jeff Sutherland, the SCRUM creator)&lt;br /&gt;• Win&lt;br /&gt;Pay more attention to winning than to looking good, &lt;br /&gt;“Do not do anything useless”&lt;br /&gt;&lt;br /&gt;Here I also would like to copy what his rules for learning the art ( from page 41):&lt;br /&gt;1. Think of what is right and true.&lt;br /&gt;2. Practice and cultivate the science.&lt;br /&gt;3. Become acquainted with the arts.&lt;br /&gt;4. Know the principles of the crafts.&lt;br /&gt;5. Understand the harm and benefit in everything.&lt;br /&gt;6. Learn to see everything accurately.&lt;br /&gt;7. Become aware of what is not obvious.&lt;br /&gt;8. Be careful even in small matters.&lt;br /&gt;9. Do not do anything useless.&lt;br /&gt;&lt;br /&gt;The interesting thing is that in the book, Mushasi use carpentry as a metaphor for mastering his science of martial art. (from page 9, Likening the Science of Martial Arts to Carpentry). It seems every word can be used to software development, used as principles of mastering programmer's skills.&lt;br /&gt;&lt;br /&gt;In future I will post more about this book.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-9012049164104339620?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/9012049164104339620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/10/learning-from-book-of-five-rings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/9012049164104339620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/9012049164104339620'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/10/learning-from-book-of-five-rings.html' title='Learning from the Book Of Five Rings'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lxmigwrwDfI/StOY3XQtTcI/AAAAAAAAAAM/wx4WbgBDHG0/s72-c/Thebookof5rings.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4566935702099894469</id><published>2009-10-12T15:54:00.004-04:00</published><updated>2010-02-10T18:47:11.328-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>My vision of a good software developing team</title><content type='html'>We need to do things in the right way. In Chinese, “way” means “TAO”. If we follow the TAO of the software development, then we can deliver the great product in a short time.&lt;br /&gt;&lt;br /&gt;Following are my vision for a good software developing team, and what the TAO should be:&lt;br /&gt;&lt;br /&gt;- Follow good design&lt;br /&gt;We need follow good OO design principles, and good design patterns. A good design is a foundation of a software product, and a good design is the DNA of a good product.&lt;br /&gt;&lt;br /&gt;- Build Quality in&lt;br /&gt;We need to balance between long-term benefits with short term benefits&lt;br /&gt;Our software should be: flexibility, maintainability, and readability.&lt;br /&gt;&lt;br /&gt;- Write clean code, constantly keep refactoring, continuously improving design&lt;br /&gt;I like Uncle Bob’s saying” If code is messy, so does the product”.&lt;br /&gt;Bad code slows down the productivity&lt;br /&gt;Only one way to go fast is going well, writing clean code.&lt;br /&gt;&lt;br /&gt;- Design for maintenance&lt;br /&gt;The only way to develop maintainable code is to design the maintainability at design phase&lt;br /&gt;&lt;br /&gt;- Deliver DRY project&lt;br /&gt;DRY means “Don’t Repeat Yourself”.     &lt;br /&gt;Here I would like to mention the definition of what does mean a project is Done:&lt;br /&gt;1. Deliver the product to our customer&lt;br /&gt;2. Developers improve their skills;&lt;br /&gt;3. Team gain knowledge;&lt;br /&gt;4. The design and code is easier for future project&lt;br /&gt;I think all these 4 things together means a project is done, but currently we only focus on No. 1, which cause on the problem in future: since the code is not reusable, we have to rebuild the entire app, or we have to duplicate all the old code, which either by fixing duplicating bugs or by spending long time to fix the issues by adding new codes. Finally we spend more time and money by reinventing the wheels.&lt;br /&gt;&lt;br /&gt;- Test Driven Development&lt;br /&gt;We need are not only use JUnit, but also to make sure our design is easier for unit test, our framework is easier to using unit test.&lt;br /&gt;&lt;br /&gt;- Build automation&lt;br /&gt;Our build automation should support everywhere, server side code, client side code, and test code.&lt;br /&gt;Everything we need should be checked in the repository, including dependent libraries, config files, property files, database script, build tools, etc.&lt;br /&gt;&lt;br /&gt;- Use static analysis tools&lt;br /&gt;Currently there a lots of open source static analysis tools. For example they can find the potential bugs; tell you how complex of your code, how messy your code is, and tell you the coverage of your test code, etc. which will help us improving our code quality greatly&lt;br /&gt;&lt;br /&gt;- Foster knowledge sharing and internal training&lt;br /&gt;We need to build an environment which can foster knowledge management in our company, which is called ‘ba’ in “Lean technology”. We need to use Wiki, internal forum, internal training to share the knowledge for all the developers.&lt;br /&gt;Knowledge management is very important &lt;br /&gt;&lt;br /&gt;- Following the Agile&lt;br /&gt;We need not only do the agile practices, but need also fully understand the agile principles and its values.&lt;br /&gt;And each team needs to use different agile methods.&lt;br /&gt;Developer needs to follow XP;&lt;br /&gt;Manager team needs to follow Scrum&lt;br /&gt;The whole company needs to follow Lean technology&lt;br /&gt;&lt;br /&gt;- Training developer to be professionalism&lt;br /&gt;We need our developers have the concept of:&lt;br /&gt;Professionalism, craftsmanship, discipline, ethics, etc.&lt;br /&gt;&lt;br /&gt;Next I want to discuss more about the gap between the manager and developer. I think there is a role we are missing – “coach”. I think a good coach will be a bridge connecting developers and managers, his role is filling the gap. &lt;br /&gt;I would like to make a metaphor: thinking our software team as a sports team- whether basketball team or a hokey team. In a sports team a coach plays a very important role:&lt;br /&gt;- Design the wining strategy for the team&lt;br /&gt;- Instruct each player not only what to do but also how to do;&lt;br /&gt;- start timeout when he found the issue during the game, either by substituting a new player or set up a new strategy;&lt;br /&gt;- Training players and improve their skills;&lt;br /&gt;- Motivate players and find their potentials;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So my suggestion is we need a coach or several coaches in our development team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4566935702099894469?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4566935702099894469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/10/my-vision-of-good-software-developing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4566935702099894469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4566935702099894469'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/10/my-vision-of-good-software-developing.html' title='My vision of a good software developing team'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-7192846884518667671</id><published>2009-10-02T19:25:00.007-04:00</published><updated>2009-10-02T19:35:33.653-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Be prepared to leave</title><content type='html'>I was totally motivated by the book -&lt;a href="http://www.amazon.com/Passionate-Programmer-Remarkable-Development-Pragmatic/dp/1934356344"&gt;The passionate programmer&lt;/a&gt;. Now I am trying to copy the author’s idea and write an essay using his style, the name is called “Be prepared to leave”.&lt;br /&gt;&lt;br /&gt;Usually people start to update their resume when they want to find a new job, then they realize their problems: they found it is hard to review what they did in the past few years; they realize their skills might be outdated; they don’t know where to go, just randomly submit their resumes. Every thing seems to be by accident, not deliberately.&lt;br /&gt;&lt;br /&gt;So how can we plan our career deliberately? My answer is be prepared to leave. If you have this mind set, you have a positive attitude of doing your daily jobs. Suppose you are going to leave or be fired, then it force you to update your resume regularly, to update your resume, it forces you to review yourself constantly:&lt;br /&gt;&lt;br /&gt;• For every project you finished, you ask yourself: how did I finish it, what kind of skills I used, how can I add a good achievement in my resume? How can I improve it? How can I use the current new technology into my project, so that I can improve my work and also I can add it into my resume? If you summarize and review your work constantly, you will find you have many good points to put into your resume. &lt;br /&gt;&lt;br /&gt;• Find your blind spots. Since you are going to leave, you need to take chance trying to learn what you don’t know. Think it proactively, when you find your blind spot, then try to fix it as soon as possible. When you find you have a challenge to do some job, then it is probably a blind spot for you, and it is a good opportunity for you to get improved. For example you found it is very painful for you to deploy or build a project, because it needs you manually do many different steps and easy to make error. So why not improve the build script and improve the build automation process? If you have this attitude, you will find every job is interesting, even it is a maintain job.&lt;br /&gt;&lt;br /&gt;• Research the market regularly, try to find the skills the market need and what skills you need to improve and learn; try to find the company you want to go and find out what kind of technologies they are using, then try to learn it, try to use them into your current project.&lt;br /&gt;&lt;br /&gt;In summary when you have a “be prepared to leave” attitude, you will not find your daily job is boring any more, you will find many opportunities to improve yourself. Sooner or later your skills and thoughts will go to next level, and you will be easily got a good new job when chances come.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-7192846884518667671?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/7192846884518667671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/10/be-prepared-to-leave.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7192846884518667671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/7192846884518667671'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/10/be-prepared-to-leave.html' title='Be prepared to leave'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-4030025588134794579</id><published>2009-10-02T14:27:00.005-04:00</published><updated>2009-10-02T14:42:26.188-04:00</updated><title type='text'>IPhone development: memory management rules</title><content type='html'>Right now I am learning the IPhone development using objective-C, I have to admit that I am a new beginner of objective-C, even if I have lots of experience of C/C++ development, the syntax of object-C confuse me a lot. &lt;br /&gt;&lt;br /&gt;Right now I run into a problem: when should we release the object? Here is the example:&lt;br /&gt;&lt;br /&gt;           &lt;span style="font-weight:bold;"&gt; YellowViewController *yellowController = &lt;br /&gt;             [ [YellowViewController alloc] initWithNibName:@"YellowView" &lt;br /&gt;                                                   bundle:nil];&lt;br /&gt;            self.yellowViewController = yellowController;&lt;br /&gt;            [yellowController release];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It seems an idiom for objective-c memory management, since I’ve seen lots of source code did in the similar way. I was really confused, since I treated the objective-c object as a c++ pointer. In the above example, &lt;span style="font-weight:bold;"&gt;yellowController &lt;/span&gt;and &lt;span style="font-weight:bold;"&gt;self.yellowViewController&lt;/span&gt; are pointers, they are pointing to the same memory address, if we release yellowController, then how about &lt;span style="font-weight:bold;"&gt;self.yellowViewController&lt;/span&gt;?  Will it become an invalid object because it is pointing to the memory address which was released already?&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Through me research, then I understand the memory management rule of objective-c. It uses reference counting method to manage the memory:&lt;br /&gt;- When create an object using alloc, the reference count will be 1;&lt;br /&gt;- When release method is called,  decreases reference counter by 1;&lt;br /&gt;- When copy or retain method is called, increases the reference counter by 1;&lt;br /&gt;&lt;br /&gt;Then I have a question: how about the assignment operation? What does it exactly do? Will it increase the reference counter or will it copy the whole object data to the variable &lt;span style="font-weight:bold;"&gt;self.yellowViewController&lt;/span&gt;?&lt;br /&gt;&lt;br /&gt;Finally I realize that the key is in the definition of  the instance variable &lt;span style="font-weight:bold;"&gt;self.yellowViewController&lt;/span&gt;:&lt;br /&gt;It’s definition is like this:&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;@property (retain, nonatomic) YellowViewController *yellowViewController;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Which means we do the assignment operation to the class variable self.yellowViewController, the retain method will be called, which means the reference counter will be increased by 1.&lt;br /&gt;&lt;br /&gt;We can use the following methods to check the reference counter:&lt;br /&gt;NSLog([NSString stringWithFormat:@"%u", [yellowController retainCount]]);&lt;br /&gt;self. yellowViewController = yellowController;&lt;br /&gt;NSLog([NSString stringWithFormat:@"%u", [yellowController retainCount]]); &lt;br /&gt;&lt;br /&gt;In summary, here is the simple rules for object-c memory management:&lt;br /&gt;&lt;br /&gt;Retention Count rules: (copy from &lt;a href="http://www.stepwise.com/Articles/Technical/2001-03-11.01.html"&gt;here&lt;/a&gt;) &lt;br /&gt;1. Within a given block, the use of -copy, -alloc and -retain should equal the use of -release and -autorelease.&lt;br /&gt;2. Objects created using convenience constructors (e.g. NSString's stringWithString) are considered autoreleased. &lt;br /&gt;3. Implement a -dealloc method to release the instance variables you own&lt;br /&gt;&lt;br /&gt;Some good references:&lt;br /&gt;1. &lt;a href="http://www.stepwise.com/Articles/Technical/2001-03-11.01.html"&gt;Very simple rules for memory management in Cocoa&lt;/a&gt;&lt;br /&gt;2.  &lt;a href="http://www.cocoadevcentral.com/d/learn_objectivec/"&gt;Learn Objective-C&lt;/a&gt;&lt;br /&gt;3.  &lt;a href="http://www.iphonedevforums.com/forum/general-development-questions-advice/131-newbie-memory-management-question-release.html"&gt;Forum thread: newbie memory management question ("release")&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3555300218296290557-4030025588134794579?l=code-dojo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-dojo.blogspot.com/feeds/4030025588134794579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://code-dojo.blogspot.com/2009/10/iphone-development-memory-management.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4030025588134794579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3555300218296290557/posts/default/4030025588134794579'/><link rel='alternate' type='text/html' href='http://code-dojo.blogspot.com/2009/10/iphone-development-memory-management.html' title='IPhone development: memory management rules'/><author><name>Steve Zhang</name><uri>http://www.blogger.com/profile/11521569965417254322</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://2.bp.blogspot.com/_lxmigwrwDfI/SvIzD--m6-I/AAAAAAAAAAY/yKSH1QWypPk/S220/mypic3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3555300218296290557.post-8368242885922552766</id><published>2009-09-20T21:17:00.002-04:00</published><updated>2009-09-20T21:53:09.912-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blackberry'/><title type='text'>Using ANT to build BlackBerry J2ME application - source code build</title><content type='html'>&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CSTEVEN%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"&gt;&lt;o:smarttagtype namespaceuri="urn:schemas-microsoft-com:office:smarttags" name="place"&gt;&lt;/o:smarttagtype&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 pt&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if !mso]&gt;&lt;object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id="ieooui"&gt;&lt;/object&gt; &lt;style&gt; st1\:*{behavior:url(#ieooui) } &lt;/style&gt; &lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:黑体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimHei; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:1 135135232 16 0 262144 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@黑体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:1 135135232 16 0 262144 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;} h2 	{mso-style-next:Normal; 	margin-top:13.0pt; 	margin-right:0cm; 	margin-bottom:13.0pt; 	margin-left:0cm; 	text-align:justify; 	text-justify:inter-ideograph; 	line-height:173%; 	mso-pagination:lines-together; 	page-break-after:avoid; 	mso-outline-level:2; 	font-size:16.0pt; 	font-family:Arial; 	mso-fareast-font-family:黑体; 	mso-bidi-font-family:"Times New Roman"; 	mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink 	{color:blue; 	text-decoration:underline; 	text-underline:single;} a:visited, span.MsoHyperlinkFollowed 	{color:purple; 	text-decoration:underline; 	text-underline:single;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;}  /* List Definitions */  @list l0 	{mso-list-id:175920663; 	mso-list-type:hybrid; 	mso-list-template-ids:1014896698 1932950732 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 	{mso-level-tab-stop:18.0pt; 	mso-level-number-position:left; 	margin-left:18.0pt; 	text-indent:-18.0pt;} @list l1 	{mso-list-id:330641824; 	mso-list-type:hybrid; 	mso-list-template-ids:954993436 1706983106 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l1:level1 	{mso-level-tab-stop:18.0pt; 	mso-level-number-position:left; 	margin-left:18.0pt; 	text-indent:-18.0pt;} @list l2 	{mso-list-id:1618216096; 	mso-list-type:hybrid; 	mso-list-template-ids:-1182115782 -118063052 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l2:level1 	{mso-level-tab-stop:18.0pt; 	mso-level-number-position:left; 	margin-left:18.0pt; 	text-indent:-18.0pt;} ol 	{margin-bottom:0cm;} ul 	{margin-bottom:0cm;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0cm 5.4pt 0cm 5.4pt; 	mso-para-margin:0cm; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;&lt;meta equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;meta name="ProgId" content="Word.Document"&gt;&lt;meta name="Generator" content="Microsoft Word 11"&gt;&lt;meta name="Originator" content="Microsoft Word 11"&gt;&lt;link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CSTEVEN%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"&gt;&lt;o:smarttagtype namespaceuri="urn:schemas-microsoft-com:office:smarttags" name="place"&gt;&lt;/o:smarttagtype&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:drawinggridverticalspacing&gt;7.8 pt&lt;/w:DrawingGridVerticalSpacing&gt;   &lt;w:displayhorizontaldrawinggridevery&gt;0&lt;/w:DisplayHorizontalDrawingGridEvery&gt;   &lt;w:displayverticaldrawinggridevery&gt;2&lt;/w:DisplayVerticalDrawingGridEvery&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:spaceforul/&gt;    &lt;w:balancesinglebytedoublebytewidth/&gt;    &lt;w:donotleavebackslashalone/&gt;    &lt;w:ultrailspace/&gt;    &lt;w:donotexpandshiftreturn/&gt;    &lt;w:adjustlineheightintable/&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:usefelayout/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if !mso]&gt;&lt;object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id="ieooui"&gt;&lt;/object&gt; &lt;style&gt; st1\:*{behavior:url(#ieooui) } &lt;/style&gt; &lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Font Definitions */  @font-face 	{font-family:宋体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimSun; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:黑体; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-alt:SimHei; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:1 135135232 16 0 262144 0;} @font-face 	{font-family:"\@宋体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 16 0 262145 0;} @font-face 	{font-family:"\@黑体"; 	panose-1:2 1 6 0 3 1 1 1 1 1; 	mso-font-charset:134; 	mso-generic-font-family:auto; 	mso-font-pitch:variable; 	mso-font-signature:1 135135232 16 0 262144 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0cm; 	margin-bottom:.0001pt; 	text-align:justify; 	text-justify:inter-ideograph; 	mso-pagination:none; 	font-size:10.5pt; 	mso-bidi-font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:宋体; 	mso-font-kerning:1.0pt;} h2 	{mso-style-next:Normal; 	margin-top:13.0pt; 	margin-right:0cm; 	margin-bottom:13.0pt; 	margin-left:0cm; 	text-align:justify; 	text-justify:inter-ideograph; 	line-height:173%; 	mso-pagination:lines-together; 	page-break-after:avoid; 	mso-outline-level:2; 	font-size:16.0pt; 	font-family:Arial; 	mso-fareast-font-family:黑体; 	mso-bidi-font-family:"Times New Roman"; 	mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink 	{color:blue; 	text-decoration:underline; 	text-underline:single;} a:visited, span.MsoHyperli
