About me

Profile Picture

Full-stack software developer living in Auckland, New Zealand

Have rich experience and strong problem solving skills.
Know how to apply best practices in real product development.
A quick learner and always want to learn emerging techniques.

Skills & Interests

Learn as if you were to live forever.

– Mahatma Gandhi


HTML, JavaScript/CoffeeScript, CSS/LESS

Bootstrap, jQuery, AngularJS, Dojo, Backbone, RequireJS

Grunt, Bower, Yeoman



Spring, Hibernate, JPA, JSP, servlet





Jenkins, Gradle, Maven, Ant

Docker, Vagrant

MySQL, MongoDB






If you have knowledge, let others light their candles in it.

– Margaret Fuller


“Understanding the Java 7: the Core techniques and best practice” covers Java SE 7 new features and deep dive of Java platform core features, including JVM internals, byte code manipulation, class loader, generics, security, concurrent programming and serialization.

(Simplifed Chinese edition)

Technical articles

A regular author of IBM developerWorks China and InfoQ China website with more than 50 published technical articles covering various technical topics.

(Simplifed Chinese)

Recent Posts

Use Synapse to workaround AWS ELB static IP limitations

Jan 21, 2015


The system receives data from a third-party service using TCP sockets. The service requires a static IP address to send the data. Several app nodes are created to receive and process data. AWS ELB is used as the load balancer for app nodes. But currently AWS ELB only has host name, but no static IP address. AWS has elastic IP addresses which are static, but cannot be associated with ELB.

Spring RestTemplate Basic Authentication

Jan 17, 2015

I’m using Spring RestTemplate to consume REST service with basic authentication, so I need a way to set the username and password. After running some searches, it turns out that it’s not that easy to set the username and password directly. So I manually created the Authorization header.

Maven failsafe plugin to fail builds

Dec 31, 2014

Maven failsafe plugin is used to run integration tests. If you only add this plugin to integration-test phase, it won’t fail the build. So you will have builds with failed integration tests. This design is to make sure the post-integration-test phase can run and tear down the environment correctly. This is because integration tests usually involve preparing the environment (DB, file system, network, etc.) before tests run, so cleaning up is required. To check the result of integration tests, verify phase needs to be used and fail builds correctly in this phase.