GERONIMO-6560 JSON spec jar is not able to load provider in an OSGi environment

Based on https://github.com/apache/geronimo-specs/pull/6 by @sseifert

Signed-off-by: Raymond Auge <rotty3000@apache.org>

git-svn-id: https://svn.apache.org/repos/asf/geronimo/specs/trunk/geronimo-json_1.1_spec@1834162 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index f04bebf..6eca012 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,10 @@
             <Provide-Capability><![CDATA[
                osgi.contract;osgi.contract=JavaJSONP;uses:="${packages;NAMED;javax.*}";version:List<Version>='1.1,1.0'
             ]]></Provide-Capability>
+            <Require-Capability><![CDATA[
+              osgi.serviceloader;filter:="(osgi.serviceloader=javax.json.spi.JsonProvider)";cardinality:=multiple,
+              osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)"
+            ]]></Require-Capability>
           </instructions>
         </configuration>
       </plugin>
diff --git a/src/main/java/javax/json/spi/JsonProvider.java b/src/main/java/javax/json/spi/JsonProvider.java
index ab7a0a6..9ab4838 100644
--- a/src/main/java/javax/json/spi/JsonProvider.java
+++ b/src/main/java/javax/json/spi/JsonProvider.java
@@ -55,8 +55,10 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.ServiceLoader;
 
 /**
  * JsonProvider is the actual implementation of all the Json logic.
@@ -88,69 +90,30 @@
     }
 
     private static JsonProvider doLoadProvider() throws JsonException {
-        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
-        try {
-            final Class<?> clazz = Class.forName("org.apache.geronimo.osgi.locator.ProviderLocator");
-            final Method getServices = clazz.getDeclaredMethod("getServices", String.class, Class.class, ClassLoader.class);
-            final List<JsonProvider> osgiProviders = (List<JsonProvider>) getServices.invoke(null, JsonProvider.class.getName(), JsonProvider.class, tccl);
-            if (osgiProviders != null && !osgiProviders.isEmpty()) {
-                return osgiProviders.iterator().next();
-            }
-        } catch (final Throwable e) {
-            // locator not available, try normal mode
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        if (tccl == null) {
+            tccl = ClassLoader.getSystemClassLoader();
         }
 
-        // don't use Class.forName() to avoid to bind class to tccl if thats a classloader facade
-        // so implementing a simple SPI when ProviderLocator is not here
-        final String name = "META-INF/services/" + JsonProvider.class.getName();
-        try {
-            Enumeration<URL> configs;
-            if (tccl == null) {
-                configs = ClassLoader.getSystemResources(name);
-            } else {
-                configs = tccl.getResources(name);
+        // try to load provider specified via system property
+        final String className = System.getProperty(JsonProvider.class.getName());
+        if (className != null) {
+            try {
+                return JsonProvider.class.cast(tccl.loadClass(className.trim()).newInstance());
+            } catch (final Exception e) {
+                throw new JsonException("Specified provider as system property can't be loaded: " + className, e);
             }
-
-            if (configs.hasMoreElements()) {
-                InputStream in = null;
-                BufferedReader r = null;
-                final List<String> names = new ArrayList<String>();
-                try {
-                    in = configs.nextElement().openStream();
-                    r = new BufferedReader(new InputStreamReader(in, "utf-8"));
-                    String l;
-                    while ((l = r.readLine()) != null) {
-                        if (l.startsWith("#")) {
-                            continue;
-                        }
-                        return JsonProvider.class.cast(tccl.loadClass(l).newInstance());
-                    }
-                } catch (final IOException x) {
-                    // no-op
-                } finally {
-                    try {
-                        if (r != null) {
-                            r.close();
-                        }
-                    } catch (final IOException y) {
-                        // no-op
-                    }
-                    try {
-                        if (in != null) {
-                            in.close();
-                        }
-                    } catch (final IOException y) {
-                        // no-op
-                    }
-                }
-            }
-        } catch (final Exception ex) {
-            // no-op
         }
 
+        // try to load via ServiceLoader (as registered in META-INF/services)
+        Iterator<JsonProvider> providers = ServiceLoader.load(JsonProvider.class).iterator();
+        if (providers.hasNext()) {
+            return providers.next();
+        }
+
+        // try to load to default provider
         try {
-            final Class<?> clazz = tccl.loadClass(DEFAULT_PROVIDER);
-            return JsonProvider.class.cast(clazz.newInstance());
+            return JsonProvider.class.cast(tccl.loadClass(DEFAULT_PROVIDER).newInstance());
         } catch (final Throwable cnfe) {
             throw new JsonException(DEFAULT_PROVIDER + " not found", cnfe);
         }