使用Glassfish的EJB JNDI

时间:2012-03-20 17:22:08

标签: servlets glassfish ejb jndi

我正在尝试让EJB与Glassfish v3一起使用。我正在使用Servlets开发Java EE Web应用程序。

当我将此Web应用程序部署到Glassfish时,它会将EJB类注册到

java:global JNDI树。但是,当我尝试将此实例注入我的

Servlet我得到了NameNotFoundException

当我查看服务器的日志时,Servlet会尝试在java:comp/env中进行查找。

有人可以帮我解决这个问题吗?

登录部分的相关代码:

UserDao.java

@Local
public interface UserDao {
    public User find(Long id);

    public List<User> findAll();

    public List<User> paginate(int offset, int nbentry) throws IllegalArgumentException, IllegalStateException;

    public User findUserByUsernameAndPassword(String username, String password);

    public User create(User user) throws UserException;

    public User update(User user) throws UserException;

    public Boolean delete(User user) throws UserException;

    public int count();
}

JpaUserDao.java

@Stateless
public class JpaUserDao implements UserDao {
    private Logger log = Logger.getLogger(JpaUserDao.class.getSimpleName());
    @PersistenceContext(unitName = "YouFood-PU")
    private EntityManager em;

    @Override
    public User create(User user) throws UserException {
        try {
            em.persist(user);
    } catch (Exception e) {

        throw new UserException("Creation of the user: " + user
                + " failed, please try later or contact the webmaster");
    }

    return user;
}

@Override
public User update(User user) throws UserException {
    try {
        em.persist(em.merge(user));
    } catch (Exception e) {
        throw new UserException("Update of the user: " + user
                + " failed, please try later or contact the webmaster");
    }

    return user;
}

@Override
public Boolean delete(User user) throws UserException {
    try {
        em.remove(em.merge(user));
        return true;
    } catch (Exception e) {
        throw new UserException("Deletion of the user: " + user
                + " failed, please try later or contact the webmaster");
    }
}

@Override
public User find(Long id) {
    User user = new User();

    try {
        user = em.find(User.class, id);
        return user;
    } catch (Exception e) {
        return null;
    }
}

@Override
public User findUserByUsernameAndPassword(String username, String password) {
    User user = null;
    try {
        log.info("findUserByUsernameAndPassword");
        user = (User) em
                .createQuery(
                        "SELECT u FROM User AS u where u.username = :username AND u.password = :password ")
                .setParameter("username", username)
                .setParameter("password", password).getSingleResult();
        return user;
    } catch (Exception e) {
        e.printStackTrace();
        log.severe(e.getStackTrace().toString());
        return null;
    }
}

@SuppressWarnings("unchecked")
@Override
public List<User> findAll() {
    List<User> users = null;
    try {

        users = (List<User>) em.createQuery("SELECT u FROM User u")
                .getResultList();
        return users;
    } catch (Exception e) {
        return null;
    }

}

@SuppressWarnings("unchecked")
@Override
public List<User> paginate(int offset, int nbentry)
        throws IllegalArgumentException, IllegalStateException {
    List<User> users = null;

    users = (List<User>) em.createQuery("FROM User").setFirstResult(offset)
            .setMaxResults(nbentry).getResultList();

    return users;
}

@Override
public int count() {
    Number count;

    count = (Number) em.createQuery("SELECT COUNT(u.id) FROM User")
            .getSingleResult();

    return count.intValue();
}
}

Authenticator.java

@Stateless
public class Authenticator {

private String userFullName;
private Long userId;

@EJB
private JpaUserDao userDao;

public Authenticator() {}

public AuthenticationError connect(String username, String password)
        throws Exception {

    String hashed_password = Authenticator.hash(password, "UTF-8");

    User user = null;

    user = userDao.findUserByUsernameAndPassword(username,
            hashed_password);

    if (user == null) {
        return AuthenticationError.UserNotFound;
    }

    this.userFullName = user.toString();
    this.userId = user.getId();

    return AuthenticationError.Success;
}

public Boolean disconnect(HttpSession session) throws Exception {
    try {
        session.invalidate();
        return true;
    } catch (Exception e) {
        return false;
    }

}

public String getUserFullName() {
    return this.userFullName;
}

public Long getUserId() {
    return this.userId;
}

/**
 * 
 * Static method
 * 
 * @throws Exception
 * 
 */

public static String hash(String data, String charset) throws Exception {
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.reset();
    md.update(data.getBytes(charset), 0, data.length());
    String hash = new BigInteger(1, md.digest()).toString(16);
    return hash;
}

}

LoginServlet.java

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private Logger log = Logger.getLogger(LoginServlet.class.getSimpleName());
@EJB
private Authenticator auth;

/**
 * @see HttpServlet#HttpServlet()
 */
public LoginServlet() {
    super();
    // TODO Auto-generated constructor stub
}

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    log.info("LoginServlet.deGet() call");
    request.getRequestDispatcher("/jsp/login.jsp").forward(request, response);
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    //auth = new Authenticator();

    log.info("LoginServlet.dePost() call");
    String message = null;
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    log.info("username: " + username);
    log.info("password: " + password);

    try {
        AuthenticationError status = auth.connect(username, password);
        System.out.println(status);
        switch (status) {
            case PasswordMissMatch:
                message = "Password missmatch";
                log.info(message);
                request.setAttribute("error", message);
                request.getRequestDispatcher("/jsp/login.jsp").forward(request, response);
                break;
            case Success:
                message = "Your are successfully logged in";
                log.info(message);
                request.setAttribute("success", message);
                request.getSession().setAttribute("loggedIn", true);
                request.getSession().setAttribute("full_name", auth.getUserFullName());
                request.getSession().setAttribute("user_id", auth.getUserId());
                break;
            case UserNotFound:
                message = "Username provided not found in our record";
                log.info(message);
                request.setAttribute("error", message);
                request.getRequestDispatcher("/jsp/login.jsp").forward(request, response);
                break;
        }
    } catch (GeneralSecurityException e) {

        message = e.getMessage();
        request.setAttribute("error", message);

    } catch (Exception e) {
        message = e.getMessage();
        request.setAttribute("error", message);
    }

    request.getRequestDispatcher("/home").forward(request, response);
}
}

Glassfish部署日志

INFO: closing
ATTENTION: DPL8027: Ignore WEB-INF/sun-web.xml in archive 
/Users/guillaume/Documents/workspace/Supinfo/YouFood/nbbuild/web/, as GlassFish 
counterpart runtime xml WEB-INF/glassfish-web.xml is present in the same 
archive.

INFO: Processing PersistenceUnitInfo [
    name: YouFood-PU
    ...]
INFO: Binding entity from annotated class: com.youfood.entity.Menu
INFO: Bind entity com.youfood.entity.Menu on table Menu
INFO: Binding entity from annotated class: com.youfood.entity.DinningRoom
INFO: Bind entity com.youfood.entity.DinningRoom on table DinningRoom
INFO: Binding entity from annotated class: com.youfood.entity.Item
INFO: Bind entity com.youfood.entity.Item on table Item
INFO: Binding entity from annotated class: com.youfood.entity.TTable
INFO: Bind entity com.youfood.entity.TTable on table TTable
INFO: Binding entity from annotated class: com.youfood.entity.Zone
INFO: Bind entity com.youfood.entity.Zone on table Zone
INFO: Binding entity from annotated class: com.youfood.entity.Country
INFO: Bind entity com.youfood.entity.Country on table Country
INFO: Binding entity from annotated class: com.youfood.entity.User
INFO: Bind entity com.youfood.entity.User on table User
INFO: Binding entity from annotated class: com.youfood.entity.Order
INFO: Bind entity com.youfood.entity.Order on table OrderTable
INFO: Binding entity from annotated class: com.youfood.entity.Restaurant
INFO: Bind entity com.youfood.entity.Restaurant on table Restaurant
INFO: Mapping collection: com.youfood.entity.DinningRoom.zones -> Zone
INFO: Mapping collection: com.youfood.entity.Zone.tables -> TTable
INFO: Mapping collection: com.youfood.entity.Country.restaurants -> Restaurant
INFO: Mapping collection: com.youfood.entity.Restaurant.dinningRoom -> DinningRoom
INFO: Hibernate Validator not found: ignoring
INFO: Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
INFO: Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
INFO: Using provided datasource
INFO: RDBMS: MySQL, version: 5.1.54
INFO: JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.13 ( Revision: ${bzr.revision-id} )
INFO: Using dialect: org.hibernate.dialect.MySQLDialect
INFO: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
INFO: Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory
INFO: instantiating TransactionManagerLookup: org.hibernate.transaction.SunONETransactionManagerLookup
INFO: instantiated TransactionManagerLookup
INFO: Automatic flush during beforeCompletion(): disabled
INFO: Automatic session close at end of transaction: disabled
INFO: JDBC batch size: 15
INFO: JDBC batch updates for versioned data: disabled
INFO: Scrollable result sets: enabled
INFO: JDBC3 getGeneratedKeys(): enabled
INFO: Connection release mode: auto
INFO: Maximum outer join fetch depth: 2
INFO: Default batch fetch size: 1
INFO: Generate SQL with comments: disabled
INFO: Order SQL updates by primary key: disabled
INFO: Order SQL inserts for batching: disabled
INFO: Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO: Using ASTQueryTranslatorFactory
INFO: Query language substitutions: {}
INFO: JPA-QL strict compliance: enabled
INFO: Second-level cache: enabled
INFO: Query cache: disabled
INFO: Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory
INFO: Optimize cache for minimal puts: disabled
INFO: Structured second-level cache entries: disabled
INFO: Statistics: disabled
INFO: Deleted entity synthetic identifier rollback: disabled
INFO: Default entity-mode: pojo
INFO: Named query checking : enabled
INFO: Check Nullability in Core (should be disabled when Bean Validation is on): disabled
INFO: building session factory
INFO: Not binding factory to JNDI, no JNDI name configured
INFO: JNDI InitialContext properties:{}
INFO: EJB5181:Portable JNDI names for EJB JpaUserDao: [java:global/YouFood/JpaUserDao, java:global/YouFood/JpaUserDao!com.youfood.dao.UserDao]
INFO: EJB5181:Portable JNDI names for EJB Authenticator: [java:global/YouFood/Authenticator!com.youfood.backoffice.utils.Authenticator, java:global/YouFood/Authenticator]
INFO: WEB0671: Loading application [YouFood] at [/web]
INFO: YouFood a été déployé en 1 279 ms.

服务器日志例外

GRAVE: EJB5070: Exception creating stateless session bean : [Authenticator]
ATTENTION: EJB5184:A system exception occurred during an invocation on EJB Authenticator, method: public com.youfood.backoffice.utils.AuthenticationError com.youfood.backoffice.utils.Authenticator.connect(java.lang.String,java.lang.String) throws java.lang.Exception
ATTENTION: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:454)
    at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2547)
    at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1899)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at $Proxy150.connect(Unknown Source)
    at com.youfood.backoffice.utils.__EJB31_Generated__Authenticator__Intf____Bean__.connect(Unknown Source)
    at com.youfood.backoffice.servlet.LoginServlet.doPost(LoginServlet.java:61)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:680)
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:726)
    at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:247)
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:449)
    ... 39 more
Caused by: javax.ejb.CreateException: Could not create stateless EJB
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:534)
    at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:95)
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:724)
    ... 41 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception lors de la tentative d'injection de l'élément Remote ejb-ref name=com.youfood.backoffice.utils.Authenticator/userDao,Remote 3.x interface =com.youfood.dao.jpa.JpaUserDao,ejb-link=null,lookup=,mappedName=,jndi-name=com.youfood.dao.jpa.JpaUserDao,refType=Session dans class com.youfood.backoffice.utils.Authenticator : Lookup failed for 'java:comp/env/com.youfood.backoffice.utils.Authenticator/userDao' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:703)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:470)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:171)
    at com.sun.ejb.containers.BaseContainer.injectEjbInstance(BaseContainer.java:1694)
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:494)
    ... 43 more
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/com.youfood.backoffice.utils.Authenticator/userDao' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.youfood.backoffice.utils.Authenticator/userDao,Remote 3.x interface =com.youfood.dao.jpa.JpaUserDao,ejb-link=null,lookup=,mappedName=,jndi-name=com.youfood.dao.jpa.JpaUserDao,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao' [Root exception is javax.naming.NamingException: Lookup failed for 'com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao not found]]]
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:599)
    ... 47 more
Caused by: javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.youfood.backoffice.utils.Authenticator/userDao,Remote 3.x interface =com.youfood.dao.jpa.JpaUserDao,ejb-link=null,lookup=,mappedName=,jndi-name=com.youfood.dao.jpa.JpaUserDao,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao' [Root exception is javax.naming.NamingException: Lookup failed for 'com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao not found]]
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:191)
    at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1109)
    at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:776)
    at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:744)
    at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:169)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:498)
    ... 51 more
Caused by: javax.naming.NamingException: Lookup failed for 'com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao not found]
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:186)
    ... 56 more
Caused by: javax.naming.NameNotFoundException: com.youfood.dao.jpa.JpaUserDao#com.youfood.dao.jpa.JpaUserDao not found
    at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
    at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
    at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
    at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
    ... 60 more

3 个答案:

答案 0 :(得分:3)

我的猜测是你指定了名字,地图名称和你有什么。这不是必需的。

以下内容应该有效:

EJB:

@Stateless
public class MyBean {
    // ...
}

的Servlet

@WebServlet(urlPatterns="/someurl")
public class MyServlet extends HttpServlet {

    @EJB
    private MyBean myBean;       

    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // ...
    }        
}

<强>更新

看到你的代码之后,问题不在于将EJB注入到Servlet中,而是在JpaUserDao中注入了Authenticator

您是按类注入的,但由于JpaUserDao实现了业务接口,因此无法正常工作:UserDao。因为它实现了这样的接口,所以不会创建本地视图。因此,您必须使用界面注入:

@Stateless
public class Authenticator {

    private String userFullName;
    private Long userId;

    @EJB
    private UserDao userDao;

    // ...
}

另外请注意,Authenticator bean的概念不起作用。它是一个无状态bean,它的实例变量对外界没有任何意义。因此,getUserFullName()无法保证返回您认为会返回的结果。当容器恰好选择相同的bean实例时,它可能会在测试中暂时发生,但这通常不起作用。

即使您坚持使用Authenticator的引用,它仍然无法正常工作。问题是你获得了一个代理,容器可能会将对它的每次调用都指向另一个实例。可以将其视为Web浏览器呼叫的Web场中服务器的URL。您无法保证连续两次将转到完全相同的物理服务器。

您尝试在那里进行的身份验证应该由Web层中的bean处理,并且HTTP会话中的身份验证详细信息(此外,您也应该使用容器身份验证,但这是一个另外这件事情太过于主题了)

答案 1 :(得分:1)

注入EJB有几种方法。最常见也是最简单的解决方案是通过 Arjan Tijms 回答的依赖注入

另一种方法是通过InitialContext.lookup()获取参考 在这种方法中,您可以选择传递的查找名称

  1. 使用声明Bean-Interface的类名

    String jindiName = BeanInterface.class.getName();
    InitialContext ctx = new InitialContext();
    BeanInterface bi = ctx.lookup(jndiName);
    

    这也适用于从任何独立客户端进行远程查找,因为界面是 public

  2. 使用组件命名环境的 JINDI名称

    String jndiName = "java:comp/env/yourejb"
    // same as shown above
    

    这只能在同一个容器内工作,因为“外部世界”无法访问组件命名环境

  3. 为了更好地理解 jndi名称,请查看this

    我希望有这种帮助,玩得开心!

答案 2 :(得分:0)

如何从独立的Java客户端访问远程EJB组件?

步骤1.在代码中使用no-arg InitialContext()构造函数。 开发人员遇到的最常见问题是将特定的JNDI引导属性传递给InitialContext(args)。其他一些供应商需要这一步,但GlassFish不需要。相反,使用no-arg InitialContext()构造函数。

步骤2.将远程EJB的全局JNDI名称传递给InitialContext.lookup() 独立Java客户端无权访问组件命名环境(java:comp / env)或@EJB批注,因此它们必须显式使用全局JNDI名称来查找远程EJB。 (有关如何将全局JNDI名称分配给EJB组件的更多信息,请参见此处)假设Remote EJB的全局JNDI名称为“FooEJB”:

对于具有3.x远程业务界面的Bean:

Foo foo =(Foo)new InitialContext()。lookup(“FooEJB”);

请注意,在EJB 3.x情况下,可以直接将查找结果强制转换为远程业务接口类型,而无需使用PortableRemoteObject.narrow()。

对于EJB 2.1及更早版本的会话/实体bean:

Object homeObj = new InitialContext().lookup("FooEJB");

FooHome fooHome =(FooHome)     PortableRemoteObject.narrow(homeObj,FooHome.class);

Foo foo = fooHome.create(...) 步骤3.在java客户端的类路径中包含适当的GlassFish .jars。 对于GlassFish 3。 在客户端的类路径中包含$ GLASSFISH_HOME / glassfish / lib / gf-client.jar。

,假设应用程序类在/ home / user1 / myclasses中,主客户端类是acme.MyClient:

java -classpath $ GLASSFISH_HOME / glassfish / lib / gf-client.jar:/ home / user1 / myclasses acme.MyClient

请注意,gf-client.jar会自动包含Java EE 6 API类,因此无需将classee.jar显式添加到类路径中。 gf-client.jar引用GlassFish安装目录中的许多其他.jars,因此最好从安装目录本身引用它,而不是将其(以及所有其他.jars)复制到另一个位置。

注意:gf-client.jar位于GlassFish v3中的$ GLASSFISH_HOME / modules / gf-client.jar中。