Thursday, April 2, 2009

Moving away from blogger to wordpress.

I have decided to take blogging more seriously. At the same time, I feel blogger is too much work for me specially with all code editing / formatting without any built-in support. So, I have made up my mind to move to wordpress. This is my new blog @ wordpress: Lazy Programmer’s Shortcut. I promise to be more regular this time.

Thursday, March 26, 2009

Thinking in Objects

Long ago, I had to write some code which do this:

Given two list 1. oldList 2. newList you have to find out:
1. The elements which are common in both list.
2. The elements which are new in the newList (means they were added)
3. The elements which are in oldList and not in newList (means they were deleted)

Definitely not the hardest kind of problem! I quickly grabbed my keyboard and wrote something like this :

public class CollectionModificationHelper {

public static List getCommonElements(List oldCollection, List newCollection) {
//iterate on oldCollection and find the common elements
}

public static List getNewElements(List oldCollection, List newCollection) {
//iterate on newCollection and find the new elements
}

public static List getRemovedElements(List oldCollection, List newCollection) {
//iterate on oldCollection and find the deleted elements
}
}



Simple solution and works fine. Only problem is, its iterates over the same collection again and again to find the old/common/new elements, not a big deal if you are not worried about performance.

Yesterday, I had to write the same code! Almost 4 years after I wrote the first version, seeing a hell lot of code, reading a hell lot of materials about Object Oriented Programming and design, this is what I wrote without much thinking:


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import org.apache.commons.collections.CollectionUtils;

public class CollectionModificationHelper<T> {
private Collection<T> oldCollection;
private Collection<T> newCollection;

private Collection<T> newElements = new ArrayList<T>();
private Collection<T> commonElements = new ArrayList<T>();
private Collection<T> removedElements = new ArrayList<T>();

public CollectionModificationHelper(Collection<T> oldCollection,
Collection
<T> newCollection) {
super();
this.oldCollection = oldCollection;
this.newCollection = newCollection;

init();
}

public CollectionModificationHelper(T[] oldArray, T[] newArray) {
this((oldArray == null ? null : Arrays.asList(oldArray)), (newArray == null ? null : Arrays.asList(newArray)));
}

private void init() {
if(CollectionUtils.isEmpty(oldCollection) && CollectionUtils.isEmpty(newCollection)) {
//nothing to do!
} else if(CollectionUtils.isEmpty(oldCollection)) {
if(!CollectionUtils.isEmpty(newCollection)) {
this.newElements = new ArrayList<T>(newCollection);
}
}
else if(CollectionUtils.isEmpty(newCollection)) {
if(!CollectionUtils.isEmpty(oldCollection)) {
this.removedElements = new ArrayList<T>(oldCollection);
}
}
else {
for(T item : oldCollection) {
if(newCollection.contains(item)) {
commonElements.add(item);
}
else {
removedElements.add(item);
}
}

newElements.addAll(newCollection);
//first add all new Collection in new element.
newElements.removeAll(commonElements); //then remove the common elements.
}
}

public Collection<T> getCommonElements() {
return commonElements;
}

public Collection<T> getNewElements() {
return newElements;
}

public Collection<T> getRemovedElements() {
return removedElements;
}
}



Its interesting to see how your thought process changes over time. As far as I my opinion goes, the 2nd solution is much elegant than the first one! In the first one, I was just not thinking in Objects!

Over the years, as you are involved in serious development, you will surely learn many technologies, tricks, techniques. But I think you must thrive to learn how to think in Objects. Once you can achieve that, you will find a whole new world of idea about how the objects/components should interact. Once you are there, you will love it. I am not saying I am there already, but I sure did come a long way from where I started and trying to master it everyday. How do you prepare yourself? Practice & Read. My two best guru in this area are both named "Martin"! "Robert C. Martin" & "Martin Fowler" :) Do have a look at their work if you haven't already.

Lastly, what code is good code without some unit tests!


import java.util.Collection;

import junit.framework.TestCase;

public class CollectionModificationHelperTest extends TestCase {
public void testWithNullCollections() {
Integer[] old = null;
Integer[] newC = null;

CollectionModificationHelper<Integer> collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);

assertEquals(0, collectionModificationHelper.getCommonElements().size());
assertEquals(0, collectionModificationHelper.getNewElements().size());
assertEquals(0, collectionModificationHelper.getRemovedElements().size());

old = new Integer[]{1,2,3,4};
newC = null;

collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);
assertEquals(0, collectionModificationHelper.getCommonElements().size());
assertEquals(0, collectionModificationHelper.getNewElements().size());
assertEquals(old.length, collectionModificationHelper.getRemovedElements().size());

old = null;
newC = new Integer[]{1,2,3,4};

collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);
assertEquals(0, collectionModificationHelper.getCommonElements().size());
assertEquals(newC.length, collectionModificationHelper.getNewElements().size());
assertEquals(0, collectionModificationHelper.getRemovedElements().size());
}

public void testCollectionModificationHelper() {
Integer[] old = new Integer[]{1,2,3,4,5,6,7};
Integer[] newC = new Integer[]{1,4,10,11,12,13};

CollectionModificationHelper<Integer> collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);

Collection<Integer> commonElements = collectionModificationHelper.getCommonElements();
Collection<Integer> newElements = collectionModificationHelper.getNewElements();
Collection<Integer> removedElements = collectionModificationHelper.getRemovedElements();

System.out.println("commonElements: " commonElements);
System.out.println("newElements: " newElements);
System.out.println("removedElements: " removedElements);

assertEquals(2, commonElements.size());
assertEquals(4, newElements.size());
assertEquals(5, removedElements.size());
}
}

Thursday, January 29, 2009

Evidence Based Scheduling, Estimation and Scrum

People who know me would be surprised to see me talk about Estimation, Scheduling and all the related stuff. To be frank I consider that quite boring and better be left alone for managers! However, I am so loving the new process called Scrum we are following for last 6 months, I thought I should write a line or two about it.

Long ago I was reading this article by Joel which talked about doing your scheduling/estimation based on the evidence. What evidence you may ask? If I understood it right, the evidence is your team's efficiency! Being used to have the people who has no Idea about what the "NEW FEATURE" is and doing the estimation, I kind of liked the idea. How many times have you stayed late in the office to finish the "Cool and Easy" feature that your manager Promised to deliver the next release? I always felt the manager, no matter how experienced or skilled he is, should not be solely responsible for the estimation. We are in the business of programming, and programming is art! Its not the construction business, its not the military. For any work of creativity, you need freedom and comfort. Until we adopted scrum, I was always wondering how the developers can be a part of the whole management thing specially given the lack of interest of the developers in such things.

I am not going to describe what scrum is and what are the common benefits of following scrum, you will find plenty of reference in the net. I'll just point out what are the things that I think scrum is so effective from estimation point of view and lucrative from a developer's perspective, So here is my two cents:

1. The Team does the estimation! Your team is composed of people with diverse skill sets. When you throw a new story to a team, at least 2 of the team members would have some kind of idea about how to do it. For some other story, may be some other team members will put their input. So the estimation will be as good as it gets. And after two or three sprints with the similar kind of stories, the estimation should be perfect!

2. The Developers make the Promises! If you are some investor in any software business, and want to have some feature done within a specific time frame, here is a piece of advice from a man in the tranches, ask your developers, not the manager! If a developer commit he will do something done within a specific deadline, he will. We developers are so dumbly proud that we will even sacrifice our personal life to meet the deadline that we promised. On the other hand, if you ask your manager, he will just keep pushing the developers because he can't do the things himself even he wanted to. That way, you will end up with a buggy and messy product which is the outcome of all the hatred and frustration that your developers produced during the overtime that they did. Scrum does not have a project manager! Scrum has a Scrum master whose responsibility does not include estimation! It is the team who did the promise during your sprint planning that they will accomplish the features. Any self respecting and efficient team will thrive to achieve that. You will be surprised to see the team requesting you to keep the workspace open during the weekend so they can polish the stories for the reviews! Self-management- this is what scrum is all about. In a manager led project, not all the team members share the same responsibility as the manager. Since the manager is solely responsible for all the planning and estimation, other team member doesn't event feel responsible for the project because they are not at the gun point! This is specially true when the manager tries to accomplish some impossible deadline.

3. The Estimation is based on Evidence! Right after 2 months of following scrum, we kind of knew our team capacity is 80 points per 15 day sprint. After doing 10 sprints, we can now almost 90% accurately tell that if we plan 100 points, we are going to do overtime and we plan 60 points, we will be relaxing! How do we calculate the 80 point? The stories or the tasks that we estimate are constantly compared with the stories or tasks that we did in the previous sprints. We will say, it took us 2 days to do that "user registration form" with all the unit tests and automated tests which was a 5 point story. So we think the "user account detail collection" is a 8 point story which will take 3 days. Simple yet so efficient! One thing about estimation we don't give much importance is our hunch or intuition! But we develop our ability to "guess" over so many trials and errors! Our subconscious mind is constantly collecting and processing information and our "guess" is the outcome of that. When 6-7 people are guessing something, its the fruit of years of experience that should not be overlooked. It is as close an estimation as you could ever get.

4. Scrum is sustainable! Scrum is by the developers , for the developers :) Forgive my cheap joke, but couldn't help it ! We are making the estimation, we are making the promises, we decide whats best for the product, we choose the technology, we take the pride! We don't have a manager to micromanage us, instead we have a scrum master to lead us. We work for ourselves, we work for the team, we work for the product. The satisfaction that this brings us can't be compared to anything else, no amount of money or facilities can bring this. We don't feel sick every week, we don't think we are underpaid, we don't feel the constant anger, we don't think about skipping the office each morning, in a word, we don't burn out! We are happy developers who have fun in the workplace. Believe me, if you want a good product, you don't need fancy office or fancy furniture or worlds best salary package or even worlds best programmers. You need happy and motivated developers who are smart enough to get the job done. I believe scrum provides the best way to get there.

Having said all these, I must warn that scrum is not for everyone. Scrum is all about self-managed team. That requires highly skilled and seasoned developers who are matured enough to self manage. Scrum requires honesty which is usually not a problem with programmers. Most of all, scrum requires teaming. If your developers can't jell together, you will end up with highly inefficient team. One of the main reason I feel we could adopt scrum so easily is because each and every developer of the team is quite experienced and has a minimum level of competency. I wonder how we would adopt scrum if we were a bunch of armatures.

Saturday, December 27, 2008

Asterisk as Sip User Agent emulator

Most common use case of Asterisk is that of a Sip Server. User Agents register to it and can call each other. But have anyone though of using it as a sip user agent emulator? This is exactly what we are doing ! Our main product is written in java which needs to register to a Sip Service Provider, receive calls, play automated answers/forward calls and all kind of play around with the Call. We looked into various open source sip stack written in C / java. We kind of overlooked Asterisk as its known as a sip server! We were just exploring asterisk sip stack to see if we can somehow reuse it, but we were surprised to find out we can use Asterisk as it is without any modifications! Asterisk is written as a B2B UA (Back to Back User Agent) model (not so good for sip servers from performance point of view) but more than fine for us! You can register to your sip service provider as a user agent , answer calls, play messages, collect dtmf, make outgoing call and many other cool stuff! Asterisk real-time even takes this in another level where you can do the all these things dynamically! The best point is, you can write your logic in any language (in our case java) with AGI and AMI which is just TCP message based programming ! Wait, if you are using java, life is even better for you! Asterisk-java is a wonderful abstraction written on AGI/AMI so you don't even need to bother about TCP programming. Hats off to open source community, It would take us a Year to accomplish what we have accomplished in 3 months with asterisk.

The free book "Asterisk: The Future of Telephony" is a great resource but I am surprised to see how little information is there on net about using Asterisk as a Sip User Agent emulator! Are we the only one who is using asterisk this way !!!???

Thursday, November 6, 2008

Spring Session Scoped Bean

I have always hated direct usages of "HttpSession". You know how tricky it becomes when you want to do advanced things like session replications / caching etc. I have previously used home grown session factory abstraction. But just recently I came across Spring "Session Scoped Bean". So far, we have only used dependency injection of spring beans which had only 2 scopes - singleton & prototype. But now spring supports custom scopes for beans and one of them is "Session". It means that this bean is created when a new HttpSession is created and preserved as long as the HttpSession is valid. Spring uses AOP to extract the sessionId from the httprequest and manage the lifecycle of the bean. So instead of putting your object directly into the session, you get to put them in an injected POJO based placeholder. This makes it easy to do the testing and getting rid of HttpSession dependency. So when time comes, you can use solutions like "terracotta" to distribute your session without changing your code! Isn't that wonderful! Another niche Spring trick!

The details of how to setup the configurations can be found here. I followed the exact steps and it worked flawlessly.

"Enso"---where were you all these days!

Surfing the net is like a hobby/passion/addiction for me, And I mostly surf technology / computer related stuff! I work with other software professionals who are geeks. So anything new, useful comes to my attention early. Yet I am very disappointed to know that Its only today I came to know about Enso! I'v been using it for a few hours now but I am sure its going to be my most useful windows utility forever! It might even become a reason why I prefer Windows over Linux as my development environment [ They don't have the linux version yet :( ]. Just look at the demo and try using it. Using Computer will never be the same again!!!!! I pity myself for not using it earlier :(

The Productive Programmer

I'v been reading the book "The Productive Programmer". Being the lazy programmer myself, I always look for more efficient ways of doing things. There are tricks I'v learned from my experience over the years and still learning new things every now and then. But it looks like this book is the summery of all that! Any developer who wants a better way of doing things must have go through this book. How many times have you come across a niche tool and said "Wow! I only wish I knew about this earlier!". Do you remember first time you used cygwin on Windows! This book is the compilation of all those tools and tricks!

Monday, November 3, 2008

Asterisk-java + Spring

Those who don't know about Asterisk Java, its a wonderful java library to talk to a asterisk server through AGI & AMI. We are using it heavily to control our Asterisk box from our "main application". Our main application is a full fledged spring application running on tomcat. At first we were running the asterisk java components (AGIServer , AgiScripts etc) as a normal java application but soon we wanted our AgiScripts to talk to our spring beans Or even better, we want our agi scripts to be Spring beans.

The beauty of the spring and asterisk-java library is that they were made for each other! Asterisk java library was written in wonderful object-oriented way with clear separation on dependencies. So it was very easy to define the AGIServer and all its dependencies as Spring Bean. So We can inject the MappingStrategy with our own implementation of "BeanNameAwareAGIMappingStrategy" which implements ApplicationContextAware looks like this

@Override
protected AgiScript createAgiScriptInstance(String beanName) {
Object bean = applicationContext.getBean(beanName)
if(bean == null)
{
throw new IllegalArgumentException("No bean with name: [" + beanName +"] found. Make sure that you have all beans defined which are there in your fastagi-mapping.properties");
}
if(!(bean instanceof AgiScript))
{
throw new IllegalArgumentException("spring bean : " + beanName + " must implement org.asteriskjava.fastagi.AgiScript interface");
}
return (AgiScript) bean;
}
So now, instead of defining fully qualified classnames in your "fastagi-mapping.properties", you only give the bean name and our mapping strategy looks it up from the application context. So your plain agi scripts can talk to your dao, services and do all sort of fancy things! Isn't that wonderful!

Wednesday, October 22, 2008

UPDATE: How to Hotswap classes in the running jvm

If you have read my previous blog post about How to Hotswap classes in the running jvm, I am sure you will find Java Rebels even more interesting. It supports full class reloading support at runtime with method refactoring and all the stuffs that hotswap.jar could not do. Trust me, Java development has never been more fun. And if you are into spring development, it even supports spring configuration reloading without restarting the whole spring application context! Could it be better!!! I think its a must have feature for every java developer. I don't know why sun is not incorporating this in the JVM? Just because java is not a scripting based language like php/ruby , doesn't mean we can't have fun like those guys! Speaking of fun, you can have some from this Java Rebel cartoon also

Only downside is JavaRebel is not free. There is a small fee that you have to pay. But let me tell you its worth it. And if you don't trust me, you can always use the 30 Day trial version (although it will only take 3 days for you to become addicted to it).

NOTE: I don't work for java rebel.I wish they took me in :) it would be fun to develop such cool features that eases the life of so many developers.

Saturday, May 24, 2008

Which dynamic language to learn

Learning a dynamic language has long been on my to-do list. I have tried a little bit of everything , ruby, python even lisp. But I never could proceed much. After playing around with them for a while, I loose interest and find a new framework/tool in java or j2ee more interesting to learn and move on. Well, this time I am very serious and determined and I think it is high time to learn one as even Sun embraced the dynamic language pool into JVM.

Now comes the BIG question, which one to learn??? I know LISP should be my #1 choice according to Paul Graham. It is his book "Hackers And Painters" that convinced me to learn a dynamic language in the first place. But I just can't bear the braces of lisp, I tried, but its too much for me to digest. Anyway, I guess its quite challenging for anyone to choose a dynamic language to learn specially when he has no idea what he is going to do with it(I don't see myself moving away from java/j2ee in near future). After a lot of googling/reading blogs/taking suggestions, ruby & python are on the top list. But I have something else in my mind: JavaScript!

I don't understand why JavaScript is only considered for client side scripting! I can see all the features a dynamic language can offer in JavaScript. May be I'm too naive to tell right now but I am surprised why JavaScript is not mentioned more often in the Dynamic Language Shootouts.

Its not like I haven't used javascript before to write client side scripts but I have never looked at it as a language seriously. I only used it as a DOM manipulation tool. But the more I'm digging it, the more I am surprised to see its power. And probably, its one of the most used language ever.

So anyone got any advice for me? Any feedback to make me think otherwise? Should I switch to Python/Ruby?

Saturday, April 26, 2008

The Kite Runner

I used to read books like crazy before. Now, I watch movie the same way. I wish I had a video store where I can keep watching movie all the day. However, only occasionally you get to watch a movie which touches your heart. Today was one such lucky day, I watched THE KITE RUNNER. I forgot when was the last time I saw a such good movie like this.

Monday, April 21, 2008

How to mount windows shared network drive as linux directory

My development environment in office is CentOS and quite often I have to access a windows network share directory. I hate to open nautilus samba file system access every time to copy/paste into those directory. I can't use my bash console to do that. After some googling, I mounted the windows network share folder to my /home/sajid/team_members directory with this command:


mount -t smbfs -o username=sajid,password=sajid //fileserver/team_members /home/sajid/team_members


Here the username/password is my userid password to access the shared network drive, "//fileserver/team_members" is the location of the network directory.

Now that I could mount the network folder to my local drive, I wanted to automate this task every time I started my computer. So, I added this line to my /etc/fstab file.


//fileserver/team_members /home/sajid/team_members smbfs username=sajid,password=sajid 0 0


So from now on, I can use the network drive just as my local filesystem. Now that I have it fixed, I have to be extra careful not to do rm -rf /home/sajid/team_members/.. ;)

