1

I have this situation:

  • a JBOSS instance
  • application client.war
  • application server.war
  • a jboss module, properly installed, containing only the interfaces.

The server.war application implements the jboss module interfaces, and publishes these implementations with a JNDI bind. The client.war application with a lookup uses implementations server.war.

A runtime client.war can call the implementation exposed by server.war, but as soon as I try to start a transaction hibernate I get the following error:

ERROR [stderr] java.lang.IllegalStateException: JBAS016071: Singleton not set for ModuleClassLoader for Module "client.war:main" from Service Module Loader. This means that you are trying to access a weld deployment with a Thread Context ClassLoader that is not associated with the deployment.

There I bumped my head for days, but I can not understand what the problem is. Someone can help me?

1 Answers1

2

Set the class loader on the child thread to be the same as the parent.

Get parent class loader:

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

Set child class loader :

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

When the child thread is done, make sure to unset the class loader to null, to avoid leaks in case of thread pools.

Although CDI will work in the child thread other things such as remote EJB invocation and JNDI lookups will not.

A much better approch wuld be to use an async EJB invocations You can just create an EJB that looks something like:

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

This would mean that your async task will have the TCCL set correctly, JNDI will work etc (basically it is a full EE invocation).

You can configure the thread pool used for async invocations in standalone.xml, but it will be used for all @Asynchronous methods in the application.

Root Cause

When an application launches its own threads, the new threads use a classloader which is different than the classloader of the originating thread, therefore injection is failing.

Reference

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

Beryllium
  • 12,808
  • 10
  • 56
  • 86
dev
  • 1,343
  • 2
  • 19
  • 40