According to EE.6.2.3.7 CDI should be setting a TCCL during the invocation of observer methods.
Not true. EE.6.2.3.7 only requires that "...containers provide a per thread context class loader that can be used to load top level application classes..." and refers to section EE.8.2.5 “Dynamic Class Loading” which gives an example of a technique which should be used by libraries to load the classes:
ClassLoader cl = Thread.currentThread().getContextClassLoader(); // Shortened for clarity |
if (cl != null) { |
try { |
clazz = Class.forName(name, false, cl); |
} catch (ClassNotFoundException ex) { |
clazz = Class.forName(name); |
} |
}
|
Codebases, such as Apache DeltaSpike, have been written to assume that the TCCL will be the web application's ClassLoader...
That's wrong assumption.
We cannot set the TCCL for two different web applications at the same time.
First of all, the problem is only related to container lifecycle event notifications. Weld notifies all the observers using the thread which started the bootstrap, ie. calls org.jboss.weld.bootstrap.api.Bootstrap methods. It's the responsibility of the EE container/integrator to set the correct TCCL there. Weld has no way to identify the correct TCCL (container-specific) which should be used.
It seems OWB set the TCCL to the web application's classloader.
Can you point me to the place where OWB does the trick? I briefly browsed the OWB codebase and I did not find anything related. My guess would be that it works in OWB due to a different interpretation of @ApplicationScoped, extension lifecycle and bean archives in EARs (see also the very long discussion under CDI-129). |