Tuesday, April 8, 2008

How to redirect System.out.println in Java

Did you ever get frustrated with a codebase which has overuse of System.out.println??
May be it is flooding your console or even worse you need to capture the outputs to analyze them....Ever wondered how you can capture your System.out.println() 's of your tomcat application?? Well, you can always use IO Redirect in unix to send the output to a file. You can use find replace to change all System.out.println() to some method call which will write the logs to a file. But being the lazy programmer that I am, I always look for a shortcut. And sometimes I even find one :)
I was working with this code and it had important System.out.println everywhere. I wanted to use trail/grep and stuffs like that with the console logs but I couldn't do that on the application console. So this is what I did to redirect all System.out.println to a log file.

public class MyMainClass {
public static void main(String[] args) throws FileNotFoundException {

File file = new File("/home/sajid/sysout.log");
PrintStream printStream = new PrintStream(new FileOutputStream(file));

System.out.println("1");

System.setOut(printStream);


System.out.println("2");

}
}


Did you ever notice that System.out is just another PrintStream and you can replace it with your own? This is why I love java. You can replace many things with your own implementation. Did I tell you how I replaced the URLClassLoader with my JDBCClassLoader to load classes from Database? Lets keep that story for another post.

Monday, April 7, 2008

How to Hotswap classes in the running jvm?

One of the major pain of every server side java developer is that you have to redeploy your application every time you made a small change to the java classes. Now if you are working with a web application which consists 1500 classes, about 150 servlets(basically webservices), imagine how much time tomcat is gonna take to deploy or even worse redeploy that application.(it takes about 6 mins on my p4 pc). This was a small trick I learned from Masum Bhai at Therap.
JVM comes with a debugging api which actually lets you to change the defination of a class at runtime. These are the following steps you have to do.

1> Download hotswap.jar and put it in the "run-classpath" of your ant script.
2> JVM must start with debugging parameter. So add the following parameters at your java start command:
      -Xint -Xdebug -Xrunjdwp:transport=dt_socket,address=${hotswap.port},server=y,suspend=n
For example, if you are using tomcat, you can add this line at the beginning of the catalina.sh

export JAVA_OPTS="-Xint -Xms256m -Xmx256m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
alternatively , you can uset the "tomcat-start" ant task given below to start your tomcat. Just make sure you have the tomcat-home ant property defined.
<property name="date-pattern" value="MM/dd/yyyy kk:mm:ss"/>
<property name="hotswap.port" value="8787"/>

<target name="compile" depends="prepare-common"

description="Compiles the application source code">

<echo message="Compiling the application source code...."/>

<!--enable timestamping upto second level (required for hotswapping)-->
<tstamp>

<format property="class.tstamp" pattern="${date-pattern}" />
</tstamp>

<javac

srcdir="${src.dir}"
destdir="${build.classes.dir}"
verbose="false" debug="true"

listfiles="false">
<!-- Use this when you want to see which files are being compiled -->
<classpath refid="run-classpath"/>
</javac>
</target>



<target name="reload" depends="compile">

<taskdef name="hotswap" classname="dak.ant.taskdefs.Hotswap">

<classpath refid="run-classpath"/>
</taskdef>

<hotswap verbose="true" port="${hotswap.port}">

<fileset dir="${build.classes.dir}" includes="**/*.class">
<date datetime="${class.tstamp}" pattern="${date-pattern}" when="after" granularity="0"/>

</fileset>
</hotswap>
</target>

<target name="tomcat-start"
description="Start Tomcat with hotswapping enabled" >


<exec executable="${tomcat.home}/bin/catalina.sh" >
<arg value="start"/>
<env key="JAVA_OPTS"

value="-Xint -Xdebug -Xrunjdwp:transport=dt_socket,address=${hotswap.port},server=y,suspend=n"/>

</exec>
</target>


The rest is simple! When you change anything in a class/group of classes, just use "ant reload" and you will see the hotswap output like this:

ant reload
Buildfile: build.xml

prepare-common:

compile:
[echo] Compiling the application source code....
[javac] Compiling 1 source file to /home/sajid/projects/cmsstandaloneportal/,tmp/cmsstandaloneportal/WEB-INF/classes

reload:
[hotswap] hotswapping 1 files from /home/sajid/projects/cmsstandaloneportal/,tmp/cmsstandaloneportal/WEB-INF/classes
[hotswap] hotswapping com.x.y.z.p.web.struts.QDispatchAction

BUILD SUCCESSFUL
Total time: 10 seconds



10 seconds! Thats all you need!

I have used this trick with Tomcat, JBoss, and standalone java applications and every time it worked like a charm! I can't tell how much deployment time it saved me. So No doubt its my most favorite ant task to date!

Note Of Caution:
Hotswapping doesn't work when you change the structure of a class (add new method/delete method/rename method). It only works when you change the logic inside a method. Thats what we do most of the time anyway, isn't it?

Sunday, April 6, 2008

How to get the calling method information in Java

I was wondering around in a huge code base trying to figure out whats going on.
I wouldn't say it was a bad code base, but it was done by a single geeky programmer who never cared about the readability because I guess he never thought anyone else would ever try to read it. Anyway, I could see all these meaningful log messages coming out from it but I didn't know from where. I think he never heard of log4j or anything like that but luckily he used a class like this:

public class LogHelper{
public static void log(String log){

System.out.println(log);
}
}

and used it like this:
 1 public class X
2 {
3 public void doA()

4 {
5 Logger.log("doing A");
6

7 //..
8 //..
9 Logger.log("done doing A");

10 }
11
12 public void doB()
13 {

14 Logger.log("doing B");
15
16 //..
17 //..

18 Logger.log("done doing B");
19 }
20 }

So he called this static log method from all over the code base to do the logging.
And the log looked like this:

doing A
doing B
done doing B
done doing A

I desperately wanted to know which class/method/line was calling this method like I am used to in log4j.

Then I thought the calling Thread has this information. The question is how can I get it! After playing a bit with stack information, I came up with this:
public static String getCallingMethodInfo() {
StackTraceElement[] stackTrace ;

try{
throw new Exception();
}

catch (Exception e) {
stackTrace = e.getStackTrace();

}

if(stackTrace != null && stackTrace.length >= 2) {

StackTraceElement s = stackTrace[2];
if(s != null) {

return s.getClassName() + ".(" + s.getMethodName() +"):["+ s.getLineNumber() + "] -:";

}
}

return null;
}
So finally the log method looked like this:
public class LogHelper {
public static void log(String log){

String caller = getCallingMethodInfo();
System.out.println(caller + ": " + log);

}
}

So, finally the logs looked like this:

X.(doA):[5]-: doing A
X.(doB):[14]-: doing B
X.(doA):[9]-: done doing A
X.(doB):[18]-: done doing B
In jdk 1.5 you can actually get the stack information like this:
Thread.currentThread().getStackTrace()
but unfortunately I was working with a 1.4 codebase. But Throwing an exception and catching it back did the trick :)

Having said all that, It will be an insane idea to put this code to production. But can be very helpful when you are trying to understand the code.

Thursday, April 3, 2008

Bla bla bla

My brain has got new formula for interpreting human language..what ever goes in my ear, they get compiled into "bla bla bla"--is it me or people around me??!! Its quite refreshing though since most of the time thats the actual meaning. So what did you say your name was? "Bla"??