[jsf] javax.el.PropertyNotFoundException 식별 및 해결 : 도달 할 수없는 대상

EL에서 관리 Bean을 참조하려고 할 때 #{bean.entity.property}가끔 javax.el.PropertyNotFoundException: Target UnreachableBean 특성이 설정되거나 Bean 조치가 호출 될 때 예외가 발생합니다.

다섯 가지 종류의 메시지가있는 것 같습니다.

  1. 연결할 수없는 대상, ID ‘bean’이 널로 분석되었습니다.
  2. 연결할 수없는 대상입니다. ‘entity’가 널을 리턴했습니다.
  3. 연결할 수없는 대상입니다. ‘null’이 null을 반환했습니다.
  4. 연결할 수없는 대상, ”0 ”이 (가) null을 반환 함
  5. 연결할 수없는 대상입니다. ‘BracketSuffix’가 널을 리턴했습니다.

그들은 무엇을 의미합니까? 그것들은 어떻게 발생하며 어떻게 해결되어야합니까?



답변

1. 연결할 수없는 대상, 식별자 ‘bean’이 null로 확인되었습니다.

이것은 관리 Bean 인스턴스 자체를 EL의 해당 식별자 (관리 Bean 이름)로 찾을 수 없다는 것으로 요약됩니다. #{bean} .

원인을 식별하는 것은 세 단계로 나눌 수 있습니다.

ㅏ. 누가 콩을 관리하고 있습니까?
비. (기본) 관리 Bean 이름은 무엇입니까?
씨. 백킹 빈 클래스는 어디에 있습니까?

1a. 누가 콩을 관리하고 있습니까?

첫 번째 단계는 Bean 인스턴스 관리를 담당하는 Bean 관리 프레임 워크를 확인하는 것입니다. 그것은인가 JSF 를 통해 @ManagedBean? 아니면은 CDI 를 통해 @Named? 아니면 봄을 통해 @Component입니까? 동일한 백킹 Bean 클래스에서 여러 Bean 관리 프레임 워크 특정 어노테이션을 혼합하지 않도록 할 수 있습니까? 예 : @Named @Component또는 @Named @ManagedBean, 또는 @ManagedBean @Component. 이것은 잘못이다. Bean은 최대 하나의 Bean 관리 프레임 워크에서 관리해야하며 해당 프레임 워크가 올바르게 구성되어 있어야합니다. 어떤 것을 선택 해야할지 모르는 경우 Backing Beans (@ManagedBean) 또는 CDI Beans (@Named)로 이동하십시오. 봄 JSF 통합 : JSF는 빈 관리에 어떻게 봄의 구성 요소 / 서비스를 주입하는 방법?

를 통해 Bean을 관리하는 JSF 인 경우 @ManagedBean다음을 확인해야합니다.

  • faces-config.xml루트 선언은 JSF 2.0과 호환됩니다. 따라서 XSD 파일과 version필수 는 적어도 JSF 2.0 이상을 지정 해야 하므로 1.x가 아닙니다.

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

    JSF 2.1의 경우, 바로 교체 2_02.0의하여 2_12.1 각각.

    JSF 2.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">

    JSF 2.3의 경우, 바로 교체 2_22.22_32.3각각.

  • 실수로 javax.annotation.ManagedBean대신 수입하지 않았습니다javax.faces.bean.ManagedBean . IDE 자동 완성 기능을 살펴보면 Eclipse는 목록의 첫 번째 항목으로 잘못된 항목을 자동 제안합니다.

  • 다른 관리 Bean 이름과 함께 매우 동일한 지원 Bean 클래스 에서 @ManagedBeanJSF 1.x 스타일 <managed-bean>항목을 대체하지 않았습니다 faces-config.xml. 이것보다 우선합니다 @ManagedBean. faces-config.xmlJSF 2.0부터 관리 Bean을 등록 할 필요가 없습니다. 제거하십시오.
  • 런타임 클래스 경로는 깨끗하고 JSF API 관련 JAR에서 중복되지 않습니다. 여러 JSF 구현 (Mojarra 및 MyFaces)을 혼합하지 않아야합니다. 대상 컨테이너가 이미 상자에 JSF API를 번들로 제공하는 경우 webapp와 함께 다른 JSF 또는 Java EE API JAR 파일을 제공하지 않아야합니다. JSF 위키 페이지의 “JSF 설치”섹션 도 참조 하십시오. JSF 설치 지침을. 컨테이너 자체가 아닌 WAR에서 컨테이너 번들 JSF를 업그레이드하려는 경우 대상 컨테이너에 WAR 번들 JSF API / impl을 사용하도록 지시했는지 확인하십시오.
  • JAR에 JSF 관리 Bean을 패키징하는 경우 JAR에 적어도 JSF 2.0 호환이 있는지 확인하십시오 /META-INF/faces-config.xml. JAR 파일로 제공되는 JSF 관리 Bean을 참조하는 방법참조하십시오.
  • 이 경우 실제로 쥬라기 JSF 1.x에서를 사용하여, 당신은 업그레이드 할 수 없습니다, 당신은을 통해 빈을 등록해야합니다 <managed-bean>으로 faces-config.xml대신 @ManagedBean. JSF 2.x 라이브러리가 더 이상 없으므로 @ManagedBean주석이 혼란스럽게 컴파일되지 않도록 프로젝트 빌드 경로를 수정하는 것을 잊지 마십시오 .


를 통해 Bean을 관리하는 CDI 인 경우 @Named다음을 확인해야합니다.

  • /WEB-INF/beans.xmlWAR에서 CDI를 사용 하려면 CDI 1.0 (Java EE 6)에 파일이 필요합니다 . 그것은 할 수 비우 아니면 그냥 다음과 같은 내용을 가질 수 있습니다 :

    <?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>
  • CDI 1.1 (자바 EE 7) 어떤없이 beans.xml, 또는 빈 beans.xml파일, 또는 호환 CDI 1.0 위의와 beans.xmlCDI 1.0과 동일하게 동작합니다. CDI 1.1 호환있을 때 beans.xml명시 적으로 version="1.1", 그것은 기본적으로 만 등록합니다 @Named 같은 명시 적 CDI 범위 주석 @RequestScoped, @ViewScoped, @SessionScoped, @ApplicationScoped, 등의 경우 당신은 심지어 명시하지 않고, CDI는 콩을 관리하는 모든 콩을 등록하려는 CDI 범위는 아래의 CDI 1.1과 호환 /WEB-INF/beans.xml되는 bean-discovery-mode="all"set을 사용하십시오 (기본값은 bean-discovery-mode="annotated").

    <?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>
  • CDI 1.1+를 bean-discovery-mode="annotated"(기본값) 과 함께 사용 하는 경우 실수 javax.faces.bean.RequestScoped로 CDI scope 대신 과 같은 JSF 범위를 가져 오지 않았는지 확인하십시오 javax.enterprise.context.RequestScoped. IDE 자동 완성으로 조심하십시오.

  • Mojarra 2.3.0-2.3.2 및 CDI 1.1+ bean-discovery-mode="annotated"(기본값)를 사용하는 경우 버그 로 인해 Mojarra를 2.3.3 이상으로 업그레이드해야합니다 . 경우 당신은 다음 세트 중 하나를 필요로 업그레이드 할 수 없습니다 bean-discovery-mode="all"beans.xml, 또는 JSF 2.3 특정에 넣어 @FacesConfig(일반적으로 응용 프로그램의 일종이 시작 클래스를 범위) 전쟁에서 임의의 클래스에 주석을.
  • Tomcat 및 Jetty와 같은 Java 이외의 EE 컨테이너는 CDI 번들과 함께 제공되지 않습니다. 수동으로 설치해야합니다. 라이브러리 JAR을 추가하는 것보다 약간 더 많은 작업입니다. Tomcat의 경우이 답변의 지침을 따르십시오 . Tomcat에서 CDI를 설치하고 사용하는 방법은 무엇입니까?
  • 런타임 클래스 경로가 깨끗하고 CDI API 관련 JAR에서 중복되지 않습니다. 여러 CDI 구현 (Weld, OpenWebBeans 등)을 혼합하지 않아야합니다. 대상 컨테이너가 이미 상자에 CDI API를 번들로 제공하는 경우 webapp와 함께 다른 CDI 또는 Java EE API JAR 파일을 제공하지 않아야합니다.
  • JAR에서 JSF보기 용 CDI 관리 Bean을 패키징하는 경우 JAR에 최소한 유효한 /META-INF/beans.xml(비어있을 수있는) 것이 있는지 확인하십시오 .


