Showing posts with label rant. Show all posts
Showing posts with label rant. Show all posts

Tuesday, March 31, 2009

RTFL - Read the Fucking Logs

Read the fucking logs? Yes, it happened so many times, on so many guys. Something that I always try to avoid.

Say, you hit into a problem, you looked into the log file, you could see a bunch of error messages and stacktrace, you read the first line, you didn't bother to read the second and further.

You tried to change the configurations or something that you thought would make sense but the same (or new) error came out. You spent quite some time on it like an hour or a day.

You asked me / your supervisor to look into it and they found clear error messages or indications somewhere down the error log. You felt sorry, you found yourself stupid to waste so much time, you wished to be in the hall of shame for that day.

If this is a recurring habit of your, can you make "reading logs carefully" as a troubleshooting principle?

Wednesday, February 18, 2009

Brush up your Support-Fu, can?

Wasted about an hour at the Public Bank HQ this morning, more than 30 minutes on waiting, 2 minutes on getting confused and 5 minutes on getting an answer.

Long story short, yes.

I want to start a long term investment on a mutual fund that I selected and I do not have a saving account in this bank, which you will need to have $ transferred monthly to the investment account. I have my forms, my 500K bank draft (nuh, don't trust this) and my temporary IC (as I lost my purse a few days ago).

There.. reached my turn to be served by this first customer service dude.
Dude A: So you want to open a saving account for that?
Dude A: You will need a minimum of MYR 250. Can I have your IC please?
Me: I do not have an IC.. now. But I can show you my temporary IC.
Dude A: I am sorry sir, we will need that otherwise the system won't pass you.
Me: So does it mean I have to wait 3 weeks before I come here?
Dude A: Yes. I'm sorry.
Me: Options?
Dude A: We need your IC, the system has to scan it.
Me: And there's nothing I can do here anymore today, right?
Dude A: Yes, I'm sorry.
I walked away then paused, and I was annoyed by not giving much details about how exactly it works. I spent my morning to be stuck in the jam, some time to find a parking, waited on the bench, and I got knocked out with a confused mind.

I waited to be served again and this time (by a lady) I got my answer. To start an investment, you do not need a saving account, it's only for the convenience of not needing you to visit the bank to deposit $ for the investment every month. Basically, I could just start it by dumping all my 500K into it, which of course is not my plan. So there're a few options:
  1. Create the investment account, pass them my 500K.
    1. Come back 3 weeks later to open a saving account, OR,
    2. Come back every month to deposit your $.

  2. Wait for 3 weeks to open both accounts and start the investment with your desired amount of $.

I have some Customer Service experience (I worked in both the Atlassian and MuleSource team) and there're a number of things that you have to avoid while handing a ticket / customer.
  1. Never assume that the customers are smart. Like me, I was clueless. So, ask them questions.
  2. Don't jump into solution too fast. Get the context right and make sure that both of you are on the same understanding.
  3. Always give them a solution, if not, workarounds, still not, explain why.
Public Bank, you could lose me as a customer, I still have 3 weeks to think.

Friday, October 17, 2008

The guys behind the new Maybank2U, please read

Epic fail! For the past few days, I had been hearing people ranting about the new site in Twitter, Facebook and my IM.

I haven't been using my Maybank account (basically abandoning it unless there's a need to M2U to some friends for convenience sake, oh.. and, it has more ATM machines than HSBC that is true) for the past 2 months ever since I changed my job.

As I am NOW doing some book keeping, as well as to experience the pain others are suffering, I convinced myself to log into the site. Clicking on "Transaction History", the cool Ajaxy waiting icon appeared and.. woohoo, a few 10 seconds later:

Ah, ArrayIndexOutOfBoundsException, caused by a JSP tag. I don't want to know what else they're doing with Struts and in the JSP, but surely, these guys wrote some shit to make almost every customer suffers.

- yc

Saturday, October 4, 2008

Let's complain about the local taxi service!

In a yumcha session last week, my friends told me that the taxi service in our country has recently been rated as the worst in the region. This morning, one of my friends shared this article in Facebook, which is on the same topic.

The past 2 months, I have been driving frequently than I ever had before. I hate (hated, hate still) driving because it adds one more car to the already-busy traffic, it pollutes the environment, it causes fuel depletion too. For these reasons, I always took taxi last time (for years), because I didn't travel much.. I didn't feel the pain although I ranted about it sometimes.

What're the problems? Two problems:
  1. The taxi drivers never use the meter if you're traveling from one town to another. Say, Setapak to Mid Valley, Chow Kit to One Utama, KLCC to anywhere, etc.
  2. Most Malaysians do not queue (esp. couples), I usually shout to stop them from taking my taxi.
I drive because I travel far these days and I got enough of being ripped off by the taxi drivers. But that doesn't solve the problem I faced and other people are facing. So, inspired by OpenMalaysia's Yoon Kit, I decided to lodge a complain to the ministry of domestic trade and consumer affairs.

Please join me:

The local taxi service has gotten out of control to the extent that we are now rated as the worst country in taxi service provision in the region. We're also featured in the MSN Singapore News<http://news.sg.msn.com/lifestyle/article.aspx?cp-documentid=1682889> too.

I am a residence of Kuala Lumpur and the situation has become worse to me these days as I have to travel frequently than I ever had to, to/from Mid Valley, 1 Utama, KLCC, etc.

The taxi drivers never follow the meter, every time I travel to/from these places, I have to bargain for a good price in order to get into the cab. At the first place, it is so wrong for them to break the rules, secondly, it has made me to look like a an idiot for so many times by walking from one taxi to another. There was once in Mid Valley that I had to try seven taxis.

Another issue is that, most general passengers do not use the queue and taxi drivers just stop their car before the station when someone waves their hand at another end.

Can someone do something about it? It's not just hurting the local consumers, it's also tarnishing the image of our country because tourists don't really love it too.

Act now!

From @yoonkit: @yclian you may need to name specific taxi companies and events, otherwise they won't know how to react.

- yc

Monday, July 14, 2008

PropertyPlaceholderConfigurer.ignoreUnresolvablePlaceholders and my precious one hour

To speed up my prototyping process, I decided to use Mule to takecare of the integration of my core code with the persistence layer for me. Yes, basically I am lazy to write all the polling, updating, etc. This did not turn out good as I was stupidly assuming a startup problem a Mule issue and tried to fix it in the past 1 hour.

So what was it about?

I have a Mule configuration and also a Spring beans configuration which is used to configure datasource. PropertyPlaceholderConfigurer is also defined in the Spring configuration to read a jdbc.properties file and those properties will be filled into the datasource settings, e.g.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>${jdbc.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>

Great, unit test goes easier now. Not yet.

I have this JDBC query settings in my Mule configuration:

<jdbc:connector name="jdbcConnector" dataSource-ref="dataSource" pollingFrequency="5000">
<jdbc:query key="getSurrogateById" value="SELECT * FROM surrogate WHERE surrogateId=${header:test}" />
</jdbc:connector>

Tried to start Mule, but it failed with this error:

[07-15 00:47:34] ERROR AbstractConfigurationBuilder [main]: Configuration with "org.mule.config.spring.SpringXmlConfigurationBuilder" failed.
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'jdbcConnector' defined in null: Could not resolve placeholder 'header:test'
at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:268)
at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:554)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:528)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:363)
at org.mule.config.spring.MuleApplicationContext.<init>(MuleApplicationContext.java:102)</init>

Changing the Mule version didn't help (something stupid that I did), until I uncommented PropertyPlaceholderConfigurer, Mule was able to start. That gave me the clue to look into the class (which I didn't have to as the stacktrace was obvious enough) to find out the ignoreUnresolvablePlaceholders property.

Bah.

- yc, finished ranting

Friday, June 27, 2008

Maven does NOT support SOCKS for HTTP

I have a internal repository which can only be accessed through SOCKS, so I thought, if I set up a <proxy> in settings.xml with SOCKS_5 as its protocol, it shall work -- to download artifacts from the repository through the proxy. By the way, the documentation is not clear about what you should specify for the protocol. I used SOCKS_5 because ProxyInfo sounded right.

After a few attempts, I realized from the error logs that Maven did not go through the SOCKS proxy I defined, it basically skipped it. I hooked my IDE to the process to for some debugging to realize that Wagon (the transport abstraction of Maven) chose to use LightweightHttpWagon to download the artifacts and would only know how to deal with HTTP based proxy. Wagon chose it by looking up for Plexus component with the role-hint of http, damn.

