Skip to content

Latest commit

 

History

History
247 lines (186 loc) · 13.2 KB

File metadata and controls

247 lines (186 loc) · 13.2 KB

Autonomous Logic Commons Java

GitHub release (latest by date) javadoc GitHub Workflow Status (branch) GitHub

Common Java functionality. The implementations in this library are intended to solve simple problems in simple ways.

Usage

Gradle:

implementation 'com.autonomouslogic.commons:commons-java:version'

Maven:

<dependency>
  <groupId>com.autonomouslogic.commons</groupId>
  <artifactId>commons-java</artifactId>
  <version>version</version>
</dependency>

CachedSupplier

Wraps a Supplier and caches its result, so the underlying logic runs only once. Useful for expensive operations like opening database connections or loading large datasets.

Supplier<DatabaseConnection> supplier = () -> new DatabaseConnection();
CachedSupplier<DatabaseConnection> cached = new CachedSupplier<>(supplier);

cached.get(); // Creates connection
cached.get(); // Returns cached connection (no new creation)

Collection Utilities

ListUtil

Utilities for combining lists. Two approaches depending on your needs:

  • concat() — Combines lists into a read-only view without copying elements. Useful for iteration and searching across multiple lists as one logical sequence.

    List<String> first = List.of("a", "b");
    List<String> second = List.of("c", "d");
    List<String> combined = ListUtil.concat(first, second);  // lightweight, no copy
    combined.size();   // 4
    combined.get(2);   // "c"
  • concatCopy() — Copies all elements from multiple lists into a new ArrayList. Useful when you need a mutable list or standalone data.

    List<String> combined = ListUtil.concatCopy(first, second);  // new ArrayList with all elements
    combined.add("e");  // works, unlike concat()

Javadoc | Source

SetUtil

Utilities for combining sets.

  • mergeCopy() — Merges multiple sets into a new LinkedHashSet. Duplicates are automatically handled.

    Set<String> colors1 = Set.of("red", "blue");
    Set<String> colors2 = Set.of("blue", "green");
    Set<String> merged = SetUtil.mergeCopy(colors1, colors2);  // {red, blue, green}
  • addAll() — Adds elements from multiple sets to an existing target set (in-place).

    Set<String> existing = new HashSet<>();
    SetUtil.addAll(existing, Set.of("apple"), Set.of("banana"));

Javadoc | Source

Config

Builder-based configuration reader that parses environment variables into typed values with fallback defaults. Supports many types out-of-the-box (Integer, Boolean, Duration, URI, etc.) and file-based secret injection.

// Define configs statically
public class AppConfig {
    public static final Config<String> ENVIRONMENT = Config.<String>builder()
        .name("ENVIRONMENT")
        .type(String.class)
        .defaultValue("dev")
        .build();

    public static final Config<Integer> PORT = Config.<Integer>builder()
        .name("PORT")
        .type(Integer.class)
        .defaultValue(8080)
        .build();
}

// Read values
Optional<String> env = AppConfig.ENVIRONMENT.get();  // with default
Integer port = AppConfig.PORT.getRequired();         // throws if not set

File-based secrets: set PORT_FILE=/run/secrets/port to read from a file instead of the PORT variable directly.

ResourceUtil

Loads resources (files) from the classpath and throws clear exceptions if resources are not found. Particularly useful for loading configuration files and test fixtures, with contextual loading for organizing test data by test class.

// Load from classpath
try (var in = ResourceUtil.loadResource("/config.json")) {
    var config = new String(in.readAllBytes());
}

// Load test fixtures organized by test class
// For class com.example.MyTest, loads from /com/example/MyTest/data.json
try (var in = ResourceUtil.loadContextual(MyTest.class, "/data.json")) {
    var data = new String(in.readAllBytes());
}

Throws FileNotFoundException with the missing path if a resource doesn't exist, unlike standard Java resource loading which returns null. Two methods: loadResource() for absolute/package-relative paths, loadContextual() for paths relative to a test class's directory.

Rx3Util

RxJava 3 utilities for non-blocking async operations and stream processing.

Key methods:

  • toSingle(), toMaybe(), toCompletable() — Convert CompletionStage to RxJava types (non-blocking, unlike fromFuture)

  • retryWithDelayFlowable() — Retry streams with configurable delay and error filtering

  • orderedMerge() — Merge sorted streams while maintaining order

  • zipAllFlowable() — Zip streams until all complete (vs standard zip which stops at shortest)

  • wrapTransformerErrors() — Wrap transformer errors with context for debugging

  • windowSort() — Sort stream items within a sliding window

  • checkOrder() — Verify stream is strictly ordered, error if not

  • Javadoc

  • Source

Stopwatch

Simple stopwatch for measuring elapsed time with nanosecond precision using System.nanoTime(). Supports multiple start/stop cycles with accumulated time, useful for benchmarking and performance monitoring.

Stopwatch watch = Stopwatch.start();
doWork();
watch.stop();

System.out.println("Elapsed: " + watch.getDuration());

// Resume measuring and accumulate more time
watch.restart();
doMoreWork();
watch.stop();

System.out.println("Total: " + watch.getDuration());  // combined time from both cycles

Key methods: start() creates and starts a stopwatch, stop() accumulates time, restart() resumes measurement, getNanos() gets total nanoseconds, getDuration() gets total as Duration. Idempotent: calling stop/restart multiple times won't cause errors.

VirtualThreads

Executes I/O-bound tasks on virtual threads with bounded concurrency. Virtual threads are lightweight and can handle blocking I/O efficiently without tying up platform threads for APIs, database calls, and file operations.

Key capabilities:

  • callAll() - Execute callables/functions and collect results in submission order

    List<String> urls = List.of("https://api1.com", "https://api2.com");
    List<String> responses = VirtualThreads.callAll(urls, url -> fetchUrl(url), 2);
    // results in order: responses.get(0) is from urls.get(0)
  • runAll() - Execute runnables with bounded concurrency (no results)

    List<String> files = List.of("file1.txt", "file2.txt", "file3.txt");
    VirtualThreads.runAll(files, filename -> processFile(filename), 5);
  • isVirtual() / checkIsVirtual() - Detect if running on a virtual thread

    if (VirtualThreads.isVirtual()) {
        // Safe to block on I/O without hurting throughput
    }
  • onVirtualThread() - Execute a task on a virtual thread if not already on one

    String result = VirtualThreads.onVirtualThread(() -> blockingDatabaseCall());
  • Javadoc

  • Source

  • Oracle Virtual Threads Documentation

  • JEP 444: Virtual Threads

Other Common Libraries

Versioning

This project follows semantic versioning.

Code Style

This project follows Palantir with tabs. Automatic code formatting can be done by running ./gradlew spotlessApply.

License

This project is licensed under the MIT-0 license.

Status

Type Status
CodeClimate Maintainability
SonarCloud Maintainability Rating Code Smells
Libraries.io Libraries.io dependency status for latest release
Snyk Known Vulnerabilities
Codecov codecov
Synatype Lift link