Sunday, November 23, 2014

Major Bursary in Science Talent Search 2014

It's the 6th year the boy participated the competition and he got his 4th major bursary.

I started programming at his age now and won 4 awards before I went to university studying computer science. That's a connection spanning nearly 30 years between a father and a son.

Friday, November 07, 2014

Method names are new (redundant) comments

It's very interesting to see how developers react to commonly accepted coding conventions.

We all know methods should be short, and comments can be avoided when methods are short and with meaningful names. But by following these conventions, we sometimes only generate another form of redundant comments. Let me explain it with an example.

    if (feeType == FeeType.PERCENTAGE) {
        ...
    }

What's the problem here? It reads not like in human language, or not DSL enough. Let's extract the condition to a one-liner method, and make the method name suitable to be appeared after if.

    if (feeIsBasedOnPercentage(feeType)) {
        ...
    }

Much better, right? Now the question is, if the condition needs further explanation, why not explain it directly with a comment side by side, like this.

    if (feeType == FeeType.PERCENTAGE) {
        // fee is based on percentage
        ...
    }

No, this's not good. The comment looks like redundant. It just repeats what's in the if statement. Okay, let's remove the redundant comment.

    if (feeType == FeeType.PERCENTAGE) {
        ...
    }

So, what was the question again?

If you find yourself extract / write
  • a very short, usually one-liner, method, and
  • it's only called once, and
  • method name is repeating what's in the body
you're actually writing a redundant comment, but at a different place from what it comments on, like this.

    private boolean feeIsBasedOnPercentage(FeeType feeType) {
        return feeType == FeeType.PERCENTAGE;
   }

Finally, I'd like to guess how this redundant way of programming was developed, just for fun.

   private boolean feeIsBasedOnPercentage(FT ft) {
       return ft == FT.P;
   }

Hope you get the idea of why I call it redundant. If you do, Dependency is the new Inheritance is another one for you.

Disclaimer, code snippets used here are for illustration only.

Thursday, August 07, 2014

Are you setting Connect Timeout correctly?

Application development nowadays is becoming more and more like mashing up. Unless you provide file storage service, or data repository service, there's no way you can avoid consuming 3rd party APIs / (micro-) services. In Java battlefield, most of the time, internal or external APIs are provided via RESTful interface. If this is the case, chances are to consume a web service you'll be using one of
No matter which one you end up use, it's always a good practice to set timeout for HTTP clients, and this can be done only by org.apache.http.client.config.RequestConfig. Now can you please check the value you pass into RequestConfig.Builder#setConnectTimeout()? If it's significantly larger than 5(ms, not a typo here), you're not setting it correctly.

Connect timeout is used to provide QoS of the creation of TCP connection between client and server, not the whole lifecycle of the connection, or in pooled environment, from borrow to return. If this process can't finish in few milliseconds, org.apache.http.conn.ConnectTimeoutException should be thrown to speed up the exception handling. It's not the end of the world however, if you misuse it. It's just better to fail fast in case something goes wrong for better user experience, rather than wasting the x seconds you set.

Then how about the RequestConfig.Builder#setSocketTimeout()? Well, I may have another post on it. Until then, it's more like the meaning you think setConnectionTimeout has.

Never take anything for granted.

Sunday, June 08, 2014

Couchbase and couchbase-client


If you got this when starting Couchbase,

Port server memcached on node 'babysitter_of_ns_1@127.0.0.1' exited with status 71. Restarting. Messages: Thu Oct 3 14:13:51.448736 EST 3: failed to ensure corefile creation

make below changes in /etc/security/limits.conf
couchbase hard nofile 10240
couchbase hard core unlimited

See http://www.couchbase.com/issues/browse/MB-4727

If you got exception about XML datatype like this, exclude org.codehaus.jettison:jettison from couchbase:couchbase-client will solve it.

13:50:00,995 ERROR [[resteasy-servlet]] Servlet.service() for servlet resteasy-servlet threw exception
java.lang.LinkageError: loader constraint violation: when resolving field "DATETIME" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/datatype/DatatypeConstants, and the class loader (instance of ) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
 at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.(RuntimeBuiltinLeafInfoImpl.java:267)
 at com.sun.xml.bind.v2.model.impl.RuntimeTypeInfoSetImpl.(RuntimeTypeInfoSetImpl.java:65)
 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:133)
 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:85)
 at com.sun.xml.bind.v2.model.impl.ModelBuilder.(ModelBuilder.java:156)
 at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.(RuntimeModelBuilder.java:93)
 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:450)
 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:298)
 at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:141)
 at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1157)
 at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:145)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Wednesday, March 12, 2014

install Docker on Ubuntu 13.10

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D8576A8BA88D21E9
$ sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker

$ sudo docker version
Client version: 0.9.0
Go version (client): go1.2.1
Git commit (client): 2b3fdf2
Server version: 0.9.0
Git commit (server): 2b3fdf2
Go version (server): go1.2.1
Last stable version: 0.9.0

