Why the injection of Session beans gives null pointer exception? - jsf

I have a very simple JSF 2.2 ( hibernate 4.3 ) application that has 2 pages.
first page is login.xhtml which is bound to below session bean
import javax.inject.Named;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
#Named(value = "loginBean")
#SessionScoped
public class LoginBean implements Serializable {
/**
* Creates a new instance of LoginBean
*/
Company company;
private static final long serialVersionUID = 1520318172495977648L;
public String Login() {
CompanyHelper companyHelper = new CompanyHelper();
company = companyHelper.Login(this.loginName, this.password);
if (company != null) {
return "";
} else {
FacesMessage msg = new FacesMessage("Failed", "Wrong Usernames or password.");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(null, msg);
return "";
}
}
}
It just validate the Username and password from the DB and returns the company object
the second page delivery.xhtml which bound to view bean. Inside this bean I have injected the login bean but it returns null every time I use Company object. However, when I go to login.xhtml I found that company object is not null.
Below is the delivery bean.
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
#Named(value = "deliveryBean")
#ViewScoped
public class DeliveryBean implements Serializable {
/**
* Creates a new instance of DeliveryBean
*/
#Inject
private LoginBean loginBean;
#PostConstruct
public void init() {
// returns null pointer exception
Logger.getLogger(LoginBean.class.getName()).log(Level.SEVERE, loginBean.company);
}
public String SendItem() {
// reutn null point exception
String personName=deliverRequest.setDeliverFrom(loginBean.company.getContactPersonName());
return "";
}
}
here is the pom.xml
<dependencies>
<!-- https://mvnrepository.com/artifact/org.primefaces/primefaces -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
I am deploying the application on Glassfish 4.1

