Proxying Objects Causes OutOfMemoryError

I have retrieving my Object instances from a class with a method called getProxy. That method adds InvocationHandlers to extract out logic like tracing logic. Inside my TracingInvocationHandler, I print a statement before a method is executed and one after. I am able to run this fine through some functionality, but other methods cause an OutOfMemoryError. Those methods may create massive size lists within them...would this cause a problem? Is the Proxy to slow in performance to use it to do this?

/**

* @param obj param

*

* @return returned

*/

publicstatic Object getProxy(Object obj){

Object proxiedObject = obj;

if(logger.isTraceEnabled()){

InvocationHandler tracingHandler =new TracingProxyHandler(proxiedObject);

proxiedObject =

Proxy.newProxyInstance(proxiedObject.getClass().getClassLoader(),

proxiedObject.getClass().getInterfaces(), tracingHandler);

}

return proxiedObject;

}

publicclass TracingProxyHandlerimplements InvocationHandler{

privatestaticfinal Logger logger = Logger.getLogger(TracingProxyHandler.class);

protected Object delegate;

/**

* Creates a new TracingProxyHandler object.

*

* @param delegate param

*/

public TracingProxyHandler(Object delegate){

this.delegate = delegate;

}

/**

* @param proxy param

* @param method param

* @param args param

*

* @return returned

*

* @throws Throwable can be thrown

*/

public Object invoke(Object proxy, Method method, Object args[])

throws Throwable{

String methodName ="";

String className ="";

try{

methodName = method.getName();

className = method.getDeclaringClass().getName();

enterScope(methodName, className);

Object result = method.invoke(delegate, args);

exitScope(methodName, className, result);

return result;

}

catch(InvocationTargetException e){

throw e.getTargetException();

}

finally{}

}

/**

* @param methodName

* @param className

*/

privatevoid enterScope(String methodName, String className){

DateTime dateTime =new DateTime();

logger.trace(dateTime.getDateTimeFormat1() +"\nEntering -> " + className +"." +

methodName);

}

/**

* @param methodName

* @param className

* @param result

*

* @throws NoSuchMethodException

*/

privatevoid exitScope(String methodName, String className, Object result){

Object resultOutput = result;

DateTime dateTime =new DateTime();

if(resultinstanceof List && (result !=null)){

resultOutput ="Result is a collection != null and could possibly be too big to print.";

}

logger.trace(dateTime.getDateTimeFormat1() +"\nExiting -> " + className +"." +

methodName +"\nReturn -> " + resultOutput);

}

}

Thanks for your help,

-jay

[4966 byte] By [jaybyteza] at [2007-10-2 18:39:54]
# 1

It's hard to say much without also seeing the code which uses the proxy, but one thing which might be worth doing is making sure that you're never proxying a proxy. I'd change the test to if (!(obj instanceof Proxy) && logger.isTraceEnabled())

You should try using a profiler to debug the memory usage.

YAT_Archivista at 2007-7-13 20:01:59 > top of Java-index,Core,Core APIs...
# 2

Here is an example...this factory calls the ProxyFactory for every request for a ZipCodeBO interface.

/**

* This method retrieves the concrete implementation of the ProviderFacilityDAO.

*

* @return ProviderFacilityDAO the current implementation of the DAO.

*/

public static ProviderZipCodeBO getProviderZipCodeBO() {

return (ProviderZipCodeBO)ProxyFactory.getProxy(new ProviderZipCodeBOImpl());

}

This is the actual code in the ZipCodeBOImpl

