Thanks, that is a great presentation! Regards, Steffen
On Wed, Jan 28, 2026 at 8:59 AM Remi Forax <[email protected]> wrote: > > 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: > > Tier 1: Type Specialization: Most specific generic match wins, applying the > same scrutiny and rules currently used for existing static overloaded method > resolution. > Tier 2: Physical Locality: Provider in the same file (.jar/.class) as the > caller wins. > Tier 3: Loader Proximity: Nearest ClassLoader in the delegation path wins. > Tier 4: Modular Topology: Internal > Explicit > java.base > Transitive > > Automatic. > 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? >