I believe I could create a local repository by mounting the remote end using FUSE/sshfs. I didn't anyway, I made HTTPd to allow external connections to the repository with basic auth enabled (the server uses Archiva anyway). That's quick and at least I wouldn't have to guess why scp or file wasn't working later.

Playing with Maven is a pain, sometimes.. or most of the time if it doesn't work.

P/S: If you can really make Maven to work with HTTP+SOCKS, let me know and tell me that I'm wrong.

- yc

Monday, June 16, 2008

WTF is wrong with RMI

Yes, WTF is wrong with RMI. Taken from the "Getting Started using RMI" page:

Note: Before you start the rmiregistry, you must make sure that the shell or window in which you will run the registry either has no CLASSPATH set or has a CLASSPATH that does not include the path to any classes that you want downloaded to your client, including the stubs for your remote object implementation classes.

If you start the rmiregistry, and it can find your stub classes in its CLASSPATH, it will ignore the server's java.rmi.server.codebase property, and as a result, your client(s) will not be able to download the stub code for your remote object. For an explanation of how code downloading works in RMI, please take a look at the tutorial on Dynamic code downloading using RMI.

UPDATED: Omg :) That's documentation for 1.4.2. If you refer to the latest one, it actually highlights on the classDir. So ultimately, my problem of not referring to a newer documentation.

Not paying much attention to these lines, it got me wasted a few valuable hours to get a simple example working. I have a Hello interface and a HelloImpl implementation with a main method in it to do the binding.

I kept getting either:

java.lang.ClassNotFoundException: foo.Hello
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)

and

java.lang.ClassNotFoundException: foo.HelloImpl_Stub
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)

Whenever I ran:
java -classpath classes/ foo.HelloImpl

The error is misleading. It made me wondered why Java would complain about ClassNotFoundException when those classes were in the classpath! To put that paragraph in bullet points:

  • Please set the CLASSPATH variable before you run rmiregistry, e.g.
    export CLASSPATH=classes/
    rmiregistry &
    java -classpath classes/ foo.HelloImpl

  • Or, please set the -Djava.rmi.server.codebase system property to point to your classpath when you start your application, e.g.
    rmiregistry &
    java -Djava.rmi.server.codebase=file:classes/ -classpath classes/ foo.HelloImpl

Yes, it was actually my problem of not reading the documentation clearly. But can't just the Java guys fix it so that it will pick up from the classpath without setting either the environment variable or system property?

- yc, rants!!

Sunday, March 2, 2008

Are you overworked, IT guys?

I have come across so many friends who are overworked by their employers, especially those from the IT field, the issue of underpaid sounds serious in Malaysia. I could be wrong, so feel free to drop a comment if you have other opinions.

In Malaysia, our salary has been stagnant for years, and I believe that's part of the reason why it attracts foreign investors. When it comes to the argument of employees being overworked, there are two factors that we can look into:

  1. Employees are not being efficient.
  2. Management is being unreasonable, in terms of deadline and human resource.
Most of the time, both are valid. For an old-school manager who is not willing to adopt to new methodologies, his interest is to squeeze the most out from the project and his employees for a high ROI. Driven by this, he is likely to commit to an unreasonable deadline and cut down the cost by hiring just-sufficient (usually turned out to be not, due to inefficiency) human resources.

Sounds familiar to you? I am happy that I am not working for this kind of company.

In the end, the development team faces huge pressure, as the deadline comes closer it turns worse, and they stay late to work even on the weekends. Driven by this, the employees are no longer efficient and neither they are happy and motivated -- They will choose to leave.

What will happen when they leave? The company has to hire and train new guys again, that's a terrible investment and due to their management style the company will forever be haunted by high turnover rates. And generally (yes, I say generally, not all, based on my experience) since most Asian companies share the same management style, the employees will end up in the same type of company and they will.. be forever unhappy until they are retired.


I have created a Jyte claim: You are overworked and your employer is not hiring sufficient human resources. When I'm writing this, one of my friends is making the decision to leave her company. Why? The project has to be delivered on April, but she has been working 7 days per week since late-January. On Friday, she was talking with me on MSN when she was still in the office, the time was 1am morning.


- yc, what do you feel?

Monday, November 26, 2007

One of the many problems of OpenID

I have just come back from a short trip, which has given me some space off work and had some time to start thinking about getting things done.

So, one of the very first actions is to get into Issues Done then realized I could not login as my OpenID server -- Videntity is either down or gone.

