Java › Class Loading & Bytecode Verification
How does the ServiceLoader mechanism (java.util.ServiceLoader) provide a standardized way to discover and load implementations at runtime without hardcoding class names, and how does it relate to class loading?
IntermediateAnswer
ServiceLoader implements the Service Provider Interface (SPI) pattern: a service interface is defined, implementations are registered by listing their fully-qualified class name in a META-INF/services/ file named after the interface (or via a `provides...with` declaration in module-info.java under JPMS), and ServiceLoader.load(MyService.class) discovers and instantiates all registered implementations found on the classpath/module path at runtime -- this relies on the underlying class loading mechanism to actually resolve and instantiate each discovered implementation class, providing a clean decoupling between an interface's consumers and its concrete implementations.
// META-INF/services/com.example.PaymentProcessor (file content, one implementation class name per line)
// com.example.impl.StripeProcessor
// com.example.impl.PayPalProcessor
ServiceLoader<PaymentProcessor> loader = ServiceLoader.load(PaymentProcessor.class);
for (PaymentProcessor processor : loader) {
System.out.println("Found processor: " + processor.getClass().getName());
}Real-world example The JDBC 4.0+ driver auto-registration mechanism uses ServiceLoader internally to automatically discover and register any JDBC driver JAR present on the classpath, eliminating the need for the older explicit Class.forName() driver-registration call entirely.