jsfcdielmanaged-beanpropertynotfoundexception

Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable


When trying to reference a managed bean in EL like so #{bean.entity.property}, sometimes a javax.el.PropertyNotFoundException: Target Unreachable exception is being thrown, usually when a bean property is to be set, or when a bean action is to be invoked.

There seem to be five different kinds of messages:

  1. Target Unreachable, identifier 'bean' resolved to null
  2. Target Unreachable, 'entity' returned null
  3. Target Unreachable, 'null' returned null
  4. Target Unreachable, ''0'' returned null
  5. Target Unreachable, 'BracketSuffix' returned null

What do they all mean? How are they caused and how should they be solved?


Solution

  • 1. Target Unreachable, identifier 'bean' resolved to null

    This boils down to that the managed bean instance itself could not be found by exactly that identifier (managed bean name) in EL like so #{bean}.

    Identifying the cause can be broken down into three steps:

    a. Who's managing the bean?
    b. What's the (default) managed bean name?
    c. Where's the backing bean class?

    1a. Who's managing the bean?

    First step would be checking which bean management framework is responsible for managing the bean instance. Is it CDI via @Named? Or is it JSF via @ManagedBean? Or is it Spring via @Component? Can you make sure that you're not mixing multiple bean management framework specific annotations on the very same backing bean class? E.g. @Named @ManagedBean, @Named @Component, or @ManagedBean @Component. This is wrong. The bean must be managed by at most one bean management framework and that framework must be properly configured. If you already have no idea which to choose, head to Backing beans (@ManagedBean) or CDI Beans (@Named)? and Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

    In case it's CDI who's managing the bean via @Named, then you need to make sure of the following:

    In case it's JSF who's managing the bean via the since 2.3 deprecated @ManagedBean, and you can't migrate to CDI, then you need to make sure of the following:

    In case it's Spring who's managing the bean via @Component, then you need to make sure of the following:

    In case it's a repeater component who's managing the (nested) bean via its var attribute (e.g. <h:dataTable var="item">, <ui:repeat var="item">, <p:tabView var="item">, etc) and you actually got a "Target Unreachable, identifier 'item' resolved to null", then you need to make sure of the following:

    1b. What's the (default) managed bean name?

    Second step would be checking the registered managed bean name. JSF and Spring use conventions conform JavaBeans specification while CDI has exceptions depending on CDI impl/version.

    1c. Where's the backing bean class?

    Third step would be doublechecking if the backing bean class is at the right place in the built and deployed WAR file. Make sure that you've properly performed a full clean, rebuild, redeploy and restart of the project and server in case you was actually busy writing code and impatiently pressing F5 in the browser. If still in vain, let the build system produce a WAR file, which you then extract and inspect with a ZIP tool. The compiled .class file of the backing bean class must reside in its package structure in /WEB-INF/classes. Or, when it's packaged as part of a JAR module, the JAR containing the compiled .class file must reside in /WEB-INF/lib and thus not e.g. EAR's /lib or elsewhere.

    If you're using Eclipse, make sure that the backing bean class is in src and thus not WebContent, and make sure that Project > Build Automatically is enabled. If you're using Maven, make sure that the backing bean class is in src/main/java and thus not in src/main/resources or src/main/webapp.

    If you're packaging the web application as part of an EAR with EJB+WAR(s), then you need to make sure that the backing bean classes are in WAR module and thus not in EAR module nor EJB module. The business tier (EJB) must be free of any web tier (WAR) related artifacts, so that the business tier is reusable across multiple different web tiers (JSF, JAX-RS, JSP/Servlet, etc).


    2. Target Unreachable, 'entity' returned null

    This boils down to that the nested property entity as in #{bean.entity.property} returned null. This usually only exposes when JSF needs to set the value for property via an input component like below, while the #{bean.entity} actually returned null.

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

    You need to make sure that you have prepared the model entity beforehand in a @PostConstruct, or <f:viewAction> method, or perhaps an add() action method in case you're working with CRUD lists and/or dialogs on same view.

    @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();
        }
    
        // ...
    }
    

    As to the importance of @PostConstruct; doing this in a regular constructor would fail in case you're using a bean management framework which uses proxies, such as CDI. Always use @PostConstruct to hook on managed bean instance initialization (and use @PreDestroy to hook on managed bean instance destruction). Additionally, in a constructor you wouldn't have access to any injected dependencies yet, see also NullPointerException while trying to access @Inject bean in constructor.

    In case the entityId is supplied via <f:viewParam>, you'd need to use <f:viewAction> instead of @PostConstruct. See also When to use f:viewAction / preRenderView versus PostConstruct?

    You also need to make sure that you preserve the non-null model during postbacks in case you're creating it only in an add() action method. Easiest would be to put the bean in the view scope. See also How to choose the right bean scope?


    3. Target Unreachable, 'null' returned null

    This has actually the same cause as #2, only the (older) EL implementation being used is somewhat buggy in preserving the property name to display in the exception message, which ultimately incorrectly exposed as 'null'. This only makes debugging and fixing a bit harder when you've quite some nested properties like so #{bean.entity.subentity.subsubentity.property}.

    The solution is still the same: make sure that the nested entity in question is not null, in all levels.


    4. Target Unreachable, ''0'' returned null

    This has also the same cause as #2, only the (older) EL implementation being used is buggy in formulating the exception message. This exposes only when you use the brace notation [] in EL as in #{bean.collection[index]} where the #{bean.collection} itself is non-null, but the item at the specified index doesn't exist. Such a message must then be interpreted as:

    Target Unreachable, 'collection[0]' returned null

    The solution is also the same as #2: make sure that the collection item is available.


    5. Target Unreachable, 'BracketSuffix' returned null

    This has actually the same cause as #4, only the (older) EL implementation being used is somewhat buggy in preserving the iteration index to display in the exception message, which ultimately incorrectly exposed as 'BracketSuffix' which is really the character ]. This only makes debugging and fixing a bit harder when you've multiple items in the collection.


    Other possible causes of javax.el.PropertyNotFoundException: