簡體   English   中英

EJB已添加到JNDI,但無法使用@EJB注入

[英]EJB added to JNDI, but can't inject with @EJB

在過去的一周中,我一直試圖擺脫Java EE和EJB的困擾。

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

在我的項目中,我有一個Author和一個Book類。 這些依次具有各自的DAO。 (下面列出)

問題是,我的EJB正在正確創建並添加到JNDI樹中,只有我似乎無法將它們注入到我的AuthorAPI REST提供程序中。當我調用AuthorAPI.getAllAuthors方法時,服務器將響應指向AuthorDAO對象為null的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(): org.apache.openejb.cdi.ThreadSingletonServiceImpl@80169cf
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)

作者.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;
    }
}

作者DAO.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>

無法解析@EJB的原因是您不在EE容器上下文中。 最簡單的解決方案是使Web服務成為EJB。 這可以通過添加無狀態注釋來完成:

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

更改之后,您的dao應該被注入其中。

附帶說明一下,一些代碼提示可能有助於防止將來出現問題:您應該為以下代碼提供一種getter / setter方法:

private AuthorDAO authorDAO;

否則,容器將無法在運行時注入實現。

在相關說明中:我不知道您使用的是哪個版本的EJB,但在3.0中,有必要為EJB的接口創建接口。 從3.1開始,不再需要它了,但是我仍然認為最好是對接口而不是對實現類進行編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM