Hello, Alex Buckley has a nice presentation about how to use modules and services. [1]
And you can then binds the services using jlink. regards, Rémi [1] https://www.youtube.com/watch?v=RjVjm4uuMvc > From: "Steffen Yount" <[email protected]> > To: "amber-dev" <[email protected]> > Sent: Wednesday, January 28, 2026 1:28:40 AM > Subject: Proposal: Static Service Traits—Enhancing Java’s Static Polymorphism > and ServiceLoader Facilities > The recent thread "Java Language Enhancement: Disallow access to static > members > via object references" highlights a long-standing tension in Java's handling > of > static members. While that thread seeks to further decouple instance state > from > static logic, I would like to propose moving in the opposite direction: > "doubling down" on Java’s compile-time and link-time static polymorphism. > By beefing up java.util.ServiceLoader facilities and integrating its discovery > mechanism directly into the language via Static Service Traits , we can > facilitate the "Witness Object" paradigm discussed by Brian Goetz's " growing > the java language " presentation and the algebraic "well-known interface" > model > for custom numeric types (like Float16 ) proposed in Joe Darcy's " Paths to > Support Additional Numeric Types on the Java Platform " presentation. > == Static Service Traits for Java == > I propose a system of Static Service Traits . I use the term "Trait" > advisedly: > this feature adopts a rigorous Coherence Model (inspired by systems like Rust) > to ensure that service resolution is not merely a dynamic search, but a > type-safe, deterministic binding of static capabilities to types. > 1. The service Contextual Keyword > We introduce service as a contextual modifier for interface declarations. > Marking an interface as a service identifies it as a "service type" with a > contract for static capabilities and a high-performance service provider > registry. > 2. Static Implementations and Extension Methods > * Static Implementations: > * In Interface Headers: interface MyTrait implements ServiceX<T> . > Methods are > fulfilled as static . > * In Class Headers: class MyClass implements static Numeric<Float16> . > Methods > are implemented as static on the class. Existing signature rules > prevent a > method from being both a static and an instance implementation > simultaneously. > * Static Extension Methods: Desugared at the call site. myInstance.method() > becomes MyClass.method(myInstance) . Notably, if myInstance is null , it > desugars to MyClass.method(null) without an immediate > NullPointerException . > * Ergonomic Aliases: To simplify signatures, we introduce private nested > static > type aliases This and Super (e.g., static This add(This a, This b) ). > 3. Operational Mechanics & Link-Time Integration > A ServiceLoader Controller is integrated into the JVM’s class-loading > pipeline. > During class definition, the Controller eagerly extracts all relevant metadata > to populate the Static Service Provider Registry, including: > * Header-level static implements and implements declarations. > * Service binding descriptors from module-info.class . > * META-INF/services/ provider-configuration files. > Hierarchical Precedence Resolution: To ensure deterministic binding, the > Controller resolves call sites to their most specific service provider via a > waterfall dispatch model: > 1. Tier 1: Type Specialization: Most specific generic match wins , > applying the > same scrutiny and rules currently used for existing static overloaded > method > resolution. > 2. Tier 2: Physical Locality: Provider in the same file (.jar/.class) as > the > caller wins. > 3. Tier 3: Loader Proximity: Nearest ClassLoader in the delegation path > wins. > 4. Tier 4: Modular Topology: Internal > Explicit > java.base > Transitive > > Automatic . > 5. Tier 5: Sequential Order: Final tie-breaker via Classpath order. > 4. Coherence, The Orphan Rule, and Quarantining > To achieve the type-safety of a trait system, we enforce an adapted Orphan > Rule > : A module (or package on the classpath) must own either the service interface > or the target type to define an implementation. > * Coherence Enforcement: Violations in modular code trigger a > LinkageError . > * Behavioral Continuity: Violations in classpath code trigger a load-time > warning and the provider is quarantined from the Static Registry. To ensure > continuity, quarantined providers remain accessible via existing > java.util.ServiceLoader API calls , protecting legacy iteration-based > discovery > while ensuring the integrity of the new link-time dispatch. > 5. Performance and AOT Considerations > This model transforms ServiceLoader into a link-time resolver. JIT compilers > can > treat service calls as direct invokestatic instructions, enabling aggressive > optimization. This is highly compatible with Project Leyden and GraalVM , as > precedence can be "baked" into the binary during AOT compilation. > Conclusion > By transitioning ServiceLoader to a link-time resolver, we provide a > type-safe, > high-performance path for algebraic types and witness-based generics. This > allows Java to "grow" through libraries—fulfilling the goals of both Darcy and > Goetz—while maintaining the performance and stability characteristics of the > modern JVM. > Thoughts?
