From ba1531c2772656fdce30740fe25b5394f5323701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raymond=20Aug=C3=A9?= Date: Fri, 22 Jun 2018 21:00:36 +0000 Subject: [PATCH] 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 git-svn-id: https://svn.apache.org/repos/asf/geronimo/specs/trunk@1834162 13f79535-47bb-0310-9956-ffa450edef68 --- geronimo-json_1.0_spec/pom.xml | 4 + .../java/javax/json/spi/JsonProvider.java | 65 ++-------------- geronimo-json_1.1_spec/pom.xml | 4 + .../java/javax/json/spi/JsonProvider.java | 75 +++++-------------- 4 files changed, 35 insertions(+), 113 deletions(-) diff --git a/geronimo-json_1.0_spec/pom.xml b/geronimo-json_1.0_spec/pom.xml index 9e2fd0bd3..31a44a543 100644 --- a/geronimo-json_1.0_spec/pom.xml +++ b/geronimo-json_1.0_spec/pom.xml @@ -100,6 +100,10 @@ ='1.0' ]]> + diff --git a/geronimo-json_1.0_spec/src/main/java/javax/json/spi/JsonProvider.java b/geronimo-json_1.0_spec/src/main/java/javax/json/spi/JsonProvider.java index af8289153..119f8790e 100644 --- a/geronimo-json_1.0_spec/src/main/java/javax/json/spi/JsonProvider.java +++ b/geronimo-json_1.0_spec/src/main/java/javax/json/spi/JsonProvider.java @@ -28,21 +28,16 @@ import javax.json.stream.JsonGeneratorFactory; import javax.json.stream.JsonParser; import javax.json.stream.JsonParserFactory; -import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.lang.ref.WeakReference; -import java.lang.reflect.Method; -import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.Enumeration; -import java.util.List; +import java.util.Iterator; import java.util.Map; +import java.util.ServiceLoader; import java.util.WeakHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -155,17 +150,8 @@ private static JsonProvider doLoadProvider() throws JsonException { if (tccl == null) { tccl = ClassLoader.getSystemClassLoader(); } - 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 osgiProviders = (List) 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 - } + // try to load provider specified via system property final String className = System.getProperty(JsonProvider.class.getName()); if (className != null) { try { @@ -175,47 +161,13 @@ private static JsonProvider doLoadProvider() throws JsonException { } } - // 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 { - final Enumeration configs = tccl.getResources(name); - if (configs.hasMoreElements()) { - InputStream in = null; - BufferedReader r = null; - 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 providers = ServiceLoader.load(JsonProvider.class).iterator(); + if (providers.hasNext()) { + return providers.next(); } + // try to load to default provider try { return JsonProvider.class.cast(tccl.loadClass(DEFAULT_PROVIDER).newInstance()); } catch (final Throwable cnfe) { @@ -224,4 +176,3 @@ private static JsonProvider doLoadProvider() throws JsonException { } } } - diff --git a/geronimo-json_1.1_spec/pom.xml b/geronimo-json_1.1_spec/pom.xml index f04bebf88..6eca012a0 100644 --- a/geronimo-json_1.1_spec/pom.xml +++ b/geronimo-json_1.1_spec/pom.xml @@ -86,6 +86,10 @@ ='1.1,1.0' ]]> + diff --git a/geronimo-json_1.1_spec/src/main/java/javax/json/spi/JsonProvider.java b/geronimo-json_1.1_spec/src/main/java/javax/json/spi/JsonProvider.java index ab7a0a62c..9ab483801 100644 --- a/geronimo-json_1.1_spec/src/main/java/javax/json/spi/JsonProvider.java +++ b/geronimo-json_1.1_spec/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 @@ public JsonProvider run() { } 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 osgiProviders = (List) 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 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 names = new ArrayList(); - 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 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); }