Add compatibility with HK2 service locator lookup
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/api/pom.xml b/api/pom.xml
index 4395bb1..cf6547f 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -331,6 +331,11 @@
<Bundle-Description>Jakarta JSON Processing API ${spec.version}</Bundle-Description>
<Specification-Vendor>${vendor.name}</Specification-Vendor>
<Implementation-Build-Id>${buildNumber}</Implementation-Build-Id>
+ <DynamicImport-Package>*</DynamicImport-Package>
+ <Import-Package>
+ !org.glassfish.hk2.osgiresourcelocator,
+ *
+ </Import-Package>
</instructions>
</configuration>
<executions>
diff --git a/api/src/main/java/jakarta/json/spi/JsonProvider.java b/api/src/main/java/jakarta/json/spi/JsonProvider.java
index 4a01d27..3cfbee6 100644
--- a/api/src/main/java/jakarta/json/spi/JsonProvider.java
+++ b/api/src/main/java/jakarta/json/spi/JsonProvider.java
@@ -20,6 +20,7 @@
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
+import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
@@ -107,6 +108,15 @@
if (it.hasNext()) {
return it.next();
}
+
+ // handling OSGi (specific default)
+ if (isOsgi()) {
+ JsonProvider result = lookupUsingOSGiServiceLoader(JsonProvider.class);
+ if (result != null) {
+ return result;
+ }
+ }
+
try {
Class<?> clazz = Class.forName(DEFAULT_PROVIDER);
return (JsonProvider) clazz.getConstructor().newInstance();
@@ -573,7 +583,46 @@
throw new UnsupportedOperationException(number + " type is not known");
}
}
-
+
+ /** OSGI aware service loader by HK2 */
+ private static final String OSGI_SERVICE_LOADER_CLASS_NAME = "org.glassfish.hk2.osgiresourcelocator.ServiceLoader";
+
+ /**
+ * Check availability of HK2 service loader.
+ *
+ * @return true if HK2 service locator is available
+ */
+ private static boolean isOsgi() {
+ try {
+ Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
+ return true;
+ } catch (ClassNotFoundException ignored) {
+ }
+ return false;
+ }
+
+ /**
+ * Lookup the service class by the HK2 service locator.
+ *
+ * @param serviceClass service class
+ * @param <T> type of the service
+ * @return a provider
+ */
+ private static <T> T lookupUsingOSGiServiceLoader(Class<? extends T> serviceClass) {
+ try {
+ // Use reflection to avoid having any dependendcy on HK2 ServiceLoader class
+ Class<?>[] args = new Class<?>[]{serviceClass};
+ Class<?> target = Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
+ Method m = target.getMethod("lookupProviderInstances", Class.class);
+ @SuppressWarnings({"unchecked"})
+ Iterator<? extends T> iter = ((Iterable<? extends T>) m.invoke(null, (Object[]) args)).iterator();
+ return iter.hasNext() ? iter.next() : null;
+ } catch (Exception ignored) {
+ // log and continue
+ return null;
+ }
+ }
+
/**
* Lazy loads the class specified in System property with the key JSONP_PROVIDER_FACTORY.
* If no property is set, the value of {@link #JSON_PROVIDER} will be null.