Tuesday, December 28, 2010

The power of Groovy - notes of "Transforming to Groovy"

Yesterday I watched a video presentation from infoQ:"Transforming to Groovy", presented by Venkat Subramaniam, I read his book: Programming Groovy. 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.  I remembered the author describe the Groovy using the term "less ceremony", 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 "reducing the noise".  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 ( essential problem), and spend less time to deal with the language issues (accidental problem), which is noise compare to the business problem.

What I learned
AST transformation
   Before I did not aware the feature of AST transformation in Groovy, probably this is the new feature,  because I did not find this topic in the book.
  The author covered @Immutable, @Newify, and @Delegate

@Immutable
@Immutable class Person {
   String firstName;
   String lastName;
   int age;
}
@Immutable annotation applies to class level only, it does not support on the field level.

@Newify
@Newify def createPerson {
    Person.new("John", "Smith", 28)
}

@Newify(Person)
def createPerson {
   Person("John", "Smith", 28)
}

@Delegate
class TirelessWorker {
   public void work() {}
   public void report() {}
}

class Manager {
   @Delegate employee = new TirelessWorker();
   public void schedule() {}
}

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.

Multimethods
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 multiple dispatch, 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.

ArrayList
use spread-dot operator to access ArrayList
*.  is called spread-dot operator, for example:
list*.member  =  list.collect { item -> item?.member }

It means given a list, iterate each item's specific method, form the return value as a collection.
get each item's first name: list*.firstName

Groovy follows the Kanban principle
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 Kanban's 2 foundational principles: Start with what you do now; Agree to pursue incremental, evolutionary change. Pretty similar.

Based on this, I think Groovy is an important language that worth every Java developer to looking at.

Wednesday, December 15, 2010

Try Pomodoro

Today I finished the book of "Pomodoro Technique Illustrated". 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.

The Pomodoro technique is pretty simple:
- Choose one single activity from your TO DO List;
- Set clock to 25 minutes focused on a single activity for 25 minutes, during this time-boxed 25 minutes,  you only have one activity, and one goal: finish it.
- After 25 minutes, take 5 minutes break;
- Choose the next most important activity, start again;

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.
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,  actually I have not finished the GTD book  yet. It focus on only one thing at a time, and its emphasize on NOW remind me the ZEN philosophy.

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.

I only started Pomodoro for only a week, I like it because it provide you the awareness the time,prioritizing and single minded; 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.

Some notes from the book:

- time-boxed, single activity,single goal
- 5 stages: Planing, Tracking, Processing, Visualizing - retrospective
- Deming-Shewart cycle: plan, do, check, act
- Tools: TODO Today Sheet, Activity Inventory,Record Sheet
- Pomodoro will first Prioritize, then focus on the most important activity (like scrum)
- Pomodoro need to see the big picture before you decide what to do
- it is goal oriented
- it has immediate feedback

Interruptions
- principle: neither switch activities nor stop an activity in the middle of a Pomodoro.
- avoid LIFO
- avoid BPUF

Deal with internal interruptions
- Strategy: Accept, Record and continue
- Write it into Unplanned & Urgent
- never switch activities in the middle of Pomodoro: "Once a Pomodoro begins, it has to ring."

Deal with external interruptions
- Strategy: inform, negotiate,schedule,call back

Resources:
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 link, it tells you how to set the silence only ringtone

Sunday, December 12, 2010

Some thoughts about Conway's law

One of my best learned from QCon San Francisco is Conway's Law, 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:
organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations
In short, you can understand Conway's law like this:

  • The software design structure is constrained or shaped by the company's physical structure;
  • Your code structure mirrors your organization's structure.


This concept is quite interesting and so striking, it forced me into further thinking:

Constraints
Based on Conway's law, we can conclude:

  • Good organization's structure generate good software architecture, bad organization's structure generates bad software architecture;
  • The messy code base reflect its organization's messy management, the clean code base reflects the organization's clear structure;
  • 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.
  • The software manager's style, like/dislike and skills may also constraints the software product;
  • 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.

Conway's law in the other way
Can we good developer influence/improve organization by applying the good practices/patterns/principles?  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: manage a company is like managing software, if you are a good developer you can be a good CEO or manager. We can use the software technologies to manage the company team. Although the context is quite different, they both solve the similar problems: How to manage dependency, how to make the team or software product more adaptable. 
This seems has a higher requirement for the manager, 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.

Thursday, December 2, 2010

Use your pain point to measure your incompetence

Corey Haines's presentation Software Craftsmanship, Beyond the Hype is interesting.
What I get most impressed is what he mentioned a simple way to measure your level of incompetence:
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.
In short, the difference between your ideal and your reality is the measuring of your suck.

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,  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.

