3

我有一个 MDB EJB,里面有静态块。我使用静态块在应用程序第一次运行时(即部署时)只初始化一些组件一次。MDB EJB 部署在除 Admin_Server 之外的单独服务器 (My_Server) 上。

问题是静态块被调用了两次!

  • 第一次:就在部署 MDB EJB(标记到 My_Server)之后。
  • 第二次:在 JMS 队列(与 MDB 关联)收到消息之后。

另外,我打印了服务器名称和 pid,它们在两者中都是相同的:

System.out.println("server name: " + System.getProperty("weblogic.Name"));
System.out.println("pid: " + ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);

我还注意到一些奇怪的行为。基本上,我附加了一个 Shutdown Hook(从静态块内部)在应用程序关闭时向我发送电子邮件。

  • 一旦我关闭 My_Server,我就会收到通知。
  • 关闭 Admin_Server 后,我也会收到通知。

我该如何解决这个问题?


一些额外的信息:

Weblogic version: 10.3.0
EJB version: 3.0
4

2 回答 2

7

只有当您有多个类加载器时才会发生这种情况。我不会在 EJB 中使用静态初始化程序,依赖于 EJB 生命周期挂钩或将初始化程序导出到非托管类中。

EJB 3.1 添加了 @Singleton 和 @Startup 之类的注解,但不幸的是,在 3.0 中,您不得不为这些保证使用基于提供程序的解决方案。

管理员与常规服务器行为相当普遍,因为 WebLogic 通常部署到两者。请参阅此页面了解更多信息。

对于 Weblogic 关闭挂钩,请查看此文档页面

于 2013-01-21T07:18:12.653 回答
4

是的,您可以多次执行静态初始化程序的唯一方法是,如果您实际上已经加载了该类的两个不同副本。只有当你有两个不同的类加载器都加载类时,才会发生这种情况。

防止这种情况的方法是安排有问题的类由两个类加载器的共同祖先类加载器加载。我不知道您将如何使用 Weblogic 执行此操作,但对于 Tomcat,您会将相关 JAR 文件放入指定的公共库目录中,该目录由容器中运行的所有 webapps 共享。

于 2013-01-21T07:32:06.947 回答