claudecode4j
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 8 GitHub stars
Code Gecti
- Code scan — Scanned 11 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Java integration for Claude Code CLI. Features Virtual Thread execution, Spring Boot auto-configuration, Kafka request-reply adapters, and REST/SSE streaming endpoints.
A modern Java library for integrating with Claude Code CLI — Anthropic's agentic coding tool.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- Spring Boot Integration
- REST API
- OpenAI-Compatible API
- Anthropic-Compatible API
- Kafka Integration
- Module Structure
- Exception Handling
- Observability
- Security
- Building from Source
- Running Tests
- Contributing
- License
- Acknowledgments
Features
- Pure Java API - Clean interfaces with sealed types and records
- Virtual Threads - Efficient concurrent execution using Project Loom
- Structured Concurrency - Safe parallel process management
- Spring Boot 4 Integration - Auto-configuration, health checks, and metrics
- REST API Adapter - HTTP endpoints with SSE streaming support
- Kafka Adapter - Request-reply pattern with correlation IDs
- WebSocket Terminal - Interactive sessions with human-in-the-loop support
- MCP Server - Expose Java methods as Claude tools via Model Context Protocol
- Smart Context - Token-aware context optimization using JTokkit
- Resilience - Built-in retry with exponential backoff
- JPMS Ready - Full Java Platform Module System support
- Null-Safe - JSpecify annotations throughout
Requirements
- Java 25+
- Claude Code CLI installed (
npm install -g @anthropic-ai/claude-code) - Maven 3.9+
Installation
Maven BOM (Recommended)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-bom</artifactId>
<version>2026.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Core Library (No Spring)
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-core</artifactId>
</dependency>
Spring Boot Starter
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-spring-boot-starter</artifactId>
</dependency>
REST Adapter
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-rest-adapter</artifactId>
</dependency>
Kafka Adapter
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-kafka-adapter</artifactId>
</dependency>
WebSocket Adapter
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-websocket-adapter</artifactId>
</dependency>
MCP Server
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-mcp-server</artifactId>
</dependency>
Context Module (Token Optimization)
<dependency>
<groupId>io.github.sudoitir</groupId>
<artifactId>claudecode4j-context</artifactId>
</dependency>
Quick Start
Standalone Usage (No Spring)
import ir.sudoit.claudecode4j.api.client.ClaudeClient;
import ir.sudoit.claudecode4j.api.model.request.Prompt;
import ir.sudoit.claudecode4j.core.client.DefaultClaudeClientFactory;
// Create client using SPI
ClaudeClient client = new DefaultClaudeClientFactory().create();
// Execute a prompt
Prompt prompt = Prompt.of("Explain what this code does");
ClaudeResponse response = client.execute(prompt);
// Handle response using pattern matching
switch (response) {
case TextResponse text -> System.out.println(text.content());
case StreamResponse stream -> stream.events().forEach(System.out::println);
case ErrorResponse error -> System.err.println(error.message());
}
Async Execution
CompletableFuture<ClaudeResponse> future = client.executeAsync(prompt);
future.thenAccept(response -> {
if (response instanceof TextResponse text) {
System.out.println(text.content());
}
});
Streaming
import ir.sudoit.claudecode4j.api.model.response.StreamEvent;
import java.util.stream.Stream;
Stream<StreamEvent> events = client.stream(prompt);
events.forEach(event -> {
switch (event) {
case StreamEvent.Text text -> System.out.print(text.content());
case StreamEvent.Tool tool -> System.out.println("Tool: " + tool.name());
case StreamEvent.Result result -> System.out.println("\nDone: " + result.success());
}
});
Session Management
// Create a conversation session
ClaudeSession session = client.createSession();
// Continue conversation with context
ClaudeResponse response1 = session.send(Prompt.of("Create a Java class for User"));
ClaudeResponse response2 = session.send(Prompt.of("Add validation annotations"));
// Session maintains conversation history
session.close();
Spring Boot Integration
Configuration
claude:
code:
binary-path: /usr/local/bin/claude # Optional: auto-detected
concurrency-limit: 4 # Max concurrent executions
default-timeout: 5m # Execution timeout
dangerously-skip-permissions: false # Security flag
health:
enabled: true # Enable health indicator
cache-duration: 30s # Health check cache
metrics:
enabled: true # Enable Micrometer metrics
Auto-wired Usage
@Service
public class CodeAssistantService {
private final ClaudeClient claudeClient;
public CodeAssistantService(ClaudeClient claudeClient) {
this.claudeClient = claudeClient;
}
public String analyzeCode(String code) {
Prompt prompt = Prompt.builder()
.text("Analyze this code for potential issues:\n" + code)
.outputFormat(OutputFormat.TEXT)
.build();
ClaudeResponse response = claudeClient.execute(prompt);
return switch (response) {
case TextResponse text -> text.content();
case ErrorResponse error -> "Error: " + error.message();
default -> "Unexpected response";
};
}
}
Concurrency Limiting with AOP
@Service
public class RateLimitedService {
private final ClaudeClient claudeClient;
@ConcurrencyLimit(permits = 2) // Max 2 concurrent calls to this method
public ClaudeResponse processWithLimit(Prompt prompt) {
return claudeClient.execute(prompt);
}
}
REST API
Enable the REST adapter to expose Claude functionality via HTTP:
claude:
code:
rest:
enabled: true
base-path: /api/claude
Endpoints
| Method | Path | Description |
|---|---|---|
POST |
/api/claude/prompt |
Execute prompt synchronously |
POST |
/api/claude/prompt/async |
Execute prompt asynchronously |
POST |
/api/claude/stream |
Stream response via SSE |
GET |
/api/claude/health |
Health check |
Example Request
curl -X POST http://localhost:8080/api/claude/prompt \
-H "Content-Type: application/json" \
-d '{
"text": "Write a hello world in Rust",
"outputFormat": "TEXT",
"timeout": "PT30S"
}'
SSE Streaming
curl -N http://localhost:8080/api/claude/stream \
-H "Content-Type: application/json" \
-d '{"text": "Explain microservices architecture"}'
OpenAI-Compatible API
The REST adapter includes an OpenAI-compatible /v1/chat/completions endpoint, allowing tools and applications designed for OpenAI's API to work with Claude Code CLI.
Configuration
claude:
code:
rest:
openai:
enabled: true # Enable OpenAI-compatible endpoint (default: true)
base-path: /v1 # Base path for OpenAI endpoints (default: /v1)
Endpoints
| Method | Path | Description |
|---|---|---|
POST |
/v1/chat/completions |
OpenAI-compatible chat completions API |
Example Request
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a hello world in Rust"}
],
"max_tokens": 1000,
"temperature": 0.7,
"stream": false
}'
Streaming Example
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"messages": [
{"role": "user", "content": "Explain quantum computing"}
],
"stream": true
}'
Response Format (Non-Streaming)
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1234567890,
"model": "claude-3-5-sonnet-20241022",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello, World! in Rust:\n\nfn main() {\n println!(\"Hello, World!\");\n}"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 30,
"total_tokens": 50
}
}
Streaming Format
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1234567890,"model":"claude-3-5-sonnet-20241022","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1234567890,"model":"claude-3-5-sonnet-20241022","choices":[{"index":0,"delta":{"content": " World!"},"finish_reason":null}]}
data: [DONE]
Anthropic-Compatible API
The REST adapter also includes an Anthropic-compatible /v1/messages endpoint, following Anthropic's Messages API specification.
Configuration
claude:
code:
rest:
anthropic:
enabled: true # Enable Anthropic-compatible endpoint (default: true)
base-path: /v1 # Base path for Anthropic endpoints (default: /v1)
Endpoints
| Method | Path | Description |
|---|---|---|
POST |
/v1/messages |
Anthropic-compatible Messages API |
Example Request
curl -X POST http://localhost:8080/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: not-required" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 1000,
"system": "You are a helpful assistant.",
"messages": [
{"role": "user", "content": "Write a hello world in Rust"}
],
"stream": false
}'
Streaming Example
curl -X POST http://localhost:8080/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 1000,
"messages": [
{"role": "user", "content": "Explain reactive programming"}
],
"stream": true
}'
Response Format (Non-Streaming)
{
"id": "msg_abc123",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "Here is a hello world in Rust:\n\nfn main() {\n println!(\"Hello, World!\");\n}"
}
],
"model": "claude-3-5-sonnet-20241022",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 15,
"output_tokens": 25
}
}
Streaming Format
event: message_start
data: {"type":"message_start","message":{"id":"msg_abc123","type":"message","role":"assistant","content":[]}}
event: content_block_start
data: {"type":"content_block_start","index":0}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Here is"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":25}}
event: message_stop
data: {"type":"message_stop"}
Kafka Integration
Enable request-reply messaging over Kafka:
claude:
code:
kafka:
enabled: true
request-topic: claude-requests
reply-topic: claude-replies
group-id: claude-processor
reply-timeout: 5m
Producer (Request Side)
@Service
public class KafkaPromptService {
private final ClaudeKafkaProducer producer;
public CompletableFuture<String> sendPrompt(String text) {
return producer.sendRequest(text);
}
}
Consumer (Processing Side)
The ClaudeKafkaListener automatically:
- Consumes messages from
request-topic - Executes prompts via
ClaudeClient - Sends responses to
reply-topicwith correlation ID
Module Structure
claudecode4j/
├── claudecode4j-bom/ # Bill of Materials
├── claudecode4j-api/ # Interfaces & DTOs
│ ├── client/ # ClaudeClient, ClaudeSession
│ ├── model/ # Prompt, Response records
│ ├── exception/ # Sealed exception hierarchy
│ └── spi/ # Extension points
├── claudecode4j-core/ # Pure Java implementation
│ ├── client/ # DefaultClaudeClient
│ ├── process/ # VirtualThreadExecutor
│ ├── parser/ # StreamJsonParser
│ └── resolver/ # Binary resolvers
├── claudecode4j-context/ # Token-aware context optimization
│ ├── spi/ # TokenCounter, ContextOptimizer
│ ├── model/ # ContextBudget, ModelTokenLimits
│ ├── tokenizer/ # JTokkit implementation
│ └── optimizer/ # DefaultContextOptimizer
├── claudecode4j-spring-boot-starter/ # Spring Boot integration
│ ├── autoconfigure/ # Auto-configuration
│ ├── properties/ # ConfigurationProperties
│ ├── health/ # HealthIndicator
│ ├── metrics/ # Micrometer metrics
│ └── resilience/ # Retry with backoff
├── claudecode4j-rest-adapter/ # REST API
│ ├── controller/ # ClaudeController
│ └── dto/ # Request/Response DTOs
├── claudecode4j-kafka-adapter/ # Kafka messaging
│ ├── listener/ # Message consumer
│ ├── producer/ # Request producer
│ └── correlation/ # Correlation ID manager
├── claudecode4j-websocket-adapter/ # WebSocket terminal
│ ├── handler/ # WebSocket handler
│ ├── session/ # Session management
│ └── message/ # Sealed message types
└── claudecode4j-mcp-server/ # MCP Server support
├── annotation/ # @ClaudeTool, @ToolParam
├── registry/ # Tool discovery
└── server/ # Tool invocation
Exception Handling
All exceptions extend the sealed ClaudeException:
try {
ClaudeResponse response = client.execute(prompt);
} catch (ClaudeException e) {
switch (e) {
case ClaudeBinaryNotFoundException ex ->
log.error("Claude CLI not found: {}", ex.getMessage());
case ClaudeExecutionException ex ->
log.error("Execution failed: {}", ex.getMessage());
case ClaudeTimeoutException ex ->
log.error("Timeout after: {}", ex.getTimeout());
case ClaudeConfigurationException ex ->
log.error("Configuration error: {}", ex.getMessage());
}
}
Observability
Health Check
{
"status": "UP",
"components": {
"claudeCode": {
"status": "UP",
"details": {
"binaryPath": "/usr/local/bin/claude",
"version": "1.0.0"
}
}
}
}
Metrics (Micrometer)
| Metric | Type | Description |
|---|---|---|
claude.code.executions |
Counter | Total executions |
claude.code.executions.active |
Gauge | Currently running |
claude.code.execution.duration |
Timer | Execution time |
claude.code.errors |
Counter | Error count by type |
Security
The library includes built-in security measures:
- Input Sanitization - Prevents command injection attacks
- Concurrency Limiting - Protects against resource exhaustion
- Permission Control -
dangerously-skip-permissionsmust be explicitly enabled
Building from Source
git clone [https://github.com/sudoit/claudecode4j.git](https://github.com/sudoit/claudecode4j.git)
cd claudecode4j
mvn clean install
Running Tests
Test Profiles
# Unit tests only (default - fast, no external dependencies)
mvn test
# Integration tests (requires Docker for Testcontainers)
mvn verify -Pintegration
# All tests including E2E (requires Claude CLI installation and authentication)
mvn verify -Pall
# Run specific test class
mvn test -Dtest=ClaudeRestIntegrationTest
# Run specific test method
mvn test -Dtest=ClaudeRestIntegrationTest#shouldExecutePromptAndReturnResponse
Test Categories
- Unit Tests (
*Test.java): Fast, isolated tests with mocked dependencies - Integration Tests (
*IntegrationTest.java): Tests with real containers (Testcontainers) - E2E Tests (
*E2ETest.java): Full end-to-end tests requiring Claude CLI
Note: E2E tests should only be run manually. They require:
- Claude CLI installed:
npm install -g @anthropic-ai/claude-code - Claude CLI authenticated (run
claudeonce to authenticate)
Contributing
Contributions are welcome! Please read our Contributing Guide for details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Anthropic for Claude and Claude Code
- Spring Team for Spring Boot 4
- Project Loom for Virtual Threads
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi