Milesoft Commons Library (commons)
1. Overview & Purpose
The commons library is a unified, high-performance foundation library that encapsulates core utilities, multi-tenant context propagation, timezone-aware date/time holders, lightweight self-validation helpers, and fault-tolerant retry/validation workflows used across the Milesoft ecosystem.
1.1 Strategic Architecture: Lightweight & Safe Dependency Facades
To minimize transitive dependency footprints for client-facing SDKs and downstream microservices, commons features highly optimized, null-tolerant utility facades. These facades encapsulate the most frequently used patterns from popular external libraries like Google Guava and Apache Commons Lang:
Preconditions: A lightweight facade for standard sanity checks (checkNotNull,checkArgument,checkState), shielding downstream projects from Guava's complex dependency graph.StringUtils: A null-safe facade for fundamental character sequence checks (isBlank,isEmpty,equals), matching Apache Commons Lang behavior.BooleanUtils: Null-safe Boolean assertions (isTrue,isFalse, etc.).ObjectUtils: Null-safe object operations (defaultIfNull).
This strategic approach allows both lightweight client-facing SDKs and heavy internal microservices to share the exact same runtime contracts without incurring classpath pollution.
2. Installation & Status
To resolve this package from our secure Google Cloud Artifact Registry repository, configure your build.gradle as follows:
repositories {
mavenCentral()
maven { url "artifactregistry://us-west2-maven.pkg.dev/milesoft-repo/repo-maven" }
}
dependencies {
// Standard platform dependency
implementation "io.milesoft:commons:2.0.1"
}
2.1 Status
The commons library is Production-Ready and fully integrated across the Milesoft ecosystem.
3. Core Modules & Multi-Tenant Context Holders
3.1 Multi-Tenant Context Propagation (io.milesoft.actors.holders)
To guarantee secure, multi-tenant isolation, Milesoft relies on the thread-local propagation of execution contexts.
ActorHolder: Manages a ThreadLocal-boundActorcontext representing the current request's calling entity (appId,accountId, anduserId).- Standard Fallback: If no thread-bound context is present,
ActorHolderdefaults toActorConstants.ACTOR_UNKNOWN.
import io.milesoft.primitives.actor.Actor;
import io.milesoft.actors.holders.ActorHolder;
// Binding a multi-tenant actor context to the active ThreadLocal
ActorHolder.setActor(Actor.of("app-123", "account-456").withUser("user-789"));
// Retrieving the current context safely deep in the call stack
Actor currentActor = ActorHolder.getActor();
System.out.println(currentActor.appId()); // "app-123"
System.out.println(currentActor.accountId()); // "account-456"
// Best practice: Always clear thread-local state in a try-finally block!
try {
ActorHolder.setActor(myActor);
// Execute tenant-isolated business logic...
} finally {
ActorHolder.setActor(null);
}
3.2 Thread-Local Timezone Propagation (io.milesoft.temporal.holders)
Just like execution context, timezones are propagated through ThreadLocal bindings to support multi-tenant, localized date/time formatting and processing.
TimeZoneHolder: Manages a thread-boundZoneIdfor context-specific datetime formatting, defaulting dynamically to Arizona standard time (US/Arizona).
import io.milesoft.temporal.holders.TimeZoneHolder;
import java.time.ZoneId;
// Establish active user/tenant timezone
TimeZoneHolder.setTimeZone(ZoneId.of("America/New_York"));
// Retrieve thread-bound timezone
ZoneId activeZone = TimeZoneHolder.getTimeZone();
System.out.println(activeZone.getId()); // "America/New_York"
// Reset default fallback timezone globally (e.g., at application bootstrap)
TimeZoneHolder.setDefault(ZoneId.of("America/Phoenix"));
4. High-Performance Utility Suites
4.1 Null-Tolerant JSON Processing (io.milesoft.commons.json)
The platform standardizes JSON operations on Jackson, pre-configured with time/date modules and serializers tailored for UTC compliance.
ObjectMapperFactory: Instantiates clean JacksonObjectMapperinstances preconfigured withJavaTimeModuleand specific serializers forDuration,ZonedDateTime,OffsetDateTime, andOffsetTime.lenientObjectMapper(): Returns an mapper configured withDeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIESandSerializationFeature.FAIL_ON_EMPTY_BEANSdisabled.
ObjectMapperUtils: Provides rapid, null-safe conversions between Java POJOs and map containers (Map<String, Object>).
import io.milesoft.commons.json.ObjectMapperUtils;
import io.milesoft.commons.json.ObjectMapperFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
// Convert DTOs to standard JSON maps
Map<String, Object> map = ObjectMapperUtils.toMap(myDto);
// Instantiate maps back to structured POJOs
MyDto restoredDto = ObjectMapperUtils.fromMap(map, MyDto.class);
// Create custom, thread-safe lenient object mappers
ObjectMapper customMapper = ObjectMapperFactory.lenientObjectMapper();
4.2 Sophisticated Collections Operations (io.milesoft.commons.utils.CollectionUtils)
Simplifies java.util collection manipulation with clean null-safe builders and utilities.
- Null-Safe Immutability:
immutableList(List),immutableSet(Set), andimmutableMap(Map)guarantee non-null, unmodifiable containers, avoidingNullPointerExceptionand boilerplate checks. - Null-Safe Mutability:
mutableList(List),mutableSet(Set), andmutableMap(Map)safely instantiate new collections, copying source elements if present. listEqualsIgnoreOrder(list1, list2): Compares lists for equivalent elements regardless of order.randomItem(List): Retrieves a random element from a list, backed by cryptographically secure random numbers.
import io.milesoft.commons.utils.CollectionUtils;
import java.util.List;
import java.util.Set;
// Safely convert a potentially null list into an unmodifiable list
List<String> safeList = CollectionUtils.immutableList(externalInputList);
// Instantiates a new LinkedHashSet from an input set (handling null cleanly)
Set<Integer> newSet = CollectionUtils.mutableSet(sourceSet);
// Compare collections for contents equality ignoring element ordering
boolean match = CollectionUtils.listEqualsIgnoreOrder(listA, listB);
4.3 Secure Random Generation (io.milesoft.commons.utils.RandomUtils)
RandomUtils: High-security random utility utilizing a thread-local, cryptographically secureSecureRandominstance.- Random strings: Easily generates high-entropy strings for credentials, passwords, or salts.
import io.milesoft.commons.utils.RandomUtils;
boolean flag = RandomUtils.nextBoolean();
int randomNum = RandomUtils.nextInt(1, 100); // 1 inclusive to 100 exclusive
// Generate random strings for secure tokens
String numericToken = RandomUtils.nextNumeric(6); // e.g. "508314"
String alphabeticSalt = RandomUtils.nextAlphabetic(16); // e.g. "gKdJSbQpxLmsAtPw"
String securePassword = RandomUtils.nextAlphanumeric(32); // e.g. "z9Kq8P2xW1mSb7vYt9R0nK3xJ2mL4v7P"
4.4 Date & Chronological Calculations (io.milesoft.temporal.utils)
DateUtils: Features comprehensive calculation, boundary evaluation, and formatting support.isWithin: Evaluates whether a timestamp falls within chronological boundaries (or whether oneDateTimeRangefits inside another).daysApart/hoursApart: Computes the exact absolute elapsed duration between twoZonedDateTimeinstances, localized to a specified timezone.getBeginningOfWeek/getDayOfWeek: Returns theLocalDatematching the specified day (e.g., Sunday) for a timezone, taking into account timezone-specific date boundaries.
ClockUtils: Provides standard mechanisms for capturing current times or fixing clock configurations for unit test predictability.
import io.milesoft.temporal.utils.DateUtils;
import io.milesoft.temporal.utils.ClockUtils;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.Clock;
ZonedDateTime start = ZonedDateTime.parse("2026-07-20T00:00:00Z");
ZonedDateTime stop = ZonedDateTime.parse("2026-07-25T00:00:00Z");
ZonedDateTime target = ZonedDateTime.parse("2026-07-22T12:00:00Z");
// Boundary checking
boolean inside = DateUtils.isWithin(start, stop, target); // true
// Calculate absolute timezone-specific days apart
long days = DateUtils.daysApart(start, stop, ZoneId.of("America/New_York")); // 5
// Unit Testing utility: generate mock clock fixed on specific instants
Clock fixedClock = ClockUtils.getFixed(target);
ZonedDateTime now = ClockUtils.getNow(fixedClock); // Always returns target timestamp!
5. Advanced Flow & Logic Orchestrators
5.1 Fault-Tolerant Retry Loop Runner (io.milesoft.commons.utils.RetryUtils)
Encapsulates retry logic cleanly inside functional closures, avoiding noisy exception-handling loops.
RetryUtils.retryIfNecessary(maxAttempts, Supplier<RetryResult<P>>): Continually executes a functional supplier block up tomaxAttempts, checkingisFailure()andisRetriable()conditions.
import io.milesoft.commons.utils.RetryUtils;
import io.milesoft.commons.domain.RetryResult;
RetryResult<String> result = RetryUtils.retryIfNecessary(3, () -> {
try {
String response = httpClient.callExternalApi();
return RetryResult.success(response);
} catch (TransientException e) {
// Mark as failure but flag as retriable
return RetryResult.failure(true);
} catch (FatalException e) {
// Mark as failure and abort future retries immediately
return RetryResult.failure(false);
}
});
if (result.isSuccess()) {
String data = result.getPayload();
System.out.println("Succeeded: " + data);
}
5.2 Programmatic Multi-Validator Suite (io.milesoft.validation.utils)
Allows building compound pipelines of isolated, single-responsibility business validators.
Validator<I>: Functional interface exposingValidationResult validate(I item).ValidationResult: Tracks validation errors, exposingisSuccess(),isFailure(), andgetErrors().ValidationUtils.validate(item, List<Validator<I>>): Coordinates sequential execution of multiple validation policies on an object, aggregating all validation violations into a unified result.
import io.milesoft.validation.utils.ValidationUtils;
import io.milesoft.validation.domain.Validator;
import io.milesoft.validation.domain.ValidationResult;
import java.util.List;
// 1. Define custom, single-responsibility validators
Validator<UserDto> emailValidator = user -> {
ValidationResult.Builder builder = ValidationResult.builder();
if (!user.getEmail().contains("@")) {
builder.error("Email is malformed");
}
return builder.build();
};
Validator<UserDto> passwordValidator = user -> {
ValidationResult.Builder builder = ValidationResult.builder();
if (user.getPassword().length() < 8) {
builder.error("Password must be at least 8 characters");
}
return builder.build();
};
// 2. Validate DTOs sequentially and gather aggregated reports
ValidationResult result = ValidationUtils.validate(
myUser,
List.of(emailValidator, passwordValidator)
);
if (result.isFailure()) {
List<String> allErrors = result.getErrors();
System.out.println("Validation failed with: " + allErrors);
}
6. Additional Essential Utilities
The utility packages also include helper operations designed to simplify common microservice and controller tasks:
| Class | Primary Purpose | Key Methods |
|---|---|---|
CryptoUtils |
Fast SHA-256 generation & OAuth/JWK signing support. | hashSha256(String), isSha256(String), encodeForJwk(byte[]) |
WordUtils |
Grammar formatting & human-readable joiners. | plural(String, int), count(String, int), commaSeparated(List<String>) |
UrlUtils |
Null-safe HTTP/HTTPS path manipulation. | appendParam(String, String, Object), isAbsolute(String), getDomain(String) |
Base64Utils |
Safe, UTF-8 based Base64 translation. | encodeBase64(String), decodeBase64(String) |
HtmlUtils |
HTML text preparation. | newToBr(String) (transforms \n to <br>) |
PropertyUtils |
Clean, resource-based properties retrieval. | read(String) (loads classpath properties files into Properties) |
ResourceUtils |
Resource file retrieval. | read(String) (reads classpath files directly into Strings) |
StreamUtils |
Null-safe Java Stream initialization. | stream(Collection), stream(Array), parallelStream(Collection) |