Try multiple providers from OSGi until first succeeds. (#211) Signed-off-by: arjantijms <arjan.tijms@gmail.com>
diff --git a/api/src/main/java/jakarta/xml/bind/ContextFinder.java b/api/src/main/java/jakarta/xml/bind/ContextFinder.java index 727bbb1..623b71a 100644 --- a/api/src/main/java/jakarta/xml/bind/ContextFinder.java +++ b/api/src/main/java/jakarta/xml/bind/ContextFinder.java
@@ -19,6 +19,7 @@ import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.logging.ConsoleHandler; @@ -309,11 +310,17 @@ return obj.createContext(contextPath, classLoader, properties); } - Class<?> ctxFactory = (Class<?>) ServiceLoaderUtil.lookupUsingOSGiServiceLoader( + Iterable<Class<? extends JAXBContextFactory>> ctxFactories = ServiceLoaderUtil.lookupsUsingOSGiServiceLoader( JAXBContext.JAXB_CONTEXT_FACTORY, logger); - if (ctxFactory != null) { - return newInstance(contextPath, contextPathClasses, ctxFactory, classLoader, properties); + if (ctxFactories != null) { + for (Class<? extends JAXBContextFactory> ctxFactory : ctxFactories) { + try { + return newInstance(contextPath, contextPathClasses, ctxFactory, classLoader, properties); + } catch (Throwable t) { + logger.log(Level.FINE, t, () -> "Error instantiating provivder " + ctxFactory); + } + } } // else no provider found
diff --git a/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java b/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java index 5ab87b7..bed8b66 100644 --- a/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java +++ b/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java
@@ -74,6 +74,25 @@ } } + @SuppressWarnings("unchecked") + static <T> Iterable<T> lookupsUsingOSGiServiceLoader(String factoryId, Logger logger) { + try { + // Use reflection to avoid having any dependency on ServiceLoader class + return (Iterable<T>) + Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME) + .getMethod(OSGI_SERVICE_LOADER_METHOD_NAME, Class.class) + .invoke(null, Class.forName(factoryId)); + + } catch (IllegalAccessException | + InvocationTargetException | + ClassNotFoundException | + NoSuchMethodException ignored) { + + logger.log(Level.FINE, ignored, () -> "Unable to find from OSGi: [" + factoryId + "]"); + return null; + } + } + static void checkPackageAccess(String className) { // make sure that the current thread has an access to the package of the given name. SecurityManager s = System.getSecurityManager();