我使用Java EE 8,JSF和JPA创建了一个小型在线商店。每当在我的代码中(在Item item1 = itemDAO.findById(1);
中调用行ShoppingCartPresenter.class
时,我都会得到一个空指针异常。每当我尝试加载showcart.xhtml
JSF文件时,都会出现异常。当我尝试调试程序时,我看到itemDAO
不为null。我还注意到,从未输入findById()
方法。我怀疑这是注入问题,但是我真的不确定,因为异常消息确实无法帮助我找到问题的根源。
能否请您帮我找出在哪里发生空指针异常?
异常堆栈:
org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void com.javaproject.musicbox.managedbeans.storefront.ShoppingCartPresenter.init() on com.javaproject.musicbox.managedbeans.storefront.ShoppingCartPresenter@41230ce7
at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:85)
at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.postConstruct(DefaultLifecycleCallbackInvoker.java:66)
at org.jboss.weld.injection.producer.BasicInjectionTarget.postConstruct(BasicInjectionTarget.java:122)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:162)
at org.jboss.weld.util.bean.IsolatedForwardingBean.create(IsolatedForwardingBean.java:45)
at org.jboss.weld.contexts.AbstractContext.get(AbstractContext.java:96)
at org.jboss.weld.contexts.PassivatingContextWrapper$AbstractPassivatingContextWrapper.get(PassivatingContextWrapper.java:76)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:100)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.get(ContextualInstanceStrategy.java:177)
at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:700)
at org.jboss.weld.module.web.el.AbstractWeldELResolver.lookup(AbstractWeldELResolver.java:107)
at org.jboss.weld.module.web.el.AbstractWeldELResolver.getValue(AbstractWeldELResolver.java:90)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:188)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:180)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:208)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:116)
at com.sun.el.parser.AstValue.getBase(AstValue.java:151)
at com.sun.el.parser.AstValue.getValue(AstValue.java:200)
at com.sun.el.parser.AstNot.getValue(AstNot.java:63)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:97)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:337)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1663)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1673)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1673)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:492)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:194)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:156)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:126)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:223)
at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:732)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:475)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1628)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:755)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:575)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:520)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:217)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:524)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:89)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:94)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:33)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:83)
... 63 more
Caused by: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:446)
at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2635)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:2028)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90)
at com.sun.proxy.$Proxy332.findById(Unknown Source)
at com.javaproject.musicbox.daos.__EJB31_Generated__ItemDAO__Intf____Bean__.findById(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:410)
at org.jboss.weld.module.ejb.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:134)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.module.ejb.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:68)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
at com.javaproject.musicbox.daos.ItemDAO$Proxy$_$$_Weld$EnterpriseProxy$.findById(Unknown Source)
at com.javaproject.musicbox.managedbeans.storefront.ShoppingCartPresenter.init(ShoppingCartPresenter.java:32)
... 68 more
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:715)
at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:219)
at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:442)
... 85 more
Caused by: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:525)
at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:99)
at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:713)
... 87 more
Caused by: java.lang.reflect.InvocationTargetException
at com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1738)
at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:467)
... 89 more
Caused by: java.lang.NullPointerException
at com.sun.ejb.containers.interceptors.CallbackInvocationContext.<init>(CallbackInvocationContext.java:119)
at com.sun.ejb.containers.interceptors.CallbackInvocationContext.<init>(CallbackInvocationContext.java:134)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:399)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:380)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:2071)
at org.glassfish.weld.services.JCDIAroundConstructCallback.aroundConstruct(JCDIAroundConstructCallback.java:83)
at org.jboss.weld.injection.ConstructorInjectionPoint.invokeAroundConstructCallback(ConstructorInjectionPoint.java:109)
at org.jboss.weld.injection.ConstructorInjectionPoint.invokeAroundConstructCallbacks(ConstructorInjectionPoint.java:95)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:78)
at org.jboss.weld.injection.producer.AbstractInstantiator.newInstance(AbstractInstantiator.java:28)
at org.jboss.weld.injection.producer.BasicInjectionTarget.produce(BasicInjectionTarget.java:112)
at org.jboss.weld.injection.producer.BeanInjectionTarget.produce(BeanInjectionTarget.java:186)
at org.jboss.weld.module.ejb.SessionBeanInjectionTarget.produce(SessionBeanInjectionTarget.java:124)
at org.glassfish.weld.services.JCDIServiceImpl._createJCDIInjectionContext(JCDIServiceImpl.java:260)
at org.glassfish.weld.services.JCDIServiceImpl.createJCDIInjectionContext(JCDIServiceImpl.java:188)
at com.sun.ejb.containers.BaseContainer._createJCDIInjectionContext(BaseContainer.java:1768)
at com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1719)
... 90 more
ShoppingCartPresenter.class:
package com.javaproject.musicbox.managedbeans.storefront;
import com.javaproject.musicbox.daos.ItemDAO;
import com.javaproject.musicbox.daos.ShoppingCartDAO;
import com.javaproject.musicbox.entities.Item;
import com.javaproject.musicbox.entities.ShoppingCart;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Named
@SessionScoped
public class ShoppingCartPresenter implements Serializable {
private ShoppingCart shoppingCart;
@Inject private ShoppingCartDAO shoppingCartDAO;
@Inject private ItemDAO itemDAO;
@PostConstruct
private void init() {
// Since we don't have logged in users yet, every time a session is created
// a new cart is created for this session. Later a check will be needed to
// verify if the user is logged and load his cart if he is logged in
shoppingCart = new ShoppingCart();
Item item1 = itemDAO.findById(1);
Item item2 = itemDAO.findById(2);
Item item3 = itemDAO.findById(3);
shoppingCart.addItem(item1);
shoppingCart.addItem(item2);
shoppingCart.addItem(item3);
}
/**
* This addItemToCart() method adds an item to the cart
*
* @param itemId The id of the item to add
*/
public void addItemToCart(int itemId) {
// Finding the item with the itemId that was passed to the method
Item itemAdded = itemDAO.findById(itemId);
shoppingCart.addItem(itemAdded);
}
/**
* This removeItemFromCart() method removes an item from the cart
*
* @param itemId The id of the item to remove
*/
public void removeItemFromCart(int itemId) {
Item itemToRemove = itemDAO.findById(itemId);
shoppingCart.removeItem(itemToRemove);
}
/**
* The isCartEmpty() method verifies if the cart is empty
*
* @return True if the shopping cart is true
*/
public boolean isCartEmpty() {
return shoppingCart.getItems().size() == 0;
}
/**
* Calculate the total price of the cart
*
* TODO Add taxes
*
* @return The total price of the cart
*/
public double calculateTotal() {
double total = 0;
for (Item item: shoppingCart.getItems()) {
total += item.getListPrice();
}
return total;
}
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
}
AbstractDAO.class:
package com.javaproject.musicbox.daos;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import java.util.List;
/**
* The AbstractDAO contains the common functionality for almost all the DAOs,
* for example, create(), findById(), update(), delete() ...
*
* @param <T> The type of the Entity
*/
public abstract class AbstractDAO<T> {
@PersistenceContext(unitName = "bookspu")
protected EntityManager entityManager;
private Class<T> entityClass;
public AbstractDAO(Class<T> entityClass)
{
this.entityClass = entityClass;
}
/**
* Creates an entity (i.e. takes an entity object and persists it)
*
* @param entity The entity to create
* @return The same entity that was created
*/
public T create(T entity) {
entityManager.persist(entity);
return entity;
}
/**
* Finds an entity by id
*
* @param id The id of the entity to find
* @return The entity that has the id that was searched
*/
public T findById(int id) {
return entityManager.find(entityClass, id);
}
/**
* Updates an entity
*
* @param entity The entity to update
* @return The same entity that was updated
*/
public T update(T entity) {
return entityManager.merge(entity);
}
/**
* Deletes an entity from the database
*
* @param entity The entity to remove
*/
public void delete(T entity) {
entityManager.remove(entityManager.merge(entity));
}
}
ItemDAO.class
package com.javaproject.musicbox.daos;
import com.javaproject.musicbox.entities.Item;
import javax.ejb.Stateless;
import java.io.Serializable;
/**
* The ItemDAO is a data access class that is responsible for the
* Item Entity
*/
@Stateless
public class ItemDAO extends AbstractDAO<Item> implements Serializable {
ItemDAO () {
super(Item.class);
}
}
ShoppingCart.class
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.javaproject.musicbox.entities;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import javax.persistence.*;
/**
* The Shopping Cart entity
*
* @author Yanik
*/
@Entity
@Table(name = "shopping_cart")
public class ShoppingCart implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "shopping_cart_id")
private int shoppingCartId;
@JoinTable(
name = "shopping_cart_item",
joinColumns = @JoinColumn(name = "shopping_cart_id"),
inverseJoinColumns = @JoinColumn(name = "item_id")
)
@ManyToMany
private List<Item> items;
public int getShoppingCartId() {
return shoppingCartId;
}
public void setShoppingCartId(int shoppingCartId) {
this.shoppingCartId = shoppingCartId;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public void addItem(Item item) {
items.add(item);
}
public void removeItem(Item item) {
items.remove(item);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ShoppingCart that = (ShoppingCart) o;
return Objects.equals(shoppingCartId, that.shoppingCartId);
}
@Override
public int hashCode() {
return Objects.hash(shoppingCartId);
}
@Override
public String toString() {
return "ShoppingCart{" +
"shoppingCartId=" + shoppingCartId +
", items=" + items +
'}';
}
}
Item.class
package com.javaproject.musicbox.entities;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* The Item entity
*
* @author Yanik
*/
@Entity
@Table(name = "item")
public class Item implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id")
private int itemId;
@Column(name = "list_price")
private double listPrice;
@Column(name = "cost_price")
private double costPrice;
@Size(min = 1, max = 50)
@Column(name = "name")
private String name;
@Size(max = 200)
@Column(name = "picture_path")
private String picturePath;
@Temporal(TemporalType.DATE)
@Column(name = "date_added")
private Date dateAdded;
@Temporal(TemporalType.DATE)
@Column(name = "date_removed")
private Date dateRemoved;
@ManyToMany(mappedBy = "items")
private List<ShoppingCart> shoppingCarts;
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
public double getListPrice() {
return listPrice;
}
public void setListPrice(double listPrice) {
this.listPrice = listPrice;
}
public double getCostPrice() {
return costPrice;
}
public void setCostPrice(double costPrice) {
this.costPrice = costPrice;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPicturePath() {
return picturePath;
}
public void setPicturePath(String picturePath) {
this.picturePath = picturePath;
}
public Date getDateAdded() {
return dateAdded;
}
public void setDateAdded(Date dateAdded) {
this.dateAdded = dateAdded;
}
public Date getDateRemoved() {
return dateRemoved;
}
public void setDateRemoved(Date dateRemoved) {
this.dateRemoved = dateRemoved;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
return itemId == item.itemId;
}
@Override
public int hashCode() {
return Objects.hash(itemId);
}
@Override
public String toString() {
return "Item{" +
"itemId=" + itemId +
", listPrice=" + listPrice +
", costPrice=" + costPrice +
", name='" + name + '\'' +
", picturePath='" + picturePath + '\'' +
", dateAdded=" + dateAdded +
", dateRemoved=" + dateRemoved +
", shoppingCarts=" + shoppingCarts +
'}';
}
}
showcart.xhtml(JSF文件):
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/templates/storefrontTemplate.xhtml">
<ui:define name="content">
<h:form rendered="#{!shoppingCartPresenter.cartEmpty}">
<h:dataTable value="#{shoppingCartPresenter.shoppingCart.items}" var="item" styleClass="table">
<!-- ITEM PICTURE -->
<h:column>
<h:graphicImage url="/resources/images/music.png" alt="Item"/>
</h:column>
<!-- ITEM NAME -->
<h:column>
<h:outputText value="#{item.name}"/>
</h:column>
<!-- ITEM PRICE -->
<h:column>
<h:outputText value="#{item.listPrice}"/> $
</h:column>
<!-- REMOVE FROM CART BUTTON -->
<h:column>
<h:commandLink action="#{shoppingCartPresenter.removeItemFromCart(item.itemId)}"
styleClass="remove-from-cart"
value="Remove">
</h:commandLink>
</h:column>
</h:dataTable>
<br/>
<!-- TOTAL PRICE -->
<div>
Total $
<h:outputText value="#{shoppingCartPresenter.calculateTotal}"/>
</div>
</h:form>
</ui:define>
</ui:composition>
</html>
答案 0 :(得分:1)
您的基本bean类不是托管类,但是正在尝试注入@PersistenceContext,这将始终失败,从而导致NPE。
我以前见过这种“把戏”,这是不必要的技巧。使您的EJB简单,精简。顺便说一句,如果您使用EJB,则不需要DAO层(在某些特殊情况下除外),因为JPA是您的DAO层。只需简化您的ejb并直接从中拨打电话即可。