代码之家  ›  专栏  ›  技术社区  ›  Dherik

在多模块项目中通过本地接口查找EJB

  •  1
  • Dherik  · 技术社区  · 7 年前

    我试图通过ServiceLocator进行EJB查找,而不硬编码JNDI名称,只使用本地接口名称。问题是EJB分布在其他模块(JAR)中。例如,我有这样一个场景:

    项目xxx

    @Stateless
    class EjbXBean implements EjbX {
    
    }
    

    java:global/project-xxx/EjbXBean

    项目yyy :

    @Stateless
    class EjbYBean implements EjbY {
    
    }
    

    java:global/project-yyy/EjbYBean

    EjbX和EjbY都是 @Local

    EjbX ejbx = ServiceLocator.lookup(EjbX.class);
    EjbY ejby = ServiceLocator.lookup(EjbY.class);
    

    EjbX ejbx = ServiceLocator.lookup("java:global/project-yyy/EjbXBean");
    EjbY ejby = ServiceLocator.lookup("java:global/project-yyy/EjbYBean");
    

    我试图找出这种情况下的最佳实践是什么,因为我不知道硬编码的JNDI名称在JavaEE世界中是否是一种好的实践。

    我使用OpenEjb 4.7.4进行开发和集成测试,使用Wildfly 10.1.0进行生产。

    我可以在Wildfly 10.1.0中使用CDI来实现这一点:

    @Override
    public Object lookup(Class<?> type, Annotation... annotations) throws NamingException {
        BeanManager manager = CDI.current().getBeanManager();
        Iterator<Bean<?>> beans = manager.getBeans(type, annotations).iterator();
    
        if (!beans.hasNext()) {
            throw new NamingException("CDI BeanManager cannot find an instance of requested type " + type.getName());
        }
        Bean<?> bean = beans.next();
        CreationalContext<?> ctx = manager.createCreationalContext(bean);
        return manager.getReference(bean, type, ctx);
    }
    

    MyClass.lookup(EjbX.class);
    

    但我不想使用CDI,因为 I had some problems to put this to work

    1 回复  |  直到 7 年前
        1
  •  2
  •   aschoerk    7 年前

    @Inject 豆子。(您只需要一个 beans.xml 在每一场包含托管bean的战争中)

    我不确定命名的标准化是否适用于openejb和wildfly。由于两者都是ejb 3.1,所以应该是这样的,但您是否检查了自己的名字是否符合标准?。我过去在使用队列和主题时遇到过问题。可能 jboss naming ejb3.1 我能帮上忙。

    为了确保名称可用,也许您应该考虑使用 arquillian 用于测试。

    此外,我不会使用openejb进行测试。我知道它是可嵌入的,但差异很大。另一个CDI容器,可能是eclipselink而不是hibernate。两者都有很大的不同。我不会在wildfly上测试和部署。

    cdi-unit ejb-cdi-unit (好的,那是我的项目,所以我不是完全公正的;-))