Memory Leak in shared Containers


Basic Reason for the leak:

Every time an application is deployed and un-deployed in a container, the application is given its own class loader (application class loader) by the container’s class loader. This application class loader might end up creating a cyclic reference to the container’s class loader, which makes it un-garbage collectible. From my observations getting rid of the application’s class loader from memory (1 to 2 MBs) could be a very difficult and tedious task because of the amount of third party tools we use, but can be contained, although not ideal.

Avoiding the leak from Crossing Threshold:

a) One Main Culprit : Spring Class Based Proxies

Many Enterprise applications use Spring, AOP and Hibernate as tools for their projects. With Hibernate comes the Session Factory beast in memory. The Hibernate Session Factories can become huge based on the project’s DB tables count and Hibernate Mapping Structure (150MB for the application that I work on). So when Session Factory gets attached to the un-garbage collectible Class Loader which has been left behind, we have huge memory leak in containers causing us losing valuable resources.

So how does this Session Factory get attached to the un-garbage collectible class loader?

Spring uses proxies to weave in Advices. Transactions are most commonly “AOP Advised” in Enterprise Applications using Declarative Transaction Management.

As you might know, there are 2 types of Proxies that Spring creates, based on the implementation of the class that needs to be advised

1) Interface Based Proxies – not a problem

Spring uses JDK proxies if there is an interface available for all the advised methods; this is the default type of proxy that is created. A new class is created with methods that needs to be advised, through which advises will be weaved in. A call is then delegated from the new class to the actual class that had to be advised.

2) Class Based Proxies – A Problem

Spring uses CGLIB to create proxies if an interface is not available for the existing methods that needs to be advised. This type of Proxy should be an exception in general, and it is only provided for backward compatibility for third party libraries that cannot be modified.
The problem here is CGLIB’s implementation leads it to tie a hard link between the Application Class Loader and the Session Factory when it is trying to advise the method of particular transaction choice.
Hence trying to avoid Class based proxies for Spring Transaction Management, in an application with an existing Class Loader leak, may avoid it from crossing the “Threshold” (2 MB to 154MB in a project that I was working on).

b) Some Third Party Libraries:

There are some third party tools that do the same thing of attaching itself to the class loader and creating a hard link between the runtime classes that they create and the class loader itself. Some examples that I know of right away are Dozer and Apache Common’s Logging.

So it looks like there is no good way to solve the problem of Application Class Loader’s Footprint leak in a Shared Container turning out of control, hence the intent of this article is to make one aware of the issues and point them in the right direction.

PermGen Space will be affected as well

Now this leak may also cause your PermGen Space run out of memory since the meta-inf about the loaded classes may not be garbage collected.

Krank Keviet has done a pretty good job explaining the issue in one of his blogs with respect to Perm Gen Space, a reference to his blog is below.

Posted in Uncategorized | Tagged , , , , | 1 Comment

Server side Pagination using JSF Data table and Hibernate


Following is the working example of Dynamic or server side pagination.

Your DataModel class

/**
*
*/

/**
* @author muhammad.shouab
*
*/
import java.util.List;
import javax.faces.model.DataModel;

public class PagedListDataModel extends DataModel {

private int rowIndex = -1;

private int totalNumRows;

private int pageSize;

@SuppressWarnings("unchecked")
private List list;

public PagedListDataModel() {
super();
}

@SuppressWarnings("unchecked")
public PagedListDataModel(List list, int totalNumRows, int pageSize) {
super();
setWrappedData(list);
this.totalNumRows = totalNumRows;
this.pageSize = pageSize;
}

public boolean isRowAvailable() {
if (list == null)
return false;

int rowIndex = getRowIndex();
if (rowIndex >= 0 && rowIndex < list.size())
return true;
else
return false;
}

public int getRowCount() {
return totalNumRows;
}

public Object getRowData() {
if (list == null)
return null;
else if (!isRowAvailable())
throw new IllegalArgumentException();
else {
int dataIndex = getRowIndex();
return list.get(dataIndex);
}
}

public int getRowIndex() {
return (rowIndex % pageSize);
}

public void setRowIndex(int rowIndex) {
this.rowIndex = rowIndex;
}

public Object getWrappedData() {
return list;
}

@SuppressWarnings("unchecked")
public void setWrappedData(Object list) {
this.list = (List) list;
}

}

JSF Component Util to find datatable at runtime


import java.util.Iterator;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

/**
* @author muhammad.shouab
*
*/
public class JSFComponentUtil {
public static UIComponent findComponentInRoot(String id) {
UIComponent component = null;

FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext != null) {
UIComponent root = facesContext.getViewRoot();
component = findComponent(root, id);
}

return component;
}

public static UIComponent findComponent(UIComponent base, String id) {
if (id.equals(base.getId()))
return base;

UIComponent kid = null;
UIComponent result = null;
Iterator kids = base.getFacetsAndChildren();
while (kids.hasNext() && (result == null)) {
kid = (UIComponent) kids.next();
if (id.equals(kid.getId())) {
result = kid;
break;
}
result = findComponent(kid, id);
if (result != null) {
break;
}
}
return result;
}
}


Your Controller Method

