Java EJB中的IoC抛出ClassNotFoundException和';未能封送EJB参数';
我有以下设置: 我们正在JBoss6.4上运行一个应用程序,其中部署了一个ear,其中包含业务逻辑的EJB。一些Web服务和WebSocket所在的地方也部署了war 现在我想要这样的东西: 耳侧Java EJB中的IoC抛出ClassNotFoundException和';未能封送EJB参数';,java,jakarta-ee,dependency-injection,Java,Jakarta Ee,Dependency Injection,我有以下设置: 我们正在JBoss6.4上运行一个应用程序,其中部署了一个ear,其中包含业务逻辑的EJB。一些Web服务和WebSocket所在的地方也部署了war 现在我想要这样的东西: 耳侧 @Remote public interface EventConsumer extends Serializable { void onEventMessage(Topic topic, String message, String principalName); void on
@Remote
public interface EventConsumer extends Serializable {
void onEventMessage(Topic topic, String message, String principalName);
void onErrorMessage(Topic topic, Throwable t, String principalName);
}
@ServerEndpoint("/ws/eventLog/")
@Stateless
public class EventLogWebsocket implements EventConsumer {
private static final long serialVersionUID = 1L;
private final EventLog eventLogService;
public EventLogWebsocket() {
eventLogService = createEventLogService();
}
@OnOpen
public void open(Session session) {
eventLogService.registerEventConsumer(this);
}
// other ws stuff
@Override
public void onEventMessage(Topic topic, String message, String principalName) {
System.out.println(message);
}
@Override
public void onErrorMessage(Topic topic, Throwable t, String principalName) {
System.out.println(message);
}
private EventLog createEventLogService() {
EventLog logService = // some proxy stuff since its remote. works fine
return logService;
}
}
及
在战争方面
@Remote
public interface EventConsumer extends Serializable {
void onEventMessage(Topic topic, String message, String principalName);
void onErrorMessage(Topic topic, Throwable t, String principalName);
}
@ServerEndpoint("/ws/eventLog/")
@Stateless
public class EventLogWebsocket implements EventConsumer {
private static final long serialVersionUID = 1L;
private final EventLog eventLogService;
public EventLogWebsocket() {
eventLogService = createEventLogService();
}
@OnOpen
public void open(Session session) {
eventLogService.registerEventConsumer(this);
}
// other ws stuff
@Override
public void onEventMessage(Topic topic, String message, String principalName) {
System.out.println(message);
}
@Override
public void onErrorMessage(Topic topic, Throwable t, String principalName) {
System.out.println(message);
}
private EventLog createEventLogService() {
EventLog logService = // some proxy stuff since its remote. works fine
return logService;
}
}
问题
毫无疑问,当调用ws-open方法时,这不起作用:
ERROR [xyz.ws.EventLogWebsocket] (http-/0.0.0.0:8280-17) error occurred in websocket: java.lang.reflect.InvocationTargetException
...
Caused by: java.lang.RuntimeException: JBAS014154: Failed to marshal EJB Parameters
...
Caused by: java.lang.ClassNotFoundException: xyz.ws.EventLogWebsocket from [Module "deployment.abc-app-0.6.0-SNAPSHOT.ear.abc-infrastructure-ejb-0.6.0-SNAPSHOT.jar:main" from Service Module Loader]
...
在jboss ModuleClassLoader中调试表明EJB无法加载EventLogWebsocket类。但在这个IoC设置中,这正是我想要的:不关心这个特定接口的实现
现在我看不出解决办法。。。是吗?:) 您需要记住@Remote方法调用使用RMI,因此:
java.io.Serializable
eventLogService.registerEventConsumer(this);
有问题:
当EJB端尝试反序列化使用者
对象时,它尝试重新创建事件日志WebSocket
的副本,但该类在EAR中不可用,因此失败
此外,EventLogWebsocket
参数必须是可序列化的对象。它声称是可序列化的,但这并不是因为它包含不可序列化的EventLog
对象
即使您纠正了所有这些问题,它仍然无法工作,因为EJB有一个EventLogWebsocket
的副本,因此无论如何都不会发送任何事件通知
因此,您需要做的第一件事就是去掉@Remote接口。这意味着您必须在EAR中包含WAR并使用@Local接口
但是您仍然需要小心,因为EAR/WAR文件中的类可以看到EAR/EJB类,但反之则不然——EAR/EJB类无法看到EAR/WAR文件中的类
如果你在重新打包后仍然有类装载问题,那么考虑把所有东西放在战争文件中,完全失去耳朵。
是耳朵里的战争还是与之分离的?战争是分开的,但在同一个JJ中运行,谢谢你的回答。好像我太经常忘记这整件事了。在这种情况下,一些消息队列框架会有帮助吗(HornetQ可能可用?或者我们在那里也会面临同样的问题?我的意思是,他们是如何处理这种回调的?如果你需要单独的部署,那么你可以使用JMS来实现这一点-是的。您也可以尝试类似于本文中使用的ApacheKafka。但是,如果您可以将所有内容都放入同一个类加载器(单次WAR部署),那么您可以使用CDI事件和观察者。如果可以的话,你当然想避免RMI。