Saturday, December 12, 2009

Opera Turbo

Someone asks me if is it safe browsing with Opera mini (which defaulted to use Turbo)? The safe here mentioned refer to the data sent being stored by Opera Turbo (remember, all data traffic goes thru Opera Turbo so that it could compressed the content and sent the result to the browser). This question is answered on the following link:

If you are using ssl, Opera Turbo is bypassed and we're communicating with the SSL site directly. Which implies that turbo is turned "off" and you're back to the old way of browsing. Opera Turbo also declares that it doesn't store any user's information.

The conclusion is if we're looking for a cheaper way to browse, which is the case where the price mostly depends on the data being transferred (usually per KB), Opera Mini will be a great choice. Bear in mind, the statement declares that no user's data is stored. If you don't trust it then it simply mean don't use Opera.

Before I finished, I read one of the comments on this blog. It mentioned that Opera is a Norwegian company, which means that it follow the Personal Data Act ( And it is extremely strict.

Wednesday, December 09, 2009

Agile Manifesto

The thought of using agile methodology started about 3 years ago. Never been involved in a project using agile, I was looking for one to be involved in or have "my" project using it.
It seems to be challenging enough to use it, to know the advantage and of course the weaknesses. To find out the know how-when to use agile or waterfall. I'm not all for agile, but I have to admit agile excites me more. Adopting one of agile practice in one of the projects I'm involved in, which is daily meeting (face to face communication), opened my eyes to realize that the team starts to become more alive. Everyone starts to involve themselves more, discussion on the requirements become more often. As opposed to developer works only as they're told to.

Reading on agile manifesto, quoted below

We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value:

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan
That is, while there is value in the items on the right, we value the items on the left more.

quite confirms that agile might be the one we should use for the development. But still I'm not all for agile, there're still some factors that drives me to choose the old methodology. Such as large complex projects, the number of developers involved. Maybe it's me not knowing in depth on how agile methodology really works.

After all, it fall back to one step at a time. Welcome agile, I'm looking forward to really understand you more :)

Tuesday, July 07, 2009

Connect to wireless network using netsh

If you kinda tired of constantly changing your wireless network when you're at home or office, batch file could be a great help for you. A single click is enough to setup your wireless connection. I was using Net Profiles and I'm a satisfied user, but this single click idea beats Net Profiles.
Of course you've to create a batch file for each connection you want to setup, but that's not too much to do (imho).

FYI, I'm using Vista. For XP, the command could be a bit different but the idea is still the same (c'mon improvise).

Now, here's the simple command line to connect to a wireless lan:
netsh wlan connect name="network name" interface="Connection name under Manage Network Connection" ssid="the ssid"

netsh wlan connect name="hpsetup" interface="Wireless Network Connection" ssid="hpsetup"

in case you use static ip in your office or home, the command goes like this:
netsh interface ipv4 set address "Connection name under Manage Network Connection" static the_static_ip mask the_gateway

netsh interface ipv4 set address "Wireless Network Connection" static

One more thing, running under Vista you need to run the batch file as administrator.

After all, it's only one click away.....

Tuesday, June 16, 2009

Virtual Serial Port

How did I start to play around with it? It all began when a friend of mine was asking me for a favour to help him develop a simple software to communicate to another software thru serial port. My laptop doesn't have a serial port (of course, unless it was a very very old laptop) and I only have one usb to serial converter.

My first idea is to buy another usb to serial converter and a null modem cable to connect 2 laptops, thereby I can test the serial communication. Another idea is to use my old desktop (I have one and lent it to someone and actually forgot about it until I need it) but I don't think it is easy to do.
Then today at the office, asking my friend and he gave me one brilliant solution called VIRTUAL SERIAL PORT. I never heard it until today and my oh my... it is the solution to my problem (Thanks Adhi).

Googling around and I found one free driver ( Easy to install and I think I don't need to setup anything more, unless I need to configure another serial port pair. One thing lacking is the GUI to configure the ports. Anyway, it's free and open source, I couldn't be happier.

Friday, June 05, 2009

Turning Toshiba Satellite illumination led off

The first time I got my Toshiba M300 (actually it's not mine, it's my office's), I love to see all the LEDs light up the laptop.

Not until a week that it already bored me to see my laptop lights up as if it was a festival. Then to my dismay, I found out that turning off the LEDs wasn't easy (I did manage to turn it off though).
My colleague buying the same laptop as mine, also find it difficult and he did ask me how.

Today, someone asked me (she's using toshiba also) how to turn the LED off and gladly I told her and write in this post on the how to.

1. Press fn button and click on the rightmost button

2. Click on the HWSetup button

3. Go to Illumination tab and select Off and click OK. You're done.

MD5 hash

This morning I read a blog discussing about how to keep a secure password. The usual way to store a password is first to hash it using MD5 hash and store it in a db. The benefit of using MD5 is you cannot do a reverse-hash.

Here's how you code it in Java :

MessageDigest md ="MD5");
md.update("your password here");
byte[] hashed= md.digest();

To convert it in hex, here's the code (actually I got it from here):

One more tips, for better security, you might consider to add salt before hashing the password to make it less vulnerable. The changes looks like this :

md.update("The salt" + "your password here");

"The salt" here should be created dynamically and stored it along with the hashed password to be used later.

An excellent post on secure password scheme could be found here.

Friday, May 22, 2009

Being critical with your own capacity

This post I think only relates to small company where employees are less than 30 ppl or where there're no strict structure applied.
It's about how people responses when they're given task while they're still working on one.

By far, I've seen 3 ways of ppl managing their capacity:
  • "Yes man" (or "can do guy")
    This guy will say yes and confidently say I can to all the tasks given to him. Usually this type of guy is a smart guy, able to work everything fast and done as it seems. This guy is willing to sacrifice everything for the sake of finishing all the tasks. One thing I notice though, shortcuts were applied everywhere to get things done. The simple reason for this is there are a lot of tasks in hand, and as quickly as possible he wants to get rid of them all one by one.

  • Rational guy
    This type of guy is the rational thinking one, when given a new task he will look at his capacity first and dare to say "I can't" if he's asked to finish the task using the time allocated for other task. Mostly guys with this type are a bit perfectionist, they have their argument that task should be finished in a right way, with few shortcuts (or none if possible).

  • Quiet guy
    Given tasks beyond his capacity, he will keep quiet. He will keep on working on the tasks one by one, sadly without minding the time limit he has. The result is this guy will work overtime at most and doesn't meet the schedule. The quality of his work might not matter for him, he will keep on working and someday when he is tired enough, he will resign and start over in other place.

So which type is the best?
I would say a small company only needs 1 or 2 "Yes man" and a lot of "rational guy".
There are times where resources are limited and adding more resource is not the best solution. This is where "Yes man" is very helpful, however having too many "Yes man" won't be good either considering the quality of the work.
A growing company is a company which also learn to realize quality does come with price.

One caution for "rational guy", sometimes he might become too rational that he start to reject the task for the sake of task dislike using the current task as an excuse.

Thursday, March 19, 2009

Scheduling a project correctly? Almost impossible!

Scheduling a software project, I can't say that it's enjoyable. To say that it's complicated, risky and very unreliable task is agreeable for me. All the task durations set are all guestimate, basically based on hunches. After all, who can measure software development correctly. And to imagine that everything would go smooth is one thought that should never cross your mind.

The latest schedule that I arranged was a schedule for documentation project, actually it was a product reverse engineereed and documented. We have a client bought the product and they're interested in buying the source code along with the complete documentation.

At first, I thought for this project I was a bit lucky, no development needed. The thought that I forbid to cross my mind actually entered in. Thinking that documentation are all measureable, I began to arrange the schedule. The project started and after a month passed by, I begin to notice that problems start to creep in along with their surprises :
  1. New things to be documented start to pop up, things that I didn't see in the first place.
  2. Tools that we used sometimes stressed us up, even M$Word! The documentation has reached almost 500 pages, when my team tried to format the doc sometimes it stopped working. And still not to mention other tools we used. Are we picking a wrong tools here? Nope, I don't think so. Problems definitely will be met whatever the tools we picked.
  3. Human resources. When one member of the team quits, it left a hole that couldn't be filled straight away.
  4. The skills required. Not everybody has the skill to document, create diagrams, read existing code.
  5. Interrupt. I have to help other project and what can I do but to assign my time to help.

I hate the idea that working over hours is the only solution to finish the project on time. I prefer working smart, which are :
  • Finding patterns repeatedly used in the documentation. I'm lucky enough to have a teammate who is also able to recognize patterns repeatedly used in the documentation. Create/automate it once and solve it for all.
  • Start measuring the time spent for a task and focus on working faster for the same task either by optimizing the way we work, finding the common things (i.e. pattern) or even using copy paste :)
  • Spend less time on the normal working hours for other things we usually do (e.g. reading mails, newspaper, etc).

The project is still on its way, let's see whether we could finish the project on time or not :)
and whether the smart way will prevail over working over hours.

Before I finish, some books that I read also mentioned that software projects tend to not meet it's schedule, which I hope I could disagree with. These two books I would like to recommend : Secrets of Success Software and Mythical Man Month.

Tuesday, February 17, 2009

Running grails app in eclipse

Running grails app in eclipse actually is quite simple if... you know how.

Here's how :
- Import your grails app as existing project in eclipse
- Find {app-name}.launch in the project root and right click select Run As and the .launch configuration name
- There's all to it :)

If you want to know how to debug grails app, see my previous post.

Debugging Grails

Debugging grails almost got me crazy. I followed as said, trying it many times. At last google led me to this link which shed some light.

Let's get to the point, here's how to enable debugging grails (groovy) :
- Add JDK's tools.jar to your project build path.

Yep, that's all.
Or I'll be more specific here :
- Open your project properties, go to Java Build Path
- On tab Libraries, Add External JARs.
- Pick tools.jar from your {JDK_HOME}/lib

Fyi, I'm using grails 1.0.4 and groovy eclipse

Tuesday, January 27, 2009

Extracting excel sheet index

First, this post has nothing to do with Java. It only serves as a reminder for me.
I was in the middle of documenting things where I have to use Excel with many sheets. The need for me is to have automatic numbering on each sheet, where the index depends on the sheet index (fortunate for me). Excel doesn't provide a function for retrieving index, I tried to put the index on the sheet name and further extract it. It works with the 1st excel file (because the other sheets were copied from the 1st sheet and excel voluntarily add index to the new copy's name), but with the 2nd excel file I don't want to put the index on the sheet name myself. The macro below (see this link) helps me on extracting the sheet index :

  1. Type above code.
  2. In Excel press Alt + F11 to enter the VBE.
  3. Press Ctrl + R to show the Project Explorer.
  4. Right-click desired file on left (in bold).
  5. Choose Insert -> Module.
  6. Paste code into the right pane.
  7. Press Alt + Q to close the VBE.
  8. Save workbook before any other changes.