Stefan Brands wrote a good entry to discuss about the problems of and with OpenID. Do check it out.

The model of OpenID suggests a decentralized approach which arguably is its strength and at the same time its biggest weakness. The service is no longer dependent on just the service provider but also the external authentication service provided by a third party.

Ideally, if all servers are available, everything works in yours and the dreams' favor. But at this moment, I am totally prohibited to enter any of my sites registered under my OpenID. How bad it is?

- yc, pffft

Monday, October 29, 2007

Cp1252 Nightmare

It was a horrible experience. Spending more than an hour to recreate workspaces and reimport projects, just to get rid of the strange Eclipse build error:

The project was not build since the source file ${path} could not be read

I did not have any problems to compile the code using Maven though.. So, why was Eclipse complaining? Some search results in Google suggested to me that it could be a file encoding issue. I was pretty sure that would be the case since the code might be checked in by someone on a Windows machine.

I switched to my Windows environment and the code could be successfully built.

Well, well.. but what's the solution? After being annoyed by the error for more than an hour, I slammed Eclipse by forcing the project to use Cp1252 encoding and dramatically the build works. Now, changing the text file encoding back to UTF-8 works too (which previously did not).

Why?

- yc, pwnz0r

Friday, October 19, 2007

Every character counts

I have been fixing up some funny Spring/Acegi<->LDAP issue in the past two days. What I was trying to achieve is some AOP using BeanNameAutoProxyCreator to intercept invocations to methods of a particular interface/class, so that it authenticates against an LDAP repository and validate if a user has one of the specified roles. Something wasn't really working at the DefaultLdapAuthoritiesPopulator -- the authorities/roles list was empty.

Now, it's solved, yes it is.. with shame.

I turned on an even detailed debug logging and that's when I started to realized my.. stupidity ;-)

conn=2 op=1 SRCH base="ou=groups,dc=my,dc=com,dc=customware" scope=2 deref=3

filter="(member=uid=clim,ou=people,dc=my,dc=com,dc=customware)"
conn=2 op=1 SRCH attr=cn
bdb_idl_fetch_key: [01872a84]
bdb_idl_fetch_key: @ou=groups,dc=my,dc=com,dc=customware
<= bdb_equality_candidates: (member) index_param failed (18) => access_allowed: search access to "ou=groups,dc=my,dc=com,dc=customware" "member" requested
<= root access granted => access_allowed: search access to "cn=mule01,ou=groups,dc=my,dc=com,dc=customware" "member" requested
<= root access granted dnMatch 0 "uid=clim,ou=people,dc=my,dc=com,dc=customware" "uid=clim,ou=people,dc=my,dc=com,dc=customware" => access_allowed: read access to "cn=mule01,ou=groups,dc=my,dc=com,dc=customware" "entry" requested
<= root access granted => access_allowed: read access to "cn=mule01,ou=groups,dc=my,dc=com,dc=customware" "cn" requested
<= root access granted => access_allowed: search access to "cn=managers,ou=groups,dc=my,dc=com,dc=customware" "member" requested
<= root access granted dnMatch -1 "uid=clim,cn=people,dc=my,dc=com,dc=customware" "uid=clim,ou=people,dc=my,dc=com,dc=customware" send_ldap_result: err=0 matched="" text="" conn=2 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=

Did you see that? I will do it again:

dnMatch 0
"uid=clim,ou=people,dc=my,dc=com,dc=customware"
"uid=clim,ou=people,dc=my,dc=com,dc=customware"
...
dnMatch -1
"uid=clim,cn=people,dc=my,dc=com,dc=customware"
"uid=clim,ou=people,dc=my,dc=com,dc=customware"

cn=people and ou=people?!

dn: ou=people,dc=my,dc=com,dc=customware
...

dn: cn=managers,ou=groups,dc=my,dc=com,dc=customware
member: uid=clim,cn=people,dc=my,dc=com,dc=customware
...

dn: uid=clim,ou=people,dc=my,dc=com,dc=customware
...

WTF! Worse than failure hey! LDAP did not fail me at the time I was importing from the LDIF with invalid member attribute value. I could have saved a few hours to do something.. more significant than sitting in front of my Eclipse to figure out why wasn't DirContext.search() returning any results. In fact, I have learned a very good lesson.

- yc, rantinggggggggggg!