【问题标题】:javax.el.PropertyNotFoundException Target Unreachable, identifier 'xxxController' resolved to nulljavax.el.PropertyNotFoundException 目标无法到达,标识符“xxxController”解析为空
【发布时间】:2014-03-13 16:19:21
【问题描述】:

我正在使用 @ManagedBean 并尝试更改为 CDI @Named,因为前者将被弃用。

当我将其中一个控制器类更改为使用 CDI 时,我遇到了异常,说控制器被解析为 null。

我已经在谷歌上搜索了很多关于这个问题的帖子,尽可能多地阅读,但是,到目前为止似乎没有什么可以帮助我,请就我的情况提出建议。 (也尝试删除 lib/javax.inject-1.jar 作为建议的帖子之一,但没有运气。)

  1. 我在 NB 7.4 中启动了 GF4。
  2. 部署我的应用程序没有任何错误。
  3. 访问页面没有错误,除了所有变量文本都是空白的,因为它们是在控制器中设置并使用 value="#{xxxController.someText}" 加载的。
  4. 我单击提交按钮,控制台日志中弹出空控制器错误,因为输入变量是使用 value="#{userController.user.username}" 之类的表达式设置的。

环境:

NetBeans 7.4
Glassfish 4
JDK 1.7

pom:

 <dependencies>

<!-- MySQL Connector -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.28</version>
  <scope>provided</scope>
</dependency>

<!-- Hibernate -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>4.2.8.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.2.8.Final</version>
</dependency>

<!-- JSF -->
<dependency>
  <groupId>org.glassfish</groupId>
  <artifactId>javax.faces</artifactId>
  <version>2.2.5</version>
</dependency>

<!-- JSTL -->
<dependency>
  <groupId>jstl</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>

<!-- PrimeFaces -->
<dependency>
  <groupId>org.primefaces</groupId>
  <artifactId>primefaces</artifactId>
  <version>4.0</version>
</dependency>
<dependency>
  <groupId>org.primefaces.themes</groupId>
  <artifactId>all-themes</artifactId>
  <version>1.0.10</version>
</dependency>

<!-- Security -->
<dependency>
  <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
  <version>1.2.3</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
  <version>1.2.3</version>
</dependency>

<!-- Commons -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.2.1</version>
</dependency>
<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.1.3</version>
</dependency>

<!-- CDI -->
<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.1</version>
</dependency>

<!-- Logger -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.6</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.0-rc1</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.0-rc1</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j-impl</artifactId>
  <version>2.0-rc1</version>
</dependency>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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-app_3_0.xsd" 
version="3.0">

beans.xml:

<?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>

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
</faces-config>

控制器类如下所示:

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class UserController implements Serializable {

xhtml 调用 bean:

<h:outputText value="Username: " />
  <p:inputText value="#{userController.user.username}">
</p:inputText>

maven 文件夹结构后跟:

WEB-INF
--beans.xml
--faces-config.xml
--glassfish-web.xml
--web.xml

2014 年 3 月 14 日: 发现使用 CDI 时从未调用过控制器的构造函数。使用@ManagedBean 完全没有问题。

【问题讨论】:

  • 请发布您的 faces-config.xml 文件的内容。
  • 已添加,感谢您的快速提醒。
  • 发现控制器的构造函数在使用 CDI 时从未调用过。使用@ManagedBean 时完全没有问题。
  • 不要使用构造函数将业务逻​​辑放置在您的 bean 中。在 public void 方法上改用 @PostConstruct
  • 我确实使用了@PostConstruct,但由于没有任何效果,所以我在构造函数和 postConstruct 中都添加了日志记录,这就是我发现构造函数从未在 CDI 下调用过的原因。

标签: maven jsf cdi jsf-2.2 glassfish-4


【解决方案1】:

您是类路径污染的受害者,并且对针对非 Java EE 容器(例如 Tomcat)的在线教程/示例感到困惑。 GlassFish 是一个真正的 Java EE 容器,它已经捆绑了其他 JSF 和 CDI 开箱即用,但是您的 pom.xml 指示 Maven 将其他容器与 webapp 捆绑在一起,这仅在非 Java EE 容器(例如 Tomcat)上是必需的:

<!-- JSF -->
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.2.5</version>
</dependency>

<!-- CDI -->
<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.1</version>
</dependency>

这是不对的。这最终会在运行时类路径中出现重复的 JSF 和 CDI 库,它们只会相互冲突,并且会导致您的问题成为后果之一。

您需要将它们标记为&lt;scope&gt;provided&lt;/scope&gt;,这应该告诉 Maven 目标环境(在您的情况下:GlassFish)已经将它们捆绑在一起,因此 Maven 不会将它们捆绑在 WAR 中。

<!-- JSF -->
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.2.5</version>
    <scope>provided</scope>
</dependency>

<!-- CDI -->
<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.1</version>
    <scope>provided</scope>
</dependency>

顺便说一句,同样的问题也适用于该 JSTL 依赖项,但这超出了问题的范围。

另一种方法是将它们全部删除(JSF、CDI 和 JSTL),只指定完整提供的 Java EE Web 配置文件依赖项(其中还包括另一个 Java EE 很棒,例如 EJB 和 JPA)。

<!-- Java EE 7 web profile -->
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

这样您就不需要将每个已经捆绑的 Java EE 工件单独声明为编译时依赖项。

【讨论】:

    【解决方案2】:

    听起来您的“用户”对象未正确实例化。在控制器类的 GET 方法中试试这个:

    public User getUser() {
       if (user == null) {
          user = new User();
       }
       return user;
    } 
    

    希望这可以帮助您,如果没有,请为“用户”发布您的实体和 DAO 类。

    【讨论】:

    • 发现控制器的构造函数在使用 CDI 时从未调用过。使用@ManagedBean 时完全没有问题。
    • 吸气剂应该尽可能干净。您应该避免在托管 bean 中包含任何逻辑。如果您需要初始化任何变量,请改用@PostConstruct 方法。
    猜你喜欢
    • 1970-01-01
    • 2014-02-10
    • 2015-05-18
    • 2022-12-12
    • 2016-03-09
    • 2012-02-22
    • 2014-06-12
    • 1970-01-01
    • 2013-09-26
    相关资源
    最近更新 更多