Saturday, March 28, 2015

Javascript oddities #1

var func = function() {}
console.log(func.prototype.constructor == func); // return true

Thursday, March 12, 2015

JHipster: A code generator with a truck load of tech for AngularJS and Spring Boot based projects

I recently came across a JHipster - a Yeoman-based generator, which generates a based project which includes a truck load of technologies (taken directly from JHipster's Technology Stack page):

Technology stack on the client side

Single Web page application:

  • Responsive Web Design
  • HTML5 Boilerplate
  • Twitter Bootstrap
  • AngularJS
  • Full internationalization support with Angular Translate
  • Optional Compass / Sass support for CSS design
  • Optional WebSocket support with Spring Websocket

With the great Yeoman development workflow:

  • Easy installation of new JavaScript libraries with Bower
  • Build, optimization and live reload with Grunt or Gulp.js
  • Testing with Karma and PhantomJS

And what if a single Web page application isn't enough for your needs?

  • Support for the Thymeleaf template engine, to generate Web pages on the server side

Technology stack on the server side

A complete Spring application:

  • Spring Boot for easy application configuration
  • Maven or Gradle configuration for building, testing and running the application
  • "development" and "production" profiles (both for Maven and Gradle)
  • Spring Security
  • Spring MVC REST + Jackson
  • Optional WebSocket support with Spring Websocket
  • Spring Data JPA + Bean Validation
  • Database updates with Liquibase
  • MongoDB support if you'd rather use a document-oriented NoSQL database instead of JPA
  • Cassandra support if you'd rather use a column-oriented NoSQL database instead of JPA

Ready to go into production:

  • Monitoring with Metrics
  • Caching with ehcache (local cache) or hazelcast (distributed cache)
  • Optional HTTP session clustering with hazelcast
  • Optimized static resources (gzip filter, HTTP cache headers)
  • Log management with Logback, configurable at runtime
  • Connection pooling with HikariCP for optimum performance
  • Builds a standard WAR file or an executable JAR file
Although I did not use it for any of my projects (yet), it is a great reference to see how to setup a project which truly separate the front and back development. What I meant by that is the project is setup where the front-end can be served via 'grunt serve', i.e. NodeJS, decoupled from the back-end Spring Boot server. Yet, we all these goodies, you can still easily call 'mvn package' to build a complete Spring Boot powered executable JAR.

It is a great project to get a glimpse of all these technologies and how they can integrate together. More importantly, it set up a viable project which separates but integrated workflow for front-end and back-end. After working with it for a bit, I do have some reservations and comments, but that for another post.

Have you used JHipster in your projects? In a production setting? If so, I love to hear your comments.

Monday, December 15, 2014

SOAPUI 5.0.0 hangs after upgrading OS X to Yosemite

After upgrading to the company's Mac OS X to Yosemite, SOAPUI 5.0.0 refuse to load properly. It will start, and the UI will come up, but it just hang with the spinning wheel right away.

I was able to resolve this issue by uncommenting the line #53 in $SOAP_HOME/bin/

#   JAVA_OPTS="$JAVA_OPTS -Dsoapui.browser.disabled=true"

I hope this help someone else out there who has the same problem, and also for myself to reference again if face with the same problem in the future.

Sunday, April 6, 2014

Getting edx devstack to run on Windows

1) Fix issue

2) Change Vagrant ansible-play command to

ansible-playbook -i localhost, -c local vagrant-devstack.yml --tags=deploy -e configuration_version=master -e edx_ansible_source_repo= -e edx_platform_repo= -e edx_platform_version=master -vvv

