Sunday, July 15, 2007

Procedural or Object-Oriented?

The title might be misleading to some people, certainly, when you are writing Java code you are breaking things into objects. So, please let me define what they are about:
  • Procedural -- Code written in procedural and sequential style. Uses primitive types and common data structures. Multiple steps and conditions are defined in a single or few massive methods to reach program to a happy state.
  • Object-Oriented -- Code written in object-oriented style. Uses beans, DAOs, manager objects, etc. Code is constantly refactored, such as decomposing and using "extract method".
Recently, I have been working on some pieces of code and I came to a point to discuss with a friend this afternoon. He talked about the advantages of procedural style over overly-designed and object-oriented style, esp. when you are writing integration code and business process.

For example, in a procedural manner,


public MyActionClass{

public void doAction(){

Map vars = new HashMap();

if(condition1){
SomeClass.doSomething(vars);
SomeClass.doTransaction(vars.get("var1"));
}
else{
// .. Something similar
}

SomeClass.finalizeSomething(vars.get("var2"));
}
}

In an object-oriented manner,

public MyActionClass{

public void doAction(){

MyActionContext context = MyActionThreadLocal.getContext(); // Or a bean, or something similar

if(condition1){
doTransactionForCondition1(context);
}
else{
// .. Something similar
}

SomeClass.finalizeSomething(context.getVar2());
}

protected void doTransactionForCondition1(MyActionContext context){
SomeClass.doSomething(context);
SomeClass.doTransaction(context.getVar1());
}
}

Whatever above is just a very small piece of code, imagine in a class with complex business logic, how much they both can grow.

Maintainability is something subjective which I have to say. In a business world, code is subject to change as new requirements come in every day (expectedly). Procedural style coding might seem lengthy but it does not hide too much (object-oriented is a black-box). Object-oriented style coding is not unnecessary but not overly-designed and should be discouraged when you are working on something that is established or recognized by a group which you might handover stuffs to.

Your say?

- yc, fowler-ed then rob-ed

Sunday, July 8, 2007

Bloggers Buff 2007

Oh.. hi? So, I went to the Bloggers Buff 2007 held at Dewan Dato' Haji Sidek in Sunday arvo and I turned up pretty late for the forum/conference. I managed to join the session about "Responsible blogging and self censorship" by Dato Ahmad Talib, Ahirudin, and Li Tsin from MalaysiaKini.

I'm glad to be able to share a little bit about internal blogging (in a corporate), wiki and some Web 2.0 features.

Anyway, I'm sorry that I am bad in remembering names but I have to thank Rames as it was because of his blog that I discovered this event and some people who I had a chance to chit-chat with. I'd like to highlight the Think Rich Enterprise as well, although I am not a fan of blogging for $, it is interesting to see such company which helps driving the local people into the trend.

So, you might be interested with what I'm actually doing. I am employed by a Sydney based company CustomWare Asia Pacific as a developer and support engineer. Part of my job is to provide support to various Atlassian products. I love technology and technology makes our today.

There's one thing that I care much about is the growth of Web 2.0 in Malaysia. It does seem like a lot of its features haven't yet become widely spread and integrated into our daily practice.

It's time to back to Silverstone anyway ;-) (Massa is doing a good overtaking job). I'd love to see each other again soon.

- yc, silverstoned

Monday, July 2, 2007

Son oh son.. JSON

Learning a new techy stuff every weekend of mine seems to have turned into a real habit. JSON (or you can call it Jason ;-)), not something entirely new but it has been really hot these days. It stands for "JavaScript Object Notation" and it exists today is to make the AJAX programmers life easier.

I will briefly show you how you can get a hang of it using a simple JSP file and a small piece of JavaScript (YUI). If you do not have an idea about AJAX yet, you'd probably want to read about it first before going beyond this paragraph.

An AJAX response in XML format requires writing client code to parse it into DOM model, for instance:


<bean>
<name>foo</name>
<description>foobar</description>
<id>10000</id>
</bean>


Then some annoying JSDom bits to extract the data, which I'm not going to write. As I could recall, my last time of writing AJAX and DOM stuffs was a year ago for a Java webapp which requires validating the form fields by sending synchronous request to webMethods endpoints.

This might just be another article about JSON which you have read before from other sites, yes, it is. Anyway, a response can also be sent in JSON (which is basically string then be evaluated using JavaScript eval() method), e.g.

{"name": "foo",
"description": "foobar",
"id": "10000"}



Data can then be extracted easily unlike DOM, e.g.

var jsonObj = eval("(" + responseText + ")");
var name = jsonObj.name;


Before I end this blog so that you can find out more by yourself ;-), this is the JSP used to generate the response:

