-
Enhancement
-
Resolution: Obsolete
-
Major
-
None
-
6.0.1.Final
-
None
Currently, org.infinispan.util.ModuleProperties.resolveModuleLifecycles(...) uses a ServiceLoader to directly load ModuleLifecycle instances. However, if a jar exists on the classpath containing a META-INF/services/org.infinispan.lifecycle.ModuleLifecycle file, but the class name contained within cannot be loaded, due to, for example, a dependency jar being missing, then the whole resolveModuleLifecycles(...) method chokes due to a ServiceConfigurationError. For example, if infinispan-query is on the classpath, but hibernate-search is not, Infinispan is unusable.
I can see 2 ways to fix this:
1. Use the iterator directly instead of the enhanced for-loop, and catch and handle the SCE:
e.g.
Iterator<ModuleLifecycle> lifecycles = ServiceLoader.load(ModuleLifecycle.class, classLoader); while (lifecycles.hasNext()) { try { ModuleLifecycle lifecycle = lifecycles.next(); // This can throw SCE result.add(lifecycle); } catch (ServiceConfigurationError e) { // Log error } }
2. Introduce a ModuleLifecycleProvider abstraction - that won't throw an SCE. The ServiceLoader spec actually recommends this:
"The provider class is typically not the entire provider itself but rather a proxy which contains enough information to decide whether the provider is able to satisfy a particular request together with code that can create the actual provider on demand."
In the end, this would look something like:
for (ModuleLifecycleFactory factory: ServiceLoader.load(ModuleLifecycleFactory.class, classLoader)) { if (factory.isEnabled()) { // returns true if create method will not throw SCE ModuleLifecycle lifecycle = factory.createModuleLifecycle(); result.add(lifecycle); } }
- relates to
-
ISPN-15446 Remove ModuleProperties
- Resolved