2015-12-21 57 views
0

我一直試圖在上週得到一堆Java EE和EJB。將EJB添加到JNDI中,但無法使用@EJB注入

我已經能夠創建實體,DAO,持久單位等,但我仍然遇到一些問題。

在我的項目中,我有作者和書籍班。這些反過來又有各自的DAO。 (下面列出)

問題是,我的EJB正在創建並正確添加到JNDI樹,只是我似乎無法將它們注入到我的AuthorAPI REST提供程序中......當我調用AuthorAPI .getAllAuthors方法,服務器響應指向AuthorDAO對象爲空的500錯誤。

任何幫助將不勝感激!

TomEE登錄

INFO: PersistenceUnit(name=libraryPU, provider=org.hibernate.ejb.HibernatePersistence) - provider time 969ms 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=BookDAOLocalBean) --> Ejb(deployment-id=BookDAO) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/BookDAO!org.ucll.rest.dao.BookDAO) --> Ejb(deployment-id=BookDAO) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/BookDAO) --> Ejb(deployment-id=BookDAO) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=AuthorDAOLocalBean) --> Ejb(deployment-id=AuthorDAO) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/AuthorDAO!org.ucll.rest.dao.AuthorDAO) --> Ejb(deployment-id=AuthorDAO) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/AuthorDAO) --> Ejb(deployment-id=AuthorDAO) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=AuthorLocalBean) --> Ejb(deployment-id=Author) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/Author!org.ucll.rest.model.Author) --> Ejb(deployment-id=Author) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/Author) --> Ejb(deployment-id=Author) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=BookLocalBean) --> Ejb(deployment-id=Book) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/Book!org.ucll.rest.model.Book) --> Ejb(deployment-id=Book) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.JndiBuilder bind 
INFO: Jndi(name=global/rest-web/Book) --> Ejb(deployment-id=Book) 
dec 21, 2015 2:25:53 PM org.apache.openejb.cdi.CdiBuilder initSingleton 
INFO: Existing thread singleton service in SystemInstance(): [email protected] 
dec 21, 2015 2:25:53 PM org.apache.openejb.cdi.OpenEJBLifecycle startApplication 
INFO: OpenWebBeans Container is starting... 
dec 21, 2015 2:25:53 PM org.apache.openejb.cdi.OpenEJBLifecycle startApplication 
INFO: OpenWebBeans Container has started, it took 19 ms. 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Created Ejb(deployment-id=AuthorDAO, ejb-name=AuthorDAO, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Created Ejb(deployment-id=Book, ejb-name=Book, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Created Ejb(deployment-id=Author, ejb-name=Author, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Created Ejb(deployment-id=BookDAO, ejb-name=BookDAO, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Started Ejb(deployment-id=AuthorDAO, ejb-name=AuthorDAO, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Started Ejb(deployment-id=Book, ejb-name=Book, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Started Ejb(deployment-id=Author, ejb-name=Author, container=Default Stateless Container) 
dec 21, 2015 2:25:53 PM org.apache.openejb.assembler.classic.Assembler startEjbs 
INFO: Started Ejb(deployment-id=BookDAO, ejb-name=BookDAO, container=Default Stateless Container) 

HTTP狀態500堆棧跟蹤

javax.servlet.ServletException: java.lang.NullPointerException 
    org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:487) 
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223) 
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 

root cause 

java.lang.NullPointerException 
    org.ucll.rest.web.api.AuthorAPI.getAllAuthors(AuthorAPI.java:25) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    java.lang.reflect.Method.invoke(Method.java:497) 
    org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) 
    org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) 
    org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) 
    org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) 
    org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 
    org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 
    org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 
    org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 
    org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) 
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
    org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
    org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
    org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) 
    org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
    org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471) 
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336) 
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223) 
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 

Author.java
package org.ucll.rest.model; 

import java.io.Serializable; 
import java.util.List; 
import javax.ejb.Stateless; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 

/** 
* 
* @author larsv 
*/ 
@Entity 
@Table(name = "author", schema = "library") 
@Stateless 
public class Author implements Serializable { 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private long id; 

    @Column(name = "name", length = 100, nullable = false) 
    private String name; 

    @OneToMany(mappedBy = "author") 
    private List<Book> books; 

    public Author() {} 

    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public List<Book> getBooks() { 
     return books; 
    } 

    public void setBooks(List<Book> books) { 
     this.books = books; 
    } 
} 

Book.java
package org.ucll.rest.model; 

import java.io.Serializable; 
import javax.ejb.Stateless; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 

/** 
* 
* @author larsv 
*/ 
@Entity 
@Table(name = "book", schema = "library") 
@Stateless 
public class Book implements Serializable { 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private long id; 

    @Column(name = "title", length = 100, nullable = false) 
    private String title; 

    @ManyToOne 
    @JoinColumn(name = "name") 
    private Author author; 

    public Book() {} 

    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public Author getAuthor() { 
     return author; 
    } 

    public void setAuthor(Author author) { 
     this.author = author; 
    } 
} 

AuthorDAO.java

package org.ucll.rest.dao; 

import javax.ejb.Stateless; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import org.ucll.rest.model.Author; 

/** 
* 
* @author larsv 
*/ 
@Stateless 
public class AuthorDAO extends AbstractDAO<Author> { 
    @PersistenceContext(unitName = "libraryPU") 
    private EntityManager em; 

    public AuthorDAO() { 
     super(Author.class); 
    } 

    @Override 
    protected EntityManager getEntityManager() { 
     return em; 
    } 
} 

BookDAO.java

package org.ucll.rest.dao; 

import javax.ejb.Stateless; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import org.ucll.rest.model.Book; 

/** 
* 
* @author larsv 
*/ 
@Stateless 
public class BookDAO extends AbstractDAO<Book> { 
    @PersistenceContext(unitName = "libraryPU") 
    private EntityManager em; 

    public BookDAO() { 
     super(Book.class); 
    } 

    @Override 
    protected EntityManager getEntityManager() { 
     return em; 
    } 
} 

AuthorAPI.java

package org.ucll.rest.web.api; 

import javax.ejb.EJB; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import org.ucll.rest.dao.AuthorDAO; 
import org.ucll.rest.web.helper.JSONConverter; 

/** 
* 
* @author larsv 
*/ 
@Path("/author") 
public class AuthorAPI { 
    @EJB 
    private AuthorDAO authorDAO; 

    @GET 
    @Path("/all") 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getAllAuthors() { 
     String json_response = JSONConverter.covertAuthorList(authorDAO.readAll()); 
     return Response.status(200).entity(json_response).build(); 
    } 
} 

的persistence.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="libraryPU" transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <jta-data-source>jdbc/library</jta-data-source> 
    <class>org.ucll.rest.model.Author</class> 
    <class>org.ucll.rest.model.Book</class> 

    <properties> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> 
     <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/> 
     <property name="hibernate.hbm2ddl.auto" value="create-drop"/> 
    </properties> 
    </persistence-unit> 
</persistence> 

回答

0

的原因,您的@EJB沒有被解決的是你是n在EE容器上下文中。 最簡單的解決方案是使您的web服務成爲EJB。 這可以通過將無狀態註釋來完成:

@Path("/author") 
@Stateless 
public class AuthorAPI { 

在此之後改變你的刀應該得到注入到它。

在一個側面說明一些技巧爲你的代碼,這可能有助於防止未來的問題: 您應該

private AuthorDAO authorDAO; 

提供的getter/setter方法否則容器注入不能在運行時執行。

在相關說明上:我不知道您使用的是什麼版本的EJB,但在3.0中爲您的EJB創建接口是必需的。從3.1開始不再需要,但我仍然認爲最好的做法是編寫vs接口而不是vs實現類。

+0

感謝您的快速回答! 我重構了代碼來處理接口而不是實現類,並在我的REST API中添加了setter/getter,但這似乎並沒有解決問題。 我試圖打印出完整的JNDI樹,但它似乎總是空的......任何想法,爲什麼這可能是? –

+0

看看這個問題:http://stackoverflow.com/questions/3027834/inject-an-ejb-into-jax-rs-restful-service看來,我看着你在一個web服務調用的事實。在這種情況下,您將手動輸入DI – steelshark

+0

我編輯了我的原始答案以包含建議,使您的webservice成爲EJB。這應該可以解決您的問題。 – steelshark