<%@ page
language="java" contentType="text/json; charset=utf-8"
import="org.json.simple.JSONObject"
%>
<% response.setContentType("text/json; charset=utf-8"); %>
<%
JSONObject jsonObj = new JSONObject();
jsonObj.put("name", request.getParameter("name"));
jsonObj.put("description", request.getParameter("description"));
jsonObj.put("id", new Long(request.getParameter("id")));
out.print(jsonObj);
out.flush();
%>
And this is the HTML used to send the request and receive the response:

<html>
<head>
<title>Test AJAX</title>
<script type="text/javascript" src="js/yui-2.2.2/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="js/yui-2.2.2/connection/connection-min.js"></script>
<script type="text/javascript">
function getAjaxRequest(url, callback){
return YAHOO.util.Connect.asyncRequest('POST', url, callback, "name=foo&description=foobar&amp;amp;id=10000");
}
</script>
</head>
<body>
<script type="text/javascript">
var callback = {

success: function(o){ alert("Successful: \n" + o.responseText + "\n" + o.getAllResponseHeaders)

var jsonObj = eval("(" + o.responseText + ")");

// Some reflection here
var jsonDump = "";
for(key in jsonObj){
jsonDump += key + ": " + jsonObj[key] + "\n";
}
alert(jsonDump);

},
failure: function(o){ alert("Failed: \n" + o) },
argument: []

}

getAjaxRequest("testJsonResponse.jsp", callback);
</script>
</body>
</html>

One final and common note though, if you ever come across designing a webapp with AJAX functionality, do keep the response format consistent, i.e. use application/xml OR text/json NOT both, so that you will not confuse the developers at another end of which they should expect.

- yc, raining

Thursday, June 28, 2007

On Optimization and Tuning

I came across reading the basic principles of optimization and performance tuning from two books, and I actually thought of sharing it here:

Chapter 1 of Java Performance Tuning:

Don't Tune What You Don't Need to Tune

The most efficient tuning you can do is not to alter what works well. As they say, "If it ain't broke, don't fix it." This may seem obvious, but the temptation to tweak something just because you have thought of an improvement has a tendency to override this obvious statement.

Item 37 of Effective Java Programming:

More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason—including blind stupidity.

– William A. Wulf

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

– Donald E. Knuth

We follow two rules in the matter of optimization:

Rule 1. Don't do it.
Rule 2 (for experts only). Don't do it yet—that is, not until you have a perfectly clear and unoptimized solution.

– M. A. Jackson

As mentioned in the book above, performance issues should be thought of while the application is being designed. Therefore,

  • A good design is very important. Spend more time on the design or spend even more time to get things really working happily one day
  • Don't do optimization if:
    • You have not gotten something working yet
    • The measurable gain is insignificant

- yc, reading

Sunday, June 24, 2007

Troubleshooting JVM, Part I

Part of my job is to provide support for the famous issue tracker JIRA. Sometimes, we will have to look into client's stack traces and thread dumps to troubleshoot some memory or locking issues which usually caused by third-party plug-ins, Lucene, etc.

One of the excellent articles I came across is "Of Thread dumps and stack traces" written by Rajiv Shivane. There are also some people who have given me some good pointers, like, Jed (one of my co-workers, the memory guy) who pointed me to "JDK 1.5 - Trouble-shooting and Diagnostic Guide" and Rob who lent me the book "Inside the Java 2 Virtual Machine". Some other good reads that you shouldn't miss are:
Anyway, I spent some time in the weekend to play around with java, jmap and jhat.

Note: jhat 1.1 doesn't recognize 64-bit dump, simply download JDK 1.6 and use the jhat 2.0 which shipped together with it.

I will go through an java.lang.OutOfMemoryError: Java heap space test I have done and give as detailed information as I can. I have demonstrated this to some people earlier on at work using one of the classic examples: String vs. StringBuffer.


public class TestStringBuffer{

public static void main(String[] args)
throws Exception{

StringBuffer sb = new StringBuffer();
String s = "foobar";
String which = args[1];

for(int i = 0; i < Integer.parseInt(args[0]); i++){
if(which.equals("sb"))
sb.append(s);
else
s += s;

System.out.println(System.currentTimeMillis() + ": " + i);
Thread.currentThread().sleep(500);
}
}
}

Using the StringBuffer way, the program remains alright even after 10K of iterations. However, it dies immediately with String concatenation around 23th iteration. Before we look deeper into this, here are two interesting JVM startup parameters that you would like to know:
  • -XX:+HeapDumpOnOutOfMemoryError, requests HotSpot to generate a binary dump when it runs out of memory.
  • -Xmx1024m, allocates 1GB of heap space
The jmap utility can be used to produce snapshot of the currently running JVM process. The jhat utility does something similar however in a post-mortem manner.

For instance, running jmap on the StringBuffer case:

yclian@kate:~/devels/test/java$ $JAVA_HOME/bin/jmap -histo 29237
Attaching to process ID 29237, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.5.0_09-b03
Iterating over heap. This may take a while...
Unknown oop at 0x00002b7df8296da0
Oop's klass is null
Object Histogram:

Size Count Class description
-------------------------------------------------------
500112 4121 * ConstMethodKlass
433192 4121 * MethodKlass
303824 283 * ConstantPoolKlass
269816 6117 * SymbolKlass
214688 265 * ConstantPoolCacheKlass
183776 283 * InstanceKlassKlass
108768 1044 char[]
83368 455 byte[]
61248 348 java.lang.Class
52096 462 java.lang.Object[]
31400 785 java.lang.String
29168 413 short[]
19584 295 int[]
18720 36 * ObjArrayKlassKlass
15048 213 java.lang.Object[]
7616 136 java.nio.HeapCharBuffer
4592 82 java.nio.HeapByteBuffer
4160 8 * TypeArrayKlassKlass
2784 58 java.util.Hashtable$Entry
2248 31 java.lang.String[]
2128 14 java.util.HashMap$Entry[]
2080 65 java.lang.StringBuilder
2064 10 java.util.Hashtable$Entry[]
2000 10 * KlassKlass
1792 14 java.lang.reflect.Field
1320 11 java.lang.reflect.Constructor
1056 22 java.util.Locale
1040 2 * ArrayKlassKlass
936 9 java.net.URL
864 6 java.lang.Thread
768 12 java.util.HashMap
736 23 java.io.File
696 21 java.lang.Class[]
672 12 java.io.ObjectStreamField
672 21 java.lang.StringBuffer
...
Heap traversal took 2.054 seconds.

And for the String case:
yclian@kate:~/devels/test/java$ $JAVA_HOME/bin/jmap -histo 29336
Attaching to process ID 29336, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.5.0_09-b03
Iterating over heap. This may take a while...
Object Histogram:

Size Count Class description
-------------------------------------------------------
906039672 578 char[]
501216 4132 * ConstMethodKlass
434336 4132 * MethodKlass
304728 284 * ConstantPoolKlass
270328 6127 * SymbolKlass
214688 265 * ConstantPoolCacheKlass
184336 284 * InstanceKlassKlass
71072 351 byte[]
61424 349 java.lang.Class
51216 446 java.lang.Object[]
28960 411 short[]
22520 563 java.lang.String
19088 291 int[]
18720 36 * ObjArrayKlassKlass
13784 202 java.lang.Object[]
4160 8 * TypeArrayKlassKlass
2736 57 java.util.Hashtable$Entry
2128 14 java.util.HashMap$Entry[]
2000 10 * KlassKlass
1936 27 java.lang.String[]
1536 12 java.lang.reflect.Field
1344 7 java.util.Hashtable$Entry[]
1320 11 java.lang.reflect.Constructor
1056 22 java.util.Locale
1040 2 * ArrayKlassKlass
864 6 java.lang.Thread
768 12 java.util.HashMap
728 7 java.net.URL
672 12 java.io.ObjectStreamField
640 10 java.util.LinkedHashMap$Entry
448 8 java.lang.ref.SoftReference
448 7 java.lang.ref.Finalizer
432 9 java.util.HashMap$Entry
384 6 java.util.Hashtable
360 9 java.util.Vector
352 10 java.lang.Class[]
288 3 java.util.jar.JarFile
272 17 java.lang.Object
264 7 java.io.ObjectStreamField[]
256 8 java.io.ExpiringCache$Entry
240 3 sun.nio.cs.UTF_8$Encoder
240 3 java.nio.DirectByteBuffer
216 3 sun.misc.Cleaner
208 2 sun.nio.cs.StreamEncoder$CharsetSE
200 5 java.util.ArrayList
192 3 sun.misc.URLClassPath$JarLoader
176 2 java.io.ExpiringCache$1
160 4 sun.reflect.NativeConstructorAccessorImpl
152 4 java.lang.reflect.Constructor[]
152 1 java.lang.ThreadLocal$ThreadLocalMap$Entry[]
152 1 java.lang.reflect.Method
144 3 java.lang.OutOfMemoryError
...
Heap traversal took 1.323 seconds.

char[], 108768 vs. 906039672. Clear example why String concatenation should be discouraged ;-). The histogram is very useful in identifying memory leakage as it shows you the size and number of instances created for a specific object type. jhat also allows you to generate some other information such as heap summary and permgen statistics, run it with the -h parameter for more information.

Let's examine the binary heap dump produced by the OutOfMemoryError using jhat.

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid29613.hprof ...
Heap dump file created [403190555 bytes in 31.321 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

jhat is one of the best tools comes together with JVM. It starts a HTTP server and provides you a simple interface which enables you to inspect the heap dump with your favorite browser.


Since we were talking about histogram, we will look into histogram again using the jhat interface.

Class Instance Count Total Size
class [C 564 402716036
class [B 350 67135
class java.lang.Class 336 48384
class [S 411 25126
class [I 291 16760
class [Ljava.lang.Object; 202 12168
class java.lang.String 552 11040
class [Ljava.util.HashMap$Entry; 14 2016
class [Ljava.lang.String; 27 1720
class java.util.Hashtable$Entry 57 1596
class [Ljava.util.Hashtable$Entry; 7 1288
class java.lang.reflect.Constructor 8 776
class java.lang.Thread 6 744
class java.util.Locale 22 704
class java.net.URL 7 616
class java.util.HashMap 12 576
class java.io.ObjectStreamField 12 444
class java.util.LinkedHashMap$Entry 10 440
class java.lang.ref.Finalizer 7 336
class java.lang.ref.SoftReference 8 320
class java.util.Hashtable 6 288
class java.util.HashMap$Entry 9 252
class java.util.jar.JarFile 3 222
class [Ljava.io.ObjectStreamField; 7 208
class java.util.Vector 9 180
class java.nio.DirectByteBuffer 3 168
class sun.misc.Cleaner 3 168
class [Ljava.lang.Class; 7 152

So, it actually produces something similar with what we have seen earlier. Except the slightly different use of notation, e.g. class [C, class [B, etc. Just if you are unsure:
  • class [C is char[]
  • class [B is byte[]
  • class [Z is boolean[]
  • class [S is short[]
  • class [I is int[]
  • class [J is long[]
  • class [D is double[]
  • class [Lpackage.ClassName is package.ClassName[]
  • class [[Lpackage.ClassName is package.ClassName[][]
And therefore, don't be panicked when you see ([[ID[Ljava/lang/String)Z in the stack trace next time. It is simply just boolean foo(int[][], double, String[]).

Clicking into one of the hyper-links (of course, it works just on my machine), for instance, class [C will bring me to a page as captured in the screenshot below:


The page gives you more details of the class, such as: loader, subclasses, static/instance data members, instances, references, etc.

I will end this blog entry at this point and I would expect you to spend some time to do some research on it too :-). When I start writing again for Part II, I will be sharing some thread dump tips that I have collected.

- yc, dumped

Sunday, June 3, 2007

Separation of Concerns

Aspect Oriented Programming (AOP), something which you might be familiar with if you are a Spring/Hibernate lover. It is definitely something new to me.

I spent some of my weekends looking for AOP articles and books. Graham O'Regan's article demonstrates how powerful AOP is and how it can be easily done using AspectWerkz. Naveen Balani's article shows you how Spring does it so that you do not need to add similar lines of code to obtain a Hibernate session to begin a transaction. Spring also

Just as you might not have an idea what AOP is:

It is a solution to the problem of creating clean and well-encapsulated without extraneous functionality.

Explained by Joseph and Nicholas in the book "Mastering AspectJ – Aspect-Oriented Programming in Java". You can find a sample chapter of the book from this link. The introduction explains how Object Oriented programming (OOP) came into play when procedural and functional programming turned ugly and how AOP fills in the blanks of OOP.

Some keywords of AOP are: Advice, Aspect, Cross-cutting concerns, Join points, Point-cut

I am not too sure how AOP can be applied to complicated frameworks such as webMethods. I certainly not a big fan of writing codes to deal with the core API to open and close connection for every transaction that I make. I got around this in my earliest webMethods related project by writing some Plain Old Java Objects (POJOs), Data Access Objects (DAOs) and Data Transfer Objects (DTOs). But they still took me quite some time and I would not know how complicated they could be if someone raised some new concerns.

I am new to Mule but I certainly love how lightweight it is and its support for regular POJOs and Spring embedment.

- yc, aspected

Saturday, May 12, 2007

Pidgin was Gaim

Something might have slipped through the cracks of my RSS reader (or simply I wasn't free to read them these days), that I didn't realized that Gaim isn't there anymore. I went to http://gaim.sourceforge.net/ yesterday night, something that I do occasionally as I've been following the development of the version 2.x, shocked by its new name and the change of look-and-feel.

As you can read from Wikipedia, all the changes were due to the settlement with AOL, which includes:

Gaim would become Pidgin, libgaim would become libpurple, and gaim-text would become finch. The name Pidgin was chosen in reference to the term "pidgin", which describes communication between people who do not share a common language. The name "purple" refers to "prpl", the internal libgaim name for an IM protocol.




Gaim 2.0 Beta 6 was the last version to be called Gaim, and Beta 7 was the first version to be called Pidgin. The final version was released on the 3rd of May.

Anyway, if you're interested, please follow the links below:

Have fun!


- yc, sleepy