Wednesday, March 16, 2011

Its time for some code review

I know some of us just hate it when we hear the word code review. The thought of some one else going through our code is somewhat offensive to some people. I myself have come across many. But for me this is a good thing given that my reviewer knows what to look for and have a set of parameters set out as a base for him/her to review on. So in this article i would like to highlight a few mistakes i have come across when doing code reviews. Most of them are common but we tend to often miss out on those. This is not the end of them. So if you guys have come across any thing other than what is highlighted here please do leave a comment as it would be beneficial for me as well as the other readers.




Integer myVal = new Integer(10);

Ofcourse by the look of this code there is nothing intrinsically wrong with it. The thing is in this code snippet you create an instance of a new Integer wrapper class. You can enhance this as follows;

Integer myVal = Integer.valueOf(10);

Using the valueOf method is better performance wise as this method returns the value from the in memory cache rather than creating a new object. Check here for what the java api says in this regard.

String records = "";

        for (int i = 0; i < 10; i++) {
            records+="new record"+i;
        }

Ok the issue here is as some of you already might have guessed is string concatenation. Though this works there is an issue with performance with respect to string concatenation. For those of you who do not know, when you concatenate two strings what really happens internally is a new string buffer is created and the new string is assigned to it and toString() is called on that string buffer object. Now this happens on every loop call. So you can understand the performance impact this will have.

Ofcourse prior to java 1.6 you would have argued about so many objects being created on the heap as a result of this. But with java 1.6 escape analysis, any object created within the scope of a method is created on the stack and not on the heap. And hence that argument is invalid. So a better way to handle this situation is to use StringBuilder as follows;



StringBuilder records = new StringBuilder(100);

        for (int i = 0; i < 10; i++) {
            records.append("new record").append(i);
        }

Note that i have also specified an initial size to the String Builder within the constructor. We do this for efficiency because if you do not define an initial size the default size of 16 characters is given by default. Whenever your buffer exceeds this limit a new StringBuilder object is created and the whole String that was in the old buffer is copied to the new one. To avoid such transactions taking place we give an initial capacity that we deem appropriate.

int i=0;
       .......
       .......
       .......
       .......
       .......
       .......
       .......
       .......
       
       i = 2+4;

This is a common mistake i see many people make. You define a variable at one point and afterwards you do various other method calls and at a latter point in that method you manipulate that variable you defined early on in the method. As a best practice always use the variable as soon as it is defined. This provides much clarity to your code and keeps it clean.

Using the same example i would like to point out another thing. See that the code above defines an integer called "i". This is ok to use within a for loop but if this is in the context of a method then always use meaningful names as this will self describe your code minimizing the code commenting you need to do.

/**
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * Blah blah blah blah blah blah blah
     * 
     */
    public void myTestMethod() {
        
    }


Please stop writing lengthy code comments. In my point of view is this is just an utter waste of time. The fact that you need to write such a lengthy explanation to me disseminates the fact that this method does more than what it should do. Write a short description on what your method does. A simple explanation of business logic is more than enough. Make your code readable which reduces the time you have to comment.


/**
     * Sets the name
     * @param name
     */
    public void setMyName(String name) {
        this.name = name;
    }

Wow what a code comment. The author says it sets the name variable. Wow really? Thank goodness for that comment else i would not have known what was going on in that method :) . Seriously stop making useless code comments. It just clutters your code and does no use for anyone reading it. Dont comment on getter/setter methods as the name it self implies what is happening.

public void doProcess()throws MyServiceException {
        
        try {
            service.doProcess();
        }catch(MyServiceException e) {
            log.error("Error occured");
            throw e;
        }
    }

Ok whats wrong here? Problem here is that this method catches a MyServiceException and logs the error and rethrows the same exception back from the method. Why would you catch an exception if you are going to rethrow the same? It just does not make sense. Proper way to handle such a thing is to let the caller handle the exception and log the error at that end rather than you trying to handle it. Anyway it is recommended now to throw Runtime exceptions rather than checked exceptions if the error you throw is like a DB exception or IO exception as these kind of exceptions does not make sense to the client.


public void doProcess()throws MyServiceException {
        
            log.debug("Started method");
            service.doProcess();
            log.debug("Method processed");


    }

Here the issue lies in the debug log statement. Often times in a production environment your log level will mostly be set to INFO or ERROR. But when your code has debug logs the Logger will try to process this which results in unnecessary executions. You can avoid this by checkin if debug is enabled as shown in the below code snippet;

public void doProcess() throws MyServiceException {

        if (log.isDebugEnabled()) {
            log.debug("Started method");
        }
        service.doProcess();
        if (log.isDebugEnabled()) {
            log.debug("Method processed");
        }

    }



