我有2个申请。一个主要的'第二个带有远程EJB。第一个应用程序在第二个应用程序中调用远程EJB。
现在我想实现Observable模式。但它似乎并不适用于跨应用程序。
所以我希望我的Observable在第二个应用程序中,而我的Observers在第一个应用程序中。当我尝试它时,它似乎不起作用。它只适用于我在同一个应用程序中创建Observable和Observers。
我有另一个解决方案,但我觉得它很脏。我可以在第二个应用程序中使用MDB,并在主题上发布消息,然后在第一个应用程序中使用这些消息。但话说回来,那似乎有点脏。
我在Payara 4.1.1.171服务器上使用JEE7。
修改: 因为我发现触发的事件不会退出EAR文件,我现在正在使用MDB方法。但那仍然行不通。 更多信息,这是EAR文件的包结构。
my-application.ear
+--- common-ejb.jar (EJB)
| +--- MessageDrivenBean.java (Triggers the event)
+--- my-application.jar (EJB)
+--- my-application.war (WEB)
+--- WEB-INF
+--- lib
| +--- common-web.jar (Resources WEB jar)
| +--- SessionBean1 to receive the events
+--- classes
+--- SessionBean2 to receive the events
正如您所看到的,有2个会话bean可以接收事件,但是2个实际上都没有接收到它们。
答案 0 :(得分:0)
给定消息驱动的bean:
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:jboss/queue/SampleQueue")
})
public class EventListener implements MessageListener {
@Inject
@Any
Event<MyEvent> loggedInEvent;
@Override
public void onMessage(Message message) {
if (message instanceof ObjectMessage) {
try {
ObjectMessage objectMessage = (ObjectMessage) message;
loggedInEvent.fire(((MyEvent) objectMessage.getObject()));
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
其中MyEvent是一个简单的POJO:
public class MyEvent implements Serializable {
private final String payload;
public MyEvent(String payload) {
this.payload = payload;
}
public String getPayload() {
return payload;
}
}
然后这个@SessionScoped bean:
@SessionScoped
public class EventHandler {
public void handleEvent(@Observes MyEvent myEvent) {
System.out.println(myEvent.getPayload());
}
}
当MyEvent
对象发送到与EventListener
关联的队列时,打印有效负载字符串
可以提供任意数量的观察员。
答案 1 :(得分:0)
启用Payara Server版本171和Hazelcast后,您可以触发CDI事件并在另一个应用程序中观察它们。请参阅有关remote CDI events
的文档如果两个应用程序都部署在同一个Payara Server实例上,您将触发类型为MyEvent.class的事件:
@Inject
@Outbound(loopBack = true) // loopBack true is required if the observing application is deployed on the same Payara Server instance
Event<MyEvent> event;
...
event.fire(new MyEvent());
另一个应用程序将通过以下方式观察这些事件:
public void receiveEvent(@Observes @Inbound MyEvent event) {
}
如果观察应用程序在同一Hazelcast群集中的另一个Payara Server实例上运行,它也会收到该事件。在这种情况下,loopBack属性不是必需的,但也不会造成任何伤害。
通过嵌入式Hazelcast数据网格调度远程CDI事件,该数据网格可以将事件可靠地传递到群集中的所有观察应用程序。观察应用程序必须在事件发生时运行 - 与通过JMS主题广播事件的行为类似。