ELResolver no puede manejar un objeto base nulo: Weblogic 10.3.x, Facelets 1.1.14, RichFaces 3.3.2

Tengo problemas para usar RichFaces 3.3.2 y Facelets 1.1.14 en Weblogic 10.3.4 y 10.3.5 (también conocido como 11g). Tengo un archivo xhtml con la expresión #{empty messages}, y en la consola obtengo la siguiente excepción:

SEVERE: Error Rendering View[/index.xhtml]
javax.el.ELException: //media/DADOS/data/java/wl1034/user_projects/domains/wlrep1034/autodeploy/SimpleJSFa/index.xhtml:

  ELResolver cannot handle a null base Object with identifier 'messages'

    at com.sun.facelets.compiler.TextInstruction.write(TextInstruction.java:48)
    at com.sun.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:39)
    at com.sun.facelets.compiler.UILeaf.encodeAll(UILeaf.java:149)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:889)
    at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:592)
    at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
    at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)

La messages La variable realmente no existe en este punto, pero es por eso que usé una empty declaración. Funciona bien en Tomcat 5.5 y Websphere 6.1.

El archivo xhtml completo:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.org/rich">

<body>

    <h1>Bean Message: #{TestBean.greeting}</h1>

    Are there messages pending? #{messages == null || empty messages} .

</body>
</html>

TestBean.java:

package eg.bean;

import java.util.ArrayList;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

public class TestBean {

    private String greeting = "Hello, World!";

    public TestBean() {
        // Uncommenting the following line puts an object in the session, under the
        // key "messages", and then the page displays properly.
        // addSomeMessages();
    }

    public String getGreeting() {
        return greeting;
    }

    public void setGreeting( String message ) {
        this.greeting = message;
    }

    public void addSomeMessages() {
        // This method is not being called for this example, but this is where
        // I would add a list of messages to be displayed to the user, and place it
        // on session scope (not advisable, I know, but bear with me)
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        List<String> messages = new ArrayList<String>();
        messages.add( "A message.");
        request.getSession().setAttribute( "messages", messages );
    }

}

Solo puedo suponer que de alguna manera Weblogic está usando una implementación diferente de ELResolver, lo que podría ser causado por conflictos del cargador de clases, pero he estado jugando con eso por un tiempo y no llego a ninguna parte.

Tengo los siguientes frascos en WEB-INF / lib:

commons-beanutils-1.7.0.jar
commons-digester-1.8.jar
commons-logging-1.1.1.jar
jsf-api.jar
jsf-facelets.jar
jsf-impl.jar
richfaces-api-3.3.2.SR1.jar
richfaces-impl-3.3.2.SR1.jar
richfaces-ui-3.3.2.SR1.jar
SimpleJSF.jar

Mi faces-config.xml se ve así:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xi="http://www.w3.org/2001/XInclude"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">

 <managed-bean>
  <managed-bean-name>TestBean</managed-bean-name>
  <managed-bean-class>eg.bean.TestBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
 </managed-bean>

 <application>
  <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
  <resource-bundle>
   <base-name>RepositoryBundle</base-name>
   <var>bundle</var>
  </resource-bundle>
 </application>
</faces-config>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

    <!-- Use Documents Saved as *.xhtml -->
    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>

    <context-param>
      <param-name>com.sun.faces.disableVersionTracking</param-name>
      <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>facelets.LIBRARIES</param-name>
        <param-value>/WEB-INF/sense.taglib.xml</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.validateXml</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
        <param-value>com.sensedia.repository.web.startup.SensediaFaceletViewHandler</param-value>
    </context-param>

    <context-param>
        <param-name>com.prime.facestrace.DISABLE_TRACE</param-name>
        <param-value>false</param-value>
    </context-param>

    <!-- ********************** SERVLETS ********************** -->

    <!-- Faces Servlet -->
    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- ********************** FILTERS ********************** -->
    <filter>
        <filter-name>richfaces</filter-name>
        <filter-class>org.ajax4jsf.Filter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>richfaces</filter-name>
        <servlet-name>FacesServlet</servlet-name>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>

    <!-- Faces Servlet Mapping -->
    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsf</welcome-file>
    </welcome-file-list>

</web-app>

EDITAR: Estaba implementando como un archivo de guerra independiente, pero también intenté empaquetarlo como un módulo EAR. El problema persiste. Al implementarlo como un archivo EAR, agregué un weblogic.xml jar además del mío web.xml con el siguiente contenido:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <container-descriptor>
        <prefer-web-inf-classes>true</prefer-web-inf-classes>
    </container-descriptor>
