从外部JVM通过Remote bean调用EJB3 Local bean

时间:2011-11-15 20:48:02

标签: java ejb-3.0 weblogic-10.x

使用EJB并不是非常有经验,我遇到了以下问题,我希望你们中的一个人可以提供帮助。

假设以下情况:已定义一组@Local bean以提供对数据库的访问。这些bean非常简单,并部署在应用程序服务器A (Weblogic 10.3.3)上。我们希望通过远程提供对这些本地 bean的访问权限,因为我们已经拥有了"服务"模块设置用于提供对我们服务的外部访问,我们的想法是创建一个使用上述本地 bean的新@Remote服务(通过@EJB注入)。这些服务bean也部署在应用程序服务器A上。例如:

@Local
public interface DatabaseBeanLocal { doStuff(); }

@Stateless(name = "ejb/DatabaseBean", mappedName = "DatabaseBean")
public class DatabaseBean implements DatabaseBeanLocal { doStuff() { ... } ; }

@Remote
public interface ServiceBean { doSomeOtherStuff(); }

@Stateless
public class ServiceBeanImpl implements ServiceBean
{
    @EJB(name = "ejb/DatabaseBean", mappedName = "DatabaseBean")
    private DatabaseBeanLocal myDatabaseBean;

    ... methods etc. ...

}

实际使用这些远程 bean的客户端实际上是在不同的应用程序服务器上运行的; 应用程序服务器B (也是Weblogic 10.3.3)。当我们从客户端查找ServiceBean bean时,它运行正常。当我们在其上调用需要访问DatabaseBean的方法时,调用失败。 Weblogic服务器说它找不到DatabaseBean接口的bean。

我的问题:这种设置是否可行?换句话说:Weblogic(或其他容器)会将本地bean注入到远程bean中,以便客户端获取能够在本地bean上调用操作的远程bean的实例(我假设没有,但是我' m无论如何要确定)?

如果没有,我猜我们除了跳过服务层并通过DatabaseBean直接访问上面的@Remote示例之外别无选择。

更新1

完成一些测试后,只需将上面的DatabaseBean定义为@Remote而不是@Local"修复"这个问题。当然,这不是一个真正的解决方案,因为它会远程调用DatabaseBean,这很荒谬,因为它与服务在同一个模块中。我开始怀疑用远程EJB包装本地EJB是不可能的。

更新2

到目前为止我们发现了什么:

  • 到目前为止,我们还无法手动注入本地EJB,因为我们实际上无法在运行时找到它。
  • Weblogic显然不包含JNDI树中的本地EJB。
  • 从部署它的AS外部调用ServiceBean仍然不起作用,因为从不解析对本地EJB的依赖,或者解析客户端,这意味着找不到它。

2 个答案:

答案 0 :(得分:3)

本地意味着EAR本地而不是AS。

您的本地和远程Bean必须位于同一个EAR中(不仅在同一个AS中)。是吗?

- 编辑 -

嗯......如果他们在同一个EAR中那么它应该可以工作。即回答你的问题“这样的设置是否可能?”是的。

不幸的是,现在我们正在谈论纯粹而简单的调试。我要做的第一件事是尝试检查本地bean(我猜是DatabaseBean)是否实际注册并使用WebLogic中的WebPhere UTC等效工作(我从未在WebLogic中工作)。我可以列出100个其他的东西,你可以检查更多的日志/痕迹/症状但是,这就是调试的方式。

答案 1 :(得分:1)

管理以解决此问题。以下配置适用于Weblogic 10.3.3,并允许远程 EJB使用本地 EJB,其中可以从任何地方调用远程EJB。

最终 - 在大量测试之后 - 诀窍显然是为beanName注释指定@EJB值,用于将本地bean标记为远程的依赖项豆。卫生署!

部署

  • @Local EJB部署在EAR-1中的AS-A上(在自己的模块/ JAR中)
  • @Remote EJB部署在EAR-1中的AS-A上(在自己的模块/ JAR中)
  • 调用远程服务的客户端代码在AS-B上部署在自己的EAR存档

注解

本地 EJB是一个非常简单直接的EJB bean,具有以下接口和实现:

@Local
public interface LocalBeanLocal {
    // Implementation omitted
}

@Stateless(name = "LocalBean")
public class LocalBean implements LocalBeanLocal {
    // Implementation omitted
}

远程 EJB再次是一个相对简单的EJB bean,除了它依赖于LocalBean。此依赖关系通过@EJB注释表示;但似乎Weblogic需要beanName属性才能正确解析此依赖关系。 没有 beanName属性,调用远程EJB对我们不起作用(从某种意义上讲,当涉及到本地bean时总会出现某种错误)!

@Remote
public interface RemoteBeanRemote {
    // Implementation omitted
}

@Stateless(name = "RemoteBean")
public class RemoteBean implements RemoteBeanRemote {

    @EJB(beanName = "LocalBean")
    private LocalBeanLocal localBean;

    // Implementation omitted
}

这里显然重要的是远程服务依赖项声明(beanName)中的@EJB(beanName = "LocalBean")属性应该具有与本地定义的bean名称相同的值 bean实现(@Stateless(name = "LocalBean"))。

查找

以传统方式完成对远程EJB的引用,似乎没有特定要求。在我们的例子中,我们通过JNDI查找远程服务。