From 1ce387fa145935d5d7c098d686eb520c7ced86d9 Mon Sep 17 00:00:00 2001 From: javasabr Date: Sat, 17 Jan 2026 18:07:59 +0100 Subject: [PATCH 1/3] update README.md --- README.md | 157 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index ac110b90..45f0ad91 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,77 @@ -# License # +# RLib -Please see the file called LICENSE. +A modular Java utility library providing common utilities for classpath scanning, runtime compilation, logging, networking, mail, collections, concurrency, and more. -## How to use for java 21+ +[![Build Status](https://github.com/JavaSaBr/RLib/actions/workflows/develop.yml/badge.svg)](https://github.com/JavaSaBr/RLib/actions) -#### Gradle +## Requirements + +- Java 21+ +- Gradle 9.1+ (wrapper included) +- Docker (for running Testcontainers-based tests) + +## Modules + +| Module | Description | +|--------|-------------| +| `rlib-common` | Core utilities and common functionality | +| `rlib-collections` | Extended collection implementations | +| `rlib-compiler` | Runtime Java source compilation API | +| `rlib-concurrent` | Concurrency utilities and helpers | +| `rlib-classpath` | Classpath scanning and class discovery | +| `rlib-functions` | Functional interfaces and utilities | +| `rlib-geometry` | Geometry utilities | +| `rlib-io` | I/O utilities | +| `rlib-reference` | Reference utilities | +| `rlib-reusable` | Object pooling and reusable resources | +| `rlib-logger-api` | Logging API | +| `rlib-logger-impl` | Default logger implementation | +| `rlib-logger-slf4j` | SLF4J logger bridge | +| `rlib-network` | Reactive network API (client/server) | +| `rlib-mail` | Email sending utilities | +| `rlib-testcontainers` | Test utilities including Fake SMTP container | +| `rlib-fx` | JavaFX utilities | +| `rlib-plugin-system` | Plugin system framework | + +## Installation + +### Gradle ```groovy repositories { maven { - url "https://gitlab.com/api/v4/projects/37512056/packages/maven" + url "https://gitlab.com/api/v4/projects/37512056/packages/maven" } } ext { - rlibVersion = "10.0.alpha10" + rlibVersion = "10.0.alpha10" } dependencies { - implementation "javasabr.rlib:rlib-common:$rlibVersion" - implementation "javasabr.rlib:rlib-collections:$rlibVersion" - implementation "javasabr.rlib:rlib-compiler:$rlibVersion" - implementation "javasabr.rlib:rlib-concurrent:$rlibVersion" - implementation "javasabr.rlib:rlib-geometry:$rlibVersion" - implementation "javasabr.rlib:rlib-logger-api:$rlibVersion" - implementation "javasabr.rlib:rlib-logger-slf4j:$rlibVersion" - implementation "javasabr.rlib:rlib-plugin-system:$rlibVersion" - implementation "javasabr.rlib:rlib-reference:$rlibVersion" - implementation "javasabr.rlib:rlib-reusable:$rlibVersion" - implementation "javasabr.rlib:rlib-fx:$rlibVersion" - implementation "javasabr.rlib:rlib-network:$rlibVersion" - implementation "javasabr.rlib:rlib-mail:$rlibVersion" - implementation "javasabr.rlib:rlib-testcontainers:$rlibVersion" + implementation "javasabr.rlib:rlib-common:$rlibVersion" + implementation "javasabr.rlib:rlib-collections:$rlibVersion" + implementation "javasabr.rlib:rlib-compiler:$rlibVersion" + implementation "javasabr.rlib:rlib-concurrent:$rlibVersion" + implementation "javasabr.rlib:rlib-geometry:$rlibVersion" + implementation "javasabr.rlib:rlib-logger-api:$rlibVersion" + implementation "javasabr.rlib:rlib-logger-slf4j:$rlibVersion" + implementation "javasabr.rlib:rlib-plugin-system:$rlibVersion" + implementation "javasabr.rlib:rlib-reference:$rlibVersion" + implementation "javasabr.rlib:rlib-reusable:$rlibVersion" + implementation "javasabr.rlib:rlib-fx:$rlibVersion" + implementation "javasabr.rlib:rlib-network:$rlibVersion" + implementation "javasabr.rlib:rlib-mail:$rlibVersion" + implementation "javasabr.rlib:rlib-testcontainers:$rlibVersion" } ``` -## Most interesting parts: - -### Fake SMTP Server - -```java -var container = new FakeSMTPTestContainer() - .withSmtpPassword("pwd") - .withSmtpUser("test_user"); - -container.start(); -container.waitForReadyState(); - -// sending emails to this server - -// checking API -var count = container.getEmailCountFrom("from@test.com"); - -// clearing API -container.deleteEmails(); -``` +## Usage Examples ### Classpath Scanner API +Scan classpath to discover classes implementing interfaces or extending base classes: + ```java var scanner = ClassPathScannerFactory.newDefaultScanner(); scanner.setUseSystemClasspath(true); @@ -69,6 +83,8 @@ var inherited = scanner.findInherited(AbstractArray.class); ### Compiler API +Compile Java source code at runtime: + ```java var javaSource = getClass().getResource("/java/source/TestCompileJavaSource.java"); @@ -76,14 +92,14 @@ var compiler = CompilerFactory.newDefaultCompiler(); var compiled = compiler.compile(javaSource.toURI()); var instance = ClassUtils.newInstance(compiled[0]); -var method = instance - .getClass() - .getMethod("makeString"); -var result = method.invoke(instance); +var method = instance.getClass().getMethod("makeString"); +var result = method.invoke(instance); ``` ### Logger API +Flexible logging with lazy evaluation and configurable log levels: + ```java // getting logger by class/name var logger = LoggerManager.getLogger(getClass()); @@ -93,7 +109,7 @@ LoggerLevel.DEBUG.setEnabled(true); logger.debug("Simple message"); logger.debug(5, (val) -> "Lazy message with 5: " + val); -logger.debug(5, "Lazy message with 5:%d"::formated); +logger.debug(5, "Lazy message with 5:%d"::formatted); logger.debug(5, 10D, (val1, val2) -> "Lazy message with 5: " + val1 + " and 10: " + val2); logger.debug(5, 10D, "Lazy message with 5:%d and 10:%d"::formatted); @@ -106,6 +122,8 @@ logger.setEnabled(LoggerLevel.DEBUG, true); ### Mail Sender +Send emails synchronously or asynchronously: + ```java var config = MailSenderConfig .builder() @@ -128,15 +146,15 @@ var javaxConfig = JavaxMailSender.JavaxMailSenderConfig var sender = new JavaxMailSender(config, javaxConfig); -sender.send("to@test.com","Test Subject","Content"); +sender.send("to@test.com", "Test Subject", "Content"); sender - .sendAsync("to@test.com","Test Subject","Content") + .sendAsync("to@test.com", "Test Subject", "Content") .thenAccept(aVoid -> System.out.println("done!")); ``` ### Network API -#### Simple String Echo Server/Client +Reactive network communication with simple client/server setup: ```java var serverNetwork = NetworkFactory.newStringDataServerNetwork(); @@ -155,8 +173,49 @@ var clientNetwork = NetworkFactory.newStringDataClientNetwork(); clientNetwork .connected(serverAddress) .doOnNext(connection -> IntStream - .range(10,100) + .range(10, 100) .forEach(length -> connection.send(new StringWritablePacket(StringUtils.generate(length))))) .flatMapMany(Connection::receivedEvents) .subscribe(event -> System.out.println("Received from server: " + event.packet.getData())); ``` + +### Fake SMTP Server (for testing) + +Use a containerized fake SMTP server for integration tests: + +```java +var container = new FakeSMTPTestContainer() + .withSmtpPassword("pwd") + .withSmtpUser("test_user"); + +container.start(); +container.waitForReadyState(); + +// sending emails to this server + +// checking API +var count = container.getEmailCountFrom("from@test.com"); + +// clearing API +container.deleteEmails(); +``` + +## Building + +```bash +# Full build with tests +./gradlew clean build + +# Build specific module +./gradlew :rlib-common:build + +# Run tests only +./gradlew test + +# Skip tests +./gradlew clean build -x test +``` + +## License + +Please see the file called [LICENSE](LICENSE). From bd71df4aadb61f389f9154895c6f5303375a5c53 Mon Sep 17 00:00:00 2001 From: javasabr Date: Sat, 17 Jan 2026 18:18:30 +0100 Subject: [PATCH 2/3] update README.md --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/README.md b/README.md index 45f0ad91..f91e42fe 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,88 @@ var count = container.getEmailCountFrom("from@test.com"); container.deleteEmails(); ``` +### Collections API + +Extended collections with dictionaries (maps) and arrays optimized for specific use cases: + +```java +// Mutable dictionary (map) with object keys +var dictionary = DictionaryFactory.mutableRefToRefDictionary(); +dictionary.put("key1", "value1"); +dictionary.put("key2", "value2"); + +var value = dictionary.get("key1"); + +// Thread-safe dictionary with stamped lock +var lockableDictionary = DictionaryFactory.stampedLockBasedRefToRefDictionary(); +var stamp = lockableDictionary.readLock(); +try { + lockableDictionary.put("key", "value"); +} finally { + lockableDictionary.readUnlock(stamp) +} + +// Primitive key dictionaries (no boxing overhead) +var intToRefDictionary = DictionaryFactory.mutableIntToRefDictionary(); +intToRefDictionary.put(1, "value1"); + +var longToRefDictionary = DictionaryFactory.mutableLongToRefDictionary(); +longToRefDictionary.put(100L, "value2"); + +// Mutable arrays with type safety +var array = ArrayFactory.mutableArray(String.class); +array.add("element1"); +array.add("element2"); + +// Thread-safe copy-on-write array +var cowArray = ArrayFactory.copyOnModifyArray(String.class); + +// Stamped lock based thread-safe array +var lockableArray = ArrayFactory.stampedLockBasedArray(String.class); +``` + +### Object Pooling + +Reusable object pools for reducing GC pressure: + +```java +// Create a pool for reusable objects +var pool = PoolFactory.newReusablePool(MyReusableObject.class); + +// Take an object from pool (or create new if empty) +var obj = pool.take(); + +// Use the object... + +// Return to pool for reuse +pool.put(obj); + +// Thread-safe pool +var lockablePool = PoolFactory.newLockBasePool(MyObject.class); +``` + +### Plugin System + +Dynamic plugin loading and management: + +```java +var pluginSystem = PluginSystemFactory.newBasePluginSystem(); +pluginSystem.configureAppVersion(new Version("1.0.0")); +pluginSystem.configureEmbeddedPluginPath(Paths.get("plugins/")); + +// Async plugin loading +pluginSystem + .preLoad(ForkJoinPool.commonPool()) + .thenCompose(system -> system.initialize(ForkJoinPool.commonPool())) + .toCompletableFuture() + .join(); + +// Access extension points +var extensionPoint = pluginSystem + .extensionPointManager() + .getExtensionPoint(MyExtension.class); +``` + ## Building ```bash From 2cfcd546af3dcfbb139b86639da345e8d8916e8e Mon Sep 17 00:00:00 2001 From: Aliaksandr Brui Date: Sat, 17 Jan 2026 18:25:12 +0100 Subject: [PATCH 3/3] Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f91e42fe..c3e338c5 100644 --- a/README.md +++ b/README.md @@ -214,11 +214,11 @@ var value = dictionary.get("key1"); // Thread-safe dictionary with stamped lock var lockableDictionary = DictionaryFactory.stampedLockBasedRefToRefDictionary(); -var stamp = lockableDictionary.readLock(); +var stamp = lockableDictionary.writeLock(); try { lockableDictionary.put("key", "value"); } finally { - lockableDictionary.readUnlock(stamp) + lockableDictionary.writeUnlock(stamp); } // Primitive key dictionaries (no boxing overhead)