if(server.equals("TEST")) {
            //do something
        }else if(server.equals("TEST123")) {
            //do something
        }else if(server.equals("TEST1234")) {
            //do something
        }else if(server.equals("TEST12345")) {
            //do something
        }else if(server.equals("TEST123456")) {
            //do something
        }

In an instance where you are tangled in multiple if/else statement it is always much cleaner to use switch statements and use enums to hold the constants.With JDK 1.7 you are allowed to use Strings in a switch statement. So your code above will look like this with use of enums and switch statement;

switch (server) {
        case TEST:
            // do something
            break;

        case TEST123:
            // do something
            break;
        case TEST1234:
            // do something
            break;
        case TEST12345:
            // do something
            break;
        case TEST123456:
            // do something
            break;
        }

Those are few of the things that came to my mind at the time of writing this post. Ofcourse there are many more which i will follow in subsequent posts. Pls do leave a comment which will be an additions to this post that you deem appropriate for a code review session.


Cheers Guys

Saturday, March 5, 2011

Time to get rid of EARs

We all know what EARs(Enteprise Archive) are. When talking about enterprise software this is a common term used where we bundle up our application with all the required JAR(Java Archive) files needed by our application at runtime. This has been done for many years and people have adapted to it. Bundling up WARs(Web Archive) inside EARs is a common practice too.

In the initial stage even our current application was structured in such a way that in the end an EAR is deployment to our Application server along with the configs needed. Note that i am talking with respective to JBoss Application Server 4.2.3 ( Refereed as Jboss from here onwards). Our application is hosted within a Jboss A/S and hence it goes into the server/default folder in development.

The problem we faced was when we were doing a production release. Our servers were remotely hosted at a local internet service provider's(ISP) data warehouse. And our typical EAR came to about 40MB in size which took about 45min - 1 hr to copy to the remote servers. This posed a problem and a probable bottleneck in the overall process of pushing a build as i saw it. So i was looking at any other way we can achieve some efficiency in this regard.

The solution i came up with was influenced by Julius Ceasar many years ago when He devised the Divide and Conquer Mechanism. Our problem as i saw was that our application code was only a mere 5-8MB where as the dependent JAR files amounted around 30MB in size.

So what i did was i took our the EAR building(Note that we are using Maven as our build tool) out of the process and bundled up our application as shown in the diagram below. Note that the diagram below depicts my approach to the problem at hand.

Note that now as we have separated the thirdparty JARs into a separate JAR file we only deploy this once and whenever a new dependency adds up (which is rare because the project is matured into a stable position). Now we only have to deploy the Other JAR files including the WAR which is only around 8-10MB of size overall. So overall our deployment time is now reduced to 10-15 mins which took almost an hour before with the EAR approach. I wrote a separate assembly descriptor to bundle up the required JAR files in our project into a single JAR file. If any of you guys want this i can share the assembly descriptor file i wrote.

One downside i have to note with this approach is that we cannot use JPA as JPA requires you to have a persistence.xml inside your EARs/WARs META-INF directory. But still it might work if we put the persistence.xml inside the domain/dto jar file but i have not tested this. But this was not an issue for us because we initially decided to go with Hibernate using Spring's Hibernate Template as the abstraction layer.

With the advent of jee6 now you can have your EJBs running inside your WAR. But the application server i have talked about here does not support jee6 and hence this is the only viable solution i could come up with.

That's about it. I do not know how this will scale with other application servers as i can only guarantee this working in JBoss. But for me its time to say good by to EARs which is too bloated as per my experience.

Wednesday, March 2, 2011

Twitter Based Alert System

We were in need of an alert system for our system in order to notify relevant parties of any errors which would occur in our production servers. There was already an email alert system in place but hey you have to admit no one is going to be checking emails 24x7 yea? :) ... We needed a solution like getting an SMS to our support team's phone, but we didnt have any SMS gateway available.

So thinking in the same lines i came up with a solution which enabled us to receive an SMS whenever an error occurred in our production systems. The solution was not a complex one and was very easy to implement with Spring 3 support.

The implemented solution was first we created a twitter account for our application and made the tweets private and followers to be authenticated. We dont want the whole world to know of the errors in our system now do we :) ... Then there was a very comprehensive tutorial available in Spring which you can find here which shows how to easily publish messages to your twitter account using Spring Integration. I honestly felt it was very easy to adapt with minimal changes.

Afterwards we created a twitter account for our support staff and followed the twitter account created for the application and enabled mobile alerts for that account. So now whenever an error occurs the application publishes the message via Spring's twitter plugin and consequently the support staff receives an update to their phones because we enabled mobile alerts on that specific account.



Now we have a fully fledged SMS based alert system without any cost involved. Someone somewhere said the best solution was almost always the simplest solution, i got to admit they were right on the money on that..

Cheers folks!!!!

Thursday, February 24, 2011

JMS and Async, Dont mess with it

JMS stands for Java Message Service which is an API which is used by middle ware service providers such as ActiveMQ, JBoss MQ, Rabbit MQ etc etc. Its main purpose is to allow disparate systems to communicate based on a common platform. Which means that if i have my front end written in .Net and my back end written in Java for example one way of communicating between the two (other than Webservices etc) is to use a JMS provider in a publisher-subscriber or peer-to-peer configuration.

In our own project we have used JMS but not to communicate between two disparate systems but to get the asynchronous capability integrated to our application. What we do is push the message into a queue and get along with the rest of the business process. But from what i see this is not the correct way of achieving this. Of course at the end of the day we have achieved asynchronous behavior but not in the right way. A solution just came to light a few months back with the release of Spring 3. Spring 3 provided an implementation allowing asynchronous capability with the @Async annotation. I will not go into the details of this feature as it is very well explained here.


I have changed the previously JMS oriented code which mimicked the asynchronous capability and introduced Spring's Async implementation as i felt it was much cleaner and reduced all handling i needed to do with onMessage(),Connection Factory and the rest of the code needed to deal with JMS queues and topics.


Wednesday, February 16, 2011

Learn, Respect, Triumph

This post is for all the new developers out there coming to the industry. Take a look at the Title of this post. Ok read it again. Ok Again. Alright now lets get going. I wanted to post something to all the new developers that come into the field of IT. I myself am not a veteran software engineer, i count a little over 4 years of experience. Wanted to share my thoughts about the new guys who come in. I see them and remember myself 4 years back and wanted to share some insights.

I often see new people who come in, fresh and pumped up to work. This is just great to see, reminds me when i was first entering the world of IT. Few things i noted which i myself was a victim back in the days are the ones i am going to go through within this post.

 Learn

I see few people these days who just enter the field of IT and they expect to work on the latest technology, with the latest frameworks and what not. This is great and there should be that hunger for technology but i would like to point out that you will not always get the chance to work on a project with all the latest technology. You would probably blame the company for not adapting to the new trends. Ok take two steps back. Look at it from this angle. Before two to three years did we have all these awesome java script frameworks that we now have? No. So people adapted their own frameworks that fit their needs which runs perfectly fine and has being running fine for quite a few years. Now when you fall into a project like that, you will probably think why would i ever want to learn all these boring old things since i know the new stuff. Ok again take two steps back. Look at current frameworks. Dont just look at them, dive into the code and look. Do you see a slight similarity between that and the current code of what your company use?

See everything that is there currently is a development of what already existed. Learn what you might think as "old" technology because these are the foundation on what current frameworks are built upon. Just because they are old does not mean its useless.

A few interns joined our company recently. A very talented group i must say. One guy was seated next to me, so i was asking how everything was going for him so far. He says "everything is good but i sure wish that i did not have to understand other's code and just write my own code instead". He was on a maintenance project and was mostly involved in bug fixes and enhancements. What i told him was that you will in a majority of cases be reading other's code and some may be bad and others would be good quality code. But whats important here is that you get to learn what is meant by bad code and good code my looking at other's code. Just writing your own code will get you no where. 

There are many other cases i would like to share but i do not want to lengthen this post much :) .. Ill probably break it down into sub posts in the time to come. Ok moving on to my next point,

Respect
As new people who enter the field of IT learn to always respect your seniors. That does not mean that you have to shake your head and agree on everything that they say or tell you to do. But dont think less of them just because they might know the latest technology that is out there or has just come out. Remember this, as you mature in this field you see many technology come and go. Some stick around and others fail. Maybe you like a certain new framework or language that has just come out, but just because your senior engineers do not want to incorporate it into the project does not mean they do not know that specific technology, it means that they with their experience often can judge if a certain technology is mature enough to adhere and incorporate. 

I must say i was in a similar situation when i first started working. Fresh out of grad school i was excited about going to work and starting off with the cool technology i just learned. But alas non of the tech leads or senior engineers even want to know about a particular technology i was talking about. I was left with some mix emotions. Sad, frustrated, angry and many more. Now when i look back i can see that those guys were actually right on the money. Because those technology i was talking about actually never materialized and some of them were a failure.

Remember to always respect your seniors no matter what. Some of them might be wrong sometimes. But most of the time they are right. Learn from them. If they think something you say is not correct dont be silent and in your mind mark that senior person as an idiot or incompetent. Ask him/her why that is so and the reason behind it. You will get a rationale answer i guarantee. You might not understand it fully at that moment, but some day you will.

 


Triumph
Ok last point. For anyone who got to this point thank you for reading this post and bare with me,just few more lines to go :) ... Actually this is an ongoing thing and you cant just accomplish this and wash your hands clean. To excel in this industry i believe the points i highlighted above are very important. Always keep learning, and i do not mean just about IT. Read anything that interests you. My father always says reading is the best habit you can have. Dont just be a nerd on a PC 24x7. Enjoy life, go out, play some sport you love, spend some time with family and loved ones. These i believe are all important things that make the essence of life just beautiful and more meaningful.


Ok thats about it guys. I know the last part is a bit too profound but just wanted to get that in there too :) . Cheers guys.....

Wednesday, February 9, 2011

The problem i faced with jqGrid and IE

Ok first of all before i start let me say this was not a problem with jqGrid or IE. I just started using jqGrid (hats off to the development team for the comprehensive documentation) in one of my projects i do in my free time. All was going well and i tested it out in IE7/8,FF2/3 and chrome. But i made a common mistake of not testing it in IE 6. When i went to deploy this at the clients environment alas it was IE 6. And the page i was using the jqGrid loaded and showed the message

Internet Explorer cannot open the Internet site http://<web site="">.com. Operation aborted.

I was baffled as to what this was. Debugging code at the client's environment was a pain. So as a work around i installed firefox for the moment until i found out what the issue was.

Went home, fired up note pad ++ and google of course :) .. in one site it mentioned that this could be the cause of a child element trying to modify a parent element. But i didnt find anything of such in my code.
In the path of an answer i saw that IE 8 was also giving the same error message but as a warning which didnt catch my eye. so i checked what that error was. it was as such;


Yikes now why didnt i see that first before my visit to the client. Oh well. So looking at the code, note that this was the only page that gave the problem and it was the only place where jqGrid was used. Looking at the DOM again i caught up with a code snippet of mine as such;


<div style="padding:10px 0 0 30px;">
    <table id="list2"></table> 
    <div id="pager2"/>
</div>

I saw the pager2 div didnt have a </div> element as i have just closed it within the same element it was defined. So hence i changed the following code as such;

<div style="padding:10px 0 0 30px;">
   <table id="list2"></table> <div id="pager2"></div>
   </div>
WAM!!! the bug dissapeared. So it seems that every div should be closed with a separate close div element rather than within the same opening tag although it doesnt have any content.

Now im not sure why that is. I Googled about it but didnt find any results as to why that happens. Maybe if you guys know the answer please do leave by a comment which would be highly appreciated.

Hope this helps any other person who would face a similar situation.

Cheers and happy coding to all !!!!!

Saturday, December 11, 2010

Technical innovation within a company, how do we approach it?

What does it mean to say technology innovation within the context of a company? Is it the the ability to create the next break through innovative project? Is it about creating the next best framework for development? 
It can be so many things. But if you look at it, innovation should be looked at from the ground up approach. We cannot have technology innovation without first improving the skill levels of the existing and the newly joining developers within the company. True that only a few may be involved in creating the next best framework, but there should be proper processes in place so that newly joined people are given thorough knowledge on what goes on the inside of these frameworks.

I often meet people who uses highly optimized, efficient frameworks that are put together by people within a company using the current technologies working together pretty well. So i had a chat with this developer who was working in this project using this framework. This is how it went down;

Me : "Hey this looks pretty neat... How is this functionality handled within the framework?"
New guy : "Oh thats easy, i just put this entry to this file and it works just like that..."
Me: " :S ....."

Thats a puzzled face btw :) ... It was pretty clear that he/she had no idea what was going on in the inside of the framework. In the frameworks point of view this was great because it hides alot of complex details from the developer and handles it internally which is why we standardize good frameworks, but if you look at it from the companies perspective, now we have a few developers who just dont understand what goes on within the framework. So how is that a problem some might ask ( specially the management ;) ).

To the management its great because they see that any new developer can come in and start working on the project from day one which results in maximum efficiency right? WRONG.... If any issue comes up whilst working, they would have no ground knowledge to figure out where it is going wrong. 

Im not saying that every developer should know in and out of the framework their project is working, but at least the high level understanding should be there so that when a problem arise, they will at least know where to start from to find the issue.

So how do we achieve this? When we start off with a particular framework for a project we should ask the main people involved in creating the framework to have a few slides explaining the high level details of why certain things were done the way they are in the current framework. And have at least a one day work shop organised for people who join newly to the respective project.This way the load on the technical leads will be less as they now have new people with a fare amount of knowledge on whats going on in the inside of the project which will prevent them from doing something radical which would break the whole concept of the framework.

And in terms of the company technology innovation has taken place, but this time its not just involving few people who develop the frameworks, but every one including the new people are included as part of the innovation. I believe innovation cannot happen unless the whole set of developers are inline with what we have achieved.

Innovation is a must in every IT company, in this post i just wanted to layout some basics that need to be in place for technical innovation to take place.  If everyone knows where we are heading as a company then the path we should take is clear and transparent to everyone.