Wednesday, November 6, 2013

Typical issue of thread context class loader in OSGi


Recently got an opportunity to look at a problem that one teammate was facing in thread context class loader with embedded Felix container. The issue was with thread context class loader that was working in one bundle and was failing in another bundle. This happens during the start up of web application which has embedded Felix container. After start up, if the failed bundle is restarted alone, then it works fine. Thought there was this workaround to start the bundle alone after application starts up, automation required more work. So worked for couple of hours to fix this issue. 

To explain in more detail of this problem, here is the illustration:

There are two bundles in the OSGi container:

Bundle A
Bundle B depends on A

Bundle A has below one line code and it was not setting back to the original class loader after changing it:

Thread.currentThread().setContextClassLoader(getClass().getClassLoader());


Same thread which invokes A was calling B while OSGi container start up and as B also needs to use class loader logic as A, it was failing to get the class loader object.

This was breaking B from achieving its functionality. Debugging showed the class loader gets just the reference of A bundle and returns nothing other than only the bundle ID. So had to take a look at bundle A to fix the issue in B.


Solution
The simple solution in this context is like below which makes sure to set the original context class loader back in bundle A

ClassLoader orignalCL = Thread.currentThread().getContextClassLoader();
try{
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
//some logic
}finally{
logger.info("Back to original class loader");
Thread.currentThread().setContextClassLoader(orignalCL);
}

Output Before
CL.toString() : 91.0 -> which is nothing but ID of the A bundle.

Output after fix :
CL.toString()  :
com.ibm.ws.classloader.CompoundClassLoader@790079[war:ear_name/war_name] Local ClassPath: ....


The learning from this is that never forget to re-set to original context class loader when you done with logic. If the same thread later calls some other code that relies on the context class loader and that code is not written to properly set the context class loader, then that code will fail majestically. The debugging such errors is of course time consuming.

Sunday, April 28, 2013

Capacity Planning for J2EE applications

As per Wiki, Capacity planning is the process of determining the production/serving capacity needed by an organization to meet changing requirements for its products/solutions.  This process strategically assess requirements for new solution, additional network capacity and underlying IT architectures. The information provided by capacity planning helps to : 
  • Characterize the solution workloads more accurately
  • Analyze the performance of various modules
  • Model contention for application servers, and ensure scalability
  • Model and plan for communications infrastructure
  • Forecast and cope with peak demand
  • Project the impact of agent technologies and non-PC devices.
Capacity planning is more cost-effective and efficient if done prior to deployment. Performance problems resulting from a lack of capacity are more complex and costly to resolve after deployment. However, in post deployment scenarios, it is possible to identify the impact on:
  • Code changes required
  • Existing Java Heap footprint
  • Native Heap footprint
  • CPU utilization or other negative side effect
Benefits of this exercise:
  • Avoid losing customers due to site crashes
  • Performance modeling and capacity planning for infrastructure
  • Build and analyze customer behavior models
  • Plan to avoid frequent upgrades and migrations.
  • Identify potential bottlenecks in the architecture
There are various methodologies and proven theories available to conduct this exercise. Some of them are:
  • Discrete-event simulation, 
  • Mean value analysis of product-form net-works, 
  • Analytical identification of bottleneck resources in multiclass environments, and
  • Workload characterization with fuzzy clustering.
Above methodologies in detail are complex and out of scope to discuss here. Instead let us look at the easier way to understand the whole process.  

The first and foremost step here is  to understand the IT requirements as explained below.
 
Data Gathering :
To properly determine resource requirements for an application, it requires architectural information, along with a functional description of anticipated usage. The completeness and accuracy of the sizing depends on the quality of the information received. When portions of  information are unknown or missing, the risk factor for incorrect sizing increases. Following type of information are required to drive the capacity planning analysis:
  • Percentage of new function supplied by solution
  • Percentage of new data elements created
  • Business-use scenarios
  • Data transferred to and fro
  • Peak load users size
  • Solution architecture definition:
    • Business function, scenarios and supporting models
    • Data architecture, solution architecture — business and deployment architecture diagrams
    • Technical architecture and schematic (client, server, network, Web)
Once the information is collected in standard templates,  it is time to apply right calculations considering each and every criteria. When standard benchmark data is available, the analysis need to be performed and results gets documented.

The components that need to be considered or validated are given below. This might not be the complete list and depending upon the IT system in design it could differ.  
  1. Operating systems
  2. Application servers
  3. Network protocols
  4. Data access services:DB systems
  5. Programming languages
  6. UI/Client Frameworks: AJAX, Java scripts etc.
  7. Distribution services: NFS, DFS, Kerberos
  8. Systems management: SNMP, AntiVirus, ADSM, TME
  9. Application interface with legacy data/systems
  10. Peak load: Data throughput.
 Afterthe initial assessment of architecture sizing has been completed, it is time for coding and application development. Once the development is over and solution is in deployable stage, test-based sizing process can be started. This process provides the validation sizing analysis that need to be performed and results are documented in this stage.

Hope this helps to start with and I'm thinking to post some case studies and sample reports in my next article.