This question already has answers here:
Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable
(18 answers)
Closed 1 year ago.
I am trying to make a simple JSF projects but getting errors along the way... I updated my project as a maven project but still it does not work.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>BeatifulThingsWebapp</groupId>
<artifactId>BeatifulThingsWebapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.sun.faces/jsf-impl -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.faces/jsf-api -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.20</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
</project>
this is my index.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<h1>Please fill out the form</h1>
<h:form>
Tell me about something nice:
<h:inputText value="#{bt.thingTitle}"/>
Now describe it:
<h:inputText value="#{bt.thingDescription}"/>
Rate this item:
<h:inputText value="#{bt.rating}"/>
<h:commandButton action="#{controller.onSubmitEdit()}" value="OK"/>
</h:form>
</body>
</html>
java classes
package beans;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.view.ViewScoped;
#ManagedBean(name="bt")
#ViewScoped
public class BeautifulThing implements Serializable{
int id;
String thingTitle;
String thingDescription;
int rating;
//ManagedBean has to have a non argument constructor
public BeautifulThing(int id, String thingTitle, String thingDescription, int rating) {
super();
this.id = id;
this.thingTitle = thingTitle;
this.thingDescription = thingDescription;
this.rating = rating;
}
public BeautifulThing() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getThingTitle() {
return thingTitle;
}
public void setThingTitle(String thingTitle) {
this.thingTitle = thingTitle;
}
public String getThingDescription() {
return thingDescription;
}
public void setThingDescription(String thingDescription) {
this.thingDescription = thingDescription;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
#Override
public String toString() {
return "BeautifulThing [id=" + id + ", thingTitle=" + thingTitle + ", rating=" +
rating + "]";
}
}
--------------------
package controllers;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
#ManagedBean(name="controller")
public class FormController implements Serializable{
//ManagedBean has to have a non argument constructor
public void onSubmitEdit() {
//when the user clicks on the submit button
System.out.println("You clicked the OK button");
}
public FormController() {
super();
// TODO Auto-generated constructor stub
}
}
the error I am getting:
HTTP Status 500 – Internal Server Error
--------------------------------------------------------------------------------
Type Exception Report
Message /index.xhtml #13,41 value="#{bt.thingTitle}": Target Unreachable, identifier [bt]
resolved to null
Description The server encountered an unexpected condition that prevented it from
fulfilling
the request.
Exception
javax.servlet.ServletException: /index.xhtml #13,41 value="#{bt.thingTitle}": Target
Unreachable, identifier [bt] resolved to null
javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
javax.el.PropertyNotFoundException: /index.xhtml #13,41 value="#{bt.thingTitle}": Target
Unreachable, identifier [bt] resolved to null
com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInpu
tRenderer.java:95)
javax.faces.component.UIInput.getConvertedValue(UIInput.java:1067)
javax.faces.component.UIInput.validate(UIInput.java:981)
javax.faces.component.UIInput.executeValidate(UIInput.java:1270)
javax.faces.component.UIInput.processValidators(UIInput.java:714)
javax.faces.component.UIForm.processValidators(UIForm.java:253)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1261)
javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1195)
com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
javax.el.PropertyNotFoundException: Target Unreachable, identifier [bt] resolved to null
org.apache.el.parser.AstValue.getTarget(AstValue.java:73)
org.apache.el.parser.AstValue.getType(AstValue.java:57)
org.apache.el.ValueExpressionImpl.getType(ValueExpressionImpl.java:173)
com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:98)
com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInpu
tRenderer.java:95)
javax.faces.component.UIInput.getConvertedValue(UIInput.java:1067)
javax.faces.component.UIInput.validate(UIInput.java:981)
javax.faces.component.UIInput.executeValidate(UIInput.java:1270)
javax.faces.component.UIInput.processValidators(UIInput.java:714)
javax.faces.component.UIForm.processValidators(UIForm.java:253)
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1261)
javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1195)
com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
--------------------------------------------------------------------------------
Apache Tomcat/9.0.50
Your JSF container dont create your BeautifulThing bean and therefore jsf servler dont find it.
Try change #MangedBean("bt") to #Named("bt") or delete constructor with arguments. (And totaly delete super(); because your bean don't extend any other object).
If no one from this will be work, look to logs of your application server from start or deploy war.
Related
Am using JSF Primefaces 7.0 to render an XHTML file to display a list of users (along with their e-mail addresses) inside a single HTML dropdown list.
pom.xml:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>primefaces-extensions</artifactId>
<version>7.0.3</version>
</dependency>
User class:
package com.myapp.model;
import static org.apache.commons.lang3.StringUtils.isBlank;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;
#NoArgsConstructor
#Data
public class User implements Serializable {
private String firstName;
private String lastName;
// this is their e-mail address
private String username;
public String getName() {
final StringBuilder sb = new StringBuilder();
if (!isBlank(getFirstName())) {
sb.append(getFirstName()).append(' ');
}
if (!isBlank(getLastName())) {
sb.append(getLastName());
}
return sb.toString().trim();
}
}
Inside users.xhtml:
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
>
<f:selectItems
value="#{userReport.users}"
var="user"
itemLabel="#{user.name} (#{user.username})"
itemValue="#{user}"/>
</p:selectOneMenu>
</html>
This renders correctly for an individual item if the (user.name is not null) inside an HTML dropdown list:
John Doe (jdoe#email.com)
How can I use a conditional (<c:if> with <c:else> or even the ? : ternary operator) to set the itemLabel attribute to render just the user.username without parenthesis if the user.name is empty string or null?
So, it should set to this (the e-mail address) if user.name is null or an empty string:
itemLabel="#{user.username}"
To make display (if user.name is null or empty string):
jdoe#email.com
Tried doing this:
itemLabel="#{not empty user.name ? user.name (user.username) : user.username}"
Which gives me the following stack trace:
javax.servlet.ServletException: Method not found: class com.myapp.model.User.name(java.lang.String)
at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:749)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:475)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
Caused by: javax.el.MethodNotFoundException: Method not found: class com.myapp.model.User.name(java.lang.String)
at javax.el.Util.findWrapper(Util.java:373)
at javax.el.Util.findMethod(Util.java:219)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:149)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:79)
... 35 more
Don't understand why this is the case because the original attribute did find the User.getName() method:
itemLabel="#{user.name} (#{user.username})"
Is there a better way to do this?
Figured it out by using the += concatenation operator:
itemLabel="#{!empty user.name ? user.name += ' (' += user.username += ')' : user.username}"
related links: PrimeFaces PickList with OmniFaces validateAll leads to NullPointerException
this problem is similar with this link becuase when I do the debug of the picklistRender I got the same error showed in the link before,the same syntoms, but I am reading all issue history related, Thomas Andraschko sugguest is a problem of mojarra but I tried to test with myfaces-version-22 and myfaces-version-23 and I face the same problem
Im trying to figure out to resolve my example works like showcase p:picklist but not worls as well said the docs, I tried several options like
- don't use mojarra,use myfaces
- change primefaces version 7.0 to 8.0.RC1
- put a custom converter
-jboss-deployment-structure.xml (disables packages from jboss)
When does the error occur?
- loading page
why am I using a converter?
- is an option I tried to fix the problem, but, the ussue raises before, I test with or withoutconverter and happens the same error.
enviroment
-Jboos EAP 7.2
- repo https://github.com/Qleoz12/Primefaces-Mydemo
but always I have this error
java.lang.NullPointerException
viewId=/components/usingCompositeComponent.xhtml
location=I:\developer\Fado\Servidores\jboss-eap-7.2\standalone\deployments\Primefaces-
Mydemo.war\components\usingCompositeComponent.xhtml
phaseId=RENDER_RESPONSE(6)
Caused by:
java.lang.NullPointerException
at org.primefaces.component.picklist.PickListRenderer.encodeMarkup(PickListRenderer.java:103)
xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ccp="http://java.sun.com/jsf/composite/cc"
template="../template/ui.xhtml">
<ui:define name="body">
<p:pickList
id="FF"
value="#{CompositeComponent.cities}"
var="cities"
itemLabel="#{cities}"
itemValue="#{cities}"
converter="PickListConverter"
>
</p:pickList>
</ui:define>
</ui:composition>
bean
package Beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import org.primefaces.model.DualListModel;
#Named
#javax.faces.view.ViewScoped
public class CompositeComponent implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CompositeComponent.class);
private DualListModel<String> cities;
List<String> citiesSource = new ArrayList<String>();
List<String> citiesTarget = new ArrayList<String>();
public CompositeComponent() {
super();
}
#PostConstruct
public void init() {
// Cities
citiesSource.add("San Francisco");
citiesSource.add("London");
citiesSource.add("Paris");
citiesSource.add("Istanbul");
citiesSource.add("Berlin");
citiesSource.add("Barcelona");
citiesSource.add("Rome");
cities = new DualListModel<String>(citiesSource, citiesTarget);
}
public DualListModel<String> getCities() {
return cities;
}
public void setCities(DualListModel<String> cities) {
this.cities = cities;
}
}
converter
package converter;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import org.primefaces.component.picklist.PickList;
import org.primefaces.model.DualListModel;
#SuppressWarnings({"unused", "rawtypes"})
#FacesConverter("PickListConverter")
public class PickListConverter implements Converter{
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
PickList p = (PickList) component;
DualListModel dl = (DualListModel) p.getValue();
return dl.getSource().get(Integer.valueOf(submittedValue));
}
public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
PickList p = (PickList) component;
DualListModel dl = (DualListModel) p.getValue();
return String.valueOf(dl.getSource().indexOf(value));
}
}
question
And for the PickListRenderer the NPE is in line 78 then 128 inside PickListRenderer:
encodeList(context, pickList, clientId + "_target", PickList.TARGET_CLASS, model.getTarget(),
pickList.getFacet("targetCaption"), pickList.isShowTargetFilter(), false);
issue of primefaces
the NPE var is related with model always is null inside encodeMarkup that afterward call encodeList with this model null.
DualListModel model = getModelValueToRender(context, pickList);
stackTrace https://pastebin.com/wLKZWReg
the both question is related because in sme point in the other question they can achieve to resolve the problem but Im following all stuffs they made, but I cant figure out, yeah both questions are similar , them have somo little differets but for me is the same scenary
7: If it is not mojarra related, please remove the mojarra tag. 8: Run you jsf application in JSF development mode.
yes I trying to resolve this error testing with mojarra or testing myfaces for that I dont remove the tag of mojarra.
problems
-Fix on the xhtml the name of the bean the name of the bean usually starts with lowercase for that I chabge
value="#{CompositeComponent.cities}"
to this
value="#{compositeComponent.cities}"
-for Strings remove the converter , but for custom objects you must to write a own implemantation of the converter, I put an example into my repo in github.
I test two ways to handle JSF anottation and anothers stuff the project
you must choose one, dont use both or you have some error on deploying stage.
<!-- javax.* APIs -->
<!-- old way -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<!-- end old way -->
<!-- new way -->
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-atinject_1.0_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_2.0_spec</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-interceptor_1.2_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-annotation_1.3_spec</artifactId>
<version>1.0</version>
</dependency>
I have a simple jsf app with one Bean.
import org.omnifaces.cdi.ViewScoped;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Named;
import java.io.Serializable;
#Named
#ViewScoped
public class IndexMg implements Serializable {
List list;
#PostConstruct
public void init() {
list = new ArrayList();
list.add("as");
list.add("dsu");
}
#PreDestroy()
public void end() {
System.out.println("predestroy called");
}
}
according to this answer and conversation down this post and also OmniFaces documentation OmniFaces ViewScoped bean should invoke #PreDestroy function when I navigate away by GET, or close the browser tab/window but nothings happens until session destroy.
I'm using Wildfly 15 as Application Server and i can see activeViewMaps in sessions. Yoy can see sessions content here .
It's something like this :
com.sun.faces.application.view.activeViewMaps {1d31c745-c202-4256-a2c6-60035bfdd8e7={org.omnifaces.cdi.viewscope.ViewScopeStorageInSession=b557d2aa-ba35-4ff2-9f4e-3cc4ac312c9a}, ca02df9d-be65-4a75-a399-3df9eabbcfd3={org.omnifaces.cdi.viewscope.ViewScopeStorageInSession=aaef6a5a-d385-4e33-a990-200f94b67583}}
I opened multiple windows an closed them but non of them destroyed until session destroy(30 minutes later). What's wrong? did i forget anything?
this is my pom
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.3.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0.SP1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.omnifaces/omnifaces -->
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>3.2</version>
</dependency>
</dependencies>
following a tutorial and got stuck with an issue.
System: wildfly 10, maven project with multimodules, packaging: ear
EJB:
#Stateless
public class ToyService implements ToyServiceRemote, ToyServiceLocal {
...
}
INTERFACE:
#Local
public interface ToyServiceLocal {
...
}
BEAN:
#Named("toyProducts")
#RequestScoped
public class ProductBean {
#Inject
private ToyServiceLocal toyService;
#PostConstruct
public void initialize() {
toyList = toyService.getAllToys();
}
...
}
JSF:
<ui:repeat value="#{toyProducts.toyList}" var="toy">
...
</ui:repeat>
The application deploys, but when I try to open the page in browser I am getting:
ERROR [io.undertow.request] (default task-62) UT005023: Exception
handling request to /index.xhtml: javax.servlet.ServletException: Can
not set com.example.common.service.ToyServiceLocal field
shop.beans.ProductBean.toyService to
com.example.product.service.ToyServiceLocal$ToyServiceRemote$1303029808$Proxy$_$$_Weld$EnterpriseProxy$
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
wildfly-experiment | at
io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
wildfly-experiment | at
io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
wildfly-experiment | at
io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
...
I found the "real" answer this time: since I am using multi module maven project, packaged as EAR (with some EJBs, a common JAR and the WAR file). All I had to do was to add scope provided in the WAR file (common is JAR and product in EJB)
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>product</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
We are in the process of migrating our JavaEE app from Weblogic 10.3.6 to Weblogic 12.2.1.2. As part of this migration we are changing our JSF managaged beans to use CDI annotations rather than the standard JSF annotations. #ManagedBean to #Named and javax.faces.bean.ViewScoped to javax.faces.view.ViewScoped. This has proved successful with only minor issues. However I am having a big issue trying to get our tests to run. The tests fail with the following error:
WebBeans context with scope type annotation #ViewScoped does not exist within current thread
I have tried multiple different containers (embedded and remote) but still get this same error. Any help would be much appreciated.
I am using Arquillian with the following pom.xml dependencies:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.12.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>arquillian-openejb-embedded</artifactId>
<version>7.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.0.13</version>
</dependency>
<dependency>
<groupId>org.primefaces.themes</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
BackingBean:
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
#Named
#ViewScoped
public class AnotherBean implements Serializable {
public String doTest()
{
System.out.println("test");
return "test";
}
}
TestBean
#RunWith(Arquillian.class)
public class TestAgain {
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class, "test.jar")
.addClass(AnotherBean.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
#Inject
AnotherBean anotherBean;
#Test
public void doTest()
{
Assert.assertEquals(anotherBean.doTest(), "test");
anotherBean.doTest();
}
}
UPDATE
If I change the #Deployment to:
#Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class, "test.jar")
.addClass(AnotherBean.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
I Get:
javax.enterprise.inject.UnsatisfiedResolutionException: Api type [AnotherBean] is not found with the qualifiers
Qualifiers: [#javax.enterprise.inject.Default()]
for injection into Field Injection Point, field name : anotherBean, Bean Owner : [null]
We hat similar difficulties in testing #ViewScoped beans. We solved this by creating the bean with its injections in the test ourselfs.
The Bean instance itself ist created in the test and all dependencies are then inserted into that by using reflection. This works with beans, entitymanger etc
#RunWith(Arquillian.class)
public class ViewControllerTest {
#Inject private OtherBean otherBean;
private ViewController viewController;
#Deployment
public static WebArchive createDeployment() {
return WebArchiveFactory.getDefaultWebarchArchive();
}
#Before
public void setup() throws Exception {
viewController = new ViewController();
TestHelper.setFacesContext(); // provide FacesContextMock
TestHelper.inject(viewController, "otherBean", otherBean);
}
}
With TestHelper looking like this
public class TestHelper {
public static void inject(Object bean,
String fieldName,
Object fieldValue) throws Exception {
if (null == bean) {
throw new IllegalArgumentException("Bean must not be null");
}
Field field;
try {
field = bean.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
log.log(Level.SEVERE, "Could not find field for injection: " + fieldName);
throw e;
}
field.setAccessible(true);
field.set(bean, fieldValue);
}
}
In the end I had to work around this problem with a good old fashioned hack. I found the source for org.apache.webbeans.container.BeanManagerImpl where the original WebBeans context with scope type annotation #ViewScoped does not exist within current thread comes from. I created this class within my test sources and I then made some changes to get around the problem.
Ultimately for my tests I don't care about the scope. I'm testing that the methods run and return the correct logic/data. So in the class it goes and checks what type of scope the bean is in and throws the exception. I simply checked if it was in Viewscoped and if so changed it to Dependent. This then allowed my tests to work.
Not the best solution but it works.