Java library for fast and reliable integration with the LibreTranslate translation API. Includes synchronous/asynchronous translation, batch processing, language checks, rate limiting and circuit breaker. Built for scalability and ease of use (JDK 21+). The library is organized into modular packages, each handling specific functionalities:
com.java.vidigal.code
: Core plugin and main entry point.com.java.vidigal.code.builder
: Fluent builder for creating translation requests.com.java.vidigal.code.client
: Client interface and implementation for API communication.com.java.vidigal.code.exception
: Custom exception classes for clear error handling.com.java.vidigal.code.language
: Language management and validation.com.java.vidigal.code.request
: Data models for translation requests and responses.com.java.vidigal.code.utilities.config
: Flexible configuration management.com.java.vidigal.code.utilities.ratelimit
: Token bucket-based rate limiting.com.java.vidigal.code.test
: Comprehensive unit and integration tests.
- Synchronous and Asynchronous Translations: Supports blocking and non-blocking operations using
CompletableFuture
with virtual threads for superior concurrency. - Batch Processing: Translates multiple texts in a single API call for maximum efficiency.
- Language Validation: Validates source and target languages against a dynamic registry that can be updated from the LibreTranslate API.
- High-Performance Caching: Thread-safe cache with configurable TTL, highly efficient O(1) LRU eviction, and optional persistent storage using JSON.
- Rate Limiting: A robust token bucket algorithm to enforce API request limits and prevent
429
errors. - Retry Mechanism: Automatic retries for transient errors (HTTP 429, 500, 502, 503) with configurable exponential backoff.
- Circuit Breaker: Protects your application from repeated failures by temporarily halting requests to an unhealthy API.
- Clear Exception Handling: A modular exception hierarchy with
LibreTranslateException
andLibreTranslateApiException
for client and API errors. - Comprehensive Documentation: Javadoc for all public methods in
LibreTranslateConfig
to enhance IDE usability and developer experience.
- Purpose: The main entry point and facade for interacting with the LibreTranslate API.
- Key Methods:
translateText(String text, String targetLang)
: Translates a single text synchronously.translateTextAsync(String text, String targetLang)
: Translates a single text asynchronously.translateBatch(List<String> texts, String targetLang, String sourceLang)
: Translates a batch of texts synchronously.translateBatchAsync(List<String> texts, String targetLang, String sourceLang)
: Translates a batch of texts asynchronously.shutdown()
: Closes all underlying resources (HTTP client, thread pools, cache cleanup threads).- Javadoc: Fully documented for developer convenience.
- Purpose: Manages all HTTP communication with the LibreTranslate API.
- Features:
- Uses
java.net.http.HttpClient
with HTTP/2 support.
- Uses
- Purpose: Manages and validates language codes.
- Features:
- Pre-populated with common languages from the
Language
enum. - Supports dynamic fetching of supported languages directly from the LibreTranslate API.
- Allows adding/removing custom languages and resetting to defaults.
- Pre-populated with common languages from the
- Purpose: Constructs
TranslationRequest
objects safely. - Features:
- Fluent API for setting texts and source/target languages.
- Validates inputs to prevent invalid requests before they are sent.
- Purpose: Manages all client configuration settings.
- Features:
- Configurable API URL, auth key, timeouts, retries, rate limits.
- Fluent builder pattern with strict input validation.
- Supports loading configuration from system properties or environment variables.
- Purpose: Controls the rate of API requests to respect usage limits.
- Features:
- A thread-safe, high-performance token bucket algorithm.
- Configurable bucket capacity (requests per second) and cooldown period.
- LibreTranslateException: Base exception for client-side errors (e.g., configuration issues, interruptions).
- LibreTranslateApiException: Handles API-specific errors and includes the HTTP status code.
- Package:
com.java.vidigal.code.exception
for modularity.
- Java Version: Java 21 or later (due to the use of virtual threads and other modern features).
- Dependencies:
- Jackson (
com.fasterxml.jackson.core
) for JSON processing. - SLF4J (
org.slf4j
) for logging. - JUnit 5 and Mockito for testing.
- Jackson (
- Environment Variable: Set
LIBRETRANSLATE_API_KEY
to run the integration tests.
Add the following to your pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.java.vidigal.code</groupId>
<artifactId>libretranslate-simple-java</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<argLine>-XX:+EnableDynamicAgentLoading</argLine>
<excludes>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<!-- No excludes for integration tests -->
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<!-- Jackson for JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- SLF4J Simple Binding (for test execution) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<!-- Mockito for mocking -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito JUnit 5 extension -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Obtain an API key from LibreTranslate. The library supports both free and pro API endpoints:
- API:
https://translate.fedilab.app/translate
- API KEY:
unknown
// Remember to call shutdown() when you are done.
LibreTranslatePlugin plugin = new LibreTranslatePlugin("https://translate.fedilab.app/translate", "unknown");
try {
String result = plugin.translateText("Hello, world!", "fr");
System.out.println(result); // Output: Bonjour, le monde !
} catch (LibreTranslateException | InterruptedException e) {
e.printStackTrace();
} finally {
plugin.shutdown();
}
LibreTranslatePlugin plugin = new LibreTranslatePlugin("https://translate.fedilab.app/translate", "unknown");
try {
plugin.translateTextAsync("Hello, world!", "fr")
.thenAccept(result -> System.out.println(result)) // Output: Bonjour, le monde !
.join(); // Wait for the async task to complete
} finally {
plugin.shutdown();
}
LibreTranslatePlugin plugin = new LibreTranslatePlugin("https://translate.fedilab.app/translate", "unknown");
try {
List<String> texts = List.of("Hello", "World");
List<String> results = plugin.translateBatch(texts, "es", "en");
System.out.println(results); // Output: [Hola, Mundo]
} catch (LibreTranslateException | InterruptedException e) {
e.printStackTrace();
} finally {
plugin.shutdown();
}
LibreTranslateConfig config = LibreTranslateConfig.builder()
.apiUrl("https://translate.fedilab.app/translate")
.authKey("unknown")
.connectionTimeout(5000)
.socketTimeout(10000)
.maxRequestsPerSecond(10)
.maxRetries(3)
.enableRetry(true)
.cacheTtlMillis(3_600_000) // 1 hour
.build();
LibreTranslateConfig plugin = new LibreTranslateConfig(config);
// ... use the plugin ...
plugin.shutdown();
Load configuration automatically from system properties or environment variables.
// Requires LIBRETRANSLATE_API_URL and LIBRETRANSLATE_AUTH_KEY to be set
LibreTranslateConfig config = LibreTranslateConfig.fromProperties();
LibreTranslateConfig plugin = new LibreTranslateConfig(config);
// ... use the plugin ...
plugin.shutdown();
Example environment variables:
export LIBRETRANSLATE_API_URL="https://translate.fedilab.app/translate"
export LIBRETRANSLATE_AUTH_KEY="unknown"
System properties use the prefix libretranslate.
(e.g., libretranslate.api.url
). Environment variables use uppercase with underscores (e.g., LIBRETRANSLATE_API_URL
).
The library includes a comprehensive test suite under src/test/java/com/java/vidigal/code/test
.
-
Unit Tests (fast, no network required):
mvn test
-
Integration Tests (requires a live API key):
# Set your API key first export LIBRETRANSLATE_API_KEY="unknown" mvn test -Pintegration-tests
Option | Description | Default |
---|---|---|
apiUrl |
LibreTranslate API endpoint URL | None (required) |
apiKey |
API authentication key | None (required) |
connectionTimeout |
HTTP connection timeout (ms) | 5000 |
socketTimeout |
HTTP socket timeout (ms) | 10000 |
maxRequestsPerSecond |
Maximum API requests per second for rate limiting | 10 |
maxRetries |
Maximum retry attempts for transient errors | 3 |
rateLimitCooldown |
Rate limiter cooldown period (ms) | 5000 |
enableRetry |
Enable/disable retries for transient errors | true |
closedThreadAuto |
To enable auto-closure | false |
cacheTtlMillis |
Cache entry Time-To-Live (ms) | 3,600,000 (1 hour) |
cleanupIntervalMillis |
Cache cleanup interval (ms) | 1,800,000 (30 mins) |
trackInstances |
Auto-shutdown via JVM hook | false |
Warning: Use trackInstances
with caution in managed environments (e.g., Spring Boot, Jakarta EE), as it may conflict with the container's lifecycle. Prefer manual plugin.shutdown()
in such cases.
- Shutdown: Always call
plugin.shutdown()
to release resources like thread pools and prevent memory leaks, especially in long-running applications. - Virtual Threads: The use of Java 21 virtual threads makes this library highly scalable for I/O-bound tasks like API calls.
Contributions are welcome! Please submit issues or pull requests to the project repository. Ensure your code follows the existing style, includes tests, and updates documentation as needed.
This library is licensed under the MIT License. See the LICENSE file for more details.
- Creator: Kauan Vidigal
- Translation API: LibreTranslate
- Contributions: Contributions are welcome! Feel free to fork the repository, open an issue, or submit a pull request for improvements or new features.