1

我有一个这样的界面:

@Remote
public interface ClientDataAccessRemote

EJB 实现了它:

@Stateless
public class ClientDataAccess implements ClientDataAccessRemote 

在远程客户端中,我可以使用以下命令访问 EJB:

@EJB
private static ClientDataAccessRemote clientDataAccess;

这就是我所做的一切,并且有效。客户端和 EJB 驻留在同一台服务器上。如果分开了还能用吗?容器如何找到具有该接口的 EJB?我用 Netbeans 实现了这个,我不必指定任何位置或类似的东西。这是如何运作的?

4

1 回答 1

1

不幸的是,@EJB 注释仅适用于本地(单个 JVM)注入。对于单独的主机,您需要回退到普通的 JNDI 查找。

AFAIK 有一些专有的非便携式解决方案可以执行远程依赖注入,例如用于 WebLogic 服务器(此处),但我不会那样做。

JNDI 查找有效,但过于复杂且非常难看:

  • 您需要了解服务器供应商并将其客户端库添加到您的应用程序的依赖项中,
  • 你污染了应用程序:
    • 神秘的供应商特定的 URI 格式
    • 特定于供应商的命名服务端口号(通常默认为 1099,但谁知道...)
    • 特定于供应商的 jndi 名称模式

这是远程 JBoss 4.x 实例上托管的 bean 的示例查找:

Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
    "org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES,
    "org.jboss.naming:org.jnp.interfaces");
properties.setProperty(Context.PROVIDER_URL, "localhost:1099");
InitialContext context = null;
ClientDataAccessRemote cl = null;
try {
    context = new InitialContext(properties);
    cl = (ClientDataAccessRemote) context.lookup("ClientDataAccess/remote");
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

鉴于您的 EJB 是 EAR 的一部分,您需要在 EJBean 的名称前面加上 EAR 的名称:

cl = (ClientDataAccessRemote) context.lookup("MyEAR/ClientDataAccess/remote");

上面的例子是特定于 JBoss 的,我什至不确定它是否可以在没有修改的情况下与 JBoss 5.x 系列一起使用。

显然 EJB 3.1 规范为 jndi 命名带来了一些统一,但我还没有乐于使用它。

如果这个示例让您有些害怕,也许更好的解决方案是将您的 EJB 公开为 Web 服务(SOAP 或 REST 样式)。它带来了它自己的问题,但至少是可移植的。

于 2013-03-03T14:09:16.290 回答