Here I would like to share my experience about measuring my incompetence:
Yesterday I tried to follow this article 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:
inside local.sh,  call ant -Dbuild.env=local
inside stage.sh,  call ant -Dbuild.env=stage

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 & 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!
But I need another feature: inside one script, call the methods in another script file.  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.

In build-common.sh, define 3 functions:
 process_arguments()
 set_ant_env()
 call_ant()

buildlocal.sh

  . ./build-common.sh   # this is how to import another file
  set_ant_env
  process_arguments $*
  call_ant local

buildstage.sh
   . ./build-common.sh
  set_ant_env
  process_arguments $*
  call_ant stage

buildprod.sh
  . ./build-common.sh
  set_ant_env
  process_arguments $*
  call_ant local


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.

The most important thing is how to import another shell into your shell script:

1.
. ./buld-common.sh

2. then you can the function, like calling the local function:
   set_ant_env

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.

Tuesday, November 30, 2010

Hacking the Wireless Toolkit for Mac

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:
WTK
   - Windows PC: WTK 2.5.2
   -  Mac:     WTK 2.5.2 Linux version, copied preverify from JavaME SDK 3.0 Mac
Build tool is Antenna
   - Windows: antenna 1.1.0
   - Mac:  antenna 1.2.1 ( the earlier versions have preverify issue on Mac )

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.
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.

Finally I have to google and I was so lucky that I found Sam's blog post: J2ME Development on OS X, revisited. This is a fantastic article, the most important for me is he tells me how to get the Mac version of preverify:  Download the phoneME project source code, and the preverify for mac is under phoneme_feature/cldc/build/share/bin/darwin_powerpc/, 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  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!

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:

Download and Install the WTK 2.5.2

  • Goto here to download the Sun's WTK 2.5.2 for Linux, file is called sun_java_wireless_toolkit-2_5_2-linux.bin
  • Execute the downloaded file (sh sun_java_wireless_toolkit-2_5_2-linux.bin)
  • When asked for a path to JDK, enter “/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin/”
  • Follow the instructions, probably best to install into /Applications/WTK2.5.2

Get the preverify binary

  • Download the PhoneME project feature source code,  choose the M2 source bundle
  • Extract phoneME build, it creates a directory called “phoneme_feature”
  • Copy /phoneme_feature/cldc/build/share/bin/darwin_powerpc/preverify and overwrite the preverify binary in your WTK bin folder.
  • You might need to change the permission to w+x of preverify.
You might need to install Rosetta before running preverify
Today one of my colleague found this issue on this macbook, when I give him a copy of preverify binary file,  when he run it on his machine, it prompt need to install Rosetta to run it.  it said the Rosetta comes with the MacOS installation CD, so if you have the similar issue, then install it first.

Other tools:
Antenna:  please use the latest version for Mac (1.2.1).
Gant:  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.

Wednesday, November 17, 2010

Review of BlackBerry Eclipse Plugin for Mac OS X

Today I have a chance to look at BlackBerry's Eclipse Plugin for Mac OS X.  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.

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 BlackBerry Desktop manager for Mac.

What I don't like:

  •  Does not support simulator yet.  From the IDE menu, I could not find the where I can launch the BlackBerry simulator,  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.  
  • On-device debugging is kind of working. It takes a long time to connect the device, it can stop at the break point, but  the variable value is wrong, always 0 or null.
  • Support BlackBerry OS 6 only.
  • Signing is more restricted, in windows version you can hack the signing tool by putting the file  sigtool.csk and sigtool.db in the \bin folder of blackberry SDK component folder.  It does not working on Mac version now.
Now I understand why it is called a preview version.

What I like most is the blackberry tool "javaloader" is  now supported in Mac, I tested it works on Mac, you can install/remove an application using  javaloader via USB cable. Really nice!   

The javaloader file is under the folder like:
BBEclipse/plugins/net.rim.ejde.componentpack6.0.0_6.0.0.29/components/bin
If you are familiar with the Blackberry Windows version of Eclipse Plugin, you will find they have the same folder structure. Just remember you have to manually change the permission to make sure it is executable.  You can also find the preverify tool in the same folder, and fledge tool in the simulator folder, which is supposed to launch the simulator, unfortunately it does not working right now.

Another interesting thing is I wonder how it build the application in the IDE.  From the console window I got following output:

Compiling CLDC Application:
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

Compiling MIDlet application:
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

Now we understand that in Mac,  it uses java to launch rap compiler, and it has some option I never seen before: like  -convertpng, -exepath, etc.  I wonder RIM might upgrade it new version of RAPC compiler.



Sunday, November 14, 2010

More about "Drive"

I just by accident read Martin Fowler's article: Can Not Measure Productivity.  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 called Measuring and Managing Performance in Organizations, written by Robert Austin. but it seems it is not published any more, I just found a slide of the book., and a brief introduction of the book. 

