#jsf #richfaces #weblogic #facelets #el
#jsf #richfaces #weblogic #интерфейсы #el
Вопрос:
У меня возникли проблемы с использованием RichFaces 3.3.2 и Facelets 1.1.14 в Weblogic 10.3.4 и 10.3.5 (он же 11g). У меня есть файл xhtml с выражением #{empty messages}
, и на консоли я получаю следующее исключение:
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)
На данный момент messages
переменная действительно не существует, но именно поэтому я использовал empty
инструкцию. Он отлично работает на Tomcat 5.5 и Websphere 6.1.
Полный файл xhtml:
<?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 );
}
}
Я могу только догадываться, что Weblogic каким-то образом использует другую реализацию ELResolver, что может быть вызвано конфликтами загрузчика классов, но я некоторое время возился с этим и ничего не добился.
У меня есть следующие jar-файлы в 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
My faces-config.xml looks like this:
<?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>
РЕДАКТИРОВАТЬ: я развертывал как отдельный файл war, но я также пытался упаковать как модуль EAR. Проблема не устранена. При развертывании в виде файла EAR я добавил weblogic.xml
jar помимо своего собственного web.xml
со следующим содержимым:
<?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>
Я также добавил application.xml
в META-INF
каталог ear , просто сославшись на модуль war. Я также добавил weblogic-application.xml
файл помимо этого, чтобы дополнительно указать изоляцию classloader:
<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>
Ответ №1:
На самом деле, реализация EL должна предоставляться самим контейнером. Конфликт путей к классам приведет только к ошибкам определения класса / метода, таким как LinkageError
, NoClassDefFoundError
, AbstractMethodError
и т.д. Здесь это не так, но это действительно очень похоже на ошибку в EL-реализации Weblogic. Поскольку я не использую WebLogic, я не могу проверить / подтвердить это.
Вместо этого вы могли бы попробовать использовать следующее выражение
#{messages == null || empty messages}
Или вы могли бы попытаться полностью заменить реализацию EL, например, на JBoss (которая позволяет передавать аргументы метода). Просто удалите jboss-el.jar в /WEB-INF/lib
и добавьте следующее к web.xml
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Комментарии:
1. Спасибо за ваш вклад! К сожалению, проблема сохраняется. Я также пытался использовать EL Resolver от sun, помещая
el-api-1.0.jar
иel-impl-1.0.jar
и используяcom.sun.el.ExpressionFactoryImpl
в качестве expressionFactory. Те же симптомы. На самом деле я подозреваю, что это вообще не оказывает никакого эффекта — попытаюсь отладить и посмотреть, действительно ли вызываются эти классы. В любом случае спасибо!2. Интересно. Как насчет альтернативного выражения EL
#{messages == null || empty messages}
?3. На самом деле, использование
#{messages == null || empty messages}
или даже просто#{messages == null}
вызывает ту же проблему… Я могу подтвердить, что изменения происходят (если я полностью удалю инструкцию, страница будет отображаться нормально). Странно.4. Что такое
#{messages}
? Это определяется<ui:param>
или чем-то еще? Я думаю, был бы полезен минимальный фрагмент представления (xhtml) и модели (управляемый компонент), который воспроизводит точную проблему.5. Я обновил вопрос, включив xhtml и java-файл. Это всего лишь очень простой пример для воспроизведения проблемы. Но
messages
предназначен для того, чтобы бытьArrayList<String>
помещенным в область сеанса (см. Файл управляемого компонента).
Ответ №2:
В конце концов, это проблема с загрузчиком классов. Я упаковал jar-файлы JSF 1.2 в папку WEB-INF / lib моего приложения:
jsf-api.jar
jsf-impl.jar
Weblogic 10.3.x имеет свою собственную реализацию, расположенную в MW_HOME/wlserver/common/deployable-libraries/jsf-1.2.war
(и версию 2.0 в jsf-2.0.war
). Я заменил вышеупомянутые jar в моем собственном веб-приложении следующими jar из 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
Мне также пришлось удалить все пакеты в prefer-application-packages
элементе в 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>
-->
После этого страница отобразилась корректно. (Это действительно вызывало другие проблемы, такие как ViewExpiredException
на каждой странице, но это другая проблема, я думаю …)