August 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Don't Let Listener Logging Lower Performance, Page 2

Don't Let Listener Logging Lower Performance

While knowing in what phase each debug statement is occurring is useful, it is not always necessary or desirable. To make listener logging a useful tool, we can add a bit of control over it by using a property file to turn the behavior on or off as needed:

public static final boolean DO_PHASE_DEBUG = getDoPhaseDebug();
private static boolean getDoPhaseDebug()
{
boolean doPhaseDebug = false;
Properties props = new Properties();
try
{
props.load(new FileInputStream("phaseDebugger.properties"));
doPhaseDebug = Boolean.parseBoolean(props.getProperty("doPhaseDebug"));
logger.info("doPhaseDebug: "+doPhaseDebug);
}
catch(Exception e)
{
logger.error("Oops");
}
return doPhaseDebug;
}

Then wrap our debug statements with a check:

 public void beforePhase(PhaseEvent event)
{
if(LifeCycleListener.DO_PHASE_DEBUG)
{
... {

Dig Deeper with a Component Tree Output

One area of complexity in highly customized UIs is the number of components involved and how they interact. While volumes of books and blog entries discuss the topic, component interaction can still be hard to visualize. Adding another level of detail to the debug logs can help with that. We can do that by adding two simple methods to our PhaseListener:

private void outputComponentTree(PhaseEvent event)
{
FacesContext context = event.getFacesContext();
UIViewRoot root = context.getViewRoot();
outputComponentTreeRecur(context, root, "");
}
private void outputComponentTreeRecur(FacesContext context, UIComponent component, String prefix)
{
Iterator compIt = null;
String compId = null;
UIComponent subComp = null;
if(component!=null)
{
compId = component.getClientId(context);
compIt = component.getChildren().iterator();
logger.debug(prefix+"ID: "+compId+"tType: "+component.getRendererType());
while (compIt.hasNext())
{
subComp = compIt.next();
outputComponentTreeRecur(context, subComp, prefix+"t");
}
}
}

Now we can see much more detail about each phase and the sequence of the individual components with the structure:

++++++ START PHASE RENDER_RESPONSE 6 ++++++
DEBUG LifeCycleListener: %%%%%%%%%
DEBUG LifeCycleListener: DebugPhaseListener Tree Before Phase RENDER_RESPONSE 6
DEBUG LifeCycleListener: ID: j_id0 Type: null
DEBUG LifeCycleListener: %%%%%%%%%
DEBUG LoginBean : getName(): Scott
DEBUG LifeCycleListener: %%%%%%%%%
DEBUG LifeCycleListener: DebugPhaseListener Tree AFTER Phase RENDER_RESPONSE 6
DEBUG LifeCycleListener: ID: j_id_jsp_887103952_0 Type: null
DEBUG LifeCycleListener: ID: j_id_jsp_887103952_1 Type: javax.faces.Form
DEBUG LifeCycleListener: ID: j_id_jsp_887103952_1:j_id1 Type: javax.faces.Text
DEBUG LifeCycleListener: ID: j_id_jsp_887103952_1:j_id_jsp_887103952_2 Type: javax.faces.Text
DEBUG LifeCycleListener: %%%%%%%%%
DEBUG LifeCycleListener:
++++++ END PHASE RENDER_RESPONSE 6 ++++++

Granted, this is not as readable because it is so verbose. However, it can be useful when simply knowing the phase is not enough, such as when a third-party framework is being used in addition to the standard JSF libraries. One option would be to have a separate switch to set the level of logging as well as turning it on or off.

One Other Non-Standard Tweak

Consider logging when the class is created to monitor that it is being created when you expect it to be. You can accomplish this by adding the following:

{
if(LOGGER.isDebugEnabled())LOGGER.debug("Creating LoginBean");
}

Conclusion

I had begun investigating the PhaseListener tool for debugging after having read about it on a distribution list. I found it educational when making my first forays into JSF, and it was handy for following the lifecycle on those days when it wasn't always clear what was happening when. In one case, I ran a PhaseListener in an application with a framework that used a JSR 329 portlet bridge and discovered that the RESTORE_VIEW was called twice for each form submission. This knowledge enabled the team to catch some potential performance issues before the application went into production and saved us all from those dreaded evening and weekend support calls.

About the Author

Scott Nelson helps companies of all sizes in planning, designing, developing and maintaining Web-accessible applications. He has worked as both an independent contractor and professional services consultant for system integrators and J2EE product vendors since 1993. Scott blogs on three separate topics: personal investing (http://money.fywservices.com), forwarded jokes (http://humor.fywservices.com) and IT (http://techblog.fywservices.com).


Tags: JavaServer Faces, JSF

Originally published on http://www.developer.com.

Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel