JBoss Optimizations 101
by Sacha Labourey and Juha Lindfors
05/28/2003
This article introduces a fictitious application to show some basic
configuration mistakes, frequently made by new J2EE developers, that lead to
bad application performance. While the application is fictitious, all
surrounding issues and optimizations we cover originate from real-life
consulting experiences in the J2EE and JBoss fields.
Presentation of the CMS101
CMS101 is a basic content management server (CMS) implemented as
a J2EE application. Its purpose is to serve HTML pages that are dynamically
built, based on a set of basic elements:
- Page content
- Header
- Left side
- Right side
- Footer
Usually, different contents will share the same header, footer, and left
and right side.

Figure 1. Structure of a web page for CMS101
Obviously, the flexibility offered by this CMS is not overwhelming and will
only satisfy limited scenarios, so don't try this at work. However, its
pedagogic interest remains intact.
At the beginning of the project, after several passionate meetings, CMS101's
architecture team ended up with the EJB design excerpted here:

Figure 2. UML design of CMS101
A web page is identified by a name and has links to a header, a footer, and
left and right sides. The page content is versioned: the current production
version number is stored in the WebPage EJB and different versions are stored
in the PageContent EJB. All of these EJBs are Container Managed Persistence (CMP)
entity beans. An EJB Page Renderer stateless session bean handles web page
creation. It starts the transaction and sequentially asks each component
composing the web page for its HTML output:

Figure 3. Page-rendering activity chart
Note: for the sake of simplicity, only access to the Header EJB is
shown in the picture above. However, access to the footer and left and right
sides is similar.
A few days later, the development team comes up with a first version of
CMS101 and deploys it under JBoss 3.2. After a successful deployment, the
development teams define a set of web pages for testing and start playing with
CMS101. The result is satisfying. However, as real professionals, they decide
to put a scalability test suite into place!
First Headaches: Heavy Locking
While simple testing produced satisfactory results, the development team
quickly detects that their application doesn't scale when they run the
scalability test suite. For example, some of their test web pages contain code
that must get salary information from a remote ERP system. This operation,
while not CPU-intensive for the application server, takes a few seconds
(network latency, ERP processing time, etc.). They observe that, while such a
page is being processed, no other page can be rendered by CMS101! What is the
reason for that problem?
By default, JBoss uses pessimistic locking. An entity bean that is enrolled
in a transaction cannot be used by another transaction until the one that uses
the bean has committed or rolled back. Consequently, as the transaction is
started by the PageRenderer EJB, all entity beans used by PageRenderer are only
"released" once the whole work is finished.
As all Web pages of the CMS101 test suite use the same header and footer,
there is a huge contention taking place, namely:
- The display of a given web page is serialized: as the WebPage bean for a
given page is exclusively locked by an HTTP request, no other display of this
page is possible until the first request is finished.
- Even the display of two different pages may be serialized if they use
either the same header, footer, or left or right side (as is the case in the
test suite).

Figure 4. Activity chart showing pessimistic
locking
When you face entity bean access contention problems that lead to bad
performance of your J2EE application, there is no (magic) general solution that
can be used; each scenario must be individually analyzed.
In the current scenario, it is obvious that there is no real need for the
entity beans to be enrolled in the transaction. Each bean is only accessed
once during the transaction. None of its fields is updated. JBoss offers a way
to handle this situation by defining either an entire EJB as being "read-only"
or simply as a subset of its methods. When accessing a read-only method (or
EJB), while JBoss still prevents concurrent access to the same bean instance,
the bean will not be enrolled in the transaction and will not be locked during
the whole transaction lifetime. Consequently, other transactions can directly
use it for their own work.
Our brilliant development team decides that all calls to methods prefixed by
get were read-only, so they modify the jboss.xml
deployment descriptor accordingly:
<jboss>
<enterprise-beans>
<entity>
<ejb-name>WebPage</ejb-name>
<method-attributes>
<method>
<method-name>get*</method-name>
<read-only>true</read-only>
</method>
<method-attributes>
</entity>
<entity>
<ejb-name>PageContent</ejb-name>
<method-attributes>
<method>
<method-name>get*</method-name>
<read-only>true</read-only>
</method>
<method-attributes>
</entity>
<entity>
<ejb-name>Header</ejb-name>
<method-attributes>
<method>
<method-name>get*</method-name>
<read-only>true</read-only>
</method>
<method-attributes>
</entity>
<!-- and so on for Footer, LeftSide and RightSide -->
<session>
<ejb-name>PageRenderer</ejb-name>
<jndi-name>PageRenderer</jndi-name>
</session>
</enterprise-beans>
</jboss>
They then decide to re-run the test suite to admire the new results.
However, they still have mixed feelings. While the concurrency and overall
performance of their application is much better, their database suffers from
heavy access and quickly becomes the bottleneck of their solution.