public DataModel getPagedDataModel()
{

try
{
HtmlDataTable table = (HtmlDataTable) JSFComponentUtil.findComponentInRoot("yourDataTableID");
Long totalListSize = Your Manager Method which return data List size
List data = Your Manager Method which return data List
PagedListDataModel dataModel = null;
if (totalListSize != null && totalListSize > 0)
{
dataModel = new PagedListDataModel(data, totalListSize.intValue(), table.getRows());
}
return dataModel;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}

Your JSF Page

Posted in Hibernate, JSF | Tagged , , , , | 2 Comments

WebCenter Analytic 10.3.0.1 Installation Problem


cewolf-0.10.3 is required while installing the WebCenter Analytic 10.3.0.1 Console if you try to give any other version it will not work. Give the full path of this cewolf-0.10.3.zip file during installation and it will work fine do not give the cewolf.jar path which is inside the this zip file.

Posted in Uncategorized | Leave a comment

WebCenter Analytics 10.3.0.1 with Weblogic Portal 10.3.2 Problems.


After Successful installation and starting of Analytic Console and Collector Service, Analytic reports shows no data although data is collected by Analytic Collector and available in tables. This problem is due to following known issues or bugs and these will be fixed in future release Analytic Release 10.3.0.2.0 which is expected to be released very soon.

– BUG 10297522 – WEBLOGIC PORTAL NOT DISPLAYING ANALYTICS REPORTS

The Weblogic Portal 10.3.2 release is not displaying Analytics Reports. Events are being successfully sent to the Analytics Collector and appear in the Analytics database; accessing the Analytics Reports directly from a browser on the WLP server loads the Analytics report frame successfully, but the WLP Administrative Console is not displaying the Analytics Reports, giving instead the “Analytics Reports are not currently available, or have not been configured correct. Please contact your administrator for assistance.” message.

– Bug 10407098: ANALYTICS DOES NOT WORK WITH WLP 10.3.2 (TRACKING BUG)
This is a tracking bug for bug #10297522

– Bug 10258857: ANALYTICS FOR WLP SHOULD NOT TAG EVENTS WITH NULL USERID

WebCenter Analytics for WebLogic Portal incorrectly tries to tag events that do not have a userid associated with them. This may cause a NullPointerException (NPE) error in the Analytics Collector.

Posted in WebCenter Analytics | Tagged , , , , , , | Leave a comment

WebLogic Portal with Oracle Data Base


Web Logic Portal comes with an evaluation license of Pointbase RDBMS for now.

Especially with WebLogic Portal most people use their own RDBMS like Oracle, MySQL, SQL Server etc. In that case you have to specify or reconfigure WebLogic about the location of the database objects.

* During the domain creation process they will give you an option to specify the database configuration information for all the datasources that portal require like p13nDataSource, portalDataSource, cgDataSource etc. In the subsequent screen of the configuration wizard they will give you an option to run the DB scripts to create your database objects if the user configured for the datasources in the previous screen is setup with right permissions. More information about this process can be found here. The following screen shot show the a sample JDBC Datasource configuration screen from the configuration wizard.

With WebLogic Portal 10.3.2, the point to note when you are configuring a non-Pointbase database a problem comes when you run the server it does not start

Error should be like this

<> <Test "SELECT COUNT(*) FROM SYSTABLES" set up for pool "p13nDataSource" failed with exception: "java.sql.SQLSyntaxErrorException: [OWLS][Sybase JDBC Driver][Sybase]SYSTABLES not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).

    Reason:


It is a known bug called “WebLogic Portal Configuration Wizard Bug”.

    Workaround

Workaround is to change the connection test sql clause in the WebLogic Server Console as follows:

1. In the “domain structure” panel go to Domain > Services > JDBC > DataSources.

2. Click each data source name, then the “connection pool” tab, and then “Advanced” at the bottom of the page.

In the “Test Table Name” text box, change the sql clause according to the type of db:

Oracle: SQL SELECT 1 FROM DUAL
DB2: SQL SELECT COUNT(*) FROM SYSIBM.SYSTABLES
MS SQL Server: SQL SELECT COUNT(*) FROM sysobjects
Sybase: SQL SELECT COUNT(*) FROM sysobjects
My Sql: SQL SELECT 1
Pointbase: No change.

Posted in WebLogic Portal | 4 Comments

Invoke BPEL Process using JAVA


The Following Code will invoke the Vaccation Request BPEL process come in samples with BPEL Manager installation.


try
{
URL url = new URL("http://host:port/wsdl link of deployed bpel");
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(url);
call.setProperty(Call.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
call.setProperty(Call.SOAPACTION_URI_PROPERTY, SOAP_ACTION);

call.setProperty( Call.OPERATION_STYLE_PROPERTY , STYLE );

call.setOperationName(OPERATION_NAME);

call.addParameter(new QName(PARAMETER_NAMESPACE,"creator"), XMLType.XSD_STRING, ParameterMode.IN);
call.addParameter(new QName(PARAMETER_NAMESPACE,"fromDate"), XMLType.XSD_DATETIME, ParameterMode.IN);
call.addParameter(new QName(PARAMETER_NAMESPACE,"toDate"), XMLType.XSD_DATETIME, ParameterMode.IN);
call.addParameter(new QName(PARAMETER_NAMESPACE,"reason"), XMLType.XSD_STRING, ParameterMode.IN);
Object[] params = new Object[4];

params[0] = "Anna";
params[1] = new Date();
params[2] = new Date();
params[3] = "No Reason";

/* Invoke the service */
/*************************************/
call.invokeOneWay(params);
System.out.println( "Vacation Request BPEL process initiated" );
}
catch (SOAPFaultException e)
{
System.err.println("Generated fault: ");
System.out.println (" Fault Code = " + e.getFaultCode());
System.out.println (" Fault String = " + e.getFaultString());
}
catch (JAXRPCException e)
{
System.err.println("JAXRPC Exception: " + e.getMessage());
}
catch (ServiceException e)
{
System.err.println("Service Exception: " + e.getMessage());
}
catch(Exception e)
{
e.printStackTrace();
System.err.println("Other Exception: " + e.getMessage());
}

I write this code using apache axis client you need to add apache axis libraries in your project build path.

Posted in BPEL | 4 Comments