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