Osgi environments (like GlassFish) have trouble with BuildServicesResolver
See original GitHub issuejakarta.enterprise.inject.build.compatible.spi.BuildServicesResolver
contains the following code to load an implementation of BuildServices.class
private static void discoverFactories() {
Set<BuildServices> factories = new TreeSet<>(
Comparator.comparingInt(BuildServices::getPriority).reversed());
ServiceLoader<BuildServices> loader = SecurityActions.loadService(
BuildServices.class, BuildServicesResolver.class.getClassLoader());
The problem here is that it loads this using the class loader from BuildServicesResolver
, which in an OSGi environment is the bundle corresponding to the CDI API jar, e.g. the bundle identified by “jakarta.enterprise.cdi-api [131]” in GlassFish.
The bundle itself is not able (allowed) to load META-INF/services/jakarta.enterprise.inject.build.compatible.spi.BuildServices
from other bundles or from anywhere on the class path, as it would only look into its own bundle (where it’s obviously not found).
I think the best way to go about this is trying the context class loader as well. The environment can then set an appropriate class loader that is both OSGi aware and aware of the class path, which is able to deal with this. Alternatively, it might work if the CDI API jar defines the need for a server loader service in its manifest:
Require-Capability: osgi.extender;
filter:="(osgi.extender=osgi.serviceloader.processor)",
osgi.serviceloader;
filter:="(osgi.serviceloader=jakarta.enterprise.inject.build.compatible.spi.BuildServices)";
cardinality:=multiple
(I’d have to test whether this indeed works in GlassFish)
Issue Analytics
- State:
- Created a year ago
- Comments:8 (4 by maintainers)
I might just have found it in GlassFish:
So seemingly it “hacks” into the CDI bundle to add the service file to it, and also adds the
org.glassfish.weld
import to it.Hmmm…
I wrote that code by copying the
CDI
class (which loadsCDIProvider
) and then simplifying a little. I did notice the code inCDI
doesn’t use TCCL and thought it’s a bit weird, but I said to myself – this must already work everywhere. So I didn’t attempt to load from TCCL, even if that would be the first thing I’d normally do.