Injecting Stateless EJB into Named Bean - jsf

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>

Related

PropertyNotFoundException in JSF 2.2 [duplicate]

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.

Quarkus Unsatisfied dependency for type javax.ws.rs.sse.Sse and qualifiers [#Default]

I try to reproduce https://github.com/volkaert/events-sse-quarkus ; here is an extract :
#ApplicationScoped
#Path("/api-1.0/trevents")
public class SseRealTimeService {
private final Logger log = Logger.getLogger(getClass());
private long id;
private Sse sse;
private SseBroadcaster sseBroadcaster;
public SseRealTimeService(#Context Sse sse,final #Context HttpHeaders httpHeaders) {
this.log.debug(">>>>>>>>>>>>setSse :) " + sse);
this.log.debug(">>>>>>>>>>>>httpHeaders :) " + httpHeaders);
this.sse = sse;
}
...
And I get :
Caused by: javax.enterprise.inject.spi.DeploymentException:
Found 2 deployment problems:
[1] Unsatisfied dependency for type javax.ws.rs.sse.Sse and qualifiers [#Default]
- java member: org.avm.business.rest.api.SseRealTimeService#<init>()
- declared on CLASS bean [types=[org.avm.business.rest.api.SseRealTimeService, java.lang.Object], qualifiers=[#Default, #Any], target=org.avm.business.rest.api.SseRealTimeService]
[2] Unsatisfied dependency for type javax.ws.rs.core.HttpHeaders and qualifiers [#Default]
- java member: org.avm.business.rest.api.SseRealTimeService#<init>()
- declared on CLASS bean [types=[org.avm.business.rest.api.SseRealTimeService, java.lang.Object], qualifiers=[#Default, #Any], target=org.avm.business.rest.api.SseRealTimeService]
As far as I understood, it means it didn't find any class implementing Sse interface which could be injected.
My pom (extract dependencies node) :
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client</artifactId>
</dependency>
<!-- TESTS -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I have seen this https://github.com/quarkusio/quarkus/issues/6515
but it says v1.5 solved it ; my quarkus version is 1.8.0 (<quarkus.platform.version>1.8.0.Final</quarkus.platform.version> in pom.xml).
I'm lost ... any idea ?

Spring Data Cassandra ClassNotFoundException

get this error when start spring boot application
my spring boot application
Spring Boot version 2.2.4
and cassandra version
spring-data-cassandra 3.0.1.RELEASE
this is my error
Caused by: java.lang.ClassNotFoundException: org.springframework.data.convert.CustomConversions$ConverterConfiguration
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 113 common frames omitted
and my config class
public class CassandraConfig {
#Bean
public CqlSessionFactoryBean session() {
CqlSessionFactoryBean session = new CqlSessionFactoryBean();
session.setContactPoints("localhost");
session.setKeyspaceName("mykeyspace");
session.setUsername("cassandra");
session.setPassword("cassandra");
session.setLocalDatacenter("dc1");
return session;
}
#Bean
public SessionFactoryFactoryBean sessionFactory(CqlSession session, CassandraConverter converter) {
SessionFactoryFactoryBean sessionFactory = new SessionFactoryFactoryBean();
sessionFactory.setSession(session);
sessionFactory.setConverter(converter);
sessionFactory.setSchemaAction(SchemaAction.NONE);
return sessionFactory;
}
#Bean
public CassandraMappingContext mappingContext(CqlSession cqlSession) {
CassandraMappingContext mappingContext = new CassandraMappingContext();
mappingContext.setUserTypeResolver(new SimpleUserTypeResolver(cqlSession));
return mappingContext;
}
#Bean
public CassandraConverter converter(CassandraMappingContext mappingContext) {
return new MappingCassandraConverter(mappingContext);
}
#Bean
public CassandraOperations cassandraTemplate(SessionFactory sessionFactory, CassandraConverter converter) {
return new CassandraTemplate(sessionFactory, converter);
}
}
how can in fix this error?
Those versions are incompatible. spring-data-cassandra had a significant breaking changes from the 2.2.x version to 3.x.x version.
To use the 3.x.x version of Cassandra, you will to upgrade spring to 2.3.x. Either that or you will need to downgrade to 2.2.x version of spring-data-cassandra.
i'm get a same exception,
when i upgrade the spring boot version, it's work!
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

OmniFaces not destroying ViewScoped bean after closing tab/window

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>

Arquillian testing JSF with CDI - CDI Scope issue

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.

Resources