를 통해 bean을 관리하는 Spring 의 경우 @Component다음을 확인해야합니다.

  • 스프링은 문서에 따라 설치 및 통합되고있다 . 중요한 것은 최소한 다음에 있어야합니다 web.xml.

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    그리고 이것은 faces-config.xml:

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
  • (위의 내용은 Spring과 관련하여 알고있는 것입니다. Spring을하지 않습니다. 다른 가능한 Spring 관련 원인으로 편집 / 코멘트를 작성하십시오 (예 : 일부 XML 구성 관련 문제)


경우는 A의 리피터 구성 요소 의를 통해 (중첩) 빈을 관리하는 것 var(예를 들어, 속성 <h:dataTable var="item">, <ui:repeat var="item">, <p:tabView var="item">, 등) 당신이 실제로있어 “대상에 연결할 수는 식별자 ‘항목에’null로 해결”, 당신은 다음의 확인 필요 :

  • #{item}에서 참조되지 않은 binding하위 구성 요소의 attribtue. binding뷰 렌더링 시간이 아닌 뷰 빌드 시간 동안 속성이 실행되므로 올바르지 않습니다 . 또한 구성 요소 트리에는 물리적으로 하나의 구성 요소 만 있습니다.이 구성 요소는 모든 반복 라운드 동안 재사용됩니다. 즉, 실제로 binding="#{bean.component}"대신 사용해야합니다 binding="#{item.component}". 그러나 훨씬 더 나은 방법은 컴포넌트 빈을 빈으로 제거하고이 방법으로 해결하려고 생각한 문제에 대한 적절한 접근법을 조사 / 조회하는 것입니다. JSF에서 ‘바인딩’속성어떻게 작동합니까?를 참조하십시오 . 언제 어떻게 사용해야합니까?


1b. (기본) 관리 Bean 이름은 무엇입니까?

두 번째 단계는 등록 된 관리 Bean 이름을 확인하는 것입니다. JSF 및 Spring 사용 규칙은 JavaBeans 스펙 을 준수 하지만 CDI에는 CDI impl / version에 따라 예외가 있습니다.

  • FooBean다음과 같은 백업 빈 클래스,

    @Named
    public class FooBean {}

    모든 Bean 관리 프레임 워크에서 #{fooBean}JavaBeans 스펙에 따라 기본 관리 Bean 이름은 입니다.

  • FOOBean다음과 같은 백업 빈 클래스,

    @Named
    public class FOOBean {}

    정규화되지 않은 클래스 이름은 JSF에서 두 개 이상의 대문자로 시작하고 Spring은 기본적으로 규정되지 않은 클래스 이름의 기본 관리 Bean 이름을 가지며 #{FOOBean}JavaBeans 지정도 준수합니다. CDI의 경우 2015 년 6 월 이전에 릴리스 된 용접 버전에서도 마찬가지이지만 2015 년 6 월 이후에 릴리스 된 용접 버전 (2.2.14 / 2.3.0.B1 / 3.0.0.A9) 또는 OpenWebBeans 에서는 감시 기능이 적용 되지 않습니다 . CDI 사양 . 이 용접 버전과 모든 OWB 버전에서는 첫 문자 만 소문자로 표시 #{fOOBean}됩니다.

  • foo아래와 같이 관리 Bean 이름을 명시 적으로 지정한 경우 ,

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

    또는 동등으로 @ManagedBean(name="foo")또는 @Component("foo"), 그것은 단지로 사용할 수 #{foo}있으므로 하지 에 의해 #{fooBean}.


1c. 백킹 빈 클래스는 어디에 있습니까?

세 번째 단계는 백업 Bean 클래스가 빌드 및 배치 된 WAR 파일의 올바른 위치에 있는지 다시 확인하는 것입니다. 실제로 코드를 작성하고 브라우저에서 F5 키를 누를 때 실제로 프로젝트와 서버를 완전히 정리, 재 구축, 재배치 및 다시 시작해야합니다. 여전히 헛된 경우 빌드 시스템에서 WAR 파일을 생성 한 다음 ZIP 도구로 추출하고 검사하십시오. .class지원 Bean 클래스 의 컴파일 된 파일은의 패키지 구조에 있어야합니다 /WEB-INF/classes. 또는 JAR 모듈의 일부로 패키지 될 때 컴파일 된 .class파일을 포함하는 JAR은 /WEB-INF/libEAR /lib또는 다른 곳에 없어야합니다 .

Eclipse를 사용하는 경우 지원 Bean 클래스가 포함 src되어 있지 WebContent 않은지 확인하고 프로젝트> 자동 빌드 가 사용 가능한지 확인하십시오 . 당신은 메이븐을 사용하는 경우 백업 빈 클래스에 있는지 확인 src/main/java하여 및 하지 에서 src/main/resourcessrc/main/webapp.

EJB + WAR을 사용하여 EAR의 일부로 웹 애플리케이션을 패키징하는 경우, 지원 Bean 클래스가 WAR 모듈에 있고 EAR 모듈 또는 EJB 모듈에 없는지 확인해야합니다. 비즈니스 계층 (EJB)에는 웹 계층 (WAR) 관련 아티팩트가 없어야 비즈니스 계층이 여러 다른 웹 계층 (JSF, JAX-RS, JSP / Servlet 등)에서 재사용 될 수 있습니다.


2. Target Unreachable, ‘entity’가 null을 반환했습니다.

이것은 반환 entity 것과 같이 중첩 된 속성 으로 요약됩니다 . 이것은 일반적으로 JSF가 아래와 같이 입력 구성 요소 를 통해 값 을 설정 해야 할 때만 노출 되지만 실제로는 반환 됩니다.#{bean.entity.property}nullproperty#{bean.entity}null

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

CRUD 목록 및 / 또는 대화 상자를 동일한 뷰에서 작업하는 경우 사전에 @PostConstruct, 또는 <f:viewAction>메소드 또는 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; CDI와 같은 프록시 를 사용하는 Bean 관리 프레임 워크를 사용하는 경우 일반 생성자에서이를 수행하면 실패 합니다. 항상 @PostConstruct관리 Bean 인스턴스 초기화 @PreDestroy에 연결하고 관리 Bean 인스턴스 삭제에 연결 하는 데 사용하십시오 . 또한 생성자에서는 아직 주입 된 종속성에 액세스 할 수 없으므로 constructor의 @Inject bean에 액세스하는 동안 NullPointerException 도 참조하십시오 .

이 경우 entityId를 통해 공급되고 <f:viewParam>, 당신은 사용해야하는 것 <f:viewAction>대신에 @PostConstruct. f : viewAction / preRenderView와 PostConstruct를 언제 사용해야합니까?를 참조하십시오 .

또한 조치 메소드 null에서만 작성하는 경우 포스트 백 중에 비 모델 을 유지해야합니다 add(). Bean을 뷰 범위에 두는 것이 가장 쉽습니다. 올바른 Bean 범위를 선택하는 방법 도 참조하십시오 .


3. 대상에 연결할 수 없음, ‘널’이 널을 리턴 함

이것은 실제로 # 2와 같은 원인을 가지고 있으며, 사용되는 (구) EL 구현 만이 예외 메시지에 표시되도록 속성 이름을 보존하는 데 다소 버그가 있습니다. 결국 ‘null’로 잘못 노출됩니다. 이렇게하면 중첩 된 속성이있을 때 디버깅 및 수정이 조금 더 어려워집니다 #{bean.entity.subentity.subsubentity.property}.

해결책은 여전히 ​​동일합니다. 문제의 중첩 된 엔티티 null가 모든 레벨 에서 아닌지 확인하십시오 .


4. 대상에 연결할 수 없음, ”0 ”이 (가) null을 반환 함

이것은 또한 # 2와 같은 원인이 있으며, 사용되는 (구) EL 구현 만이 예외 메시지를 공식화하는 데 버그가 있습니다. 이것은 []EL 자체에서 널이 아닌 #{bean.collection[index]}곳과 같이 중괄호 표기법을 사용할 때만 노출 #{bean.collection}되지만 지정된 색인에 항목이 존재하지 않습니다. 그런 메시지는 다음과 같이 해석되어야합니다.

연결할 수없는 대상, ‘collection [0]’이 (가) null을 반환했습니다.

솔루션은 # 2와 동일합니다. 수집 항목을 사용할 수 있는지 확인하십시오.


5. 대상에 연결할 수 없음, ‘BracketSuffix’가 널을 리턴 함

이것은 실제로 # 4와 동일한 원인을 가지며, 사용되는 (이전) EL 구현 만이 예외 메시지에 표시하기 위해 반복 인덱스를 보존하는 데 다소 버그가 있습니다. 실제로는 실제로 문자 인 ‘BracketSuffix’로 잘못 노출됩니다 ]. 이렇게하면 컬렉션에 여러 항목이있을 때 디버깅 및 수정이 조금 더 어려워집니다.


다른 가능한 원인 javax.el.PropertyNotFoundException:


답변

여전히 붙어있는 사람들을 위해 …

CDI와 함께 NetBeans 8.1 및 GlassFish 4.1을 사용하면 어떤 이유로 든 원격 서버가 아닌 로컬에서만이 문제가 발생했습니다. 트릭은 무엇입니까?

NetBeans에서 제공하는 기본 pom 버전 대신 javaee-web-api 7.0 (javaee-web-api 6.0)을 사용합니다.

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
    <type>jar</type>
</dependency>

->이 javaee-web-api-7.0.jar을 서버 (lib1 폴더의 lib 폴더)에 lib로 업로드하고 서버를 다시 시작하십시오.


답변

이 오류를 직접 해결 한 후이 오류에 대한 결과를 공유하기로 결정했습니다.

우선 BalusC 솔루션을 신중하게 고려해야하지만 Netbeans에는 특히 Maven을 사용하여 EAR (Enterprise Application Project) 을 구축 할 때 알아야 할 또 다른 문제가 있습니다 .

Netbeans는 상위 POM 파일 , EAR 프로젝트 , EJB 프로젝트WAR 프로젝트를 생성 합니다. 내 프로젝트의 다른 모든 것이 좋았으며 GlassFish 4.1에는 GlassFish 4.0에 버그가 있다고 생각했습니다 (GlassFish 4.1에는 Netbeans 8.0에 포함 된 GlassFish 4.1을 만드는 Weld CDI 버그가 있기 때문에 아마도 GlassFish 4.0 (Netbeans에 설치하고 연결해야 함) 일 것입니다. 2 패치를 제외하고는 사용할 수 없습니다.

해결책:

결의하려면 “대상에 연결할 수 없음을, 식별자 ‘콩’null로 해결”
오류 –

상위 POM 프로젝트를 마우스 오른쪽 단추로 클릭하고 특성을 선택하십시오 . 프로젝트 속성 대화 상자가 나타나면 “소스”를 클릭하면 ” 소스 / 바이너리 형식 “이 1.5로 설정되고 ” 인코딩 “이 Windows 1250으로 설정되어 표시됩니다. ” 소스 / 바이너리 형식 “을 1.6 0r 1.7로 변경하십시오. 프로젝트 CDI를 준수 하고 UTF-8을 ” 인코딩 ” 하는 것을 선호합니다 .

다른 하위 프로젝트 (EAR, EJB, WAR)가 아직 호환되지 않는 경우 동일한 작업을 수행하십시오. 프로젝트를 실행하면 해당 오류가 다시 발생하지 않습니다.

나는 이것이 비슷한 오류가있는 누군가를 돕기를 바랍니다.


답변

여기에 제공된 많은 답변이 도움이되었지만 여전히이 문제가 있었기 때문에 솔루션을 공유하기로 결정했습니다. 필자의 경우 새 프로젝트에 JSF 2.3, jdk10, jee8, cdi 2.0을 사용하고 wildfly 웹 사이트에서 권장하는대로 standalone.sh -Dee8.preview.mode = true 매개 변수로 서버를 시작하여 wildfly 12에서 앱을 실행했습니다. . wildfly 13을 다운로드 한 후 “bean resolved to null”문제가 사라졌습니다. wildfly 13에 정확히 같은 전쟁을 업로드하면 모든 것이 제대로 작동했습니다.


답변

클래스가 @SpringBootApplication컨트롤러의 패키지 이름을 지정하는 것을 잊어 버렸기 때문에이 오류가 발생했습니다 .

이번에는 기본 패키지를 구성하는 대신 Spring이 스캔 해야하는 구성 요소를 지적하면서 더 구체적으로하고 싶었습니다.

다음과 같았습니다 :

@ComponentScan(basePackages = {"br.com.company.project.repository", "br.com.company.project.service"})

그러나 올바른 형식은 다음 중 하나입니다.

@ComponentScan(basePackages = {"br.com.company.project.repository", "br.com.company.project.service", "br.com.company.project.controller"})

@ComponentScan(basePackages = {"br.com.company.project")

정답은 매우 포괄적이지만이 (이디 오) 실수를 다루지 않기 때문에 솔루션을 공유하기로 결정했습니다. 🙂


답변

필자의 경우 @Named ( “beanName”)에서 철자 실수를 저지른 경우 “beanName”이라고 가정했지만 “beanNam”을 작성했습니다.


답변

javaee container에 wildfly 10을 사용하고 있습니다. “Target Unreachable, ‘entity’return null”문제가 발생했습니다. BalusC의 제안에 감사하지만 솔루션의 제 문제는 설명했습니다. 실수로 “import com.sun.istack.logging.Logger;” “import org.jboss.logging.Logger;”대신 CDI가 JSF EL을 구현하게했습니다. 그것이 솔루션을 개선하는 데 도움이되기를 바랍니다.