Quotes from the book introduction:
Because people often react with unanticipated sophistication when they are being measured,measurement-based management systems can become dysfunctional,interfering with achievement of intended results. Fortunately, as the author shows, measurement dysfunction follows a pattern that can be identified and avoided.
 Here I got some quotes from the slide:

        "A system of incentives is dysfunctional if the resulting effort allocation provides less value to the customer than when there is no supervision.” (Austin)

Measurement versus Delegation
• Full Supervision: incentives via measurement
  – Relies on extrinsic motivators
    • Money
    • Continued employment
    • “Forcing Contract”
• No Supervision: incentives via “delegation”
  – Relies on intrinsic motivators
    • Pride of workmanship, joy in being part of the team
    • Identification with the company’s values and goals
    • Desire to please the customer

Intrinsic versus Extrinsic Motivators
Intrinsic motivators are much more powerful
• But appear to be overridden by extrinsic motivators
• Japanese versus American management styles
  – Japanese rely heavily on delegation
  – But it is cheaper for them
  – It is both a strength and a weakness
• Delegation may not be cost effective either
• Sometimes neither style works
  – “Large software development firm”

Summary
• You may think you have full supervision
• But you are almost certainly wrong
• The ship’s wheel is not directly connected to the rudder

• Austin versus Deming
  – W. Edwards Deming, Out of the Crisis, MIT Press, 2000
  – Former BTL lead Japanese quality movement in 1980s
  – Methodology summarized in his “Fourteen Points”

So based on the text above, we can conclude that the book of "Measuring and Managing Performance in Organizations" share the same concept with the book of "Drive", use different perspective, it proves that people's performance and productivity is 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.

Another useful link: 
 http://www.slideshare.net/RobMyers64/metrics-in-an-agile-world

Saturday, November 13, 2010

Manage Change by Managing Unchanged

As a software developer, we have to deal with different changes:
 -  The changing requirements, which means change code, bug fix, revers engineering...
 -  The changing technologies, you have to deal with new buzz, new API, new languages...

How can we deal with these changing? because chasing change is really hard, because:
  • 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;
  • Some new stuffs are quite easy to obsolete, some time even when you try to start learning it, it is just gone.
  • Understand too many details in short time is really stressful
  • They are quite context specific, they will be useless in different area.
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? What I mean the unchanged is something behind the detailed technologies. For example, like principles, rules, patterns, philosophy etc. 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.

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.  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.

So how does the concept of "Manage change by manage unchanged" help in the software development?
  •  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;
  • 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;
  • It help you to identify which technology is worth learning by analyzing its unchanged properties
  • 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 Dependency Inversion Principle.

Thursday, November 11, 2010

Mind map: Continuous Delivery Notes

In QCon San Francisco, I attended the tutorial -"Continuos Delivery", it is a great training. I learned a lot, then 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 FreeMind,  so I just tried to use this tool to take my notes in the mind map format. The notes like this:

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 the pdf manual for details.

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.

The next step I need to figure out how to embed the actual map on the website. This article 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.

Saturday, November 6, 2010

Impressions of Qcon San Francisco 2010 conference

My journey of 5-day Qconsf 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.

2 Days tutorial: fantastic
1. Joseph Yoder and Rebecca Wirfs-Brock'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.

2. Continuous Delivery
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:
  •      break down one big build script to several pieces,
  •      create dependency
  •      use code analysis
  •      use build server like Hudson
  •      use Junit test
  •      set up build artifact
  •      unify configuration of developing environment and deploy environment 
  •      decouple the dependency of developing build script from deploy build script.
  •      use puppet and cucumber
  •      simplify the ant build script: use gradle or gant
My goal: shorten the deploy build time, shorten the developing unit test build time, try to automate every thing, shorten feedback, improve productivity
  
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.

overview of 3-day talks
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!

My favorite speakers
I am so happy that I have chance to meet following famous speakers:
  • Martin Fowler
  • Dan North
  • Ralph Johnson
  • Dan Ingalls
  • Erik Meijer
  • Michael Feathers
Some speakers I am not familiar, they give really wonderful talking:
   Joe and rebecca
   Stuart Halloway

What I learned
NoSQL, Concurrency & parallel programming and functional programming are my blind spots. Thorough 3 ays conference,  I just get some concepts, since they are all very good speakers, I know what I am going to learn next steps.
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.

who I meet
 Mark:  I talked to him a lot, who is a ruby guy, I got lots of information about tools of ruby from him.
 Jai:  Java guy, I found we read quite similar computer books,
 Wei: java guy, I learned some form him about NoSQL.
 Daniel: .NET guy, I am so impressed by his productivity of blogging,  I noticed he just he keep writing in a Martin Fowler's keynotes talking,  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.

