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

Saturday, October 27, 2007

Google goes Flex

I talked about Microsoft Silverlight a month back and I always have doubt how successful it could be. I have been keeping an eye on Flex (I don't do Flex though, but my company does) and it is always interesting to discover new sites adopting to this cool technology.

Yakov Fain blogged about SearchMash, a Google operated project. Take a look at it here to find out how interactive search engine will turn to.. soon.

As a side note, my friend Chee Seng runs the Malaysian Flex User Group, please join to support the community. If you are not from Malaysia, you may want to look into this directory.

- yc, sunday arvo.. is hot!

Sunday, October 21, 2007

Ubuntu 7.10 - Gutsy Gibbon with XGL

Upgraded my Ubuntu to 7.10 yesterday, the coolest add-on to it is the support of Compiz Fusion (Compiz effects came in at 7.04 actually). Some of you might have seen the effects, which I will briefly walk through those that I have experienced later before I end this short blog entry.

A few problems that I experienced after the upgrade were:

  1. Restricted drivers manager not working. It said something like this:
    You need to install the package linux-restricted-modules-* for this program to work.
    Solution: Install the restricted module, e.g.
    apt-get install linux-restricted-modules-2.6.22-14-generic

  2. Couldn't turn on Compiz effects via System -> Preferences -> Appearance -> Visual Effects. It said something like:
    Desktop effects could not be enabled
    Solution: Turn on "Composite" in /etc/X11/xorg.conf, i.e.
    Section "Extensions"
    Option "Composite" "1"

    However, before that, you have to install the GL based X server, i.e.
    apt-get install xserver-xgl

    Then, restart your X server (ALT + CTRL + Backspace) after you have made configuration changes.

  3. IDE and Java applications such as IntelliJ and Netbeans were broken with blank swing interface. I noticed that the menus were still working when I moved my mouse over them.

    Solution: Set AWT_TOOLKIT to MToolkit, for instance, add this entry to /etc/profile:
    export AWT_TOOLKIT="MToolkit"
    Then, reload the profile (source <profile>) and restart your IDE.

To find out what can Compiz effects do, please take a look at this Youtube video. I noticed and managed to discover some newly added effects:
  1. Shadow effects
  2. Maximize and Minimize effects
  3. Blinking/fading effects caused by error/alert, e.g. backspace on an empty text box in Pidgin; filling in invalid phrase in Firefox search box;
  4. Wobbly window effects while it's dragged
  5. Transparent effects (use ALT + Wheel Scroll on a window)
  6. ALT + Tab with real-time snapshots
  7. M$ + E to choose desktops
  8. M$ + Wheel Scroll to zoom
  9. M$ + Right Click to zoom in once

Read these to discover more:
  1. Compiz documentation
  2. Novel - Xgl on Suse 10.1 (see Xgl Shortcuts section)

- yc, impressed

Friday, October 19, 2007

The Fault is On Malaysians

Read a very long ranting blog entry by Su Ann, and in response to it:

And this is my favourite part. the interviewer made a comment that if action is not taken by the government soon, then this issue would be forgotten by Malaysians. And Nazri Aziz said, “Who’s fault is that? It’s not the government’s - the fault is on Malaysians.”

No one ever likes Nazri, one who is known for having a mouth full of crap. But NOT this time.

It is the fault of Malaysians:

  • It is the fault of the people to vote for the government.
  • It is the fault of so many youngsters out there to not care about this issue and the recent issues.
  • It is the fault of the government to keep doing what they have been doing.
  • It is not just the fault.. it is a real shame that the politicians are claiming all they have been doing are for the country.
  • It is the fault of the people to believe the press and all the lies.
  • It is the fault of the people to uphold the "tidak apa", "malaysia boleh", and all other attitudes and chauvinistic beliefs.

We are f**ked up.

- yc, rant2

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!

Thursday, October 18, 2007

Constant Interface or Constant Class?

I have been using classes to hold constants instead of interfaces (which we call the 'Constant Interface'), all these while. My colleague, Kynan, was reading my code today and questioned the reasons behind such practice.

There has always been debates on this subject, e.g.

TheServerSide.com - Use Interface for declaring Constants

I think it's good to share. I have read the following books which justify why should you avoid 'Constant Interface':

Philip Heller and Simon Roberts, "Complete Java 2 Certification Study
Guide":
"In the first place, to say that a class implements an interface
really means that the class exposes the public methods listed in the
interface. Interfaces are for defining types and should be used
exclusively for that purpose. Constant interfaces only contain data,
so they definitely don’t define types.

The second disadvantage is a bit more complicated. Suppose someone you
work with writes some code that uses an instance of Scales. This
person can legally reference that instance with a variable of type
Conversion, even though doing so would be quite inappropriate. Later,
if you wanted to eliminate the Conversion interface, you couldn’t do
so, because your misguided colleague would be relying on the existence
of the interface."

Joshua Bloch, "Effective Java - Programming Language Guide":
"The constant interface pattern is a poor use of interfaces. That a
class uses some constants internally is an implementation detail.
Implementing a constant interface causes this implementation detail to
leak into the class's exported API. It is of no consequence to the
users of a class that the class implements a constant interface. In
fact, it may even confuse them. Worse, it represents a commitment: if
in a future release the class is modified so that it no longer needs
to use the constants, it still must implement the interface to ensure
binary compatibility. If a nonfinal class implements a constant
interface, all of its subclasses will have their namespaces polluted
by the constants in the interface."

To sum it up, which are basically what I told Kynan:

  1. Interface is for defining types, and not solely for holding constants.
  2. Avoid creating coupling. e.g. introducing or removing a method from the interface will either take you time to fix all implementing classes or make things look ugly. Likely or not, I don't care.

Regards,
Yuen-Chi Lian

Tuesday, October 16, 2007

From ESB to REST, Polyglot Programming, JSON

I spent about an hour to do some blog reading. Around two weeks ago I left a comment in Patrick Logan's (an open-source developer) blog on More on the ESB. And just now, while rolling through the feeds consumed by the demon, I found a very good blog by Steve Vinoski (former chief engineer of IONA Technologies) in response to Patrick's blog -- The ESB question. His answer to the problems is REST. Steve subsequently wrote another two blog entries.

Bob Warfield of SmoothSpan summarized the discussion and stretched on multiple language approach as solution to enterprise problems, see ESB vs REST (Another Case for Multi-Language Programming).

They are very good reads which create room for me to start thinking again.

Lately, I am working on the JIRA Transport for Mule and one of the cool things about it is it reads JSON defined at the endpoint, then parses it to invoke the SOAP service of JIRA. I have never been a fan of writing SOAP client using Java and I hate the stubs, it is always Python or Perl.

- yc, reading

Wednesday, October 10, 2007

jdbcPersistenceAdapter myth of ActiveMQ solved

I faced this problem last week and I had some talks with my colleagues but there was no solution :( – jdbcPersistenceAdapter did not click well with my MySQL database.

This was what that happened if I configured ActiveMQ with JDBC persistence, a clean database (with no tables) did not stop the problem from occuring:

17:05:16.359 ERROR [org.apache.activemq.broker.BrokerService:start] Failed to start ActiveMQ JMS Message Broker. Reason: java.io.IOException: Failed to get last broker message id: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 'activemq.activemq_acks' doesn't exist
java.io.IOException: Failed to get last broker message id: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 'activemq.activemq_acks' doesn't exist
at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:31)
at org.apache.activemq.store.jdbc.JDBCPersistenceAdapter.getLastMessageBrokerSequenceId(JDBCPersistenceAdapter.java:145)
at org.apache.activemq.broker.region.DestinationFactoryImpl.getLastMessageBrokerSequenceId(DestinationFactoryImpl.java:148)
at org.apache.activemq.broker.region.RegionBroker.(RegionBroker.java:104)
at org.apache.activemq.broker.BrokerService.createRegionBroker(BrokerService.java:1270)
at org.apache.activemq.broker.BrokerService.createBroker(BrokerService.java:1209)
at org.apache.activemq.broker.BrokerService.getBroker(BrokerService.java:508)
at org.apache.activemq.broker.BrokerService.start(BrokerService.java:394)
at org.apache.activemq.xbean.XBeanBrokerService.afterPropertiesSet(XBeanBrokerService.java:47)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1201)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1171)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.(ResourceXmlApplicationContext.java:88)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.(ResourceXmlApplicationContext.java:76)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.(ResourceXmlApplicationContext.java:72)
at org.apache.xbean.spring.context.ResourceXmlApplicationContext.(ResourceXmlApplicationContext.java:68)
at org.apache.activemq.xbean.BrokerFactoryBean.afterPropertiesSet(BrokerFactoryBean.java:84)
at
...
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 'activemq.activemq_acks' doesn't exist
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3256)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1313)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1448)
at org.enhydra.jdbc.core.CorePreparedStatement.executeQuery(CorePreparedStatement.java:92)
at org.apache.activemq.store.jdbc.adapter.DefaultJDBCAdapter.doGetLastMessageBrokerSequenceId(DefaultJDBCAdapter.java:148)
at org.apache.activemq.store.jdbc.JDBCPersistenceAdapter.getLastMessageBrokerSequenceId(JDBCPersistenceAdapter.java:142)
... 76 more