#Inject
private LoginBean loginBean;
The way injection works is first it creates a proxy object in the loginBean field. CDI doesn't create or lookup a LoginBean instance immediately. Instead it waits until you call a method on the proxy in the loginBean field. CDI calls this a contextual reference - the instance that you'll get depends on the context in which you asked for it.
But you don't call a method:
loginBean.company.toString()
You access the company field directly - CDI can't intercept this. So you get a useless null value from the proxy.
The solution is to not access managed beans' fields directly. Instead make company private and create a getter:
public class LoginBean implements Serializable {
private Company company;
public Company getCompany() {
return company;
}
And call this getter in the DeliveryBean.

Related

Injecting FacesContext with CDI

I have my Bean:
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import br.com.dropper.web.dao.UsuarioDAO;
import br.com.dropper.web.model.Usuario;
import br.com.dropper.web.util.JpaUtil;
#Named
#SessionScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private FacesContext context;
#Inject
private Usuario usuario;
//TODO: Persistencia e Transacao controladas por EJB
private EntityManager em = new JpaUtil().getEntityManager();
private UsuarioDAO usuarioDAO = new UsuarioDAO(em);
public Usuario getUsuario() {
return usuario;
}
public String autenticar() {
Usuario usuario = usuarioDAO.obterUsuarioPorEmail(this.usuario);
if (usuario == null) {
context.addMessage(null, new FacesMessage("Usuario não encontrado."));
context.getExternalContext().getFlash().setKeepMessages(true);
return "login?faces-redirect=true";
} else {
context.getExternalContext().getSessionMap().put("usuarioLogado", usuario);
return "dashboardImagem.xhtml?faces-redirect=true";
}
}
public String cadastrarUsuario() {
System.out.println("Redirecionando para cadastroUsuario.xhtml");
return "cadastroUsuario.xhtml?faces-redirect=true";
}
public String logout() {
context.getExternalContext().getSessionMap().remove("usuarioLogado");
context.getExternalContext().invalidateSession();
return "login.xhtml?faces-redirect=true";
}
}
And my Factory:
package br.com.dropper.web.factory;
import java.io.Serializable;
import javax.enterprise.inject.Produces;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
public class FacesContextFactory implements Serializable{
private static final long serialVersionUID = 1L;
#Produces
#ViewScoped
public FacesContext getFacesContext(){
return FacesContext.getCurrentInstance();
}
}
When i run my application, im getting this exception:
Caused by: org.jboss.weld.exceptions.IllegalProductException: WELD-000053: Producers cannot declare passivating scope and return a non-serializable class: Producer for Producer Method [FacesContext] with qualifiers [#Any #Default] declared as [[BackedAnnotatedMethod] #Produces #ViewScoped public br.com.dropper.web.factory.FacesContextFactory.getFacesContext()] declared on Managed Bean [class br.com.dropper.web.factory.FacesContextFactory] with qualifiers [#Any #Default]
at br.com.dropper.web.factory.FacesContextFactory.getFacesContext(FacesContextFactory.java:16)
And when i change the produces method to #RequestScoped, my FacesContext it's inject only one time, and in my second page xhtml, i get a nullpointer =(
UPDATE: pom
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.dropper</groupId>
<artifactId>dropper-web</artifactId>
<version>0.1</version>
<packaging>war</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>dropper-web</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1212</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/postgresql-9.4.1212.jre6.jar</systemPath>
</dependency> -->
<dependency>
<groupId>dropper-web</groupId>
<artifactId>bootstrap</artifactId>
<version>1.0.10</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/bootstrap-1.0.10.jar</systemPath>
</dependency>
<dependency>
<groupId>dropper-web</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/commons-io-2.5.jar</systemPath>
</dependency>
<dependency>
<groupId>dropper-web</groupId>
<artifactId>cupertino</artifactId>
<version>1.0.10</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/cupertino-1.0.10.jar</systemPath>
</dependency>
<dependency>
<groupId>dropper-web</groupId>
<artifactId>primefaces-6.0</artifactId>
<version>6.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/primefaces-6.0.jar</systemPath>
</dependency>
</dependencies>
<build>
<finalName>dropper-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Att
The FacesContext itself is indeed not Serializable. And, more important, it is definitely not #ViewScoped. It's actually shorter than #RequestScoped, but until JSF 2.3 is released which comes with improved CDI support so you could just #Inject FacesContext without having a custom producer, you could less or more safely use #Produces #RequestScoped instead.
#Produces
#RequestScoped
public FacesContext getFacesContext(){
return FacesContext.getCurrentInstance();
}
One case where this would still fail is when you explicitly perform a forward within the same request using RequestDispatcher#forward() or ExternalContext#dispatch(). You will then face java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased. This is however a very rare case and usually only performed in a badly designed (ajax) exception handler. See also a.o. using ExternalContext.dispatch in JSF error handler causes corrupt page rendering.

JSF does not convert LinkedHashMap to the correct object (javax.el.MethodNotFoundException)

I have a JSF application, and everything is working fine, except for calling methods in the ManagedBean that have a object as parameter:
<p:dataTable value="#{sContr.privileges}" var="privilege">
<p:column>
<h:outputText value="#{privilege.name}"/>
</p:column>
<p:column>
<h:outputText value="#{privilege.description}"/>
</p:column>
<p:column>
<h:commandButton action="#{sContr.deletePrivilege(privilege)}" image="somePath"/>
</p:column>
</p:dataTable>
In the sContr:
public void deletePrivilege(Privilege privilege) {
System.out.println("test");
}
All methods, that do not have own defined objects, work (e.g. Maps, Strings, Lists, ...) and accessing the objects and even sub-objects in the xhtml works like a charm.
However, calling this deletePrivilege results in:
javax.servlet.ServletException: javax.el.MethodNotFoundException: [...]privileges.xhtml #31,138 action="#{sContr.deletePrivilege(privilege)}": Method not found: [...]sContrl#604b7816.deletePrivilege(java.util.LinkedHashMap)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
[...]
The objects are defined in another module than the JSF application and are normal java objects (no specific JSF annotations).
So, for some reason, JSF can't auto-convert the LinkedHashMap back to an instance of the class that was used to render the page.
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_2.xsd"
version="2.2">
<managed-bean>
<managed-bean-name>currentDate</managed-bean-name>
<managed-bean-class>java.util.Date</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
The maven includes for JSF and primefaces:
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.1</version>
</dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>primefaces-extensions</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.primefaces.themes</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.10</version>
</dependency>
My object:
#Entity
public class Privilege implements IEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column()
private Long id;
#Column()
private String name;
#Column()
private String description;
public Privilege(String name) {
this.name = name;
}
public Privilege(Long id, String name) {
this.id = id;
this.name = name;
}
public Privilege(Long id, String name, String description) {
this(id, name);
this.description = description;
}
public Privilege() {
}
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
}
Also to clarify: the LinkedHashMap contains the id, the name and the description (so it should have everything to build the correct object)
What could be the problem here? Do I need to define the package somehow in faces-config?
Using: Mojarra 2.2.6, primefaces 5.1, primefaces-extensions 2.1.0
This depends on how you are solving the Privilege so if you are deserializing it some how it may, I had the same issue, I was deserializing Device model from json using jackson
class Device{}
devices = objectMapper.readValue(responseBody, List.class);
and it gave the same error exactly
I solve deserializing like
devices = objectMapper.readValue(responseBody, new TypeReference<>() {});
and it worked perfectly.

Entity is not a known entity type

I try to make a simple Java EE application in java with JSF and Java EE.
I couldn't deploy the following customer entity:
package ch.uufstellend.onlineshop.model;
import java.io.Serializable;
import javax.ejb.Stateful;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import lombok.Data;
#Entity
#Data
#Table(name = "CUSTOMER")
#NamedQuery(
name = "Customer.findAll",
query = "SELECT c FROM Customer c")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
private String email;
private String password;
public Customer() {
}
#Override
public String toString() {
return id + "-" + email + "-" + password;
}
}
Because of:
Severe: Exception while deploying the app [uuf-onlineshop-ear] :
Invalid ejb jar [uuf-onlineshop-ejb-1.0-SNAPSHOT.jar]: it contains
zero ejb. Note:
A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean.
EJB3+ entity beans (#Entity) are POJOs and please package them as library jar.
If the jar file contains valid EJBs which are annotated with EJB component level annotations (#Stateless, #Stateful, #MessageDriven,
#Singleton), please check server.log to see whether the annotations were processed properly.
If I add a #Stateful annotation to the entity I'm able to deploy the app.
But when I then access the RegisterController the following exception is thrown while persisting the Customer:
exception:>
javax.servlet.ServletException: java.lang.IllegalArgumentException:
Object:
ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188
is not a known entity type. root cause
javax.faces.el.EvaluationException:
java.lang.IllegalArgumentException: Object:
ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188
is not a known entity type.
Controller:
package ch.uufstellend.onlineshop;
import ch.uufstellend.onlineshop.model.Customer;
import java.io.Serializable;
import javax.annotation.Resource;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import lombok.Getter;
import lombok.Setter;
#Named
#RequestScoped
public class RegisterController implements Serializable {
private static final long serialVersionUID = 1L;
#PersistenceUnit
private EntityManagerFactory emf;
#Resource
private UserTransaction ut;
#Inject
#Getter
#Setter
private Customer customer;
public String persist() {
try {
ut.begin();
EntityManager entityManager = emf.createEntityManager();
entityManager.persist(customer); // HERE the error is thrown
ut.commit();
FacesMessage m = new FacesMessage("Succesfully registered!", "Your email was saved under id " + customer.getId());
FacesContext.getCurrentInstance().addMessage("registerForm", m);
} catch (NotSupportedException | SystemException | RollbackException | HeuristicMixedException | HeuristicRollbackException | SecurityException | IllegalStateException e) {
e.printStackTrace();
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_WARN, e.getMessage(), e.getCause().getMessage());
FacesContext.getCurrentInstance().addMessage("registerForm", m);
}
return "/register.jsf";
}
}
Any idea where the problem could be?
Your #Entity entity bean is all fine. Don't modify it. Making it an EJB would indeed cause the described exception because the EJB container creates a proxy around the class which in turn isn't recognized as a JPA entity.
Your #Named managed bean is wrong. It is tight coupled with EJB responsibilities (persistence and transaction management). Split off EJB responsibilities into a real #Stateless session bean and have the managed bean invoke it.
#Stateless
public class RegisterService {
#PersistenceContext
private EntityManager entityManager;
public void persist(Customer customer) {
entityManager.persist(customer);
}
}
#Named
#RequestScoped
public class RegisterController {
#Inject
private Customer customer;
#EJB
private RegisterService registerService;
public String submit() {
FacesMessage m;
try {
registerService.persist(customer);
m = new FacesMessage("Succesfully registered!", "Your email was saved under id " + customer.getId());
} catch (Exception e) {
m = new FacesMessage(FacesMessage.SEVERITY_WARN, e.getMessage(), e.getCause().getMessage());
}
FacesContext.getCurrentInstance().addMessage("registerForm", m);
return "/register.jsf";
}
// ...
}
Note that you do not need to manually fiddle with user transactions in the real EJB. Only the #Inject on Customer is kind of weird. I'm not sure what the #Data does, but if it has the same effect as CDI's #Model annotation, then that's OK. Otherwise head off to second link below for concrete examples and more links.
See also:
When is it necessary or convenient to use Spring or EJB3 or all of them together?
JSF Controller, Service and DAO

Running Liquibase with CDI on Wildfly 8

I am trying to run Liquibase scripts using CDI on WildFly 8.1.0.Final and I am getting this error:
Unsatisfied dependencies for type ResourceAccessor with qualifiers #LiquibaseType
My POM has these dependencies:
<dependencies>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-cdi</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.mattbertolini</groupId>
<artifactId>liquibase-slf4j</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
My CDI Bean is as follows:
import javax.annotation.Resource;
import javax.enterprise.inject.Produces;
import javax.sql.DataSource;
import liquibase.integration.cdi.CDILiquibaseConfig;
import liquibase.integration.cdi.annotations.LiquibaseType;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.ResourceAccessor;
public class LiquibaseStarter {
#Produces
#LiquibaseType
public CDILiquibaseConfig createConfig() {
CDILiquibaseConfig config = new CDILiquibaseConfig();
config.setChangeLog("liquibase/parser/core/xml/simpleChangeLog.xml");
return config;
}
#Resource(name="java:jboss/datasources/ExampleDS")
private DataSource ds;
#Produces
#LiquibaseType
public DataSource createDataSource() {
return ds;
}
#Produces
#LiquibaseType
public ResourceAccessor create() {
return new ClassLoaderResourceAccessor(getClass().getClassLoader());
}
}
My project is a simple WAR. What am I doing wrong?
LiquibaseStarter has no bean-defining annotation. Add #Dependent at class-level.

i am getting nullpointer exception while using session ejb in my managed bean

my sessionfacade class
package com.entity;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class UsersFacade extends AbstractFacade<Users> implements UsersFacadeLocal
{
#PersistenceContext(unitName = "My_communityPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public UsersFacade() {
super(Users.class);
}
}
my managed bean class
package com.jsf;
import com.entity.Users;
import com.entity.UsersFacadeLocal;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.ManagedBean;
import javax.ejb.EJB;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
#Named(value = "loginMB")
#ManagedBean
#SessionScoped
public class LoginMB implements Serializable {
#EJB
private UsersFacadeLocal usersFacade;
protected Users user;
protected List<Users> lusers;
protected String username;
protected String password;
public LoginMB() {
lusers=usersFacade.findAll();
}
}
I dont know why my ejb injection in to mangedbean is not working. I am getting null pointer exception when i am calling findall(); method by using usersFacade
I am working on netbeans ide with glassfish server. i am just learning jpa in jsf please let me know where i am doing wrong
Container injects the EJB only after instantiating the managed bean. Use #PostConstruct annotation and use the EJB there. The annotated method will be called after the injection.

Resources