【问题标题】:How to retrieve EJB via JNDI in Tapestry application in OSGi environment running on Glassfish server如何在 Glassfish 服务器上运行的 OSGi 环境中的 Tapestry 应用程序中通过 JNDI 检索 EJB
【发布时间】:2013-09-23 07:12:30
【问题描述】:

我在 Tapestry 应用程序中检索 EJB 时遇到问题。 应用程序的另一部分在 OSGi bundle 中,全部部署在 Glassfish 上。

目前,我的东西是这样的:

我的界面(打包成jar):

@Remote
public interface MyEJBInterface {
    public static final String JNDI_NAME = "ejb/MyEJBInterface";
    public String sayHello(String name);

}

我的实现(打包为捆绑包):

@Stateless
@EJB(name = MyEJBInterface.JNDI_NAME, beanInterface = MyEJBInterface.class)
public class MyEJBImplementation implements MyEJBInterface {

    @Override
    public String sayHello(String name) {
        return "Hello " + name;
    }
}

AppModule 类中我的 Tapestry 构建方法:

public MyEJBService buildMyEJBService() {
    MyEJBInterface myEjb = new JndiLookupHelper<MyEJBInterface>().lookupNoPrefix(MyEJBInterface.JNDI_NAME);

    MyEJBService service = new MyEJBServiceMock(myEjb);

    return service;
}

我是这样查找的:

public class JndiLookupHelper<T> {
    private T remoteObject;

    public T lookupNoEjbPrefix(String name) {
        String jndiPath = "java:comp/env/" + name;
        try {
            InitialContext ic = new InitialContext();
            remoteObject = (T) ic.lookup(jndiPath);
        } catch (NamingException ne) {
            ne.printStackTrace();
        }
        return remoteObject;
    }
}

我的问题是找不到EJB并抛出异常:

javax.naming.NamingException: Lookup failed for 'java:comp/env/ejb/MyEJBInterface' 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: No object bound to name java:comp/env/ejb/MyEJBInterface]

【问题讨论】:

  • 你的异常/问题是......?
  • 抱歉,忘记包含异常。它现在就在那里。

标签: java glassfish ejb osgi jndi


【解决方案1】:

您可能会发现这样更好:

public static class EjbServiceBuilder<T> implements ServiceBuilder<T> {
    private Class<T> type;
    private String name;

    public EjbServiceBuilder<T>(Class<T> type, String name) {
        this.type= type;
        this.name = name;
    }

    public T buildService(ServiceResources resources) {
        try {
            return type.cast(InitialContext.doLookup(name));
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
    }
}

public static void bind(ServiceBinder binder) {
    binder.bind(MyEJBInterface.class, new EjbServiceBuilder<MyEJBInterface>(MyEJBInterface.class, MyEJBInterface.JNDI_NAME));
    binder.bind(MyEJBOtherInterface.class, new EjbServiceBuilder<MyEJBOtherInterface>(...));

    // MyEJBInterface will be injected into MyEJBServiceMock constructor
    binder.bind(MyEJBService.class, MyEJBServiceMock.class);
}

【讨论】:

    【解决方案2】:

    您需要在 manifest.mf 中声明 Export-EJB: ALL

    我不确定 EJB 是否会在“java:comp/env/”中提供。您可能需要通过portable global JNDI name 查找

    【讨论】:

    • 我有Export-EJB: ALL,我在java:global 下没有任何东西,甚至没有一个bean。
    【解决方案3】:

    我终于找到了解决方案。这里是:

    界面:

    public interface MyEJBInterface {
        public static final String JNDI_NAME = "java:global/ejb/MyEJBInterface";
        public String sayHello(String name);
    
    }
    

    实现:

    @Stateless
    @EJB(name = MyEJBInterface.JNDI_NAME, beanInterface = MyEJBInterface.class)
    public class MyEJBImplementation implements MyEJBInterface {
    
        @Override
        public String sayHello(String name) {
            return "Hello " + name;
        }
    }
    

    构建方法:

    public MyEJBService buildMyEJBService() {
        MyEJBInterface myEjb = new JndiLookupHelper<MyEJBInterface>().lookup(MyEJBInterface.JNDI_NAME);
    
        MyEJBService service = new MyEJBServiceMock(myEjb);
    
        return service;
    }
    

    查找:

    public class JndiLookupHelper<T> {
    
        private T remoteObject;
    
        @SuppressWarnings("unchecked")
        public T lookup(String name) {
            try {
                remoteObject = (T) InitialContext.doLookup(name);
            } catch (NamingException ne) {
                ne.printStackTrace();
            }
            return remoteObject;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-26
      • 1970-01-01
      • 2015-08-27
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-10
      • 1970-01-01
      相关资源
      最近更新 更多