(final String configuredImpl)
| 160 | } |
| 161 | |
| 162 | private static ServiceLoader.Provider<GrapeEngine> findProvider(final String configuredImpl) { |
| 163 | List<ServiceLoader.Provider<GrapeEngine>> providers; |
| 164 | try { |
| 165 | ClassLoader grapeClassLoader = Grape.class.getClassLoader(); |
| 166 | ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); |
| 167 | |
| 168 | // Keep deterministic order while avoiding duplicate provider types when both |
| 169 | // class loaders expose the same service entry. |
| 170 | Map<String, ServiceLoader.Provider<GrapeEngine>> discovered = new LinkedHashMap<>(); |
| 171 | ServiceLoader.load(GrapeEngine.class, grapeClassLoader).stream() |
| 172 | .forEach(p -> discovered.putIfAbsent(p.type().getName(), p)); |
| 173 | if (contextClassLoader != null && contextClassLoader != grapeClassLoader) { |
| 174 | ServiceLoader.load(GrapeEngine.class, contextClassLoader).stream() |
| 175 | .forEach(p -> discovered.putIfAbsent(p.type().getName(), p)); |
| 176 | } |
| 177 | providers = discovered.values().stream().toList(); |
| 178 | } catch (ServiceConfigurationError sce) { |
| 179 | LOGGER.log(ERROR, "Failed to discover service providers for {0}: {1}", GrapeEngine.class.getName(), sce.getMessage()); |
| 180 | return null; |
| 181 | } |
| 182 | |
| 183 | if (configuredImpl != null) { |
| 184 | for (ServiceLoader.Provider<GrapeEngine> provider : providers) { |
| 185 | if (provider.type().getName().equals(configuredImpl)) { |
| 186 | providers.stream() |
| 187 | .filter(p -> !p.type().getName().equals(configuredImpl)) |
| 188 | .forEach(p -> LOGGER.log(DEBUG, "Ignoring provider ''{0}'' (''{1}'' configured via -D{2})", |
| 189 | p.type().getName(), configuredImpl, GRAPE_IMPL_SYSTEM_PROPERTY)); |
| 190 | return provider; |
| 191 | } |
| 192 | } |
| 193 | LOGGER.log(WARNING, "Configured implementation ''{0}'' not found via service loader", configuredImpl); |
| 194 | return null; |
| 195 | } |
| 196 | |
| 197 | if (providers.size() == 1) { |
| 198 | return providers.get(0); |
| 199 | } |
| 200 | |
| 201 | if (providers.size() > 1) { |
| 202 | for (ServiceLoader.Provider<GrapeEngine> provider : providers) { |
| 203 | if (provider.type().getName().equals(DEFAULT_GRAPE_ENGINE)) { |
| 204 | providers.stream() |
| 205 | .filter(p -> !p.type().getName().equals(DEFAULT_GRAPE_ENGINE)) |
| 206 | .forEach(p -> LOGGER.log(DEBUG, "Ignoring provider ''{0}'' in favour of default ''{1}'' (set -D{2} to override)", |
| 207 | p.type().getName(), DEFAULT_GRAPE_ENGINE, GRAPE_IMPL_SYSTEM_PROPERTY)); |
| 208 | return provider; |
| 209 | } |
| 210 | } |
| 211 | // Multiple providers discovered but the default is not among them. |
| 212 | List<String> names = providers.stream().map(p -> p.type().getName()).toList(); |
| 213 | LOGGER.log(WARNING, "{0} providers discovered {1} but default ''{2}'' is not among them; set -D{3} to select one", |
| 214 | providers.size(), names, DEFAULT_GRAPE_ENGINE, GRAPE_IMPL_SYSTEM_PROPERTY); |
| 215 | } |
| 216 | |
| 217 | // No system property set: empty list means security lockdown — return null silently. |
| 218 | return null; |
| 219 | } |
no test coverage detected