So I started a thread in the ActiveMQ mailing list. I have also tried doing the same thing in my Ubuntu box but faced no problem. Spent a little bit more time on it, and realized that two out of the three tables were actually created, i.e. activemq_locks and activemq_msgs. And this information managed to give someone a clue on what's going on:

I just hit the same thing as well

Specified key was too long; max key length is 1000 bytes is the error not allowing the creation of ACTIVEMQ_ACKS

You are probably using utf8/some other multibyte encoding as the collation in your database....

Switch it to latin1 or ASCII... The varchar fields that the key is composed of add up to less than 1000 characters but with a multibyte encoding the key length is over 1000 bytes.

That's the case in my mysql setup here anyway.

- Alex_ynr

Bingo!
:-)

mysql> status
--------------
...
Server characterset: utf8
Db characterset: utf8
...

mysql> drop database activemq;
Query OK, 2 rows affected (0.06 sec)

mysql> create database activemq char set latin1;
Query OK, 1 row affected (0.00 sec)

mysql> use activemq;
Database changed
mysql> status
...
Server characterset: utf8
Db characterset: latin1
...

mysql> show tables;
+--------------------+
| Tables_in_activemq |
+--------------------+
| activemq_acks |
| activemq_lock |
| activemq_msgs |
+--------------------+
3 rows in set (0.00 sec)

