1

我有这种情况:

  • 一个 JBOSS 实例
  • 应用程序客户端.war
  • 应用服务器.war
  • 一个正确安装的 jboss 模块,仅包含接口。

server.war 应用程序实现 jboss 模块接口,并使用 JNDI 绑定发布这些实现。带有查找功能的 client.war 应用程序使用实现 server.war。

运行时 client.war 可以调用 server.war 公开的实现,但是当我尝试启动事务休眠时,我会收到以下错误:

错误 [stderr] java.lang.IllegalStateException: JBAS016071: 未为服务模块加载器中的模块“client.war:main”的 ModuleClassLoader 设置单例。这意味着您正在尝试使用与部署无关的线程上下文类加载器访问焊接部署。

在那里我撞了几天的头,但我不明白问题是什么。有人可以帮助我吗?

4

1 回答 1

2

将子线程上的类加载器设置为与父线程相同。

获取父类加载器:

ClassLoader cl = Thread.currentThread().getContextClassLoader();

设置子类加载器:

ClassLoader cl = Thread.currentThread().setContextClassLoader(cl);

子线程完成后,请确保将类加载器取消设置为 null,以避免在线程池的情况下泄漏。

尽管 CDI 将在子线程中工作,但其他事情(例如远程 EJB 调用和 JNDI 查找)则不会。

一个更好的方法是使用异步 EJB 调用您可以创建一个看起来像这样的 EJB:

@Singleton
public class AsyncBean {
@Asynchronous
public void performTask(int a, int b) {
// the client doesn't care what happens here
}

这意味着您的异步任务将正确设置 TCCL,JNDI 将正常工作等(基本上它是一个完整的 EE 调用)。

您可以在standalone.xml 中配置用于异步调用的线程池,但它将用于@Asynchronous应用程序中的所有方法。

根本原因

当应用程序启动自己的线程时,新线程使用的类加载器与原始线程的类加载器不同,因此注入失败。

参考

https://access.redhat.com/solutions/257663

于 2016-08-09T10:39:25.820 回答