public class ProviderZipCodeBOImpl extends BaseBO implements ProviderZipCodeBO {

/**

*

*/

public ProviderZipCodeBOImpl() {

super();

}

/**

* @return returned

*/

public ZipCodeTO getAllZipCodeData() {

ProviderZipCodeAssemblerDAO zipCodeDAO = this.getProviderZipCodeAssemblerDAO();

ZipCodeTO zipCodeTO = zipCodeDAO.selectZipCodeTO();

ProviderZipCodeTOList pfRegionZipCodes = zipCodeTO.getPfRegionZipCodes();

ProviderZipCodeTOList regionZipCodes = null;

ProviderZipCodeTO providerZipCodeTO = null;

if(pfRegionZipCodes != null) {

regionZipCodes = new ProviderZipCodeTOList();

for(int i = 0; i < pfRegionZipCodes.size(); i++) {

providerZipCodeTO = pfRegionZipCodes.get(i);

if(StringHelper.isValid(providerZipCodeTO.getRegion())) {

regionZipCodes.add(providerZipCodeTO);

}

}

}

zipCodeTO.setRegionZipCodes(regionZipCodes);

zipCodeTO.setPfRegionZipCodes(regionZipCodes);

return zipCodeTO;

}

/**

* @param zipCodeTO param

* @param userId param

*

* @return returned

*/

public DatabaseReportTOList saveZipCodeData(ZipCodeTO zipCodeTO, String userId) {

//Set the user id into the composite object

zipCodeTO.setUserId(userId);

this.processTnexZipCodeRules(zipCodeTO);

this.processRegionZipCodeRules(zipCodeTO);

ProviderZipCodeAssemblerDAO zipCodeDAO = this.getProviderZipCodeAssemblerDAO();

//Run the load process

return zipCodeDAO.insertZipCodeTO(zipCodeTO);

}

/**

* @param zipCodeTO

*/

public void processTnexZipCodeRules(ZipCodeTO zipCodeTO) {

ProviderZipCodeEnumerationTO zipCodeList = null;

ProviderZipCodeTO providerZipCodeTO = null;

ProviderZipCodeTOList updatedList= null;

//Business logic to set necessary values in tnex zip codes

String serviceType = "PRIME";

if(zipCodeTO != null && zipCodeTO.getTnexZipCodes() != null) {

zipCodeList = zipCodeTO.getTnexZipCodes().elements();

updatedList= new ProviderZipCodeTOList();

while(zipCodeList.hasMoreElements()) {

providerZipCodeTO = zipCodeList.nextElement();

//convert old dmis code to new CCS code

if(providerZipCodeTO.getDmisCode().equalsIgnoreCase("NON-PSA")) {

providerZipCodeTO.setDmisCode("NP01");

providerZipCodeTO.setServiceType("NON-PRIME");

}

else {

providerZipCodeTO.setServiceType(serviceType);

}

if("Y".equalsIgnoreCase(providerZipCodeTO.getOptimizationIndicator())) //at least 1 Y

{

providerZipCodeTO.setAreaIndicator("Y");

}

else if("N".equalsIgnoreCase(providerZipCodeTO.getOptimizationIndicator())) {

providerZipCodeTO.setAreaIndicator("N");

}

else {

providerZipCodeTO.setAreaIndicator(null);

}

updatedList.add(providerZipCodeTO);

}

zipCodeTO.setTnexZipCodes(updatedList);

}

}

/**

* @param zipCodeTO

*/

public void processRegionZipCodeRules(ZipCodeTO zipCodeTO) {

ProviderZipCodeEnumerationTO zipCodeList = null;

ProviderZipCodeTO providerZipCodeTO = null;

ProviderZipCodeTOList updatedList = null;

if(zipCodeTO != null && zipCodeTO.getRegionZipCodes() != null) {

zipCodeList = zipCodeTO.getRegionZipCodes().elements();

updatedList= new ProviderZipCodeTOList();

while(zipCodeList.hasMoreElements()) {

providerZipCodeTO = zipCodeList.nextElement();

if(StringHelper.isValid(providerZipCodeTO.getRegion())) {

if(providerZipCodeTO.getRegion().equals("01") ||

providerZipCodeTO.getRegion().equals("02") ||

providerZipCodeTO.getRegion().equals("05") ||

providerZipCodeTO.getRegion().equals("17")) {

providerZipCodeTO.setRegion("17");

}

else if(providerZipCodeTO.getRegion().equalsIgnoreCase("PR") ||

providerZipCodeTO.getRegion().equals("03") ||

providerZipCodeTO.getRegion().equals("04") ||

providerZipCodeTO.getRegion().equals("06") ||

providerZipCodeTO.getRegion().equals("18")) {

providerZipCodeTO.setRegion("18");

}

else if(providerZipCodeTO.getRegion().equals("07") ||

providerZipCodeTO.getRegion().equals("08") ||

providerZipCodeTO.getRegion().equals("09") ||

providerZipCodeTO.getRegion().equals("10") ||

providerZipCodeTO.getRegion().equals("11") ||

providerZipCodeTO.getRegion().equalsIgnoreCase("AK") ||

providerZipCodeTO.getRegion().equals("12") ||

providerZipCodeTO.getRegion().equals("13") ||

providerZipCodeTO.getRegion().equals("14") ||

providerZipCodeTO.getRegion().equals("15") ||

providerZipCodeTO.getRegion().equals("19")) {

providerZipCodeTO.setRegion("19");

}

else {

throw new HNFSRuntimeException(

"Invalid region code loaded from IW database loading tables.");

}

updatedList.add(providerZipCodeTO);

}

}

zipCodeTO.setRegionZipCodes(updatedList);

}

}

/**

* This method returns the implementation for ProviderZipCodeAssemblerDAO.

*

* @return returned

*/

protected ProviderZipCodeAssemblerDAO getProviderZipCodeAssemblerDAO() {

return ZipCodeDAOFactory.getProviderZipCodeAssemblerDAO();

}

}

So for every layer Struts Action -> SLSB (SessionFacade) -> BO -> DAO, I would

retrieve my objects from this ProxyFactory so that I could proxy them and add

tracing and other things.

jaybyteza at 2007-7-13 20:01:59 > top of Java-index,Core,Core APIs...