WildFly JNDI 查找部署在 WAR 中的本地 EJB

Posted

技术标签:

【中文标题】WildFly JNDI 查找部署在 WAR 中的本地 EJB【英文标题】:WildFly JNDI lookup for local EJB deployed in a WAR 【发布时间】:2014-11-19 00:25:18 【问题描述】:

我正在使用 WildFly 8.1.0 最终版。

我的应用程序是部署在 WAR 中的 JavaEE Web 应用程序(没有 EJB 模块 .ear)。

我想使用 JNDI 以编程方式使用他的名字调用本地 EJB。

EJB 只是用@Stateless 注释(没有本地或远程接口)

我尝试以下功能:

private <E extends DomainObject> CrudService<E> lookUp(Class<E> cl) 
    try 
        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        final Context context = new InitialContext(jndiProperties);
        // The app name is the application name of the deployed EJBs. This is typically the ear name
        // without the .ear suffix. However, the application name could be overridden in the application.xml of the
        // EJB deployment on the server.
        // Since we haven't deployed the application as a .ear, the app name for us will be an empty string
        final String appName = "";
        // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
        // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
        // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
        // jboss-as-ejb-remote-app
        final String moduleName = "jboss-as-ejb-remote-app";
        // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
        // our EJB deployment, so this is an empty string
        final String distinctName = "";
        // The EJB name which by default is the simple class name of the bean implementation class
        final String serviceName = cl.getSimpleName() + "Service";
        // let's do the lookup
        return (CrudService<E>) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + serviceName );
        //return (CrudService<E>) context.lookup(serviceName);
     catch (NamingException e) 
        log.error("NamingException ",e) ;
        throw new RuntimeException(e) ;
    

但它不起作用(显然是用于远程 EJB)

但是我在与 WildFly 的 WAR 中找不到本地 EJB 的任何示例,我不知道该怎么做,我不经常使用 JNDI...

我发现了一个使用 @Named(value="EjbClassName") 注释 EJB 并使用 JSF 调用它们的工作。

FacesContext context = FacesContext.getCurrentInstance() ;
return context.getApplication().evaluateExpressionGet(context, "#"+cl.getSimpleName()+"Service", CrudService.class) ;

它正在工作,

但我不想使用 JSF,因为它与视图层无关。

【问题讨论】:

部署战争后,WildFly 服务器不会记录正在加载的 JNDI 名称?在 glassfish 中,我这样做是为了找出正确的查找字符串... 【参考方案1】:

来自手机的简短回答: 使用 @LocalBean 获取 bean 的无接口视图。将此添加到您的无状态会话 bean 中,您应该可以在服务器的 jndi 视图中找到它。

【讨论】:

【参考方案2】:

感谢 Yamada,JNDI 名称在启动时出现在服务器日志中

此解决方案有效:

private <E extends DomainObject> CrudService<E> lookUp(@NonNull Class<E> entityClass) throws NamingException 
    try 
        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        final Context context = new InitialContext(jndiProperties);
        return (CrudService<E>) context.lookup("java:module/"+entityClass.getSimpleName()+"Service");
     catch (NamingException e) 
        log.error("lookUp() throws NamingException ",entityClass.getSimpleName(),e.getMessage()) ;
        throw e ;
    

不使用@LocalBean 注释 EJB

【讨论】:

以上是关于WildFly JNDI 查找部署在 WAR 中的本地 EJB的主要内容,如果未能解决你的问题,请参考以下文章

WildFly中的每主机或每部署子系统配置

如何将 root(/) 上下文中的 war 文件部署到 Wildfly 9.0.1 版

在 Wildfly 9 上部署 EAR 具有原始 WAR 和复制 WAR

wildfly 部署war包standalone 部署为啥要 war.deployed

java.lang.ClassCastException 在 Wildfly 10 上部署 CAS 5.3.3 Maven Overlay WAR

在 Wildfly 的战争部署期间无法访问 jar 中的类