And I talked many other guys I forget their names,  I found we almost read same books, shared same vision, like "learn a new language every year", it is a very good chance to learn, get feedback, you will aware your ignorance, your blind spot, you need to learn more !

It is really interesting that a group of people come from different country, with different back ground, share the same philosophy.

Next actions
  Am I going to come QCon next year? Maybe, it depends on my own budget.
  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!

Saturday, October 16, 2010

Gant Script: print ant default properties

If you want to know exactly what kind of ant properties in your environment, try the following gant target:

target(properties : "print ant default properties") {
     println "ant properties are:"
     ant.project.properties.each { key, value ->
         println "${key} = ${value}"
     }
}

Here are some of the out put:
ant properties are:
ant.version = Apache Ant version 1.8.1 compiled on April 30 2010
sun.os.patch.level = unknown
java.vm.vendor = Apple Inc.
environment.HOME = /Users/steve
environment.TERM_PROGRAM = Apple_Terminal
file.encoding = MacRoman
user.language = en
java.class.path = /opt/local/share/java/gant/lib/groovy-all-1.7.3.jar
file.separator = /
java.runtime.name = Java(TM) SE Runtime Environment
basedir = /Users/steve/dev/gant
java.vm.specification.version = 1.0
awt.nativeDoubleBuffering = true

...
...

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!  Byebye XML!

Build J2ME app using Gant

These days I spent some time learning Groovy. Why I learn Groovy? Because I want to use Gant.  Gant = Groovy + Ant. Gant is really powerful, since you can use Groovy script and Ant API to write your build script instead of XML. 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,  it is much easier to do that in Gant script.

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.

Requirement:
1. You need to install Groovy and Gant, here is the link, I used 1.9.3 in Mac.
2. download the latest version of antenna, here is the download link,  I used 1.2.1-beta.
3. install the JavaME SDK,  I choose  JavaME SDK 3, since it works on Mac.

The J2ME MIDlet class source code:

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
 
public class HelloWorld extends MIDlet implements CommandListener {
    private final Command exitCommand;
    private final Form form;
 
    public HelloWorld() {
        exitCommand = new Command("Exit", Command.EXIT, 1);
        form = new Form("Hello World!");
        form.append("from Steve");
        form.addCommand(exitCommand);
        form.setCommandListener(this);
    }
 
    protected void startApp() {
        Display.getDisplay(this).setCurrent(form);
    }
 
    protected void pauseApp() {}
    protected void destroyApp(boolean force) {}
 
    public void commandAction(Command cmd, Displayable disp) {
        if (cmd == exitCommand) {
            destroyApp(false);
            notifyDestroyed();
        }
    }
}

The Ant script looks like:

<project name="antenna-test" default="jar" basedir=".">
 
 <taskdef resource="antenna.properties" classpath="./antenna-bin-1.2.1-beta.jar" />
 
 <property name="wtk.home" value="/Users/Steve/dev/wtk252" />
 <property name="wtk.midp.version" value="2.0" />
 <property name="wtk.cldc.version" value="1.1" />
 
 <property name="src.dir" location="src" />
 <property name="out.dir" location="out" />
 <property name="dist.dir" location="dist" />
 <property name="preverified.dir" location="preverified" />
  
 <!-- Regular targets -->
 <target name="clean" description="cleans the target directory">
  <delete dir="${out.dir}"/>
  <delete dir="${dist.dir}"/>
  <delete dir="${preverified.dir}"/>
 </target>
 
 <target name="compile" depends="init">
  <wtkbuild source="1.3" srcdir="${src.dir}" destdir="${out.dir}">
  </wtkbuild>
 </target>
 
 
 <target name="preverify" depends="compile">
  <wtkpreverify srcdir="${out.dir}" destdir="${preverified.dir}">
  </wtkpreverify>
 </target>
 
 <target name="jar" depends="compile,jad,preverify">
  <wtkpackage jarfile="${dist.dir}/helloworld.jar"
                      jadfile="${dist.dir}/helloworld.jad"
                      obfuscate="false"
                      preverify="false">

       <fileset dir="${out.dir}"/>
        </wtkpackage>
   
 </target>
 
 <target name="jad" depends="compile">
  <wtkjad  version="0.01" name="hello" vendor="foo" jadfile="${dist.dir}/helloworld.jad" jarfile="${dist.dir}/helloworld.jar">
    <midlet name="hello" class="HelloWorld">
    </midlet> 
  </wtkjad>
 </target> 
 <target name="init" description="initialization for properties and paths" depends="clean">
  <buildnumber/>
  <mkdir dir="${out.dir}"/>
  <mkdir dir="${dist.dir}"/>
  <mkdir dir="${preverified.dir}" />
 </target>
 
 
</project>

the build script build.gant:

ant.taskdef(resource:"antenna.properties", classpath:"./antenna-bin-1.2.1-beta.jar")

ant.property(name:"wtk.home", value:"/Applications/Java_ME_SDK_3.0.app/Contents/Resources")
ant.property(name:"wtk.midp.version", value:"2.0")
ant.property(name:"wtk.cldc.version", value:"1.1")

final srcDir = "src"
final outDir = 'out'
final distDir = 'dist'
final preverifiedDir = 'preverified'

//clean target
includeTargets << gant.targets.Clean
cleanPattern << '**/*~'
cleanDirectory << [ outDir, distDir, preverifiedDir]


target(name:"init", description:"initialization") {
 depends(clean)
 /*buildnumber() */
 mkdir(dir:outDir)
 mkdir(dir:distDir)
 mkdir(dir:preverifiedDir)
}

target(name:"compile", description:"compile") {
 depends(init)
 wtkbuild( source:"1.3", srcdir:srcDir, destdir:outDir)
}

target(name:"preverify", description:"preverify") {
 depends(compile)
 wtkpreverify(srcdir:outDir, destdir:preverifiedDir)
}

//target jad file

target(name:"jad", description:"generate jad file") {
    depends(compile)
 wtkjad( version:"0.01", name:'hello', vendor:"foo", jadfile:"${distDir}/helloworld.jad", jarfile:"${distDir}/helloworld.jar" ) {
  midlet(name:"hello", class:"HelloWorld")
 }
}

//target jar
target(name:"jar", description:"generating jar file") {
 depends(compile,jad)
 wtkpackage( jadfile:"${distDir}/helloworld.jad", jarfile:"${distDir}/helloworld.jar", obfuscate:"false", preverify:"false")  {
  fileset(dir:outDir)
 }
}

//target obfuscate

//target all
target(name:"all", description: "build the whole app") {
 depends(jar)
}

setDefaultTarget(all)



From the above script, you can see how easy to write gant build script.
This is only the basic implementation, I am going to post more Gant based script in future.

In future I am going to consider:
1. How to integrate with ANT script;
2. How import multiple Gant script file.

Sunday, September 26, 2010

Use the BlackBerry Issue Tracker to find bugs

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.

Here I would like to share my experience how to use the Issue tracker:

First go to BlackBerry Developer Zone, register an account, use this link:
  https://www.blackberry.com/bdsc/?lang=na#login

After login in, in the left part of the portal, click Resources tab, it will expand several sub links, then select "Developer Issue Tracker",  then click  link "Submit an Issue", finally your will enter the BlackBerry Issue Tracker portal.

For example, to identify an BlackBerry OS 5 SMS issue, I found a bug which reported the exact same issue, which is very helpful.
JAVAAPI-553:
Java APIs
   invokeApplication() Ignores PayloadText for Populating SMS Text Message
Created: 19/Oct/09 10:44 PM   Updated: 07/Jun/10 05:50 AM
DevTrack ID: 360769
Fix Version/s: None
App Build Number: 5.0.0.224
Device: Bold 9000
Component: --
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.

You will be surprised that there are some many open issues for different blackberry OS.
So I will suggest you to go to the Issue Tracker if you want to confirm a BlackBerry device issue.

The incompatible issues of BlackBerry OS 5

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.

Here I just make a list of incompatible issues that I found recently:

1. BACK key issue
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.

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 link for details.

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!

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.

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?

Sunday, September 5, 2010

Be careful to use "Class.forName()" in J2ME

A couple weeks ago, I made another mistake: I tried to use Class.forName() 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.

Scenario
I need to provide an API to support multiple mobile platform, for example: Nokia, Blackberry, and simulator, etc.
What I implement is pretty easy:
  • define an interface: Service
  • Implement the Service interface for each mobile platform, for example: NokiaService, BlackBerryService, SimualtorService
  • At the build time, inject different Service class file in the package.
  • At the run time, the application use the Class.forName() to create the Service objects.
The snippet code looks like this:
public Service createService(int device)
 {
    Service service = null;

    if( device == NOKIA)
    {
        service = Class.forName("NokiaService").newInstance();
    }
    else if( device == BLACKBERRY)
    {
        service = Class.forName("BlackBerryService").newInstance();
    }
    else if(device == SIMULATOR)
    {
        service = Class.forName("SimulatorService").newInstance();
    }
    else 
        service = Class.forName("GenericService").newInstance();

     return service;
 }

Here I use a factory pattern to support multiple platform, no need to use preprocess, sound pretty simple, right?
But I found the above solution only works on BlackBerry platform, on other J2ME platform, the application will throw the ClassNotFound Exception.

The reason of failure
The problem is in obfuscation phase, we usually use Proguard to do preverification and obfuscation for the J2ME application. The proguard will remove the unused class file. (for detail please check this link ) 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.

But why it works on BlackBerry platform?
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

Solution
I have to rewrite the above code, remove all the Class.forName(), replaced with the explicit method call.
To support multiple platform, I use javaassit 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.

Conclusion
Class.forName() 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.

Thursday, August 19, 2010

Aspire to be agile missionary

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.

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.  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.

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. 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.

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.

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.

Sunday, August 8, 2010

Is it possible for a developer to become an artist?

I am still reading the book: Linchpin.  I am interested with the author's definition about art:
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.
The author expanded the  definition of art , it focuses on "making changes".This idea share the similar idea of software crafsmanship.

Where is the art in software developing?
The developer's daily job can be boring, repetitive instead of creative. For example:
you can just copy and paste from the old code; or just use google check some API usage;
You don't need to care the code quality, don't need to care about the maintainability.
you can also finsih the job. You can do like that everyday.
But this job is not art, you will not make the difference, any one with the similar knowledge can do it.
then your job are easily been replaced.

But the developer's job can be a kind of art if you choose to do in different way:
   there is the art of making simple design;
   there is the art of wrting clean code;
   there is the art of refactoring;
   there is the art of maintaining;
   there is the art of debugging;
   there is the art of communciation and interaction;

Anything which can make things better and make some difference is the art of programming.
if you bring your passion, and make some difference, then that is art;
if you do that day by day, keep improving yourself, then you will become a master, which is also an artist of software.

The road to become artist
I like the concept of Shu-Ha-Ri, it can be treated as a path from an average developer to a master developer:
    In Shu Level, the point is "following, copying", all you need to do is learning, so there is no art behaviour at this level;
  In Ha Level,  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;
  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.

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.

Monday, August 2, 2010

Linchpin: to be or not to be?

Are you a cog or lincphin? Every employee has to answer this question.

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.
The problem in IT industry, average and mediocrity can not survive, whether a company or a developer.  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.

So if you want to survive, secure your job,  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. 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. Think about Apple, how the iPhone makes such difference with other regular phones.

You have to make a choice between these two: to be linchpin or not to be. It is up to you.
If you want more details about linchpin, please read the book: Linchpin: Are you indispensable?



Also check this article: The indispensable Developer
And this: You are not your role

Sunday, July 25, 2010

What drive you work? - The review of book Drive

Today I finish reading the book Drive-The surprising Truth About What Motivates Us". I knew this book from this 10 minutes cartoon on twitter, and the author's video about drive.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,  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  novel.
The core concept of the book: The traditional external carrot & stick motivator does not work on 21 century; we need to upgrade to intrinsic motivator: autonomy, mastery, & purpose.
This concept is not new to me, it reminds me some other books which share the similar theory behind:
  • Maslow's self realization theory;
  • Lean Technology and Deming's theory;
  • Seven Habits
  • Maverick
  • The passionate programmer
  • The fifth discipline

This book drives me into deep thinking about the 3 factors: autonomy, mastery and purpose.

What I learned from the book
 - Autonomy, mastery and purpose are correlated, and each of them supports each other.
      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.
      Bad example: In the command & 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.
  - 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.
 -  Reinforce my goal to mastery.
  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.
     
Next step thinking:
- Compare drive with Lean technology
- Investigate the "flow" concept
- If you are a Type I person, how can you do in a Type X organization, how to deal with your Type X boss?
- What kind of Type I organization should be? How to migrate from Type X to Type I organization?
- Why we should focus Type I behavior in software industry?
- Why manager need to give up control?
- use the theory in "drive" to explain the "three stone cutter stories"
- Read the book of "the fifh discipline".

Resources:
1. 10 minutes video link
2. author Daneil Pink's presentation
3. Dan pink's website
4. The reading list of drive

Sunday, July 4, 2010

Time Machine Wireless backup using your own network drive

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.
This time it gave me a lesson: I need to backup my hard drive ASAP.
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  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.
Here I would like to share my experience about how I solve it. Basically I referred this blog, it is so great, I could not able to finish it without this article.

The Goal
Backup my mac hard drive into my own NAS via wireless network.

Environment
Computer: MacBook Pro
OS: Snow Leopard
Wireless Router: Netgear WNDR3700
Network drive: West Digit MyBook Essential

Steps
1. Setup network drive, create a network shared folder for time machine. For example, I called the folder "\mac".
2. Connect the NAS storage, for example in my netgeare wireless network, I type following in Finder:
    smb://readyshare/mac
3. Enable time machine to use your network drive, run following command in the terminal:

defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1

