druvu-lib-loader

A type-safe component loading system built on top of Java’s ServiceLoader mechanism.

View on GitHub


Overview

druvu-lib-loader provides dependency injection and singleton management through factories, with particular suitability for Java Platform Module System (JPMS) applications. It wraps Java’s native ServiceLoader with additional type safety and lifecycle management.


Quick Example

Here’s a real-world example showing how to create a pluggable accounting book loader:

1. Define your API interface, with a static load factory method:

public interface AccBook {
    String id();
    List<Account> accounts();

    // Convenience factory — discovers the implementation via ServiceLoader
    static AccBook load(Path path) {
        return ComponentLoader.load(AccBook.class,
            Dependencies.of(Path.class, path));
    }
}

2. Implement ComponentFactory in your implementation module:

public class GnucashBookFactory implements ComponentFactory<AccBook> {
    @Override
    public AccBook createComponent(Dependencies dependencies) {
        var path = dependencies.getOptionalDependency(Path.class)
            .orElseThrow(() -> new IllegalArgumentException(
                "Path dependency required"));
        return new GnucashAccBook(path);
    }

    @Override
    public Class<? extends AccBook> type() {
        return AccBook.class;
    }
}

3. Register the factory:

For non-JPMS, create META-INF/services/com.druvu.lib.loader.ComponentFactory:

com.myapp.gnucash.io.GnucashBookFactory

For JPMS, add to module-info.java:

provides com.druvu.lib.loader.ComponentFactory
    with com.myapp.gnucash.io.GnucashBookFactory;

4. Use it:

AccBook book = AccBook.load(Paths.get("/path/to/file.xml"));

Core Loaders

Loader Purpose
ComponentLoader Single implementation; fails if multiple exist
MultiComponentLoader All implementations; returns empty list if none found
SingletonLoader Application-wide services with two-phase initialization

When multiple implementations are the point — a plugin system, an exporter per format — the same pattern flips around:

// Every registered factory receives the same Dependencies; you get all the instances
List<Exporter> exporters = MultiComponentLoader.loadAll(Exporter.class, deps);

Installation

Requirements: Java 21+

Maven:

<dependency>
    <groupId>com.druvu</groupId>
    <artifactId>druvu-lib-loader</artifactId>
    <version>1.1.0</version>
</dependency>

Gradle:

implementation 'com.druvu:druvu-lib-loader:1.1.0'

Design Principles

  • Thread-safe synchronization on target classes
  • Fail-fast exception throwing
  • Type-keyed dependencies — compile-time key/value typing, runtime resolution
  • Immutable dependency containers

License

Apache License 2.0



Back to top

Copyright © 2026 druvu.com. All rights reserved.

This site uses Just the Docs, a documentation theme for Jekyll.