$ sudo docker search ubuntu | grep '^ubuntu'
ubuntu      General use Ubuntu base image. Tags availa...   108
ubuntu-upstart                                              0
ubuntu/ping                                                 0

$ sudo docker pull ubuntu:saucy
Pulling repository ubuntu
9f676bd305a4: Download complete
511136ea3c5a: Download complete
1c7f181e78b9: Download complete

$ sudo docker images -a
REPOSITORY                TAG     IMAGE ID      CREATED        VIRTUAL SIZE
ubuntu                    saucy   9f676bd305a4  5 weeks ago    178 MB
<none>                    <none>  1c7f181e78b9  5 weeks ago    0 B
<none>                    <none>  511136ea3c5a  9 months ago   0 B

$ sudo docker run -i -t -privileged=true ubuntu:saucy /bin/bash

# apt-get install openjdk-7-jdk


# exit

$ sudo docker ps -a
CONTAINER ID  IMAGE                           COMMAND    CREATED      STATUS   PORTS  NAMES
6a3720326142  ubuntu:saucy                    /bin/bash  2 hours ago  Exit 0          stupefied_bell

$ sudo docker commit 6a3720326142 jerry/ubuntu13.10_java7
5d7e72d6b3a571f384efdbe31418f47b7d32eb6e5df9fe5c7c5357dc07843f86

$ sudo docker images -a
REPOSITORY                TAG     IMAGE ID      CREATED        VIRTUAL SIZE
jerry/ubuntu13.10_java7   latest  5d7e72d6b3a5  3 minutes ago  512.5 MB
ubuntu                    saucy   9f676bd305a4  5 weeks ago    178 MB
<none>                    <none>  1c7f181e78b9  5 weeks ago    0 B
<none>                    <none>  511136ea3c5a  9 months ago   0 B

$ sudo docker rmi IMAGE_ID

$ sudo docker ps -a
CONTAINER ID  IMAGE                           COMMAND    CREATED      STATUS   PORTS  NAMES
2aec90f4a9c3  jerry/ubuntu13.10_java7:latest  /bin/bash  2 hours ago  Exit -1         nostalgic_pike
6a3720326142  ubuntu:saucy                    /bin/bash  2 hours ago  Exit 0          stupefied_bell

$ sudo docker rm CONTAINER_ID

$ sudo docker run jerry/ubuntu13.10_java7 java -version
WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.10.1)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

$ sudo docker start 2aec90f4a9c3

$ sudo docker attach 2aec90f4a9c3
ifconfig
eth0      Link encap:Ethernet  HWaddr 0e:5a:8f:4b:46:a3  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::c5a:8fff:fe4b:46a3/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:18 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1687 (1.6 KB)  TX bytes:1014 (1.0 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

$ sudo docker stop 2aec90f4a9c3

Monday, March 03, 2014

Maven 3.1 and 3.2 are incompatible with 3.0


As title says, Apache Maven 3.1.x and 3.2.x are not compatible with 3.0.x, and this may affect your artifacts.

The main difference is whether or not, the default (compile) scope dependencies in a test, or provided scope dependency will be included in the final artifact, if you know what I mean.

In Maven 3.0, all the compile scope dependencies in test or provided scope dependencies will be included, unless they're overwritten by others in any ways.

In Maven 3.1 and 3.2 however, all the compile scope dependencies in test or provided scope dependencies will NOT be included, unless they overwrite others in any ways.

Personally, I like what Maven 3.1 and 3.2 are doing. Just a heads up you may get hurt by including ugly designed test or provided dependencies.

Wednesday, February 19, 2014

Dependency is the new Inheritance

To warm up, please have a read how bad inheritance is.
disadvantages of inheritance in java
Why extends is evil

Okay, dependency is the new inheritance, just even harder to do it right.

With inheritance, you extend something means you decide to be it, just a bit special. It's more base classes' responsibilities to make sure it doesn't become something else. With dependency however, you introduce a dependency just because it has something that's useful to you, no matter how much in it you don't need at all. Check the exclusions in pom.xml to see how many dependencies, direct or indirect, you included and later you found they caused trouble. Isn't this the new Refused Bequest, except there's no better way to solve it?

With versioned dependency, you changed something but others depend on it don't know if it breaks their part. "If it ain't broke, don't fix it". They choose to stick with the old version of what you've changed, and not to move forward with you. Without their following and feedback, you make further changes more freely, knowing that only part, if any, of your users bother to follow what you're doing.

Popular languages, like C# and Java, only allow single inheritance to avoid the potential problem caused by multiple inheritance. This makes inheritance less dangerous for everyday use. But you are free to depend on no matter how many dependencies. Very likely, those dependencies depend on difference versions of same module, directly or indirectly. Then it becomes your job if this doesn't work and you have to manually exclude all but one, the one that can fit all. Put it simply, you have to manage and solve dependency conflict, which is never part of your job in single inheritance paradigm.

Hope I'm clear and to the point by now why dependency is the new inheritance. Versioned dependency is the root of Dependency Hell? Not really, but you must have the skills and experience to handle it.