4. Find out your computer name and Ethernet ID.
   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.
   For example, my computer name is: steve_zhang_mac.  The name contains space and other special characters should be fine, but I prefer to make it simple.
   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
   Or you can try to type following command in the terminal:
      ifconfig en0 | grep ether | sed s/://g | sed s/ether//
 Please remeber: it requires the computer's MAC address regardless if you use wireless or wired connection.
   If you use Wi-Fi, you will find another different ethernet ID under the  "Airport" configuration, don't use this value.
5. Create the disk image file
   Create the disk image file locally, the file name is like computername_MACaddrss.sparsebundle
   based on the information from step 4), run following in the terminal:
  
    DISK_IMAGE_NAME="steve_zhang_macbook_d49a20046534.sparsebundle"
    DISK_SIZE=200000
    hdiutil create -library SPUD -megabytes $DISK_SIZE -fs HFS+J -type SPARSEBUNDLE -volname "$DISK_IMAGE_NAME" "$DISK_IMAGE_NAME"
  

Copy the created image file into the NAS storage folder.
6.  Run Time Machine, choose your NAS box,  if everything is OK, then the time machine will start working.

Some Erorrs I met
- Error 45
  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,  copy the generated file into the specific shared folder.
  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.

- Error of" .....sparsebundle is already been used."
  The .spasebundle file is used by another process, please restart the computer to run the Time machine again, this issue will solved.

Other tricks
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.
2. How to check the connected NAS in terminal:
   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.
3. How to check the system log:
   System log is in /var/log/system.log
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.
5. If you use Parallels virtual machine, then it is better to turn off the backup for parallels virtual machine file,  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.  Or you can open the Time Machine Preferences, choose options,  add exclude the Virtual machine file: it is in /Users/Shared/Parallels/Windows XP.pvm


References
1.  Getting Time Machine to work on an Unsupported NAS
2. Time Machine Wireless Backup without Time Capsule
3. Time Machine Editor

Sunday, June 27, 2010

Debug BlackBerry Application Inside NetBeans

This post continues the my last post  about blackberry application development.

I added the ANT target to launch the blackberry JDWP debugger from these two articles: 1) and 2). I can launch the BlackBerry JDWP and simulator, but unfortunately the app did not stopped at the break point.
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.
So I have to figure out by myself by using reverse engineering again.

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;
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
 .debug, .jar, and .alx file. I realize this might be the reason: you need to copy .debug files in the simulator! In my old build script, I only copied jad and cod files, did not copy .debug files into the simulator.

So I modified my ant build script, make sure it will copy all the rapc generated files into the simulator folder, which includes:
  - .jad and .jar file, I don't know why JDWP needs jar file, but it works any way;
  - debug file, like .debug and xxx-1.debug, xxx-2.debug, etc;
  - .cod file
  - .alx file

The ant script snippet look like this:
1.  ANT target: copy files.  Since I used bb-ant, this target means copy all the file contains the project name under \bbant folder to the simulator folder.

<target name="copyBBSimulator" if="do.rapc">
    <copy todir="${platform.home}/simulator" verbose="true">
             <fileset dir="${dist.dir}/bbant">
                <include name="**/${name}*"/>
            </fileset>
    </copy>
</target>


2. ANT target: launch blackerry debugger, this target will launch the blackberry JDWP remote server and blackberry simulator.

<target name="bb-debug" depends="copyBBSimulator" if="do.rapc">
    <delete file="${preprocessed.dir}/.timestamp"/>
    <parallel>
          <java jar="${platform.home}/bin/JDWP.jar" fork="true" dir="${platform.home}/bin">
            <jvmarg value="-Xmx128M"/>
          </java>

          <sequential>
              <sleep seconds="5"/>
              <antcall target="nbdebug"/>
         </sequential>
   </parallel>
</target>


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.
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.


For your reference, I post the whole build script and source code:
1. bb-build.xml

<target name="post-init">
          <available file="${platform.home}/bin/rapc.exe" property="do.rapc" />
          <condition property="jpda.port" value="8000">
              <isset property="do.rapc">
              </isset>
         </condition>
        
  </target>


   <target name="post-jar" if="do.rapc">
     <antcall target="bbbuild" />
   </target>

   <target name="run" depends="init,jar,bb-run,cldc-run" />
   <target name="debug" depends="init,jar, bb-debug, cldc-debug" />


   <target name="cldc-run" unless="do.rapc" >
       <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}"/>
   </target>

   <target name="cldc-debug" unless="do.rapc">
       <delete file="${build.dir}/.timestamp"/>
                <parallel>
                    <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}"/>
                    <sequential>
                        <sleep seconds="5"/>
                        <antcall target="nbdebug"/>
                    </sequential>
                </parallel>
   </target>

