为什么JSF 2.0 RI(Mojarra)没有扫描我的班级注释?

DWo*_*ich 13 jsf annotations jsf-2

我在基于Eclipse的JSF项目中有一个War and Jar项目.我已经决定使用注释来声明我的FacesConverter(在众多其他事物中),而不是使用我的faces-config.xml声明它.

@FacesConverter(value="passwordFieldStringConverter")
public class PasswordFieldStringConverter implements Converter {

 public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) throws ConverterException {
  try {
   return arg2.getBytes("UTF-16BE");
  }
  catch(UnsupportedEncodingException uee) {
   Assert.impossibleException(uee);
  }

  return(null);
 }

 public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) throws ConverterException {
  try {
   return new String((byte[]) arg2, "UTF-16BE");
  }
  catch(UnsupportedEncodingException uee) {
   Assert.impossibleException(uee);
  }

  return(null);  
 }

}
Run Code Online (Sandbox Code Playgroud)

然后我直接在我的.xhtml中使用passwordFieldStringConverter:

<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:sec="http://www.springframework.org/security/facelets/tags">
 <ui:composition>
  <f:view>
      <f:loadBundle basename="landingPage.bundle" var="bundle" /> 

   <ui:decorate template="/WEB-INF/jsf_helpers/htmlShell.xhtml">
    <ui:param name="PageTitleParam" value="#{bundle.pageTitle}" />

    <h:form>
      <h:dataTable var="rowVar" value="#{userListContainer.users}">
       <f:facet name="header"><h:outputText value="Users you are currently managing:" /></f:facet>
       <h:column>
        <f:facet name="header">
         <h:outputText value="Screen Name" />
        </f:facet>
        <h:outputText value="#{rowVar.screenName}" />
    </h:column>
       <h:column>
        <f:facet name="header">
         <h:outputText value="Password" />
        </f:facet>
        <h:outputText value="#{rowVar.password}">
         <f:converter converterId="passwordFieldStringConverter" />
        </h:outputText>
       </h:column>
      </h:dataTable>
    </h:form>
   </ui:decorate>
  </f:view>
 </ui:composition>
</html>
Run Code Online (Sandbox Code Playgroud)

JSF应该在部署时扫描我的战争中的jar并检测哪些类具有注释(并相应地自动配置应用程序).我的问题是JSF显然没有检测到我所拥有的带有注释的类.

War项目包含我的所有.xhtml文件以及项目的faces-config.xml,我的Jar项目有我所有的面孔相关的Java代码(动作bean,托管bean,自定义转换器等)

DWo*_*ich 29

是的,我现在正在回答我自己的问题,因为我已经花了一个星期的时间在桌子上敲我的头,我只是在通过JSF 2.0 RI(Mojarra)调试之后才发现我的问题,看看它在做什么.

基本上,注释扫描程序仅查询WAR的/ WEB-INF/classes .class文件以进行注释(假设您在/ WEB-INF中有faces-config.xml).如果将代码保存在单独的Jar文件中,并希望扫描/ WEB-INF/lib .jar文件中的.class文件以进行注释,则必须在Jar的META-INF文件夹中有faces-config.xml.你插入罐子里的faces-config.xml可能是空的,它只需要在那里,否则注释扫描器就会像你的剩余肉饼那样过去你的罐子.

空faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee /WEB-INF/schema/web-facesconfig_2_0.xsd" 
              version="2.0" metadata-complete="false">
    <!-- This file must be present with our jar, even if it is empty.  Otherwise, our Java annotations won't get scanned! -->
</faces-config>
Run Code Online (Sandbox Code Playgroud)

我知道在那里抛出了很多-INF.所以,回顾一下.你战争中的faces-config.xml在WEB-INF中.您的每个Jar文件中可能为空的注释扫描器启用faces-config.xml都在Jar的META -INF中.

如果你想知道为什么这种行为必须如此坚定,那是因为JSF配置可以通过这种方式分散和分散在第一方和第三方库中.如果你想知道jar中的faces-config.xml的整体存在是一个因素,那么,我的意见是,这标志着Jar对引擎很有趣 - 并且没有faces-config .xml表示注释扫描程序可以避免该jar并在部署节省处理.如果那些扫描仪语义在某处更清楚地解释,那就好了,<expletives deleted>!

以下博客文章对我理解代码的作用非常有用:

http://one-size-doesnt-fit-all.blogspot.com/2007/01/using-multiple-faces-configxml-files-in.html

我真的希望这可以拯救像我一样痛苦一周的人.


And*_*dis 5

JAR 包含 EJB 和 FacesBean:

如果包含 Faces Beans 的 JAR 已经捆绑在一个 Ear 中(因为它包含 EJB),那么您还必须将相同的 JAR 放在 war 的 WEB-INF/lib 中(在添加面的基础上) config.xml 在 META-INF 目录中),以便容器识别 JSF 2.0 Annotations。

在这种情况下,最好创建两个 JARS,一个用于 EJB,一个用于 FacesBean。