How to reference JSF managed beans which are provided in a JAR file?
Asked Answered
F

3

11

I have a WAR file with the following structure:

enter image description here

The JSF managed bean BusinessObjectTypeListController is located in commons-web-1.0.jar in /WEB-INF/lib and referenced in BusinessObjectTypeListView.xhtml. When I run my web application and I call that view, I get the following error:

javax.servlet.ServletException: /view/common/businessObjectTypeListView.xhtml @34,94 listener="#{businessObjectTypeListController.selectData}": Target Unreachable, identifier 'businessObjectTypeListController' resolved to null

Why isn't the controller class found? It should be in the classpath, is it?

Foetid answered 5/10, 2011 at 15:31 Comment(2)
How are you running the application? Did you simply choose to "Run on Server" from Eclipse? Or are you deploying to a container manually? And which container is this?Marylou
I deploy it using ant into Glassfish.Foetid
B
29

You need to have a JSF 2.0 compliant /META-INF/faces-config.xml file in the commons-web-1.0.jar file in order to get JSF to scan the JAR file for classes with JSF annotations like @ManagedBean and auto-register them.

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

JSF does namely not scan every class of every single JAR file in the classpath, that would have been too expensive. Only JARs with the above /META-INF/faces-config.xml file will be scanned.

You should also ensure that you do not have the metadata-complete="true" attribute in the <faces-config> declaration of webapp's own /WEB-INF/faces-config.xml file, otherwise JSF will assume that this faces config is complete and therefore won't auto-scan JAR files for annotations.

If none of those conditions are (or can be) met, then you need to manually register the bean as <managed-bean> in webapp's own /WEB-INF/faces-config.xml instead of relying on annotations.

See also chapter 11.4.2 of JSF 2.0 specification (emphasis mine).

11.4.2 Application Startup Behavior

...

This algorithm provides considerable flexibility for developers that are assembling the components of a JSF-based web application. For example, an application might include one or more custom UIComponent implementations, along with associated Renderers, so it can declare them in an application resource named “/WEB-INF/faces-config.xml” with no need to programmatically register them with Application instance. In addition, the application might choose to include a component library (packaged as a JAR file) that includes a “META-INF/faces-config.xml” resource. The existence of this resource causes components, renderers, and other JSF implementation classes that are stored in this library JAR file to be automatically registered, with no action required by the application.

Bignoniaceous answered 5/10, 2011 at 15:37 Comment(2)
Is this still sufficient for more modern JSF versions? I'm trying to help stackoverflow.com/questions/59742677/… and read many sort of 'duplicates' in SO (to many to link here, many should be marked as duplicates). Might web-fragment.xml be needed in addition? Just asking before I'm going to try to replicate the issue.Anybody
@Anybody yes. The problem in the linked question is most likely caused by incorrect placement of web fragment libraries. They belong in WAR/WEB-INF/lib not in EAR/lib.Bignoniaceous
J
1

I have same problem with CDI beans in my case.

I have common.jar project where i placed the CDI beans. (without beans.xml) and I have webapp.war that contains common.jar in it`s lib and beans.xml.

when i call a cdi bean from jsf, i get it is not reachable exception:/

project structure is created using maven : - maven-archetype-quickstart for common.jar - maven-archetype-webapp for webapp.war

I am using eclipse/juno en deploy to Glassfish 3.1.x.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Resolved: For EJB and JAR packaging you should place the beans.xml in src/main/resources/META-INF/. For WAR packaging you should place the beans.xml in src/main/webapp/WEB-INF/. Remember that only .java files should be put in the src/main/java and src/test/java directories. Resources like .xml files should be in src/main/resources.

from topic: CDI: beans.xml, where do I put you?

Jocularity answered 15/2, 2013 at 9:24 Comment(0)
H
0

In my opinion the class BusinessObjectTypeListController is founded properly but does not instantiated.

How you create the instance of class on a view? If you use a BeanFactory review the config xml files

Heall answered 5/10, 2011 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.