diff --git a/api/src/main/java/jakarta/json/spi/JsonProvider.java b/api/src/main/java/jakarta/json/spi/JsonProvider.java index 28fe280a..8b74d617 100644 --- a/api/src/main/java/jakarta/json/spi/JsonProvider.java +++ b/api/src/main/java/jakarta/json/spi/JsonProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -107,6 +107,34 @@ protected JsonProvider() { * @return a JSON provider */ public static JsonProvider provider() { + return provider(null); + } + + /** + * Creates a JSON provider object. + * + * Implementation discovery consists of following steps: + *
    + *
  1. If the system property {@value #JSONP_PROVIDER_FACTORY} exists, + * then its value is assumed to be the provider factory class. + * This phase of the look up enables per-JVM override of the JsonProvider implementation.
  2. + *
  3. The provider is loaded using the {@link ServiceLoader#load(Class)} method. When 'providerClassName' + * is not null, it will return the instance having the same class qualified name if exists. This + * is useful when more than one JsonProvider is loaded by the {@link ServiceLoader#load(Class)}.
  4. + *
  5. If all the steps above fail, then the rest of the look up is unspecified. That said, + * the recommended behavior is to simply look for some hard-coded platform default Jakarta + * JSON Processing implementation. This phase of the look up is so that a platform can have + * its own Jakarta JSON Processing implementation as the last resort.
  6. + *
+ * Users are recommended to cache the result of this method. + * + * @see ServiceLoader + * @param providerClassName The name of the class to be found from the {@link ServiceLoader#load(Class)}. + * @return a JSON provider + * + * @since 2.2.0 + */ + public static JsonProvider provider(String providerClassName) { LOG.log(Level.FINE, "Checking system property {0}", JSONP_PROVIDER_FACTORY); final String factoryClassName = System.getSecurityManager() != null ? AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty(JSONP_PROVIDER_FACTORY)) @@ -121,11 +149,13 @@ public static JsonProvider provider() { LOG.log(Level.FINE, "Checking ServiceLoader"); ServiceLoader loader = ServiceLoader.load(JsonProvider.class); Iterator it = loader.iterator(); - if (it.hasNext()) { + while (it.hasNext()) { JsonProvider provider = it.next(); - LOG.log(Level.FINE, "ServiceLoader loading Facility used; returning object [{0}]", - provider.getClass().getName()); - return provider; + if (providerClassName == null || provider.getClass().getName().equals(providerClassName)) { + LOG.log(Level.FINE, "ServiceLoader loading Facility used; returning object [{0}]", + provider.getClass().getName()); + return provider; + } } // handling OSGi (specific default)