To use it you could simply type "=SheetNum()".

Thursday, January 22, 2009

Javascript root objects available for webscript

In this post I'm quoting the wiki content for the sake of ease to find it later.

One link that might be of interest : Javascript API cookbook

The following JavaScript root objects are available to all Web Scripts, regardless of their hosting environment.

an associative array of all URI parameters. See example.
an associative array of all URI parameters (where each key is an argument name and each value is an array containing all respective argument values, even if only one is supplied). See example.
an associative array of all request headers.
an associative array of all request headers (where each key is an header name and each value is an array containing all respective header values, even if only one is supplied). See example.
provides access to the URI (or parts of the URI) that triggered the web script.
An empty associative array which may be populated by the JavaScript. Values placed into this array are available as root objects in Web Script response templates.
provides ability to control response status codes.
provides ability to control caching of response.
provides access to the Web Script configuration.
provides access to Web Script localized messages.
provides information on the response format to be rendered.
A boolean indicating whether the web script is executing as "Guest".
An associative array of meta-data properties describing the Web Script.
An associative array of meta-data properties describing the server hosting the Web Script.
A host object for parsing and generating JSON objects.
A host object for parsing and generating Atom (Publishing) documents.
A host object providing access to console logging facilities for debugging of scripts. See the Logging API.

Web Scripts hosted within the Alfresco Repository tier also have access to the following root objects which provide direct access to Repository services and content.

the repository root node (only available if authenticated)
the company home folder (only available if authenticated)
the person node of the currently authenticated user (only available if authenticated)
the user home folder (only available if authenticated)
A host object providing access to Lucene and Saved Search results. See the Search API.
A host object providing access to Alfresco people and groups. See the People API.
A host object providing invocation of registered Alfresco Actions. See the Actions API.
Session related information such as the current authentication ticket. See the Session API.
Access to the root elements of the classification API. See the Classification API.
Access to a library of useful helper functions not provided as part of generic JavaScript. See the Utility Functions.
Access to WCM objects such as AVM paths and searching within AVM stores and web projects. See the AVM API.
Cross repository copy support. See the Cross Repository Copy.
Start workflows and access, control in-flight workflows. See the JavaScript API#Workflow API.

Web Scripts hosted within the presentation tier (i.e. within Alfresco SURF) have their own extras as described in the Surf Platform - Freemarker Template and JavaScript API.

Wednesday, January 21, 2009

Thread safe singleton implementation

Singleton pattern is used in many projects I've gone through and I implemented it the same way in all the projects just like others did. Luckily for me the many projects could be safely assumed as thread safe projects. Thread safe project for me is a project where no thread programming is required. Before continuing, below is how I implemented singleton pattern.

public class SingletonClassic {
static SingletonClassic instance;

public static SingletonClassic getInstance() {
if (instance == null) {
instance = new SingletonClassic();
return instance;

I guess the code above should be familiar to programmers. Now, we delve into the reason of why I spend my time writing this blog. The code above is actually not thread safe, let's consider for example we have 2 threads running. Both are trying to access the singleton above (assume that the singleton isn't accessed yet), the 1st thread already pass the "if (instance == null) {" statement and the thread scheduler thinks that it's the 2nd thread time to run so the 1st thread got paused and the 2nd thread runs. 2nd thread arrive at the "if (instance == null) {" statement, the instance isn't instantiated yet so it enters into the if clause and create an instance and returns the instance. 2nd thread sleeps and 1st thread wakes up and continue where it left before which is creating another instance.
So, we have a Singleton which is not so Singleton. At this point we see no harm done but if you're a perfectionist, the problem above will annoy you :)
To ease you, here's the solution that I read in some article which unfortunately I forgot (very very unfortunate for me not to keep the link) :

public class SingletonClass {

public static SingletonClass getInstance() {
return SingletonHolder.getInstance();

static class SingletonHolder {
static SingletonClass instance;

static {
instance = new SingletonClass();

static SingletonClass getInstance() {
return instance;

I just go straight to the point here, the reason why the new code above is thread safe is because the static initializer is guaranteed to be thread safe in the jvm specification. It will be initialized only once when the class is loaded.

still confused? let me break it down :
1. SingletonClass.getInstance() is called
2. which in turn will call SingletonHolder.getInstance()
3. at this point static initializer in SingletonHolder will be executed where SingletonClass instance is initialized
4. the new SingletonClass instance is returned, the instance will not be instantiated twice. Guaranteed!

If I ever meet the article again, I will write the name of the guy who found this method here.

Problem with subclipse and tortoisesvn

If you use subclipse and tortoisesvn on the same checkout folder on your machine, you might got this exception while working with subclipse :

"svn: This client is too old to work with working copy"

The reason is your tortoisesvn is using the latest svn version to perform some actions on the checkout folder.
The solution is to replace libsvnjavahl-1.dll in your [eclipse-root]/plugins/org.tigris.subversion.javahl.win32_1.1.0 with the latest one found in the zip file on this link.

I guess that's all that I did on my machine.