Category Archives: Java

Tips for J2EE optimisation

There was one time when I had finished coding and verifying my project module in my local computer. Passed it to the UAT. The UAT team had also verified the functionalities. Everything seemed to work pretty well. “So, it is now ready to be deployed to Production, right?” was what I thought until they mentioned such thing that there is still another test called Load / Stress Testing. What the heck is that?

I wasn’t very prepared with such terms while I did my coding since I was still fairly new as a programmer (about a year) at that time. To make the story short, it failed. It’s supposed to be strong enough to handle 140 users at the same time. My project module could handle 5. Only FIVE users at the same time! Oh dear…

I learned then that it’s not just about making sure that all the functionalities are to work properly, no critical bug, no error page, and so that’s it. There is another dimension that should be considered to make sure that the project is ready to face the world. You’re doing no good if you show your Masterpiece Project to the WORLD in the end just to know that only five people can actually use it at the same time.

I learned that Performance is an important factor.

There are many tips & tricks for performance boosts for J2EE scattered all over the web. It might be too huge to compile them all into one blog post. Some of them are no longer relevant considering all the tweaks / fixes done by the marvelous Java Team to Java community. Nevertheless I am still eager to share those that I have got and learned so far.

I’d like to start with my favourite principle from Kevlin Hennely. I personally consider it a very basic principle of performance optimisation:

There is no code faster than no code
Kevlin Hennely

That is, don’t put unnecessary lines  into your program. You have to regularly review your code or have someone else to review your code to make sure that there is a purpose for the existence of every line.

Other than the basic principle mentioned by Kevlin Hennely above, these are the list of some of the rules that I have learned so far:

1. String operations.

What is the best way to concatenate Strings together? Is it by using ‘+’ operator or by using StringBuffer, or even StringBuilder?

The answer is: All of them. We just need to know how and when to use them properly, based on these rules below:

  • Use ‘+’operator to combine two String constants together, e.g.:
    + "WHERE QTY<QTY_THRESHOLD;" // good example. 
  • Don’t use ‘+’operator to combine a constant with a variable, or a variable with a variable, e.g.:
    + "WHERE QTY<" + var_qty_threshold; // bad example

    Use either StringBuffer or StringBuilder instead.

  • Use StringBuffer when one of those Strings to be combined are variables and you want to make it thread-safe, e.g.:
    StringBuffer sb = new StringBuffer("SELECT * FROM SHOP_STOCK " 
    + "WHERE QTY<").append(var_qty_threshold);
  • Use StringBuilder when one of those Strings to be combined are variables and there is no thread-safety issue involved. It’s very suitable for most cases, e.g.:
    StringBuilder sb = new StringBuilder ("SELECT * FROM SHOP_STOCK " 
    + "WHERE QTY<").append(var_qty_threshold);


2. Combine several EJB method calls into one method call.

EJB method invocation is a heavy process. Try not to call the EJB methods too many times.

So, instead of doing this:

// Don't do this!!!
for (Document doc: documents) {
  getRemoteEJB().saveDocument(doc); // the EJB method is invoked for every document.

do this instead:

// the EJB method is invoked only once for all documents.


3. Avoid subqueries. Use “JOIN” instead.

The subqueries will be executed for each row. This is not a good idea especially if there are huge data to be processed in the database. By joining to a table, there will be only a query executed to join the two tables.

This is a bad example:


and this is the better example:



4. Put a value into a variable if it’s going to be used several times.

Avoid putting any computation in the conditional part of the for-loop if you know the value is always fixed throughout the iterations.

Bad example:

// Let's say there are 100 items in the database.
for (int i=0; i<getAllItemsFromDatabase().size(); i++) { // 100 times
  Item item = getAllItemsFromDatabase().get(i); // 100 times
  // Do whatever it is..

Note that the conditional section in the for-loop, “i<getAllItemsFromDatabase().size()”, will be evaluated for each iteration.

If the getAllItemsFromDatabase() method will return, for example, 100 items. Then the code above will in the end execute the getAllItemsFromDatabase() method 200 times! Not counting if that method will involve EJB or any database process.

It’s like going back and forth between heaven and hell 200 times. Not my favourite exercise. I mean, seriously…

and for the better example:

List<Item> items = getAllItemsFromDatabase(); // called only once
for (int i=0; i<items.size(); i++) {
  Item item = items.get(i);
  item.setTempIdx(i+1);  // Do whatever it is..

In this sample, the method getAllItemsFromDatabase() will be called just once, and the result will be reused for all the iterations.


5. Use “cheap” objects for EJB method calls.

All the parameters and return objects used in an EJB method invocation will be serialized. The heavier the object is, the longer it takes for the system to serialize the object.

When a client invokes an EJB method, this is what happens in sequence:

  1. Client invokes the method.
  2. The parameters are serialized and then sent as a stream to the server.
  3. The streams are de-serialized to be parameters again.
  4. Inside the EJB, after all the processes are completed and the result object is returned
  5. This return object will be serialized into a stream and then sent to the client.
  6. The EJB will de-serialize the stream to become the result object again.

As seen above, there are a couple of serialization and de-serialization processes going on for all the objects used in the method invocation. And it takes time! That’s why it’s good to observe the objects again (both the parameters and the return objects) whether they are really necessary or not, or if it’s possible to simplify them.

Take a look at the sample code below:

// Don't do this!!!
public List<SuperComplexDocument> updateDocumentSiblings(SuperComplexDocument doc) {
  // I'm oversimplifying here for the sake of clarity.
  return getDocumentDAO().updateSiblings(doc.getDocumentCode());

For example, in the example shown above, we see that in fact we only need to access the documentCode attribute of the Document object. If that’s the case, the method parameter should be simplified as follows:

public List<SuperComplexDocument> updateDocumentSiblings(String documentCode) {
  // I'm oversimplifying here for the sake of clarity.
  return getDocumentDAO().updateSiblings(documentCode);

After the modification, the serialization & de-serialization processes will be lighter since the EJB doesn’t serialize the SuperComplexDocument parameter object parameter anymore. It’s just serializing the String object.
The same thing also applies for the return objects (List<SuperComplexDocument> in this example). If you notice that the return objects can be simplified, then simplify it! You should even remove it if it’s unnecessary.


6. System.Out.Println < Logger < no-log-at-all.

Printing out the variables to the Production console for the sake of debugging is not a good idea. It’s time-consuming, especially when the application is about to be used by a number of users.

If you are deploying a program into a Production environment and using the System.out.println command in your application, you will likely get into a problem. If, for example, there are 100 users accessing the same module at the same time, then this very simple command will be executed 100 times. This is very inefficient because the server is spending its resources just to do what is actually not to be done in Production environment.

If you do need to print out a value for the sake of debugging a bug in your local environment but not in Production environment, use a Logger instead. Logger will filter the command and analyze whether it’s valid to print something to the console or not. So, not everything will be printed to the console for all users. The popular one for now is Log4J, and it’s sufficient enough for me so far.

The best scenario is definitely by not using a Logger at all (take a look at the initial quote I put in the beginning of this post). Whether the log is to be filtered or not by the Logger, this filtering process itself takes time although not as much as the System.out.Println method. That’s why doing excessive logging will also affect the performance of the application.


7. Favor Stateless Bean over Stateful Bean.

Stateful Bean is heavier than Stateless Bean since the system will store the transaction object of every user into the memory. If there are 100 users calling an EJB method and triggers the transaction, there will be 100 unique Beans created by the server.

By using Stateless Bean, the transaction is not unique for every user. They are all sharing the same transaction object. So, if there are 100 users calling an EJB method and triggers the transaction, there will be only one Bean created by the server.


8. Adjust the Transaction attributes as necessary.

One aspect of EJB that makes it heavier is the usage of transaction. If some EJB method is meant only to retrieve a result without modifying anything, than transaction is not necessary. Adjust the transaction attribute accordingly for all the EJB methods based on this behaviour.

You can set the transaction attributes in the ejb-jar.xml deployment descriptor file. If you don’t need a transaction for a certain method call, you can set the value to be either ‘NotSupported’ or ‘Never’. You can check the manual for more details.


9. Use ‘transient’ modifier to reduce serialization overheads.

As mentioned above, serialization and de-serialization is a heavy task. One way to lighten the burden is by showing the system which attributes that do not need to be transferred to a file / over the network, etc. Basically we’re telling the system which attributes that do not need to undergo serialization process.


10. Don’t reinvent the wheel.

If you’re using a HashMap object that is frequently accessed by concurrency actions, you might as well replace it with ConcurrentHashMap instead. That why you don’t need to manually set how to lock / unlock the key, where to synchronize, etc. The Classes / APIs provided by Java community has been tweaked, tested and optimized again and again to work the best it can possibly be.

Another example is when you try to check whether a String constant starts with a certain characters. Instead of using your own substring, iteration, etc., you can actually use method startsWith(String prefix).

Make sure that you’re not reinventing the wheel. Check first whether such functionality has been natively invented or not before deciding to make one.







As we know, we can do iterations in Java with at least two ways: For-Loop, or While-Loop. We can actually do it by using recursive as well, but let’s take it aside for now. For this post, I just want to focus a bit about For-Loop.

In For-Loop itself, we can do the looping in at least three ways:

1. Common For-Loop.

This is the most common way of doing iteration in Java. This is the basic format:

List<Book> books = new ArrayList<Book>();
// Set<Book> books = new HashSet<Book>();
books.add(new Book(“One”, 1));
books.add(new Book(“Two”, 2));
books.add(new Book(“One”, 1));
for (int i=0; i<books.size(); i++) {
 Book book = books.get(i);
 // Do something with var book here.

This iteration is good enough for you if your projects use Collection data type with List implementation or for Array. But it’s not good enough for any other Collection data types such as Vector or HashMap, since they don’t apply getter method for a specific index.

If, let’s say, one day your supervisor decides to change the data type from ArrayList to HashSet in order to prevent duplicates in the Books collection, the code above will no longer compile because HashSet doesn’t have ‘get’ method.

The code above is not flexible for modifications.

2. With Iterator.
Iterator will help to solve the flexibility issue found in the common For-Loop. This is how the code will look if you convert it to apply Iterator.

List<Book> books = new ArrayList<Book>();
// Set<Book> books = new HashSet<Book>();
books.add(new Book(“One”, 1));
books.add(new Book(“Two”, 2));
books.add(new Book(“One”, 1));
for (Iterator<Book> it = books.iterator; it.hasNext(); ) {
 Book book =;
 // Do something with var book here.

The code above in this 2nd example is more flexible than the 1st one. It’s flexible because whether the books collection will use List data type or Set data type, the code will still compile and run just fine. It solves the flexibility issue found when you use the common For-loop.

Can it get even better than this? Yes, but no longer in terms of flexibility. It’s just in terms of readability.

3. Enhanced For-Loop.
Since JDK 5, Java has launched a new form of loop, which they call Enhanced For-Loop. Actually this loop will implicitly use Iterator implementation as shown in the previous example. Implicitly. With this new for-loop format, the code will look better.

This is how the code will look if you use the Enhanced For-Loop instead.

List<Book> books = new ArrayList<Book>();
// Set<Book> books = new HashSet<Book>();
books.add(new Book(“One”, 1));
books.add(new Book(“Two”, 2));
books.add(new Book(“One”, 1));
for (Book book: books) {
 // Do something with var book here.

Now, don’t you think that this one looks much nicer than the previous one? It’s more readable, and at the very least it saves you one line of code for each iteration.

The constraint here is that the declared Collection variable must use Generics. Anyway, actually it’s not really fair to call it a constraint. It’s more correct to consider it a feature. Generic is a very good Java practice to save you from wasting your time of compiling, deploying, and running the program just to encounter ClassCastException.

Indeed there are cases where it is necessary to use the classic For-Loop (the 1st option) instead of the others. One example is when the loop index is going to be used somewhere in the iteration. It usually happens when the sequence of the data inside the collections need to be maintained, such as ArrayList, Vector, or plain Array. If the sequence doesn’t matter, it’s advised to follow this formula:

Enhanced For-loop > For-Loop with Iterator > Common For-Loop.