Modules

modules2ServiceLoaderSpi

Path
pkg15modules/modules2ServiceLoaderSpi.java
Package
pkg15modules
Study order
2
Run
Single-file source launch
Command
java pkg15modules/modules2ServiceLoaderSpi.java

There is no in-browser runner. This is the file from the curriculum, unchanged.

pkg15modules/modules2ServiceLoaderSpi.java
1package pkg15modules;2 3import java.util.List;4import java.util.ServiceLoader;5 6/*7 * modules2ServiceLoaderSpi.java8 * -----------------------------9 * ServiceLoader (SPI): discover implementations of an interface at runtime.10 *11 * DEFINITION:12 *   SPI (Service Provider Interface) lets a library find implementations without13 *   hard-coding classes. Register providers in META-INF/services/<interface-name>14 *   or via module provides/uses in module-info.java.15 *16 * KEY POINTS:17 *   - ServiceLoader.load(Encoder.class) returns all registered implementations.18 *   - JPMS: module provides com.example.Encoder with com.example.UpperEncoder.19 *   - Classpath SPI: file META-INF/services/com.example.Encoder lists impl classes.20 *   - This demo uses in-process providers (no META-INF) to stay single-file runnable.21 */22public class modules2ServiceLoaderSpi {23 24  interface Encoder {25    String encode(String input);26    String name();27  }28 29  static class UpperEncoder implements Encoder {30    public String encode(String s) { return s.toUpperCase(); }31    public String name() { return "upper"; }32  }33 34  static class ReverseEncoder implements Encoder {35    public String encode(String s) { return new StringBuilder(s).reverse().toString(); }36    public String name() { return "reverse"; }37  }38 39  /** Manual SPI registry for single-file demo (production uses META-INF or JPMS). */40  static List<Encoder> loadEncoders() {41    return List.of(new UpperEncoder(), new ReverseEncoder());42  }43 44  public static void main(String[] args) {45    String text = "hello spi";46    System.out.println("Input: " + text);47 48  // In-process demo49    for (Encoder enc : loadEncoders())50      System.out.printf("  [%s] -> %s%n", enc.name(), enc.encode(text));51 52    // Real ServiceLoader (works when META-INF/services is present on classpath)53    System.out.println("\nServiceLoader discovery (may be empty in single-file mode):");54    ServiceLoader<Encoder> sl = ServiceLoader.load(Encoder.class);55    int count = 0;56    for (Encoder enc : sl) {57      System.out.printf("  discovered [%s] -> %s%n", enc.name(), enc.encode(text));58      count++;59    }60    if (count == 0)61      System.out.println("  (none — add META-INF/services/pkg15modules.modules2ServiceLoaderSpi$Encoder)");62 63    System.out.println("\nFor a full SPI + JPMS demo run: cd pkg15modules/spi-demo && mvn -q exec:java");64  }65}