当前位置: 首页 > 知识库问答 >
问题:

识别和解决javax.el.PropertyNotFoundException:目标不可达

卢普松
2023-03-14
  1. 目标不可达,标识符'bean'解析为null
  2. 目标不可达,'Entity'返回null
  3. 目标不可达,'null'返回null
  4. 目标无法到达,“0”返回null
  5. 目标不可达,'bracketsuffix'返回null

它们都是什么意思?它们是如何造成的,应该如何解决?

共有1个答案

奚无尘
2023-03-14
  <?xml version="1.0" encoding="UTF-8"?>
  <beans 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
                             http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
  </beans>
  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                             http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
         version="1.1" bean-discovery-mode="all">
  </beans>

当使用Mojarra 2.3.0-2.3.2和CDI 1.1+以及bean-discovery-mode=“annotated”(默认)时,由于存在bug,需要将Mojarra升级到2.3.3或更高版本。如果无法升级,则需要在beans.xml中设置bean-discovery-mode=“all”,或者将JSF2.3特定的@facesconfig注释放在WAR中的任意类(通常是应用程序范围内的启动类)上。

当在Servlet 4.0容器上使用JSF2.3时,您需要将JSF2.3特定的web.xml注释显式地放在WAR中的任意类上(通常是某种应用程序范围内的启动类)。在Servlet3.x中不需要这样做。

当使用CDI 3.0(包从javax.*重命名为jakarta.*的第一个版本)时,您需要确保所有部署描述符文件beans.xmlweb.xmlfaces-config.xml符合新的jakartaee模式,因此不符合旧的javaee模式。

  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee 
                             https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
         version="3.0" bean-discovery-mode="all">
  </beans>

像Tomcat和Jetty这样的非JEE容器并不捆绑CDI。您需要手动安装。这比仅仅添加库JAR要多一点工作。对于Tomcat,请确保遵循以下答案中的说明:如何在Tomcat上安装和使用CDI?

您的运行时类路径是干净的,没有CDI API相关JAR中的重复项。确保您没有混合多个CDI实现(Weld、OpenWebBeans等)。当目标容器已经打包了CDI API时,请确保不要在webapp上提供另一个CDI甚至Java EE API JAR文件。

如果您将JSF视图的CDI托管bean打包在JAR中,那么请确保JAR至少有一个有效的/meta-inf/beans.xml(可以保持为空)。

  <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 http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
      version="2.0">

对于JSF2.1,只需将2_02.0分别替换为2_12.1

如果您使用的是JSF2.2或更高版本,那么请确保在所有地方都使用xmlns.jcp.org命名空间,而不是java.sun.com

  <faces-config
      xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
      version="2.2">

对于JSF2.3,只需将2222.2分别替换为232.3

您没有通过faces-config.xml中的JSF1.x样式 条目以及不同的托管bean名称重写@managedbean。这个将优先于@managedbean。自从JSF2.0以来,在faces-config.xml中注册托管bean是不必要的,只需删除它即可。

您的运行时类路径是干净的,没有JSF API相关JAR中的重复项。确保您没有混合多个JSF实现(Mojarra和MyFaces)。当目标容器已经打包了JSF API时,请确保不要在webapp上提供另一个JSF甚至Java EE API JAR文件。另请参见JSF wiki页面的“安装JSF”一节,了解JSF安装说明。如果您打算从WAR中而不是在容器中升级容器绑定的JSF,请确保您已经指示目标容器使用WAR绑定的JSF API/Impl。

如果您将JSF托管bean打包在JAR中,那么请确保JAR至少有一个与JSF2.0兼容的/meta-inf/faces-config.xml。另请参见如何引用JAR文件中提供的JSF托管bean?

如果您实际使用的是jurassic JSF1.x,并且无法升级,那么您需要通过faces-config.xml中的 而不是 @managedbean注册bean。不要忘记修复您的项目构建路径,使您不再拥有JSF2.x库(以便 @managedbean注释不会令人困惑地成功编译)。

如果Spring通过@component管理bean,则需要确保以下内容:

>

  • Spring正在按照其文档安装和集成。重要的是,您至少需要在web.xml中包含以下内容:

      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    
      <application>
          <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
      </application>
    

    (以上是我对Spring的全部了解--我不了解Spring--请随时编辑/评论其他可能与Spring相关的原因;例如,一些与XML配置相关的问题)

    如果是repeater组件通过其var属性(例如 等)管理(嵌套)bean,而您实际上得到了一个“目标不可达,标识符'item'解析为null”,那么您需要确保以下内容:

    >

  • 在任何子组件的绑定属性中都没有引用#{item}。这是不正确的,因为binding属性在视图生成时运行,而不是在视图呈现时运行。而且,在组件树中物理上只有一个组件,在每一轮迭代中都简单地重用它。换句话说,您实际上应该使用binding=“#{bean.component}”而不是binding=“#{item.component}”。但是更好的办法是完全摆脱组件bining bean,并调查/询问您认为可以用这种方式解决的问题的适当方法。另请参阅'binding'属性在JSF中是如何工作的?何时使用,如何使用?

    第二步是检查注册的托管bean名称。JSF和Spring的使用约定符合JavaBeans规范,而CDI则因CDI impl/version而有异常。

    >

  • 如下所示的foobean支持bean类,

      @Named
      public class FooBean {}
    
      @Named
      public class FOOBean {}
    

    如果您像下面这样显式指定了托管bean名称foo

      @Named("foo")
      public class FooBean {}
    

    或者与@managedbean(name=“foo”)@component(“foo”)等效,那么它只能由#{foo}提供,因此不能由#{fooBean}提供。

    第三步是doublechecking,如果支持bean类位于构建和部署的WAR文件中的正确位置。确保您已经正确地执行了项目和服务器的完全清理、重建、重新部署和重新启动,以防您实际上忙于编写代码并不耐烦地在浏览器中按F5。如果仍然是徒劳的,让构建系统生成一个WAR文件,然后用ZIP工具提取并检查该文件。支持bean类的编译后的.class文件必须驻留在/WEB-INF/classes的包结构中。或者,当它作为JAR模块的一部分打包时,包含编译的.class文件的JAR必须驻留在/WEB-INF/lib中,因此不能驻留在例如EAR的/lib或其他地方。

    如果使用Eclipse,请确保支持bean类位于src中,因此不在WebContent中,并确保启用了Project>Build Automatic。如果使用Maven,请确保支持bean类位于src/main/java中,而不是位于src/main/resourcessrc/main/webapp中。

    如果您使用EJB+WAR将web应用程序打包为EAR的一部分,那么您需要确保支持bean类位于WAR模块中,而不是位于EAR模块或EJB模块中。业务层(EJB)必须没有任何与web层(WAR)相关的构件,以便业务层可以跨多个不同的web层(JSF、JAX-RS、JSP/Servlet等)重用。

    这可以归结为嵌套属性Entity#{bean.entity.property}返回null。这通常只在JSF需要通过如下所示的输入组件设置属性的值时才公开,而#{bean.entity}实际上返回null

    html prettyprint-override"><h:inputText value="#{bean.entity.property}" />
    

    您需要确保在@PostConstruct 方法中预先准备了模型实体,或者在使用相同视图上的CRUD列表和/或对话框的情况下使用add()操作方法。

    @Named
    @ViewScoped
    public class Bean {
    
        private Entity entity; // +getter (setter is not necessary).
    
        @Inject
        private EntityService entityService;
    
        @PostConstruct
        public void init() {
            // In case you're updating an existing entity.
            entity = entityService.getById(entityId);
    
            // Or in case you want to create a new entity.
            entity = new Entity();
        }
    
        // ...
    }
    

    关于@PostConstruct的重要性;如果您使用的bean管理框架使用代理,比如CDI,那么在常规构造函数中执行此操作将会失败。始终使用@postconstruct挂钩托管bean实例初始化(并使用@predestroy挂钩托管bean实例销毁)。此外,在构造函数中,您还不能访问任何注入的依赖项,请参见在构造函数中尝试访问@inject bean时的NullPointerException。

    如果EntityID是通过 提供的,则需要使用 而不是@PostConstruct。另请参见何时使用f:viewaction/preRenderView与postconstruct?

    您还需要确保在回发期间保留非null模型,以防只在add()操作方法中创建该模型。最简单的方法是将bean放到视图范围中。另见如何选择正确的bean作用域?

    这实际上与#2有相同的原因,只是使用的(旧的)EL实现在保留要显示在异常消息中的属性名方面有些缺陷,最终错误地公开为'null'。当您有一些嵌套属性时,这只会使调试和修复变得更加困难,比如#{bean.entity.subentity.subsubentity.property}

    解决方案仍然是一样的:确保所讨论的嵌套实体在所有级别中都不是null

    目标不可达,“集合[0]”返回null

    解决方案也与#2相同:确保集合项可用。

    这实际上与#4有相同的原因,只是使用的(旧的)EL实现在保留在异常消息中显示的迭代索引方面有些缺陷,最终错误地公开为“bracketsuffix”,实际上是]字符。当集合中有多个项时,这只会使调试和修复变得更加困难。

      null

  •  类似资料:
    • 我正在尝试将JSF2.2与Spring4和Spring Data JPA(Hibernate)集成。按下“保存”按钮时出现以下异常: Eclipse:Oxygen.3A释放版(4.7.3A) 在使用时,导入为: 在使用时,导入为: 在使用时,导入为: } pom.xml applicationContext.xml: xhtml:

    • 借助ML Kit的地标识别API,您可以识别图像中的一些广为人知的地标。 当您将图片传递给此API时,您会看到其中已识别的地标,以及每个地标的地理坐标和发现地标的图像区域。您可以使用此信息自动生成图像元数据,根据用户共享的内容为用户创建个性化体验等等。 iOS Android 核心功能 识别著名的地标 获取自然或者已建地标的名称和地理坐标以及地标所在图像的区域。试用 Cloud Vision AP

    • 我从 http://alchim31.free.fr/m2e-scala/update-site/ 安装了Maven Scala支持,并使用Eclipse市场安装了Scala IDE插件。我可以使用命令行和来构建项目。Eclipse很好地突出显示了 Scala 代码,如果我导入项目,它就能正确识别其 Scala 性质。但它不将 识别为源文件夹,也不会生成项目。 下面是我的<code>pom.xml

    • 我试图在项目中使用活动识别来检测用户何时“在车内”。(驾驶)问题是几乎不可能使用它,因为大多数可能的活动经常报告“车内”,即使我已经在办公桌前坐了很长时间,或者只是在家里走来走去。很高兴知道API是如何得出这一结论的。 我认为这个功能有很大的潜力,但现在有些东西显然不起作用。 这是一份每30秒进行一次的最有可能的活动日志,以显示我的意思。坐在办公桌前,4分钟后,我把电话转了几次,结果是“最有可能的

    • 我想将dir中的环境文件从本地计算机复制到远程计算机。 根据这个答案,我尝试了以下方法,但得到了一个错误: 编辑2:以下是工作原理

    • 我在webstorm中使用ES6风格的模块包含,我有一个express应用程序,它有一个自定义的d.ts(用于更改对象的中间件),类似于以下内容: (Express.d.ts extends应用程序中的Express,该应用程序包含其他文件中的增强项。) 所以我很困惑,为什么它在IDE中工作,而在TSC中却不工作,因为TSC包括一个键入目录中的所有*.d.ts文件,在D.ts文件中没有列出错误,只