Friday, September 15, 2006

ClassLoaders and Packaging - J2EE Servers

I bet there is not a single J2EE developer who has not had nightmares trying to solve problems regarding ClassCastException when the J2EE application is deployed on the AppServer.

Resolving such problems require a sound knowledge of Java ClassLoading mechanism. In my previous post here, I had described the class loader heirarchy of standard JRE.

After this, we need to understand the class-loading mechanisms of the J2EE AppServer we are using. The classloading mechanisms of different appservers are different and also highly configurable through configuration files of the appserver. For e.g. make the classloaders execute child-first loading or the default parent-first loading, configure the same classloader for all modules in a ear file, etc.

Here is a good article that explains the fundamentals of ClassLoading in some J2EE servers:
http://www.theserverside.com/tt/articles/article.tss?l=ClassLoading

Alternatives to Apache webserver

Learned about some new webservers that claim to be faster than Apache and can handle more traffic under heavy load:

http://www.acme.com/software/thttpd/
http://www.lighttpd.net/

These servers are being used for heavy traffic websites and its definately worth evalauting them.

ArrayList Vs LinkedList

The Java SDK contains 2 implementations of the List interface - ArrayList and LinkedList.A common design dilemma for developers is when to use what ?

Some basics first:
An arraylist used an array for internal storage. This means it's fast for random access (e.g. get me element #999), because the array index gets you right to that element. But then adding and deleting at the start and middle of the arraylist would be slow, because all the later elements have to copied forward or backward. (Using System.arrayCopy())

ArrayList would also give a performance issue when the internal array fills up. The arrayList has to create a new array and copy all the elements there. The ArrayList has a growth algorithm of (n*3)/2+1, meaning that each time the buffer is too small it will create a new one of size (n*3)/2+1 where n is the number of elements of the current buffer. Hence if we can guess the number of elements that we are going to have, then it makes sense to create a arraylist with that capacity during object creation (using the overloaded construtor or ArrayList)

LinkedList is made up of a chain of nodes. Each node stores an element and the pointer to the next node. A singly linked list only has pointers to next. A doubly linked list has a pointer to the next and the previous element. This makes walking the list backward easier.

Linked lists are slow when it comes to random access. Gettting element #999 means you have to walk either forward from the beginning or backward from the end (depending on whether 999 is less than or greater than half the list size), calling next or previous, until you get to that element.Linked lists are fast for inserts and deletes anywhere in the list, since all you do is update a few next and previous pointers of a node. Each element of a linked list (especially a doubly linked list) uses a bit more memory than its equivalent in array list, due to the need for next and previous pointers.

Ok. Cool...Now that the fundamentals are clear, let's conclude on when to use what:

Here is a snippet from SUN's site.

The Java SDK contains 2 implementations of the List interface - ArrayList and LinkedList.
If you frequently add elements to the beginning of the List or iterate over the List to delete elements from its interior, you should consider using LinkedList. These operations require constant-time in a LinkedList and linear-time in an ArrayList. But you pay a big price in performance. Positional access requires linear-time in a LinkedList and constant-time in an ArrayList.

Here are a few more links that give interesting perspectives:
http://www.javaspecialists.co.za/archive/Issue111.html
http://joust.kano.net/weblog/archives/000066.html
http://soft.killingar.net/documents/LinkedList+vs+ArrayList
http://jira.jboss.com/jira/browse/JBXB-65

Monday, September 11, 2006

Info about Credit Cards

There are always new wonderful things that U learn - things that never caught Ur attention.

I found out a few interesting things about credit card numbers recently.
Did U know that all VISA/MasterCard credit card numbers start with "4" ???
Did U know that it is possible to do basic validation of a credit card number without even hitting any database ???

For more such interesting things about Credit cards, follow these links:
http://www.merriampark.com/anatomycc.htm
http://euro.ecom.cmu.edu/resources/elibrary/everycc.htm

Reload of Struts-config file

In earlier versions of Struts (v1.0), there was a ReloadAction that allowed us to reload the struts-config file from disk without reloading the web application or restarting the server.

But since Struts 1.1, this Action was removed. So it was no longer possible to reload the struts-config file using any in-built capabilities. I could not understand why this had been done. Finally a post by Craig R. McClanahan (founder of Struts) resolved all doubts:

ReloadAction is not supported in 1.1 for two reasons:

* It never did let you reload everything that you would really want to -- particularly changed classes -- so many people ended up having to reload the webapp anyway.

* Not supporting ReloadAction lets Struts avoid doing synchronization locks around all the lookups (like figuring out which action to use, or the detination of an ActionForward) so apps can run a little faster.


But under ordinary conditions, if we reload the webapp, then all sessions are lost - atleast that's what I thought; but I was wrong. Looks like the session is kept alive, but all session objects are destroyed unless they implement the 'Serializable' interface. I found this out from another post of Craig.

You can avoid webapp reload problems (which will likely be requiredfor *any* server, not just Tomcat) by following a couple of simple rules:

* For session attributes, make sure that they implement java.io.Serializable (and that any classes used in instance variables are also Serializable). Tomcat 4+, at least, will save and restore these sessions and their attributes for you.

* For context attributes, make sure that your webapp startup procedures properly restore anything that needs to be there. For a servlet 2.3 or later container, the proper way to do this is with a class that implements ServletContextListener, regsitered in a element in your web.xml file.

Proper application architecture will avoid any reloadability problems.