<target name="post-clean">
   <delete failonerror="false">
      <fileset dir="${platform.home}/simulator">
       <include name="**/${name}*">
       </include>
      </fileset>
   </delete>
</target>

<typedef resource="bb-ant-defs.xml" classpath="bb-ant-tools.jar" />
  <target name="bbbuild" description="blackberry build" depends="init" if="do.rapc">
          <echo message="rapc build, dir=${dist.dir}"></echo>
          <mkdir dir="${dist.dir}/bbant" />
          <rapc verbose="true" output="${name}" jdehome="${platform.home}" import="${platform.bootclasspath}" destdir="${dist.dir}/bbant/" noconvert="true">
          <src>
             <fileset file="${dist.dir}/${dist.jar}" />
          </src>
          <jdp title="${app.title}" vendor="${app.vendor}" version="${app.version}" type="cldc" icon="${app.icon}" runonstartup="false" >
          </jdp>
          </rapc>

        <!-- sigtool jdehome="C:Program FilesResearch In MotionBlackBerry JDE 4.7.0" codfile="${dist.dir}/bbant/${name}.cod" password="" / -->
        <alx destdir="${dist.dir}/bbant" filename="${name}.alx">
            <application id="${app.title}">
               <codset>
                    <fileset dir="${dist.dir}/bbant" includes="*.cod">
                   </fileset>
               </codset>
           </application>
       </alx>
       <mkdir dir="${dist.dir}/bbant-final" />
       <jadtool input="${dist.dir}/bbant/${dist.jad}" destdir="${dist.dir}/bbant-final">
        <fileset dir="${dist.dir}/bbant" includes="*.cod">
        </fileset>
      
       </jadtool>
 </target>

<target name="copyBBSimulator" if="do.rapc">
    <copy todir="${platform.home}/simulator" verbose="true">
             <fileset dir="${dist.dir}/bbant">
                <include name="**/${name}*"/>
            </fileset>

    </copy>

</target>

<target name="bb-run" depends="copyBBSimulator" if="do.rapc">
    <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows XP"
             dir="${platform.home}/simulator"
            executable="${platform.home}/simulator/${platform.device}.bat"
        failonerror="true" resolveExecutable="true"/>
</target>

<target name="bb-debug" depends="copyBBSimulator" if="do.rapc">
    <delete file="${preprocessed.dir}/.timestamp"/>
    <parallel>
          <java jar="${platform.home}/bin/JDWP.jar" fork="true" dir="${platform.home}/bin">
            <jvmarg value="-Xmx128M"/>
          </java>

          <sequential>
              <sleep seconds="5"/>
              <antcall target="nbdebug"/>
         </sequential>
   </parallel>
</target>

2. build.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project [
       <!ENTITY bb-common SYSTEM "bb-build.xml">
]>
<project name="helloLWUIT" default="jar" basedir=".">
    <description>Builds, tests, and runs the project .</description>
    <import file="nbproject/build-impl.xml"/>
    <property name="app.title" value="helloLWUIT" />
    <property name="app.version" value="1" />
    <property name="app.icon"   value="/icon.png" />
    <property name="app.vendor" value="foo" />

     &bb-common;
</project>



3. source code project: helloLWUIT:
  Here
  Environment requirements: please refer Shai's blog for blackberry to set up the project environment


Next Steps:
  1. Figure out how to debug blackberry application on the actual device inside NetBeans;
  2. Make sure how to read attribute in the jad file in the BlackBerry CLDC application;
  3. How to easier copy the customized attribute in the midlet jade file to the BlackBerry CLDC jad file.

References:
  1. http://www.xenglobaltech.com/blackberry/index.php?option=com_content&view=article&id=45&Itemid=40
  2. http://supportforums.blackberry.com/t5/Java-Development/Building-Blackberry-apps-with-Netbeans/td-p/431612


Monday, June 21, 2010

Professional Devlelopers require professional managers

I realize that there are similarities between software developers and software managers:
- Developers manage codes, managers manage people;
- Developers resolve bugs in the codes, managers resolve bugs among the people;
- 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;
- A professional developer always choose the right framework and right tool for the task, a professional manager choose the right person to do the  right thing;
- A professional developer improves his code by keep constantly refactoring and reflection, a professional manager keep improving his team;
- A professional developer always follows the software principles and design patterns to guide his work, deliberately improve his skills, keep finding new tools;  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.

But in reality,  unfortunately in my career so far I haven't found a manager which I can regard as a professional manager.  Most of them I call them "event dispatcher". They  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.

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.  If a manger dos not know the principles and rules of software, how can he manage well for his team?  If a manager does not care his developer, how can his developer has motivation to become better?

A good manager for a software team just as a good coach for a soccer team. Professional developers do require professional managers.