I am trying to set up jsf 2.3 on tomcat 8 whenever I used #inject I keep having an error with it I have googled and searched on stackoverflow.com yet I can't find a solution to it. I have already installed CDI (Weld) on it following #BalusC example from here How to install and use CDI on Tomcat? yet I keep having unsatisfied dependency: no bean matches the injection point. I can't figure it out is there anything i am missing?
ConfigurationBean.java
import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
import javax.faces.annotation.FacesConfig;
#FacesConfig(
// Activates CDI build-in beans
version = JSF_2_3
)
public class ConfigurationBean {
}
beans.xml
<?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>
faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.3"
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_3.xsd">
</faces-config>
PushBean.java
#Named
#ViewScoped
public class PushBean implements Serializable {
#Inject #Push(channel="counter") //This is where i get the error message unsatisfied dependency: no bean matches the injection point
private PushContext push;
}
For me this code looks fine but am wondering if it is netbeans bug. I tried that without using spring just only tomcat with jsf i still get the same error message. I couldn't find any error message inside the stacktrace.
Spring is NOT a full blown CDI container and only 'knows' the #Named and #Inject annotations and consequently does not (most likely) recognize the #Push annotation as a qualifier and cannot find the bean and throws the error you get (posting an explicit error and stacktrace is btw something you should always do in a question!)
See also:
Inject Instance<Interface> : Spring and CDI compatibility
I'd suggest to check your scopes. The built - in CDI scopes are #ApplicationScoped, #SessionScoped, #ConversationScoped and #RequestScoped . There is no #ViewScoped annotation in CDI.
You can inject the same level or broader scope, but not one which is smaller (e.g you cannot inject #RequestScoped into #SessionScoped bean)
Related
I have problem with bean discovery in JSF 2.3 and CDI application. I am using Glassfish 5.0, Java 8 (1.8.0_151). My files:
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_3.xsd"
version="2.3">
</faces-config>
LocaleBean:
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class LocaleBean implements Serializable {
}
Message in Glassfish log after submitting a form to this bean:
javax.el.PropertyNotFoundException: /home.xhtml #15,81 value="#{localeBean.language}": Target Unreachable, identifier 'localeBean' resolved to null
Form submit works only if I use imports listed bellow instead of #Named and #SessionScoped from javax.enterprise.context package.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
But both are deprecated in JSF 2.3.
Any ideas guys? Thank you!
I have found solution and its description in this topic on GitHub:
https://github.com/javaserverfaces/mojarra/issues/4264
Just started doing my first steps with FacesFlow with Glassfish 4.1 (i.e. using Mojarra) and when invoking my flow I get an error named
[SEVERE] [] [javax.enterprise.resource.webcontainer.jsf.application] ... Error Rendering View[/register/register.xhtml]
org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.faces.flow.FlowScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:708)
Several others had that error too as I can see in the web but the solutions that worked for other somehow dont work for me (see below).
I also tried #SessionScoped which works. So it is related to #FlowScoped.
To what I read in a book that I use to get me up to speed I should be ok from coding and config end since according to API #FlowScoped is CDI based and I use the following code at my backing bean/controller.
#Named
#FlowScoped(value="register")
public class RegisterController implements Serializable {
I have a flow named register whose pages are located in a dirctory /register and the first page of the flow is named register.xhtml
Following snippet I tried both as a register/register-flow.xml config file as well as WEB-INF/faces-config.xml without success.
<?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">
<flow-definition id="register">
<flow-return id="overview">
<from-outcome>/index</from-outcome>
</flow-return>
</flow-definition>
</faces-config>
What I tried so far:
I found a post suggesting that <Context antiJARLocking="true" path="/PROJEST_NAME"/> would solve the problem but after googling the tag it turns out its an outdated Tomcat tag.
Changing #Named to #ManagedBean didn't really help as suggested on one page. I could open the pages but the data in my controller class would not be available when invoking the next page of the flow anymore. But #ManagedBean shouldn't really work I guess since #FlowScoped is CDI based.
Another post suggested to ensure that javax.faces.CLIENT_WINDOW_MODE is enabled. I tried that via adding the following to my web.xml but without success
<context-param>
<param-name>javax.faces.CLIENT_WINDOW_MODE</param-name>
<param-value>url</param-value>
</context-param>
Another suggested to use Glassfish 4.x which I already do
Any ideas?
With Glassfish 4.1 at least you need to add the cdi-api.jar directory library.
Glassfish includes the weld-osgi-bundle.jar but it also needs cdi-api.jar to work because the CDI bean scopes aren't in the weld-osgi... so make sure you have it if not its here:
[gf_installation_path]/glassfish/modules/cdi-api.jar
This will give you access to the packages used with CDI Beans i.e., javax.enterprise.context.*
If not then probably
this could help
and this
GL!
I have implemented a CDI Bean which is observing events from another bean:
#SessionScoped
public class FixedItemController implements Serializable {
....
public void onWorkflowEvent(#Observes WorkflowEvent workflowEvent) throws AccessDeniedException {
logger.info("evaluate event...");
....
}
....
}
This works fine as long as I am using the bean in a JSF page with its default name 'fixedItemController'.
But if I declare another instance of that bean in the faces-config.xml like this:
<managed-bean>
<managed-bean-name>myOrderItemController</managed-bean-name>
<managed-bean-class>org.imixs.marty.workflow.FixedItemController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>childItemProperty</property-name>
<property-class>java.lang.String</property-class>
<value>_orderItems</value>
</managed-property>
</managed-bean>
the second instance (myOrderItemController) is not registered automatically as an observer for my WorkflowEvent.
What can I do, to ensure that my second instance - declared by the faces-config.xml - will be immediately instantiated and registered as an observer to my workitemEvent?
faces-config.xml does not register CDI managed beans. It registers JSF managed beans. Effectively, your #{myOrderItemController} is a JSF managed bean. It's like as if you use #ManagedBean instead of #Named. The JSF bean management facility does not scan for CDI specific #Observes annotation.
Keep it a CDI managed bean. Whatever you tried to solve for which you thought that registering it in faces-config.xml would be the right solution has to be solved differently using the CDI API instead of the JSF API.
Edit: The only technologies required to reproduce this issue are JSF 2.2 and Spring Boot 1.2.1 + Its embedded Tomcat 8.0.5 server. Everything else listed in this question is just to give context on the tech I'm using.
Update #2: Following along with BalusC's thoughts, I ported my sample custom component into a barebones Servlet 3.1 + JSF 2.2 application. You can find the code for it on Github here.
This simple case does not exhibit the issue I'm describing here. The #FacesComponent annotation works. This heavily implies that the problem is being caused either by Spring 4.1.2 or Spring Boot itself. It's getting late, so I'll be investigating this further tomorrow.
TL;DR: I want to use #FacesComponent and its attributes to replace foundation-components-html.taglib.xml and the <component> entry in faces-config.xml
I currently have custom components working in my project using XML definitions. I recently learned that JSF 2.2 introduced a feature which removes the need for XML entirely. I would love to use this, but when I purely use annotations, they are ignored by JSF. Raw tags show up in my HTML.
(i.e. <custom:paragraph></custom:paragraph>)
I have demonstrated this issue in a sandbox of mine I keep hosted on Github. If you want to take a crack at that, I'll explain how at the bottom of this post.
All you need to do is delete foundation-components-html.taglib.xml, and comment out the faces-config.xml entry for <component> and run the application to encounter the issue. I left it in the 'functioning' state so that anyone who wishes to help has an easy, verifiably correct starting point. Just hit up http://localhost:8080
Technologies Used:
Spring Boot 1.2.1
JSF 2.2 via Mojarra 2.2.6
Embedded Tomcat 8.0.5
NOTE: Remember, this setup currently works, but it's running on the taglib and faces-config entries! My question is how to remove these dependencies using the latest features in JSF 2.2
Full Project
Custom Component
package foundation.components;
import java.io.IOException;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
/**
* The Paragraph Component
* #author Seth Ellison
*/
#FacesComponent(value=UIParagraph.COMPONENT_TYPE, createTag=true, tagName="paragraph", namespace="http://www.blah.com/components/html")
public class UIParagraph extends UIComponentBase {
public static final String COMPONENT_TYPE = "foundation.components.Paragraph";
private String value;
private String styleClass;
#Override
public void encodeBegin(final FacesContext facesContext) throws IOException {
// Encode Implementation Omitted for Brevity.
}
#Override
public String getFamily() {
return "blah.components.family";
}
// Getters/Setters...
}
Taglib Definition
<facelet-taglib version="2.2"
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-facelettaglibrary_2_2.xsd">
<namespace>http://www.blah.com/components/html</namespace>
<tag>
<tag-name>paragraph</tag-name>
<component>
<component-type>foundation.components.Paragraph</component-type>
</component>
</tag>
</facelet-taglib>
Faces Config
<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" metadata-complete="false">
<component>
<component-type>foundation.components.Paragraph</component-type>
<component-class>foundation.components.UIParagraph</component-class>
</component>
</faces-config>
XHTML Template (Stripped down for clarity)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:custom="http://www.blah.com/components/html">
<head jsf:id="head"></head>
<body jsf:id="body">
<custom:paragraph value="This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique." />
</body>
</html>
If you'd like to run this, the easiest way would be to download the Spring Tool Suite, grab the code from Github, right click the project, and run it as a Spring Boot App. You'll get a connection error when the JPA configuration fires up, because you (likely) aren't running a local MySQL server. Don't worry about this. It's not at all required to visit the index page and check out the tag status. I frequently run the app both with, and without the DB fired up to no ill effect. Lastly, to get PrettyFaces to play nice with Spring Boot, you have to create either a Symbolic Link or a Hard Link from target/classes into WEB-INF/ -- PrettyFaces is coded to look in WEB-INF/classes or WEB-INF/lib when scanning for annotations.
Snippets for BalusC
This function exists in a class which is marked with #Configuration and implements ServletContextAware
#Bean
public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
return new ServletListenerRegistrationBean<ConfigureListener>(
new ConfigureListener());
}
Alright, I figured out what was causing the issue.
This morning I sat down to think about the differences between my working Servlet 3.1 version of the code, and the broken Spring Boot version. The main difference was how the code was being run. Embedded server vs. Standalone.
Spring Boot's embedded Tomcat server was the cause.
When I switched my sandbox around in accordance with this answer, everything turned on normally, and my custom components worked purely off of the #FacesComponent annotation!
I figure this has something to do with the way classes are organized post-startup on the embedded server vs. a discrete deploy to the Pivotal Tomcat server. JSF's annotation scanner seems to simply ignore annotations in that case.
I'm new to JSF-2 and CDI (I'm from Spring world).
I want to intercept a method from #ManagedBean but my Interceptor class is never called. Is it possible to do?
LogInterceptor.java
#Interceptor
public class LogInterceptor {
#AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("begin method interceptor");
Object methodReturn = ctx.proceed();
System.out.println("end method interceptor");
return methodReturn;
}
}
RoleMB
#ManagedBean
#ViewScoped
public class RoleMB extends BaseMB {
#Interceptors(LogInterceptor.class)
public void preEditRole(Role role) {
...
}
}
beans.xml
<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">
<interceptors>
<class>br.com.preventsenior.services.log.LogInterceptor</class>
</interceptors>
</beans>
The log(InvocationContext ctx) is never called.
Java EE interceptors work only on CDI managed beans and EJBs, not on JSF managed beans.
So, you've basically 2 options:
Change JSF bean management annotations by CDI bean management annotations (#Named et.al.)
Intercept on an EJB method instead which is in turn invoked by JSF managed bean. In a sane Java EE application, the real business logic belongs in EJBs anyway.