ModuleClassLoader单例

时间:2016-07-08 06:44:54

标签: jboss singleton jndi loader modularization

我遇到这种情况:

  • 一个JBOSS实例
  • application client.war
  • application server.war
  • 正确安装的jboss模块,仅包含接口。

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

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

  

错误[stderr] java.lang.IllegalStateException:JBAS016071:Singleton   没有为Module“client.war:main”设置ModuleClassLoader   服务模块加载器。这意味着您正在尝试访问焊缝   使用未关联的线程上下文ClassLoader进行部署   部署。

在那里我撞了几天,但我无法理解问题所在。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:1)

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

获取父类加载器:

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