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();