</weblogic-web-app>

También agregué un application.xml a la oreja META-INF directorio, simplemente haciendo referencia al módulo war. También agregué un weblogic-application.xml además de ese, para especificar aún más el aislamiento del cargador de clases:

<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <application-param>
        <param-name>webapp.encoding.default</param-name>
        <param-value>UTF-8</param-value>
    </application-param>

    <prefer-application-packages>
        <package-name>org.mozilla.*</package-name>
        <package-name>javax.jws.*</package-name>
        <package-name>com.sun.*</package-name>
        <package-name>javax.xml.rpc.*</package-name>
        <package-name>javax.xml.soap.*</package-name>
    </prefer-application-packages>

</weblogic-application>

preguntado el 10 de mayo de 11 a las 12:05

2 Respuestas

En realidad, se supone que la implementación de EL la proporciona el propio contenedor. Un conflicto de ruta de clases solo conduciría a errores de definición de clase / método como LinkageError, NoClassDefFoundError, AbstractMethodError, etc. Este no es el caso aquí, pero de hecho se parece mucho a un error en la implementación EL de Weblogic. Como no uso WebLogic, no puedo probar / confirmar esto.

En su lugar, podría intentar usar la siguiente expresión

#{messages == null || empty messages}

O puede intentar reemplazar totalmente la implementación EL, por ejemplo, el JBoss uno (que permite pasar argumentos de método). Solo deja caer jboss-el.jar in /WEB-INF/lib y agregue lo siguiente al web.xml

<context-param>     
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>   
</context-param>

contestado el 10 de mayo de 11 a las 17:05

¡Gracias por tu contribución! Lamentablemente, el problema persiste. También intenté usar EL Resolver de sun, colocando el-api-1.0.jar y el-impl-1.0.jar y utilizando com.sun.el.ExpressionFactoryImpl como expressionFactory. Mismos síntomas. De hecho, sospecho que esto no tiene ningún efecto en absoluto: intentaré depurar y ver si realmente se están llamando a esas clases. ¡Gracias de cualquier manera! - st. nunca

Interesante. ¿Qué tal la expresión EL alternativa? #{messages == null || empty messages}? - BalusC

En realidad, usando #{messages == null || empty messages}, o incluso simplemente #{messages == null} causa el mismo problema ... Puedo confirmar que se están produciendo los cambios (si elimino la declaración por completo, la página se muestra bien). Extraño. - st. nunca

¿Qué es? #{messages}? ¿Está definido por <ui:param> ¿o algo? Creo que sería útil un fragmento mínimo de la vista (xhtml) y el modelo (bean administrado) que reproduce el problema exacto. - BalusC

Actualicé la pregunta para incluir el xhtml y el archivo java. Este es solo un ejemplo muy básico para reproducir el problema. Pero messages está destinado a ser un ArrayList<String> colocado en el alcance de la sesión (consulte el archivo de bean administrado). - st. nunca

Después de todo, resulta ser un problema del cargador de clases. Había empaquetado los frascos JSF 1.2 en la carpeta WEB-INF / lib de mi aplicación:

jsf-api.jar
jsf-impl.jar

Weblogic 10.3.x tiene su propia implementación, ubicada en MW_HOME/wlserver/common/deployable-libraries/jsf-1.2.war (y la versión 2.0 en jsf-2.0.war). Reemplacé los frascos anteriores en mi propia aplicación web con los siguientes frascos de jsf-1.2.war!/WEB-INF/lib:

glassfish.jsf_1.0.0.0_1-2-15.jar
glassfish.jstl_1.2.0.1.jar
javax.jsf_1.1.0.0_1-2.jar
wls.jsf.di.jar

Yo tambien tuve que remove todos los paquetes en el prefer-application-packages elemento en weblogic.xml:

<!--
<prefer-application-packages>
    <package-name>org.mozilla.*</package-name>
    <package-name>javax.jws.*</package-name>
    <package-name>com.sun.*</package-name>
    <package-name>javax.xml.rpc.*</package-name>
    <package-name>javax.xml.soap.*</package-name>
</prefer-application-packages>
-->

Después de esto, la página se muestra correctamente. (Eso sí logró causar otros problemas, como un ViewExpiredException en cada página, pero ese es otro problema, creo ...)

contestado el 11 de mayo de 11 a las 15:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.