- yc

Malaysian Java User Group - Request for Expressions of Interest

I wrote this public email, sent it to the MyJUG mailing list and also to some local organizations. I wish to receive some responses, and of course, if you're reading it, please forward to your friends or the Java persons in your organization.

Cheers.

Hello,

I am one of exco committees of the Malaysian Java User Group (MyJUG).
A Java User Group, basically, is a non-profit organization, a group of
people who share common interest in Java and related technology.

Recently, we are trying to re-establish the group and to reaffirm its
determination to be an influential group in driving the local Java
community and technology. We had a meeting in August and our agenda
contains establishing a portal, wiki, organizing monthly events and
technical talks, etc. We will be having a meeting again within the
coming weeks to bring ideas into concrete forms.

The reason you are receiving this email is because we have very strong
faith and are true believers that the IT industry's contribution is
important to the success of this group of the Java community and its
people. I would like to encourage the you and your organization to
participate in our portal, mailing list, technical talks, events,
advertisements, etc.

I kindly request you to forward this email to the point of contact (of
Java technology or sales and marketing department) in your
organization; and reply to this email to share with me your interest
on this subject.

Cheers.

References:

Java User Groups -- http://java.sun.com/community/usergroups/
Malaysian Java User Groups -- http://my-jug.org/ | Mailing list:
http://tech.groups.yahoo.com/group/myjug/

--

Regards,
Yuen-Chi Lian
"I do not seek. I find." - Pablo Picasso

- yc, let's rock

Sunday, October 7, 2007

China Dream.. Broken

Diving badly into the gravel, Lewis Hamilton -- the super rookie of F1, the championship leader, has ended his race prematurely and opened the title contest for Fernando Alonso and Kimi Raikkonen, heading to the last round at Interlagos, Brazil.

Dramatic. "That's motor-racing. Anything can happen before crossing the chequer flag." "That's football. Anything can happen before the stop-pitch." "That's life." No matter what you call it, expectation is simply a belief and it can be changed.

Two more weeks to wrap up the F1 2007, one is fighting to be the first rookie champion, one is fighting to be the youngest champion with three consecutive wins, one is trying to prove that he made the right decision to quit. Interlagos is always Interlagos, a track which Felipe Massa made his home dream, a track which Michael Schumacher wrapped up his career and proved himself supreme.

More news | More pictures

- yc, waiting, pacing.. patiently

Wednesday, October 3, 2007

ALL-BLOGS forum on "Blogs and Digital Democracy"

I attended the ALL-BLOGS forum just a few hours ago and managed to meet some friends, known bloggers and new faces.

I threw a question (with nested question anyway) which perhaps wasn't clearly asked and answered.

I was very much interested in knowing the principle of GVO (especially when we are talking about digital democracy) on online media rules and regulations, should or should not they ever exist. I used the Votergasm as an example of extreme exercise of freedom, may be not appropriate, but it woke some sleepy people up (that's what Nuraina said).. at least.

Many of us have had this discussion before I suppose. Call it contradiction or dilemma, rules are definitely needed, although once implemented, a lot will go against it.

Also bear in mind that, 5 years or 10 years down the road, blogging might not be in its form as we can see today. We have seen how things evolved from Usenet to BBS to IRC to online forums to social networks and to blogs/Web 2.0 and to morrow.. we use something else.

Let's not just focus on blogging towards democracy, let's start thinking about solid establishment of democracy and civilization on the cyberspace -- for the real world.

I never deny the fact that blogging (as of today) is something that works and has brought together all ages and nations to participate in discussion, unlike the early age of Internet / World Wide Web.

- yc