3) Fix symbolic link issue
 # You need to run this from cygwin, not the Windows command-line (see above)
 git rm --cached -r . && git reset --hard
 git config --global alias.add-symlink '!__git_add_symlink(){ dst=$(echo "$2")/../$(echo "$1"); if [ -e "$dst" ]; then hash=$(echo "$1" | git hash-object -w --stdin); git update-index --add --cacheinfo 120000 "$hash" "$2"; git checkout -- "$2"; else echo "ERROR: Target $dst does not exist!"; echo "       Not creating invalid symlink."; fi; }; __git_add_symlink "$1" "$2"'
 git config --global alias.rm-symlink '!__git_rm_symlink(){ git checkout -- "$1"; link=$(echo "$1"); POS=$'\''/'\''; DOS=$'\''\\\\'\''; doslink=${link//$POS/$DOS}; dest=$(dirname "$link")/$(cat "$link"); dosdest=${dest//$POS/$DOS}; if [ -f "$dest" ]; then rm -f "$link"; cmd //C mklink //H "$doslink" "$dosdest"; elif [ -d "$dest" ]; then rm -f "$link"; cmd //C mklink //J "$doslink" "$dosdest"; else echo "ERROR: Something went wrong when processing $1 . . ."; echo "       $dest may not actually exist as a valid target."; fi; }; __git_rm_symlink "$1"'
 git config --global alias.rm-symlinks '!__git_rm_symlinks(){ for symlink in `git ls-files -s | grep -E "^120000" | cut -f2`; do git rm-symlink "$symlink"; git update-index --assume-unchanged "$symlink"; done; }; __git_rm_symlinks'
 git config --global alias.checkout-symlinks '!__git_checkout_symlinks(){ POS=$'\''/'\''; DOS=$'\''\\\\'\''; for symlink in `git ls-files -s | grep -E "^120000" | cut -f2`; do git update-index --no-assume-unchanged "$symlink"; if [ -d "$symlink" ]; then dossymlink=${symlink//$POS/$DOS}; cmd //C rmdir //S //Q "$dossymlink"; fi; git  checkout -- "$symlink"; echo "Restored git symlink $symlink <<===>> `cat $symlink`"; done; }; __git_checkout_symlinks'
 git rm-symlinks
4) Before running `vagrant provision`, comment out the checkout and clean resets (if left in playbook, it will resets the above fix)


Monday, January 20, 2014

Co-working spaces in Hong Kong - - (no longer in operation)
Cocoon -
the Hive -
The Good Lab -
Fill in the blank -
PaperClip -
80/80 Space -
The Loft -

Play Framework 2.2.x + Twitter Bootstrap 3 + Less

There are a variety sources of How-Tos on the internet which shows how to integrate Less version of the Twitter Bootstrap into Play Framework which involves prefixing the Bootstrap files with "_". However, this is not necessary by specifying the lessEntryPoints key.
  1. Put source of bootstrap/less under app/asset/stylesheet/bootstrap
  2. Create app/asset/stylesheet/main.less with the following entry: import bootstrap/bootstrap.less
  3. Add lessEntryPoints key to build.sbt: play.Keys.lessEntryPoints <<= baseDirectory(_ / "app" / "assets" / "stylesheets" ** "main.less")
Reference: Configuration Section in

To find out whether you have configured it properly type play-less-entry-points in the Play! console and you should only see one entry.

Thursday, September 12, 2013

Immersing myself in data and database

With the buzz of Big Data, is it coincidence or deliberate measure on my part to learn more about database?

This week I finally complete the 7 week online course - M102: MongoDB for DBAs. A great course offered by MongoDB Inc. (formerly known as 10gen).

Not only do I get to learn about MongoDB, it also help me brush up on basic DBA stuff as well as infrastructure architecture for data storage.

As part of my job, I got to attend a the "DB2 10 for Linux, Unix and Windows Fundamentals" offered by IBM here locally in Hong Kong. I wasn't too excited on the first day about typical DBA administrative task, but the second day got more interested. From the course, I get to learn more about the theory behind column-based database and some basics around how DB2 implemented with their fancy name BLU Acceleration. 

Another interesting topic is Temporal Table feature in DB2. After some Googling, Temporal Table has been standardized into the ISO/IEC 9075:2011 or SQL 2011! It is already yesterday news. Even opensource database such as PostgreSQL supports Temporal Tables. I still recall those days manually doing it in the application layer, then later using Hibernate Envrs or EclipseLink History Policy and thought I was cool. Now this stuff is natively supported in standard SQL.