简体   繁体   English

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

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

I've been trying to get a hang of Java EE and EJB over the last week. 在过去的一周中,我一直试图摆脱Java EE和EJB的困扰。

I've been able to create the entities, DAOs, persistance units and such, but I'm still running into some issues. 我已经能够创建实体,DAO,持久性单元等,但是我仍然遇到一些问题。

In my project, I have an Author and a Book class. 在我的项目中,我有一个Author和一个Book类。 These, in turn, have their respective DAOs. 这些依次具有各自的DAO。 (Listed below) (下面列出)

The issue is, my EJBs are being created and added to the JNDI tree correctly, only I can't seem to be able to inject them into my AuthorAPI REST provider... When I call the AuthorAPI.getAllAuthors method, the server responds with a 500 error pointing to the AuthorDAO object being null. 问题是,我的EJB正在正确创建并添加到JNDI树中,只有我似乎无法将它们注入到我的AuthorAPI REST提供程序中。当我调用AuthorAPI.getAllAuthors方法时,服务器将响应指向AuthorDAO对象为null的500错误。

Any help would be greatly appreciated! 任何帮助将不胜感激!

TomEE log 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 Status 500 stacktrace 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 作者.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 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 作者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 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 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 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>

The reason your @EJB is not being resolved is that you are not in the EE container context. 无法解析@EJB的原因是您不在EE容器上下文中。 The easiest solution for this is to make your webservice an EJB. 最简单的解决方案是使Web服务成为EJB。 This can be done by adding the stateless annotation: 这可以通过添加无状态注释来完成:

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

After this change your dao should get injected into it. 更改之后,您的dao应该被注入其中。

On a side note some tips for your code that might help prevent future problems : You should provide a getter/setter method for 附带说明一下,一些代码提示可能有助于防止将来出现问题:您应该为以下代码提供一种getter / setter方法:

private AuthorDAO authorDAO;

Otherwise the container cant inject the implementation at runtime. 否则,容器将无法在运行时注入实现。

On a related note: I dont know what version of EJB you are using but in 3.0 it was necessairy to create an interface for your EJB's. 在相关说明中:我不知道您使用的是哪个版本的EJB,但在3.0中,有必要为EJB的接口创建接口。 Since 3.1 it is not needed anymore but I still consider it to be best practice to code vs an interface instead of vs an implementation class. 从3.1开始,不再需要它了,但是我仍然认为最好是对接口而不是对实现类进行编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM