Question

I have been using the following bit of code in a servlet to locate a session backing bean (as suggested by BalusC) without problems until recently. Now it only works on Internet Explorer. Chrome and Firefox appear to be getting a totally new backing bean rather than the original backing bean. When calling functions in the backing bean, it falls over with null pointer errors for objects in the backing bean that were definitely initialized in the original.

FacesContext facesContext = FacesUtil.getFacesContext(req, res);
ProductSelection productSelection = (ProductSelection) facesContext.getApplication().evaluateExpressionGet(facesContext, "#{productSelection}", ProductSelection.class);

if(productSelection.getProductType() == null)
{
   System.out.println("Sevlet: product type is NULL; did not get the original backing bean");
}
else
{
   System.out.println("Sevlet: product type is: " + productSelection.getProductType().getProductTypeName());
}

It is a while since I tested this code and there have been several updates to Java but I'm not sure if these are the cause; I have changed something in my configuration or Chrome and Firefox have changed something in their code (unlikely). Is anyone else having similar problems? I am at a loss as to where to go from here, as there does not appear to be any errors associated with not finding the backing bean and my debugging skills for the java lib code are not that great (they don't comment their code very well and it is hard to follow); any suggestions would be greatly appreciated.

I am using Netbeans 7.01, JSF 2.0, Glassfish 3.1, and a Derby database. I tested it on my tower and laptop and it is doing it on both (Win XP and Win 7). The JRE is 7 update 40 build 1.7.0_40-b43. JDK is 1.6.0_04. Chrome version is 29.0.1547.76 m. Firefox is 23.0.1. Internet Explorer is 8.0.6001.18702.

The FacesUtil is slightly different to BalusC's code (but it was working fine):

    package searchselection;

import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

// By BalusC http://balusc.blogspot.com
// Utility to get the FacesContext.
// Used by the CriteriaServlet to get the backing bean when the user submits a customised
// search criteria object.
public class FacesUtil 
{
    // Getters -----------------------------------------------------------------
    //
    public static FacesContext getFacesContext(ServletRequest request, ServletResponse response) 
    {
        // Get current FacesContext.
        FacesContext facesContext = FacesContext.getCurrentInstance();

        // Check current FacesContext.
        if (facesContext == null) 
        {

            // Create new Lifecycle.
            LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
            Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

            // Create new FacesContext.
            FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
            facesContext = contextFactory.getFacesContext(
                    request.getServletContext(), request, response, lifecycle);

            // Create new View.
            UIViewRoot view = facesContext.getApplication().getViewHandler().createView(
                    facesContext, "");
            facesContext.setViewRoot(view);

            // Set current FacesContext.
            FacesContextWrapper.setCurrentInstance(facesContext);
        }

        return facesContext;
    }

    // Helpers -----------------------------------------------------------------
    // Wrap the protected FacesContext.setCurrentInstance() in a inner class.
    private static abstract class FacesContextWrapper extends FacesContext 
    {

        protected static void setCurrentInstance(FacesContext facesContext) 
        {
            FacesContext.setCurrentInstance(facesContext);
        }
    }
}

Kind thanks in advance...

Was it helpful?

Solution

Work-a-round: The session Id is changing on Firefox and Chrome when the servlet is called from the applet, for some reason. I ended up storing the session ID and setting it on the HttpURLConnection connection to the servlet, which forces the servlet to get the correct backing bean.

In the productSelection backing bean:

private String sessionID = ""; // With getter
.
.
.
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
sessionID = session.getId();

On the web page containing the applet I am using a javascript function to wait until the applet is fully loaded before telling it to load a criteria file, which will be modified by the user and then sent back to the backing bean for processing. I have simply passed the session ID along with the criteria file to the applet:

<SCRIPT language="javascript">
        function waitUntilLoaded() 
        {
           if (document.criteriaApplet.isActive()) 
           {
             var object = document.getElementById ("criteriaApplet");  
             criteriaApplet.loadCriteriaFile((object.codeBase + "#{productSelection.productUsage.searchCriteriaObjectUrl}"), "#{productSelection.sessionID}");
            }
           else 
           {
               settimeout(waitUntilLoaded(),500)
           }
        }
 </SCRIPT>

In the applet button code, to submit the modified criteria file back to the backing bean via the servelet, I added the session ID to the HttpURLConnection connection:

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-java-serialized-object");
            connection.setRequestProperty("Cookie","JSESSIONID=" + sessionID);
            ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
            out.writeObject(searchSubmitObject);
            out.flush();
            out.close();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top